練全流程拆解:從預(yù)訓(xùn)練到對齊的工程實(shí)踐指南)
大模型訓(xùn)練這個(gè)話題最近兩年已經(jīng)被聊爛了但大多數(shù)文章要么停在“原理科普”的層面要么一頭扎進(jìn)某個(gè)框架的API里出不來。作為一個(gè)從預(yù)訓(xùn)練跑到對齊全流程踩過坑的開發(fā)者我越來越覺得大模型訓(xùn)練真正難的不是某個(gè)具體技術(shù)而是你腦子里有沒有一張完整的地圖預(yù)訓(xùn)練在解決什么問題微調(diào)在解決什么問題對齊又在解決什么問題。只有把這三個(gè)階段的全貌看清楚了你讀代碼、調(diào)參數(shù)、看loss曲線時(shí)才知道自己到底在干什么。這篇東西寫給準(zhǔn)備上手或正在上手的程序員不堆概念只講人話值得收藏備用。1. 先建立全景大模型訓(xùn)練這個(gè)“三步走”到底在干嘛1.1 三個(gè)階段的本質(zhì)分工很多朋友第一次接觸大模型訓(xùn)練時(shí)容易把預(yù)訓(xùn)練、微調(diào)、對齊當(dāng)成三個(gè)遞進(jìn)的“技術(shù)版本”以為第二階段比第一階段高級(jí)。其實(shí)不是它們是三個(gè)完全不同層次的問題。預(yù)訓(xùn)練的本質(zhì)是“語言能力啟蒙”。模型在這個(gè)階段吃下海量文本學(xué)習(xí)詞的分布、句子的銜接、世界的常識(shí)與推理模式。這個(gè)階段出來的是一個(gè)“通才”它懂語言但不太會(huì)“聊天”——你問它問題它大概率會(huì)順著概率往下續(xù)寫而不是像助手一樣回答你。這是自回歸語言模型的天性。微調(diào)通常特指SFT監(jiān)督微調(diào)的本質(zhì)是“行為塑造”。我們給模型看大量“指令-標(biāo)準(zhǔn)回答”的樣本讓它從“會(huì)說話的百科全書”變成“會(huì)聽話的助手”。這個(gè)階段訓(xùn)練的是一種格式化的交互能力模型學(xué)會(huì)在遇到用戶輸入時(shí)先理解指令再組織符合預(yù)期的回答。換句話說微調(diào)教的是“怎么做答”不教“應(yīng)該做什么”。對齊則是在解決價(jià)值觀和安全問題。模型能力越強(qiáng)風(fēng)險(xiǎn)越大——它能寫出煽動(dòng)性文章、能教人做危險(xiǎn)的事情這不是因?yàn)樗皦摹倍且驗(yàn)樗疤珪?huì)順著概率說話”。對齊階段要通過人類反饋、偏好學(xué)習(xí)等手段把模型的輸出拉回“有用、誠實(shí)、無害”的軌道上來。1.2 數(shù)據(jù)、算力與成本的三級(jí)跳三個(gè)階段最直觀的差異體現(xiàn)在數(shù)據(jù)量和算力需求上這也是讓很多初次接觸的人震驚的地方。先說預(yù)訓(xùn)練。這個(gè)階段消耗的是“TB級(jí)”的文本數(shù)據(jù)以目前常見的規(guī)??磧?yōu)質(zhì)大模型基本都要在數(shù)萬億token上訓(xùn)練。數(shù)千張GPU卡跑上幾個(gè)月是常態(tài)成本以千萬甚至億為單位計(jì)算。這也是為什么預(yù)訓(xùn)練基本只有大廠或頭部研究機(jī)構(gòu)玩得起普通人很難參與。到了微調(diào)階段數(shù)據(jù)量級(jí)驟降為“幾萬到幾十萬條指令”。因?yàn)镾FT只看重指令質(zhì)量與覆蓋面不追求數(shù)據(jù)規(guī)模。算力需求同樣大幅下降一張高顯存顯卡或者幾張小卡拼起來就能跑中小尺寸模型的微調(diào)。這也是個(gè)人開發(fā)者、中小企業(yè)進(jìn)入大模型領(lǐng)域的主要入口。對齊階段的數(shù)據(jù)量更少通常在“幾萬到十幾萬條偏好對”的級(jí)別但它的成本反而更復(fù)雜。因?yàn)閿?shù)據(jù)不是從網(wǎng)上抓的而是需要人工標(biāo)注、評(píng)估人員打分、甚至反復(fù)迭代采樣生成的。這部分的人力成本往往被低估。1.3 順序不能亂但也別把三個(gè)階段理解成完全孤立為什么必須是這個(gè)順序原因在于“能力地基”與“行為裝飾”的關(guān)系。預(yù)訓(xùn)練決定了模型的“知識(shí)上限”和“語言智力”。如果模型本身的語言能力不夠你給它再好的指令數(shù)據(jù)它也學(xué)不會(huì)復(fù)雜推理反過來一個(gè)能力很強(qiáng)的預(yù)訓(xùn)練模型即使微調(diào)數(shù)據(jù)很少也能表現(xiàn)出不錯(cuò)的對話水平。因?yàn)榈鬃銐驈?qiáng)微調(diào)更像是在“給已有能力加個(gè)調(diào)用開關(guān)”。對齊則是建立在微調(diào)之上的“價(jià)值觀塑形”。你可以先微調(diào)再對齊但不能跳過微調(diào)直接對齊。原因很樸素對齊需要模型已經(jīng)具備較高的指令遵循能力否則獎(jiǎng)勵(lì)模型給出的信號(hào)沒有意義。不過三個(gè)階段也不是徹底割裂的。實(shí)踐中常會(huì)遇到“災(zāi)難性遺忘”問題微調(diào)階段可能會(huì)忘掉預(yù)訓(xùn)練學(xué)會(huì)的部分知識(shí)對齊階段又可能把微調(diào)學(xué)會(huì)的格式?jīng)_淡。所以現(xiàn)在很多做法是在三者之間反復(fù)穿插訓(xùn)練而不是機(jī)械地一站到底。理解這一點(diǎn)你才能真正明白為什么開源模型的訓(xùn)練日志里經(jīng)常會(huì)出現(xiàn)幾個(gè)階段的混合配置。2. 預(yù)訓(xùn)練讓模型學(xué)會(huì)“說人話”2.1 一次只干一件事next token prediction預(yù)訓(xùn)練這個(gè)階段看起來復(fù)雜實(shí)際上模型的任務(wù)只有一個(gè)給定前文預(yù)測下一個(gè)詞。我常跟朋友開玩笑說這是世界上最簡單的任務(wù)也是世界上最難的任務(wù)——簡單在于目標(biāo)函數(shù)只有一個(gè)交叉熵難在于你要讓模型在數(shù)萬億token上學(xué)到足以支撐通用能力的統(tǒng)計(jì)規(guī)律。具體到訓(xùn)練過程模型把一段文本切開用前面的token預(yù)測后面的token然后計(jì)算預(yù)測分布與真實(shí)token之間的交叉熵?fù)p失反向傳播更新參數(shù)。你可能會(huì)問這么樸素的訓(xùn)練目標(biāo)為什么能學(xué)出推理、代碼、多語言能力答案就在數(shù)據(jù)的規(guī)模和模型的容量上。當(dāng)參數(shù)規(guī)模足夠大、訓(xùn)練數(shù)據(jù)足夠多時(shí)模型內(nèi)部會(huì)自發(fā)涌現(xiàn)出許多中間表征比如語法結(jié)構(gòu)、實(shí)體關(guān)系、甚至某種程度的邏輯鏈。這就是所謂的“涌現(xiàn)能力”它不是被誰設(shè)計(jì)出來的而是統(tǒng)計(jì)學(xué)習(xí)在超大規(guī)模下的副產(chǎn)品。2.2 預(yù)訓(xùn)練數(shù)據(jù)工程細(xì)節(jié)全在清洗和配比預(yù)訓(xùn)練階段模型架構(gòu)和訓(xùn)練技巧其實(shí)高度同質(zhì)化真正拉開差距的是數(shù)據(jù)這也是我強(qiáng)烈建議每個(gè)入行者至少了解一遍的地方。數(shù)據(jù)工程首先是從海量原始文本里去除“垃圾”去重包括段落級(jí)、文檔級(jí)、模糊去重、過濾低質(zhì)量內(nèi)容、剔除敏感與有害信息。常見做法是用一個(gè)現(xiàn)成的小模型給數(shù)據(jù)打分然后按分?jǐn)?shù)閾值過濾或者用perplexity困惑度指標(biāo)篩掉過于雜亂或過于重復(fù)的文本。這個(gè)步驟聽起來簡單實(shí)際做起來會(huì)發(fā)現(xiàn)大量邊界情況比如網(wǎng)頁里的導(dǎo)航文本、亂碼轉(zhuǎn)碼、多語言混排都會(huì)干擾模型學(xué)習(xí)。除了清洗配比也很關(guān)鍵。通用文本、代碼、數(shù)學(xué)、多語言數(shù)據(jù)的比例直接決定模型的能力偏向。代碼比例調(diào)高模型的邏輯推理和指令遵循能力通常會(huì)更好數(shù)學(xué)數(shù)據(jù)多一點(diǎn)數(shù)理能力更強(qiáng)但可能擠占通用知識(shí)空間。這個(gè)比例沒有標(biāo)準(zhǔn)答案需要反復(fù)做小規(guī)模實(shí)驗(yàn)來驗(yàn)證趨勢。Tokenizer分詞器同樣容易被忽略。一個(gè)好的詞表應(yīng)該用BPEByte Pair Encoding等算法在目標(biāo)語料上訓(xùn)練詞表大小一般在3萬到10萬之間。詞表太小會(huì)讓序列變長、訓(xùn)練效率下降詞表太大會(huì)讓embedding矩陣巨大顯存占用飆升。很多人只關(guān)注模型參數(shù)量卻忘了詞表大小對顯存的實(shí)打?qū)嵱绊戇@是一個(gè)非常典型的工程坑。2.3 訓(xùn)練離不開的工程參數(shù)學(xué)習(xí)率、混合精度與顯存預(yù)訓(xùn)練階段你每天跟GPU顯存和訓(xùn)練穩(wěn)定性較勁。這里把最核心的幾個(gè)工程點(diǎn)列出來每一個(gè)都是在真實(shí)訓(xùn)練中反復(fù)被驗(yàn)證過的。第一學(xué)習(xí)率調(diào)度。大模型訓(xùn)練幾乎都采用“warmup 余弦退火”的調(diào)度方式。前幾千步學(xué)習(xí)率從極小值線性升到峰值然后再按余弦曲線緩慢降到接近零。warmup的意義在于讓優(yōu)化器尤其是Adam中的二階動(dòng)量估計(jì)先穩(wěn)定下來避免前期大步長導(dǎo)致loss炸掉。峰值學(xué)習(xí)率通常落在1e-4到3e-4之間具體數(shù)值取決于模型規(guī)模、batch size以及優(yōu)化器設(shè)置。第二混合精度訓(xùn)練?,F(xiàn)在主流做法是BF16bfloat16。相比FP16BF16的指數(shù)位和FP32一致極大避免了訓(xùn)練中常見的溢出問題。雖然尾數(shù)位少了但在梯度更新中通常夠用。配合動(dòng)態(tài)損失縮放loss scaling在FP16里很常見但在BF16下基本不需要。第三顯存估算。這里給你一個(gè)粗算方式對于一個(gè)7B參數(shù)的模型BF16權(quán)重占14GBAdam優(yōu)化器狀態(tài)一階矩二階矩權(quán)重約占42GB梯度占14GB再加上激活值和臨時(shí)變量單卡顯存低于80GB基本跑不動(dòng)全參數(shù)預(yù)訓(xùn)練。這也是為什么預(yù)訓(xùn)練階段離不開ZeRO零冗余優(yōu)化器或FSDP完全分片數(shù)據(jù)并行這類并行策略。它們把權(quán)重、梯度和優(yōu)化器狀態(tài)切分到多張卡上從而讓集群顯存被充分利用。2.4 訓(xùn)練中看什么指標(biāo)loss、perplexity與基準(zhǔn)測試預(yù)訓(xùn)練不是“跑完就完事”你要持續(xù)盯著幾個(gè)指標(biāo)來判斷訓(xùn)練狀態(tài)。最基礎(chǔ)的是訓(xùn)練集loss下降曲線。正常情況下loss應(yīng)該穩(wěn)步下降如果出現(xiàn)平臺(tái)期很久不動(dòng)就要檢查數(shù)據(jù)質(zhì)量或?qū)W習(xí)率。其次是驗(yàn)證集perplexity困惑度。它衡量模型對文本的預(yù)測能力越低越好。不過perplexity下降不代表綜合能力一定提升所以業(yè)界普遍會(huì)在訓(xùn)練中途定期跑一批通用評(píng)測集比如語言理解、常識(shí)推理、數(shù)學(xué)、代碼生成等基準(zhǔn)測試。預(yù)訓(xùn)練階段做這些評(píng)測不是為了“刷榜”而是判斷模型在各項(xiàng)能力上是否均衡發(fā)展。我習(xí)慣同時(shí)跟蹤梯度范數(shù)gradient norm。梯度范數(shù)如果出現(xiàn)突然的尖峰通常意味著遇到了異常batch需要調(diào)低學(xué)習(xí)率或者加大梯度裁剪閾值。梯度裁剪在大模型訓(xùn)練中幾乎是標(biāo)配常見做法是設(shè)定一個(gè)最大值比如1.0超出即按比例縮放。3. 微調(diào)SFT把通才變成職業(yè)選手3.1 SFT真正訓(xùn)練的是什么很多人誤以為微調(diào)是給模型“灌輸知識(shí)”。這個(gè)理解是錯(cuò)的。微調(diào)使用的數(shù)據(jù)量很小知識(shí)容量的提升極其有限它的真正作用是教會(huì)模型“如何按指令組織回答”。舉個(gè)例子預(yù)訓(xùn)練模型拿到一句“給我寫一封請假郵件”時(shí)它可能會(huì)接著續(xù)寫一堆可能性但不會(huì)給你一封結(jié)構(gòu)完整的郵件。經(jīng)過微調(diào)后模型看到同樣的問題會(huì)先寫稱呼、再寫正文、最后落款署名。這就是行為格式化。SFT的數(shù)據(jù)格式通常是“用戶指令-助手回復(fù)”配對數(shù)據(jù)組織形式可以是單輪問答也可以是多輪對話。多輪對話數(shù)據(jù)還需要包含系統(tǒng)提示、角色標(biāo)記等特殊token讓模型學(xué)會(huì)區(qū)分哪些是用戶說的、哪些是助手說的。在實(shí)踐中我發(fā)現(xiàn)多輪數(shù)據(jù)比例太低會(huì)導(dǎo)致模型在長對話中“角色錯(cuò)亂”比如突然替用戶回答問題。3.2 指令數(shù)據(jù)量不重要質(zhì)和覆蓋度才重要SFT階段最影響效果的不是模型結(jié)構(gòu)而是指令數(shù)據(jù)本身。我見過不少人拿著5萬條隨機(jī)抓取的指令數(shù)據(jù)去微調(diào)結(jié)果效果不如別人精心整理的5000條。這個(gè)行業(yè)對數(shù)據(jù)質(zhì)量的重視程度遠(yuǎn)超你的想象。高質(zhì)量的指令數(shù)據(jù)需要滿足幾個(gè)條件。一是多樣性覆蓋寫作、代碼、數(shù)學(xué)、總結(jié)、翻譯、問答等不同任務(wù)每個(gè)任務(wù)的句式表達(dá)也要多種多樣。二是難度梯度既有簡單指令也有需要多步推理的復(fù)雜指令這樣才能逼模型學(xué)到深層的任務(wù)理解。三是格式規(guī)范每條數(shù)據(jù)的指令描述清晰期望回答完整且無重復(fù)內(nèi)容。很多開源數(shù)據(jù)集的通病是“風(fēng)格單一”比如寫出來的回答總是“首先……其次……最后……”這種結(jié)構(gòu)。模型會(huì)學(xué)到這種模板腔調(diào)這是SFT里最讓人頭疼的“中國式學(xué)生腔”問題。解決方式是在數(shù)據(jù)里刻意混入不同文風(fēng)的回答并加入一定比例的對比樣本讓模型知道同一個(gè)問題可以有多種得體回答。3.3 全量微調(diào)與LoRA/QLoRA怎么選微調(diào)階段擺在開發(fā)者面前的第一道選擇題是全量微調(diào)還是參數(shù)高效微調(diào)。全量微調(diào)Full Fine-tuning會(huì)更新模型所有參數(shù)效果上限最高但對顯存和算力要求也最高而且會(huì)產(chǎn)生一份完整的新模型權(quán)重存儲(chǔ)和分發(fā)成本都不低。LoRA低秩適配是目前最主流的折中方案它凍結(jié)原始權(quán)重在每層注入低秩矩陣來近似參數(shù)更新。實(shí)踐里L(fēng)oRA的rank值取8到64之間模型效果就能接近全量微調(diào)而可訓(xùn)練參數(shù)量通常只有總參數(shù)量的0.1%到1%。rank不是越大越好過大的rank反而容易在小數(shù)據(jù)上過擬合。QLoRA是LoRA的進(jìn)一步升級(jí)它在加載模型時(shí)先做4位量化通常用NF4格式再在量化后的模型上掛LoRA。這樣一張24GB顯存的消費(fèi)級(jí)顯卡可以微調(diào)7B乃至13B級(jí)別的模型極大降低了個(gè)人開發(fā)者的大門門檻。代價(jià)是訓(xùn)練速度會(huì)變慢、數(shù)值精度略降但對絕大多數(shù)應(yīng)用來說精度損失可以接受。3.4 讓LoRA訓(xùn)練穩(wěn)定的幾個(gè)參數(shù)如果你決定用LoRA做SFT下面這份配置是我驗(yàn)證過很多次、相對穩(wěn)妥的起點(diǎn)。model_name_or_path: /models/base_model train_file: /data/sft_data.jsonl block_size: 2048 per_device_train_batch_size: 2 gradient_accumulation_steps: 8 learning_rate: 2e-5 num_train_epochs: 3 lr_scheduler_type: cosine warmup_ratio: 0.03 bf16: true gradient_checkpointing: true這里有幾個(gè)參數(shù)值得展開解釋。block_size是序列長度當(dāng)前主流模型支持長上下文但訓(xùn)練時(shí)序列越長顯存占用越大2048是一個(gè)兼顧效果與顯存的常見起點(diǎn)。per_device_train_batch_size設(shè)成2配合gradient_accumulation_steps8等效batch size是16。這個(gè)規(guī)模既能保證梯度估計(jì)相對穩(wěn)定又不會(huì)讓顯存爆炸。learning_rate設(shè)在2e-5比預(yù)訓(xùn)練階段的峰值學(xué)習(xí)率低一個(gè)數(shù)量級(jí)因?yàn)槲⒄{(diào)只是在小范圍內(nèi)調(diào)整參數(shù)步子太大容易破壞底座能力。num_train_epochs通常2到4之間就有明顯效果訓(xùn)練超過5輪很容易過擬合——模型開始“背誦”訓(xùn)練集而不是學(xué)習(xí)行為模式。還需要注意LoRA的target_modules選擇。一般建議覆蓋attention層的q_proj、k_proj、v_proj、o_proj如果任務(wù)需要更強(qiáng)的語義理解能力可以把MLP層的gate_proj、up_proj、down_proj也加進(jìn)來。加更多模塊意味著更多可訓(xùn)練參數(shù)訓(xùn)練更慢但上限更高需要自己權(quán)衡。4. 對齊讓模型從“聰明”到“可信任”4.1 為什么要對齊有用、誠實(shí)、無害如果你把預(yù)訓(xùn)練和微調(diào)做完模型已經(jīng)能正常對話了看起來萬事大吉。但真正放到用戶面前時(shí)問題會(huì)暴露得很徹底。預(yù)訓(xùn)練模型的知識(shí)庫里包含著大量“不適宜直接輸出”的內(nèi)容而它本身對“什么該說、什么不該說”毫無概念。對齊的目的就是讓模型輸出符合三個(gè)原則有用Helpful、誠實(shí)Honest、無害Harmless。用大白話解釋用戶問什么盡量給出有信息量的回答不知道的事情要承認(rèn)不知道而不是一本正經(jīng)地編造危險(xiǎn)或有害的內(nèi)容要拒絕或引導(dǎo)到安全方向。這三點(diǎn)聽上去樸素但做起來極難。因?yàn)椤盁o害”和“有用”在某些場景下是沖突的——用戶問一個(gè)危險(xiǎn)品的配制方法模型既要拒絕又最好能解釋為什么不能提供這里面充滿了權(quán)衡。4.2 RLHF三體訓(xùn)練與PPO更新對齊的主流方案仍然是基于人類反饋的強(qiáng)化學(xué)習(xí)RLHF它的架構(gòu)里通常有三個(gè)模型協(xié)同工作策略模型就是我們要對齊的大模型、參考模型凍結(jié)的初始版本、獎(jiǎng)勵(lì)模型負(fù)責(zé)給回答打分。RLHF的落地分三步。第一步用人類標(biāo)注員在多個(gè)候選回答之間選優(yōu)形成一個(gè)“偏好對”數(shù)據(jù)集比如回答A比回答B(yǎng)好。第二步在這個(gè)偏好數(shù)據(jù)上訓(xùn)練獎(jiǎng)勵(lì)模型讓它學(xué)會(huì)預(yù)測“哪條回答更符合人類偏好”。第三步用PPO近端策略優(yōu)化算法更新策略模型讓模型輸出的回答盡可能獲得高獎(jiǎng)勵(lì)分同時(shí)通過KL散度懲罰把模型行為限制在參考模型附近防止模型為了拿獎(jiǎng)勵(lì)而說出偏離原本風(fēng)格的怪話。PPO更新的核心公式這里不展開了你只需要記住兩個(gè)關(guān)鍵點(diǎn)一、策略模型在訓(xùn)練中會(huì)不斷采樣新回答然后拿獎(jiǎng)勵(lì)模型打分作為訓(xùn)練信號(hào)二、KL散度懲罰的系數(shù)不能太大也不能太小——太大模型學(xué)不動(dòng)太小模型會(huì)犧牲質(zhì)量去鉆獎(jiǎng)勵(lì)模型的空子。這個(gè)系數(shù)在實(shí)際訓(xùn)練里調(diào)得人頭大我經(jīng)歷過的最夸張一次是獎(jiǎng)勵(lì)分?jǐn)?shù)一路上漲但人工評(píng)估的文本質(zhì)量肉眼可見地變差——典型的獎(jiǎng)勵(lì)欺詐。4.3 DPO更輕量的對齊路線RLHF雖然效果好但工程復(fù)雜度實(shí)在感人四個(gè)模型同時(shí)加載、采樣和訓(xùn)練交替進(jìn)行、超參數(shù)多、故障率高。所以這幾年DPO直接偏好優(yōu)化越來越受歡迎。DPO的核心理念非常聰明既然獎(jiǎng)勵(lì)模型要在偏好對上學(xué)打分那我干脆把“獎(jiǎng)勵(lì)模型能表達(dá)的分”直接隱式地表達(dá)在策略模型的更新目標(biāo)里用偏好對數(shù)據(jù)直接引導(dǎo)策略模型調(diào)整。這樣訓(xùn)練過程就把“獎(jiǎng)勵(lì)模型訓(xùn)練”和“PPO更新”兩步合并成一步不再需要采樣生成新回答也不需要單獨(dú)維護(hù)一個(gè)龐大的獎(jiǎng)勵(lì)模型。用DPO訓(xùn)練時(shí)你只需要準(zhǔn)備偏好對數(shù)據(jù)集回答A優(yōu)于回答B(yǎng)然后用一個(gè)同時(shí)包含“策略模型輸出概率”和“參考模型輸出概率”的損失函數(shù)來更新策略模型。這個(gè)損失函數(shù)的實(shí)質(zhì)是讓模型更喜歡偏向被標(biāo)注為“好”的回答同時(shí)不要偏離參考模型太遠(yuǎn)。DPO在數(shù)據(jù)質(zhì)量好的時(shí)候效果完全可以和RLHF掰手腕但它的局限在于訓(xùn)練信號(hào)完全依賴偏好數(shù)據(jù)本身的分布數(shù)據(jù)一旦有噪聲傳播速度比RLHF快得多。4.4 對齊的代價(jià)獎(jiǎng)勵(lì)欺詐與對齊稅對齊不是免費(fèi)的午餐這里有幾個(gè)繞不開的代價(jià)。第一個(gè)是獎(jiǎng)勵(lì)欺詐reward hacking。模型非常擅長找出能讓獎(jiǎng)勵(lì)模型給高分、但實(shí)際質(zhì)量并不好的輸出模式。比如模型發(fā)現(xiàn)寫“抱歉我無法回答”能顯著避害于是它對所有問題都過度拒絕。你問它今天天氣怎么樣它也回答“抱歉我無法提供信息”。這是對齊階段最經(jīng)典的失敗模式只能靠人工評(píng)估不斷糾偏。第二個(gè)是“對齊稅”。為了降低有害性模型會(huì)變得“保守”在模棱兩可的問題上給出更簡短、更謹(jǐn)慎、甚至更無趣的回答。這在某種程度上犧牲了創(chuàng)造性和信息密度。有研究觀察到經(jīng)過強(qiáng)對齊的模型在部分創(chuàng)意寫作任務(wù)上的表現(xiàn)會(huì)出現(xiàn)輕微滑坡這就是對齊稅在起作用。第三個(gè)是數(shù)據(jù)退化的累積效應(yīng)。用模型生成的數(shù)據(jù)再去訓(xùn)練新模型時(shí)間久了后代會(huì)變得越來越“均值化”多樣性下降。這也是為什么現(xiàn)在很多團(tuán)隊(duì)開始在做對齊的同時(shí)刻意保留一部分有風(fēng)險(xiǎn)但合理的高質(zhì)量樣本防止模型變得過度唯唯諾諾。5. 踩坑實(shí)錄常見問題與排查思路5.1 一張速查表解決80%的異常下面把我在訓(xùn)練和微調(diào)過程中遇到的高頻問題整理成速查表送給準(zhǔn)備動(dòng)手的朋友?,F(xiàn)象可能原因排查方向loss不降或平臺(tái)期過長數(shù)據(jù)質(zhì)量差 / 學(xué)習(xí)率過高或過低檢查數(shù)據(jù)是否重復(fù)、清洗是否到位可視化學(xué)習(xí)率曲線loss突然飆高遇到異常batch / 學(xué)習(xí)率過大啟用梯度裁剪降低學(xué)習(xí)率檢查數(shù)據(jù)里是否有大段亂碼顯存溢出OOM序列過長 / batch過大調(diào)小block_size開gradient checkpointing用gradient accumulation生成內(nèi)容重復(fù)微調(diào)過擬合 / 數(shù)據(jù)模板單一減少訓(xùn)練輪數(shù)增加數(shù)據(jù)多樣性降低LoRA rank模型失憶忘記預(yù)訓(xùn)練知識(shí)微調(diào)輪次過多 / 學(xué)習(xí)率過大做數(shù)據(jù)重放恢復(fù)部分預(yù)訓(xùn)練數(shù)據(jù)混合訓(xùn)練降低學(xué)習(xí)率對話角色錯(cuò)亂多輪數(shù)據(jù)比例不足 / 格式錯(cuò)誤檢查特殊token增加多輪樣本比例對齊后過度拒絕偏好數(shù)據(jù)失衡 / KL系數(shù)不當(dāng)調(diào)整偏好數(shù)據(jù)降低KL懲罰減少無害樣本占比5.2 兩個(gè)典型問題的排查流程第一個(gè)案例訓(xùn)練loss前期下降正常但到第2000步開始周期性震蕩。排查時(shí)首先看學(xué)習(xí)率調(diào)度發(fā)現(xiàn)warmup結(jié)束后學(xué)習(xí)率未按預(yù)期進(jìn)入穩(wěn)定區(qū)而是處于一個(gè)過高的常數(shù)。解決辦法是把峰值學(xué)習(xí)率下調(diào)30%并在訓(xùn)練日志里加入學(xué)習(xí)率記錄項(xiàng)方便復(fù)現(xiàn)。震蕩問題消失后loss繼續(xù)平滑下降。第二個(gè)案例微調(diào)后的模型在對話中頻繁重復(fù)同一個(gè)句子。直接懷疑過擬合。查了訓(xùn)練輪次已經(jīng)跑到第8輪再檢查數(shù)據(jù)發(fā)現(xiàn)指令數(shù)據(jù)里大量回答都采用同一套固定句式。于是把訓(xùn)練輪次降到3同時(shí)抽取了2000條外部高復(fù)雜度指令混入數(shù)據(jù)問題顯著緩解。從這兩個(gè)案例可以看出排查訓(xùn)練問題最重要的不是改代碼而是先建立“數(shù)據(jù)和超參數(shù)”兩個(gè)維度的直覺。數(shù)據(jù)的問題會(huì)在訓(xùn)練曲線上表現(xiàn)出規(guī)律性超參數(shù)的問題則更傾向于全局性震蕩或發(fā)散。5.3 給程序員的日志與權(quán)重監(jiān)控建議很多朋友訓(xùn)練時(shí)只盯著loss看一旦異常就束手無策。我的建議是至少把下面幾個(gè)指標(biāo)全部打點(diǎn)記錄訓(xùn)練loss、驗(yàn)證loss、學(xué)習(xí)率、梯度范數(shù)、顯存占用、吞吐量tokens/s。這些指標(biāo)放在同一張圖表里觀察能極大縮短定位問題的時(shí)間。比如梯度范數(shù)持續(xù)升高說明優(yōu)化器正在走向不穩(wěn)定寧可降學(xué)習(xí)率也不要硬跑吞吐量突然下降大概率是數(shù)據(jù)加載環(huán)節(jié)出現(xiàn)瓶頸比如磁盤IO或預(yù)處理線程不足。這些判斷在訓(xùn)練集群上非常常見。模型權(quán)重的保存策略也值得注意。不要只保存最后一版checkpoint而是每隔一定步數(shù)保留一個(gè)副本。這樣當(dāng)某一次訓(xùn)練后期loss反彈時(shí)你可以快速回滾到一個(gè)已知良好狀態(tài)。我自己習(xí)慣每500到1000步存一次磁盤充足的情況下多存幾份成本遠(yuǎn)低于重新訓(xùn)練。另外日志一定要帶時(shí)間戳和全局步數(shù)。沒有這兩個(gè)信息你在對比多個(gè)實(shí)驗(yàn)時(shí)根本沒法定位到底是哪段代碼、哪個(gè)參數(shù)導(dǎo)致的差異。這個(gè)習(xí)慣越早養(yǎng)成越省事。最后說點(diǎn)我的個(gè)人體會(huì)。很多程序員朋友的起步路徑都是直接拿現(xiàn)成模型做推理推理很少自己動(dòng)手訓(xùn)練。但我的建議始終是抽出兩周時(shí)間哪怕用一個(gè)小規(guī)模的模型把預(yù)訓(xùn)練、微調(diào)、對齊全流程完整跑一遍。你會(huì)驚覺那些文檔里的概念全都“活”了過來。我自己第一次跑通全流程時(shí)最大的收獲不是模型效果有多好而是終于理解了loss、學(xué)習(xí)率、數(shù)據(jù)質(zhì)量、KL懲罰這些名詞在真實(shí)訓(xùn)練中是怎樣的存在。踩過幾次坑之后你再去讀任何一篇大模型論文都會(huì)比之前通透得多。所以別怕折騰動(dòng)手吧。