階指南)
我年初在整理自己技術(shù)棧的時(shí)候?qū)χ诸^那份流傳很廣的 AI 技能清單逐條核對(duì)了一遍越對(duì)越心虛。清單上列的東西我大部分都“聽過”但真要讓我講清楚原理、寫明白代碼不少地方其實(shí)是含糊的。那份清單與其說是一張知識(shí)地圖不如說是一面照妖鏡——把“我會(huì)用”和“我真會(huì)”之間的差距照得明明白白。今天我就把這份清單拆開揉碎從工程底子到模型訓(xùn)練再到系統(tǒng)設(shè)計(jì)一層層講清楚每一項(xiàng)技能到底在解決什么問題以及怎么檢驗(yàn)自己是不是真的掌握了。這份清單適合誰看如果你正在自學(xué)機(jī)器學(xué)習(xí)或者深度學(xué)習(xí)感覺書看了不少、課也刷了但一到自己動(dòng)手做項(xiàng)目就卡殼那這篇文章能幫你找到缺口。如果你已經(jīng)工作了一兩年想評(píng)估自己是不是真的夠到了“資深工程師”那條線這份拆解也能給你一個(gè)相對(duì)客觀的尺子。文章里我會(huì)把我自己在補(bǔ)技能樹時(shí)候的教訓(xùn)和踩過的坑一并寫出來有些話不太好聽但都是實(shí)話。1. 一張技能清單背后的“能力分層”邏輯大多數(shù)人第一次看到那份技能清單的時(shí)候第一反應(yīng)是東西好多無從下手。Python、NumPy、PyTorch、TensorFlow、機(jī)器學(xué)習(xí)算法、深度學(xué)習(xí)架構(gòu)、模型部署、性能優(yōu)化……密密麻麻列了一大片感覺每一項(xiàng)都得會(huì)但又不知道先學(xué)哪個(gè)、學(xué)到什么程度算“會(huì)”。我后來反復(fù)讀這份清單發(fā)現(xiàn)它并不是簡(jiǎn)單的堆砌而是有明顯分層的。如果你把這些技能按照“解決什么問題”來歸類會(huì)得到大致三個(gè)層次工程底子層包括編程語言熟練度、調(diào)試能力、版本管理、實(shí)驗(yàn)管理、代碼組織方式。這一層解決的是“能不能把腦子里的想法變成可以運(yùn)行的代碼”。模型研發(fā)層包括數(shù)據(jù)處理、模型架構(gòu)設(shè)計(jì)、訓(xùn)練技巧、評(píng)估方法、調(diào)參經(jīng)驗(yàn)。這一層解決的是“能不能讓模型在具體數(shù)據(jù)上達(dá)到預(yù)期效果”。系統(tǒng)設(shè)計(jì)層包括算力規(guī)劃、分布式訓(xùn)練、推理優(yōu)化、部署交付、監(jiān)控運(yùn)維。這一層解決的是“模型效果之外能不能在真實(shí)環(huán)境里穩(wěn)定、高效、低成本地跑起來”。這個(gè)分層邏輯非常重要因?yàn)樗鼪Q定了你應(yīng)該按什么順序去補(bǔ)技能。很多初學(xué)者最容易犯的毛病就是直接從第二層開始甚至在第二層中段開始——模型架構(gòu)還沒吃透就想上分布式訓(xùn)練Python 基礎(chǔ)還沒夯實(shí)就開始讀大模型源碼。結(jié)果就是每一層都懸空每一層都漏洞百出。我自己的體會(huì)是這三層之間是強(qiáng)依賴關(guān)系。工程底子不牢談模型研發(fā)就是空中樓閣因?yàn)槟氵B實(shí)驗(yàn)都跑不利索數(shù)據(jù)預(yù)處理都要折騰半天更別說快速迭代驗(yàn)證想法。而模型研發(fā)經(jīng)驗(yàn)不足直接跳到系統(tǒng)設(shè)計(jì)層你根本不知道哪些環(huán)節(jié)值得優(yōu)化、優(yōu)化的瓶頸在哪里只會(huì)按部就班搬工具出了問題完全抓瞎。所以拆解這份清單的正確姿勢(shì)是先搞清楚自己目前在哪個(gè)層次、每個(gè)層次里又缺哪幾項(xiàng)然后有針對(duì)性地下功夫。下面三節(jié)我逐層展開說具體每一項(xiàng)是怎么回事、怎么檢驗(yàn)、怎么補(bǔ)。2. 第一層硬底子工程能力決定你能跑多遠(yuǎn)2.1 Python 不只是“會(huì)寫”而是要寫到能“自我糾錯(cuò)”的程度技能清單里大概率第一項(xiàng)就是 Python。但你千萬別以為“學(xué)過 Python 基礎(chǔ)語法”就夠了。在實(shí)際做 AI 項(xiàng)目的時(shí)候Python 的使用深度完全不一樣——你會(huì)面對(duì)的不只是for循環(huán)和if判斷而是一套復(fù)雜的依賴管理、異常處理、對(duì)象設(shè)計(jì)、性能瓶頸分析。我這里說的“會(huì)寫”至少包括三個(gè)層次語法層列表推導(dǎo)、生成器、裝飾器、上下文管理器、*args/**kwargs這些高級(jí)特性不要求背得滾瓜爛熟但看到要能看懂寫的時(shí)候能自然地用出來。工程層會(huì)用venv或conda管理虛擬環(huán)境知道怎么鎖定依賴版本能寫結(jié)構(gòu)清晰的模塊而不是把所有代碼堆在一個(gè)文件里能在代碼里合理處理異常而不是放任程序崩潰。性能層知道什么時(shí)候用 NumPy 向量化替代原生 Python 循環(huán)能借助cProfile或line_profiler找出性能瓶頸理解 GIL 對(duì)多線程的限制并能用多進(jìn)程或異步繞開它。我在帶新人的時(shí)候經(jīng)常出一個(gè)題給你一個(gè)包含 100 萬條記錄的文件每條記錄是一個(gè) JSON 字符串要求解析后按某個(gè)字段分組統(tǒng)計(jì)限時(shí)兩分鐘實(shí)現(xiàn)。這個(gè)題從表面看考的是 JSON 解析和字典操作實(shí)際上考的是流式讀取、內(nèi)存控制、異常數(shù)據(jù)容錯(cuò)、以及統(tǒng)計(jì)邏輯的正確性。大部分沒經(jīng)過工程訓(xùn)練的新人寫出來的版本要么慢得離譜要么程序跑到一半崩掉。提示技能清單里點(diǎn)名 Python本質(zhì)上不是在考語法而是在考你“快速把想法變成可靠腳本”的能力。檢驗(yàn)標(biāo)準(zhǔn)很簡(jiǎn)單——你能不能在一個(gè)下午內(nèi)寫一個(gè)健壯、可復(fù)用、不依賴調(diào)試器反復(fù)試錯(cuò)的數(shù)據(jù)處理腳本。2.2 調(diào)試能力訓(xùn)練模型時(shí)最吃時(shí)間的不是寫代碼我在自己帶項(xiàng)目的時(shí)候發(fā)現(xiàn)一個(gè)現(xiàn)象真正消耗研發(fā)時(shí)間的往往不是模型算法本身而是在排查數(shù)據(jù)對(duì)齊錯(cuò)誤、維度不匹配、梯度爆炸、loss 為 NaN 這類問題上。這些問題的共同點(diǎn)是——代碼邏輯本身沒有語法錯(cuò)誤但運(yùn)行結(jié)果不對(duì)只能靠系統(tǒng)性調(diào)試去定位。技能清單里的“調(diào)試”指的是一種系統(tǒng)化定位問題的能力不是零散地print大法。我認(rèn)為有三件事是必須練熟的用好調(diào)試器的斷點(diǎn)與單步比如 PyCharm 的 Debug 界面或者 PDBPython 調(diào)試器。很多人學(xué) Python 很長(zhǎng)時(shí)間也沒用過真正的調(diào)試器全程print。但在追蹤復(fù)雜狀態(tài)流時(shí)斷點(diǎn)變量查看窗口的效率是print的十倍以上。構(gòu)造可復(fù)現(xiàn)的最小樣例問題出現(xiàn)時(shí)先嘗試把數(shù)據(jù)量縮到最小比如 5 個(gè)樣本把模型規(guī)??s到最小比如單層線性層逐段驗(yàn)證。如果最小樣例能復(fù)現(xiàn)就逐層排查如果不能那大概率是你真實(shí)環(huán)境里某一步數(shù)據(jù)或邏輯有問題,縮小范圍本身就是最有效的定位手段。系統(tǒng)化消除變量訓(xùn)練不收斂候選原因可能涉及學(xué)習(xí)率、初始化、數(shù)據(jù)歸一化、梯度問題等一大堆。正確的做法是每次只動(dòng)一個(gè)變量并記錄結(jié)果而不是同時(shí)改三個(gè)超參數(shù)然后盲目碰運(yùn)氣。我自己折騰深度學(xué)習(xí)這些年最珍貴的經(jīng)驗(yàn)之一就是把每一個(gè)“異?!倍籍?dāng)成一次技能升級(jí)的機(jī)會(huì)。遇到 loss 不下降別急著調(diào)學(xué)習(xí)率先自己想為什么再上工具驗(yàn)證原因。這樣積累幾輪之后你會(huì)形成一套自己的“異常處理直覺”。2.3 實(shí)驗(yàn)管理與復(fù)現(xiàn)能力AI 項(xiàng)目爛賬的重災(zāi)區(qū)技能清單里經(jīng)常會(huì)出現(xiàn)“實(shí)驗(yàn)管理”“可復(fù)現(xiàn)性”這一類看似不起眼的條目。很多人一眼掃過覺得“這也有必要列出來”直到自己在一個(gè)項(xiàng)目里同時(shí)跑了五組實(shí)驗(yàn)、改了十幾次數(shù)據(jù)增強(qiáng)策略、存了七八份模型權(quán)重最后完全想不起來哪份結(jié)果對(duì)應(yīng)哪份代碼才明白這一項(xiàng)的份量。對(duì)實(shí)驗(yàn)管理我的建議非常樸素沒有工具的時(shí)候先用目錄結(jié)構(gòu)約定。一個(gè)典型的實(shí)驗(yàn)?zāi)夸涢L(zhǎng)這樣experiments/ ├── 2025-02-01_baseline_resnet50/ │ ├── train.py │ ├── config.yaml │ ├── logs/ │ ├── checkpoints/ │ └── eval_results.json ├── 2025-02-03_augment_color_jitter/ │ └── ... └── 2025-02-05_lr_1e-3_wd_1e-4/ └── ...約定俗成的規(guī)則是每個(gè)實(shí)驗(yàn)一個(gè)獨(dú)立目錄代碼、配置、日志、權(quán)重全都放在一起目錄名包含日期和實(shí)驗(yàn)描述。在此基礎(chǔ)上再逐步引入專門的實(shí)驗(yàn)管理工具比如記錄每次運(yùn)行的超參和指標(biāo)每次運(yùn)行自動(dòng)打上版本標(biāo)簽。這套流程的價(jià)值在于它能讓你在三個(gè)月后回頭看某個(gè)實(shí)驗(yàn)結(jié)論時(shí)還能完整還原當(dāng)時(shí)的代碼、數(shù)據(jù)、參數(shù)和結(jié)果。很多人在技能上栽跟頭并非因?yàn)槟芰Σ恍卸且驗(yàn)閷?shí)驗(yàn)記錄混亂導(dǎo)致無法從過去的經(jīng)驗(yàn)中學(xué)習(xí)和迭代。數(shù)據(jù)都丟了經(jīng)驗(yàn)也就丟了。3. 第二層核心區(qū)訓(xùn)練與診斷模型的真實(shí)手感3.1 數(shù)據(jù)工程不是“跑腿”而是整個(gè)模型效果的上限技能清單里關(guān)于數(shù)據(jù)那部分可能會(huì)列數(shù)據(jù)清洗、數(shù)據(jù)增強(qiáng)、數(shù)據(jù)平衡、標(biāo)簽質(zhì)量這些。我見過不少初學(xué)者把這部分當(dāng)成“體力活”或者“預(yù)處理雜事”恨不得讓實(shí)習(xí)生去做。但我做了這么多項(xiàng)目之后越來越確信一件事模型的上限在數(shù)據(jù)里而不在模型結(jié)構(gòu)里。舉一個(gè)很常見的例子做圖像分類類別嚴(yán)重不平衡——A 類有十萬張圖B 類只有五百?gòu)?。新手?huì)直接拿原始數(shù)據(jù)去訓(xùn)練然后發(fā)現(xiàn)模型對(duì) A 類過擬合、對(duì) B 類幾乎不識(shí)別。這時(shí)候如果你只會(huì)調(diào)模型結(jié)構(gòu)、調(diào)損失函數(shù)見效慢且效果有限但如果先在數(shù)據(jù)層面做文章——對(duì) B 類做離線增強(qiáng)旋轉(zhuǎn)、裁剪、加噪聲或者采用欠采樣/過采樣結(jié)合的方式重新組織訓(xùn)練集效果往往立竿見影。我強(qiáng)調(diào)數(shù)據(jù)工程重要性還有一個(gè)原因**數(shù)據(jù)問題的排查難度遠(yuǎn)高于模型問題。**模型不收斂你可以看梯度、調(diào)學(xué)習(xí)率手段很多但如果訓(xùn)練集和驗(yàn)證集之間存在數(shù)據(jù)泄露比如同一樣本的不同擾動(dòng)被同時(shí)分到兩邊模型指標(biāo)會(huì)虛高到令人難以置信而這個(gè)隱患若沒有系統(tǒng)性的數(shù)據(jù)審查排查幾天都未必能找到。所以我的建議很直接花時(shí)間親手做一次數(shù)據(jù)清洗和增強(qiáng)流程不要全用現(xiàn)成框架糊過去。你會(huì)在那個(gè)過程里理解到什么叫數(shù)據(jù)分布、什么叫噪聲、什么叫標(biāo)簽質(zhì)量——這些理解會(huì)陪伴你走很遠(yuǎn)。3.2 訓(xùn)練診斷看懂 loss 曲線的底層含義訓(xùn)練模型這件事很多人以為就是“把數(shù)據(jù)丟進(jìn)去跑幾十個(gè) epoch 等結(jié)果”實(shí)際上真正拉開差距的是你在訓(xùn)練過程中盯著各種曲線時(shí)能不能看出問題出在哪。技能清單里的“模型訓(xùn)練”“調(diào)參技巧”核心就是這個(gè)診斷能力。我拿到一個(gè)新模型訓(xùn)練任務(wù)習(xí)慣性盯幾張曲線訓(xùn)練集 loss、驗(yàn)證集 loss、訓(xùn)練集準(zhǔn)確率、驗(yàn)證集準(zhǔn)確率、學(xué)習(xí)率變化趨勢(shì)。這幾條線放在一起能講出很多故事訓(xùn)練 loss 降不下去驗(yàn)證 loss 也跟著不降大概率是模型容量不足或數(shù)據(jù)有問題跟正則化、學(xué)習(xí)率關(guān)系不大。訓(xùn)練 loss 降得很快驗(yàn)證 loss 卻開始回升這是典型的過擬合信號(hào)這時(shí)候該動(dòng)手的是數(shù)據(jù)增強(qiáng)、dropout、權(quán)重衰減這些手段。訓(xùn)練 loss 和驗(yàn)證 loss 差距一直很大但不是驗(yàn)證在漲而是訓(xùn)練在降說明模型欠擬合或數(shù)據(jù)分布差異過大要優(yōu)先考慮模型結(jié)構(gòu)和數(shù)據(jù)處理。loss 在訓(xùn)練過程中出現(xiàn)突然的尖峰往往是數(shù)據(jù)里有壞樣本或者學(xué)習(xí)率設(shè)置下敏感參數(shù)產(chǎn)生了梯度異常。這些判斷經(jīng)驗(yàn)不是看一篇文章就能掌握的需要靠大量實(shí)驗(yàn)來積累。但有一個(gè)方法論是通用的**永遠(yuǎn)不要只看一個(gè)最終指標(biāo)要全程跟蹤訓(xùn)練過程。**最終結(jié)果只告訴你“好或不好”訓(xùn)練曲線才告訴你“為什么好、為什么不好、問題出現(xiàn)在哪個(gè)階段”。提示每次訓(xùn)練任務(wù)設(shè)置好固定的檢查點(diǎn)頻率和日志記錄格式。比如每 200 步存一條訓(xùn)練集上的損失值每個(gè) epoch 結(jié)束存一次驗(yàn)證集指標(biāo)。這個(gè)習(xí)慣會(huì)讓你自然而然獲得診斷所需的數(shù)據(jù)。3.3 消融實(shí)驗(yàn)與評(píng)估別把“跑了就完事”當(dāng)完成標(biāo)準(zhǔn)技能清單里和評(píng)估相關(guān)的能力經(jīng)常被低估。很多人覺得評(píng)估就是看準(zhǔn)確率、F1、AUC 這些數(shù)字高不高。但這些指標(biāo)背后藏著的陷阱可不少。舉一個(gè)我踩過的坑某個(gè)二分類項(xiàng)目正樣本只占 5%我訓(xùn)練完模型一看準(zhǔn)確率 95%差點(diǎn)以為自己已經(jīng)做完了。還好多看了一眼混淆矩陣才發(fā)現(xiàn)模型把幾乎所有樣本都預(yù)測(cè)成負(fù)類——95% 的準(zhǔn)確率完全靠“猜負(fù)類”猜出來的對(duì)實(shí)際業(yè)務(wù)毫無價(jià)值。這就是只看單一指標(biāo)的下場(chǎng)。正確的評(píng)估動(dòng)作至少應(yīng)該包括看混淆矩陣而不僅是準(zhǔn)確率。針對(duì)不同子集分別評(píng)估比如按樣本來源、按類別、按數(shù)值分布區(qū)間切分看模型在哪些子集上表現(xiàn)差。做消融實(shí)驗(yàn)逐個(gè)去掉某些模塊比如去掉數(shù)據(jù)增強(qiáng)、去掉預(yù)訓(xùn)練權(quán)重、換掉損失函數(shù)觀察指標(biāo)變化從而確認(rèn)每個(gè)模塊到底貢獻(xiàn)了什么。用多個(gè)隨機(jī)種子跑多次報(bào)告均值±方差而不是只跑一次就下結(jié)論。消融實(shí)驗(yàn)這一段我想單獨(dú)強(qiáng)調(diào)一下。很多人訓(xùn)練完模型就直接寫報(bào)告完全沒做過“這個(gè)模塊到底有沒有起作用”的驗(yàn)證。這會(huì)導(dǎo)致你在做下一次迭代時(shí)完全靠猜——不知道上一次的效果到底來自哪里自然也就不知道下一步該怎么改。消融實(shí)驗(yàn)的本質(zhì)是把你對(duì)模型的理解從“它有效”升級(jí)到“我知道它為什么有效”這個(gè)過程本身就是深度學(xué)習(xí)里非常珍貴的進(jìn)階臺(tái)階。4. 第三層進(jìn)階項(xiàng)系統(tǒng)設(shè)計(jì)、算力利用與性能拆解4.1 算力規(guī)劃訓(xùn)練跑不起來一半是錢的問題一半是設(shè)計(jì)的問題技能清單里常出現(xiàn)的“GPU 訓(xùn)練”“混合精度”“分布式訓(xùn)練”往深了說其實(shí)是算力規(guī)劃能力。很多人在單卡上把模型跑通了但要放到工業(yè)級(jí)規(guī)模就卡住——顯存不夠、訓(xùn)練太慢、多卡通信開銷過大。這些問題的根源往往不是缺顯卡而是缺規(guī)劃。我先說顯存規(guī)劃。訓(xùn)練一個(gè)大模型時(shí)顯存主要被四塊占用模型參數(shù)本身、優(yōu)化器狀態(tài)Adam 會(huì)額外存一階二階動(dòng)量、中間激活值、以及梯度。很多人調(diào)了幾次 batch size 調(diào)到 OOM就開始罵顯卡不夠卻沒意識(shí)到可以通過梯度檢查點(diǎn)用計(jì)算換顯存、混合精度訓(xùn)練、更細(xì)粒度的參數(shù)優(yōu)化器狀態(tài)切分來解決。再說訓(xùn)練速度。單卡訓(xùn)練一個(gè)模型要三天四卡并行按理說應(yīng)該 18 小時(shí)跑完但實(shí)際加速比往往只有 2.5 倍左右剩下 0.5 倍被通信開銷、數(shù)據(jù)加載瓶頸、不均衡負(fù)載吃掉了。這時(shí)候去排查數(shù)據(jù)管道——是不是 GPU 在空等 CPU 喂數(shù)據(jù)是不是每個(gè) step 里都做了重復(fù)的預(yù)處理——往往比換更大的機(jī)器收益更高。我見過一個(gè)項(xiàng)目團(tuán)隊(duì)嫌訓(xùn)練太慢申請(qǐng)了八卡機(jī)器結(jié)果加速比依然很差。最后排查發(fā)現(xiàn)數(shù)據(jù)加載部分是用 Python 逐張讀圖再預(yù)處理GPU 利用率長(zhǎng)期徘徊在 30%。換用數(shù)據(jù)預(yù)取和多進(jìn)程加載之后單卡利用率直接拉到 90% 以上速度翻了兩倍多根本不需要加機(jī)器。這個(gè)案例給我留下的印象很深工具鏈沒問題的時(shí)候瓶頸大概率在工程細(xì)節(jié)里。4.2 推理優(yōu)化從“模型能跑”到“服務(wù)扛得住”技能清單里除了訓(xùn)練通常還會(huì)有推理部署、模型壓縮、量化這些偏工程落地的內(nèi)容。這塊很容易被搞研究的人忽視但在實(shí)際產(chǎn)品里它常常是決定項(xiàng)目能不能上線的關(guān)鍵。我在維護(hù)一個(gè)圖像識(shí)別服務(wù)時(shí)先后遇到兩類典型問題。一是延遲不達(dá)標(biāo)模型單張推理要 300 毫秒業(yè)務(wù)要求 200 毫秒以內(nèi)。二是吞吐扛不住上線活動(dòng)流量一上來實(shí)例 CPU 打滿大量請(qǐng)求排隊(duì)超時(shí)。針對(duì)第一類問題我做了三件事把 PyTorch 模型轉(zhuǎn)成更高性能的推理后端格式、打開動(dòng)態(tài)批處理、對(duì)輸入圖像做緩存。效果非常直接單張延遲從 300 毫秒降到 120 毫秒。這中間核心的優(yōu)化原理是——推理優(yōu)化的大部分收益來自減少重復(fù)計(jì)算和更高效的算子利用而不是對(duì)模型本身的改動(dòng)。針對(duì)第二類問題我的做法是先做壓測(cè)摸清楚每實(shí)例的極限 QPS再根據(jù)預(yù)估流量定實(shí)例數(shù)量同時(shí)給客戶端加超時(shí)與熔斷邏輯。聽起來全是運(yùn)維常識(shí)但實(shí)際項(xiàng)目里能把這些做扎實(shí)的人并不多。另外量化這個(gè)技能我也想多說一句。FP32 的模型轉(zhuǎn)成 INT8 之后體積減小四倍推理速度通常能提升兩到三倍但精度往往會(huì)掉一點(diǎn)。這里面最關(guān)鍵的能力是評(píng)估量化對(duì)精度的影響而不是盲目追求速度。我的習(xí)慣是先量化再在驗(yàn)證集上完整評(píng)估如果掉點(diǎn)超過可接受范圍就采用混合量化敏感層保持高精度非敏感層用低精度。4.3 從“調(diào)包俠”到“架構(gòu)設(shè)計(jì)者”系統(tǒng)思維是最后一道坎技能清單列到最后往往會(huì)出現(xiàn)系統(tǒng)設(shè)計(jì)、架構(gòu)選型這些條目。這一層的能力和前幾層有本質(zhì)區(qū)別前幾層解決的是“某個(gè)模型怎么訓(xùn)練、怎么優(yōu)化”這一層解決的是“整個(gè) AI 系統(tǒng)怎么搭起來、模塊之間怎么銜接、出問題時(shí)怎么快速定位”。我在評(píng)估一個(gè)人的系統(tǒng)設(shè)計(jì)能力時(shí)通常會(huì)拋出這種問題現(xiàn)在要做一個(gè)圖片內(nèi)容審核系統(tǒng)數(shù)據(jù)來自多個(gè)渠道日新增百萬級(jí)圖片需要實(shí)時(shí)返回審核結(jié)果歷史數(shù)據(jù)還要支持定期回溯檢測(cè)。你會(huì)怎么設(shè)計(jì)整體架構(gòu)追問下去涉及的問題包括訓(xùn)練和推理是否分離、數(shù)據(jù)如何分層存儲(chǔ)、批處理和單條處理怎么取舍、模型更新時(shí)怎么灰度發(fā)布、抽檢和人工復(fù)核流程怎么接上。這個(gè)問題的本質(zhì)是在考察一個(gè)人能不能跳出“訓(xùn)練一個(gè)模型”的單點(diǎn)思維把模型放到一個(gè)更大的系統(tǒng)里去理解。我觀察到能答好這類問題的人往往不是記憶了什么框架而是親手經(jīng)歷過從數(shù)據(jù)到訓(xùn)練再到部署的完整鏈路——他在每個(gè)環(huán)節(jié)踩過坑知道哪些地方最容易出問題所以設(shè)計(jì)時(shí)自然就會(huì)把這些點(diǎn)考慮進(jìn)去。這一層能力的提升沒有捷徑唯一的路徑就是完整參與幾個(gè)端到端項(xiàng)目。中途會(huì)遇到很多“不在技能清單里”的問題——存儲(chǔ)選型、任務(wù)隊(duì)列、監(jiān)控告警、容災(zāi)備份——每一件都在塑造你的系統(tǒng)設(shè)計(jì)能力。5. 用“可驗(yàn)收的項(xiàng)目”代替“學(xué)過的課程”來檢驗(yàn)技能清單5.1 三個(gè)自測(cè)項(xiàng)目覆蓋從數(shù)據(jù)到部署的完整鏈路談?wù)摷寄芮鍐魏苋菀紫萑搿懊總€(gè)都會(huì)一點(diǎn)”的自欺欺人狀態(tài)。我自己定了一套自測(cè)方法不列我會(huì)什么而是拿著三個(gè)項(xiàng)目去跑跑通了才叫會(huì)。項(xiàng)目一從零訓(xùn)練一個(gè)小模型。自己找一份公開圖片數(shù)據(jù)集不用任何預(yù)訓(xùn)練權(quán)重從零搭建一個(gè)卷積神經(jīng)網(wǎng)絡(luò)訓(xùn)練到驗(yàn)證集準(zhǔn)確率超過 90%。這個(gè)過程里你必須獨(dú)立解決數(shù)據(jù)加載與歸一化、模型結(jié)構(gòu)設(shè)計(jì)、損失函數(shù)選擇、訓(xùn)練超參調(diào)整、過擬合診斷。都不用考察別的只要你能穩(wěn)定地訓(xùn)練出效果合格的模型并且能說清楚每個(gè)超參對(duì)結(jié)果的影響第一層和第二層的大部分技能就算過關(guān)了。項(xiàng)目二做一個(gè)端到端的模型服務(wù)。訓(xùn)練好一個(gè)模型之后不滿足于在 Jupyter Notebook 里跑通推理而是把它封裝成一個(gè) HTTP 服務(wù)支持外部調(diào)用并且能在 50 QPS 的壓測(cè)下保持穩(wěn)定。這個(gè)項(xiàng)目會(huì)逼你把推理優(yōu)化、服務(wù)框架、并發(fā)處理、性能監(jiān)控全過一遍。做完之后你對(duì)“模型上線”這件事的理解會(huì)完全不同。項(xiàng)目三復(fù)現(xiàn)一篇論文的核心方法。挑一篇你覺得有意思的論文不看原作者的代碼只按論文里的描述自己實(shí)現(xiàn)一遍關(guān)鍵部分盡量復(fù)現(xiàn)出接近論文報(bào)告的指標(biāo)。這個(gè)項(xiàng)目是最能檢驗(yàn)功底的——論文寫作天然會(huì)省略大量細(xì)節(jié)所有“作者默認(rèn)你懂”的地方都會(huì)成為你的攔路虎而你每跨過一個(gè)能力就長(zhǎng)一分。這三個(gè)項(xiàng)目檢驗(yàn)的能力維度不同第一個(gè)考訓(xùn)練手感第二個(gè)考工程落地第三個(gè)考研究理解力。如果都能獨(dú)立完成我認(rèn)為對(duì)應(yīng)的技能清單項(xiàng)就算真正打通了。5.2 誠(chéng)實(shí)評(píng)估你會(huì)不會(huì)“報(bào)喜不報(bào)憂”多數(shù)人的技能自測(cè)其實(shí)有一個(gè)極大的誤區(qū)——只評(píng)估“我能做到什么”不評(píng)估“我做不到什么”。比如我明明不熟悉分布式訓(xùn)練但簡(jiǎn)歷上可能還是會(huì)寫“了解分布式訓(xùn)練”因?yàn)檫@詞自己見過、概念大致能說上幾句。這種自欺欺人的后果等真正需要上分布式項(xiàng)目的時(shí)候才會(huì)暴露。我推薦一個(gè)相對(duì)有效的評(píng)估方法準(zhǔn)備一個(gè)“不會(huì)清單”。過一遍技能清單凡是不能當(dāng)場(chǎng)給出“我用它做過一個(gè)什么具體任務(wù)、遇到了什么坑、怎么解決的”這種故事的經(jīng)歷統(tǒng)一放到不會(huì)清單里。你會(huì)發(fā)現(xiàn)這個(gè)清單比“會(huì)清單”長(zhǎng)得多而這個(gè)誠(chéng)實(shí)的視角才是你制定學(xué)習(xí)計(jì)劃的最佳依據(jù)。注意面試或者寫簡(jiǎn)歷的時(shí)候誠(chéng)實(shí)是最優(yōu)策略。真正把“不會(huì)清單”補(bǔ)成“會(huì)清單”所花的時(shí)間遠(yuǎn)比你在被問到時(shí)支支吾吾要少得多。6. 補(bǔ)技能樹最常見的幾個(gè)彎路我的教訓(xùn)你未必需要全部踩一遍6.1 彎路一只讀論文不寫代碼知識(shí)全飄在空中我早年也犯過這個(gè)錯(cuò)論文讀了一堆模型架構(gòu)說得頭頭是道但一讓自己實(shí)現(xiàn)一個(gè)簡(jiǎn)單的注意力模塊手就卡在維度對(duì)不上這一步。讀論文帶來的“熟悉感”和真正寫代碼帶來的“掌握感”之間差距巨大。我現(xiàn)在給自己定了一個(gè)鐵律一篇論文如果我不打算寫代碼復(fù)現(xiàn)它那第一次讀的時(shí)候就不要花超過兩小時(shí)。寫完代碼再回頭讀第二遍你會(huì)發(fā)現(xiàn)自己真正看懂了以前完全忽略的細(xì)節(jié)。6.2 彎路二什么熱追什么技能樹變成“熱搜清單”有一段時(shí)間我特別焦慮因?yàn)楦杏X技術(shù)更迭太快今天這個(gè)框架火了明天那個(gè)模型出來了不學(xué)就好像要落后。后來我發(fā)現(xiàn)那些追熱點(diǎn)的日子里真正的能力增長(zhǎng)幾乎為零。技能清單里真正核心的東西從來沒變過——數(shù)據(jù)能力、訓(xùn)練診斷能力、工程落地能力——變來變?nèi)サ闹皇峭庠诘墓ぞ邭ぷ?。從那以后我給自己定了個(gè)規(guī)矩核心基本功用最大精力持續(xù)打磨新工具只在真正需要解決具體問題的時(shí)候才去學(xué)。6.3 彎路三低估數(shù)據(jù)工程把精力全花在調(diào)模型上我做過一個(gè)文本分類項(xiàng)目最開始模型效果一直卡在 0.88 上下我以為是模型結(jié)構(gòu)不夠復(fù)雜換了更大的模型、調(diào)了好幾輪參最多也就到 0.90。后來仔細(xì)做了一遍數(shù)據(jù)質(zhì)量分析發(fā)現(xiàn)訓(xùn)練集里有大量標(biāo)簽錯(cuò)誤的樣本光清理這一步就把它拉到了 0.94而且模型結(jié)構(gòu)完全沒有改動(dòng)。這件事讓我徹底改變了資源配置的習(xí)慣——現(xiàn)在做任何數(shù)據(jù)集相關(guān)的活兒我一定是先把數(shù)據(jù)摸透再上模型數(shù)據(jù)問題不清完不上大模型。6.4 彎路四從不復(fù)盤經(jīng)驗(yàn)散落一地最后一條彎路可能也是我最想分享的一條實(shí)驗(yàn)做了一大堆但每個(gè)項(xiàng)目做完就扔從不整理沉淀。我后來養(yǎng)成了一個(gè)習(xí)慣每個(gè)項(xiàng)目結(jié)束之后寫下三頁(yè)紙的復(fù)盤文檔內(nèi)容包括我遇到了哪些卡點(diǎn)、每個(gè)卡點(diǎn)的排查思路、最后怎么解決的、如果重來一遍哪里能更快。這些復(fù)盤文檔后來成了我最寶貴的個(gè)人知識(shí)庫(kù)每次做新項(xiàng)目翻一翻都能避開不少以前踩過的坑。技能清單這張地圖本身并不神奇真正有價(jià)值的是你拿著它一路趟過去的過程。你會(huì)發(fā)現(xiàn)自己今天看這張清單和三個(gè)月前看這張清單感受完全不同——那些原本只是名詞的東西開始有了重量變成了你腦子里有血有肉的實(shí)戰(zhàn)地圖。祝每一位路過這張清單的人都能在一年后對(duì)著它坦然地打滿勾。