00 背景知識(shí)速成-----全流程實(shí)現(xiàn)chatgpt2(預(yù)訓(xùn)練->sft->ppo)
00 背景知識(shí)速成看代碼之前先花 20 分鐘讀懂這篇這篇不是講解某個(gè)文件而是把讀這些代碼之前必須具備的背景知識(shí)集中講一遍。整份 InstructGPT 項(xiàng)目反復(fù)用到這些概念先打通它們后面的逐行筆記會(huì)順很多。如果你是零基礎(chǔ)務(wù)必按順序讀這篇如果只是忘了某個(gè)概念可以直接跳到對(duì)應(yīng)小節(jié)。目錄數(shù)據(jù)是怎么進(jìn)模型的字符 → token → id → 向量神經(jīng)網(wǎng)絡(luò)的最小零件nn.Linear、激活函數(shù)、Dropout概率與損失logits、softmax、交叉熵、log 概率、KL 散度訓(xùn)練到底在做什么前向、反向、梯度下降、epoch/batch/step張量操作速查廣播、view/reshape、transpose、gather、flatten強(qiáng)化學(xué)習(xí)一分鐘狀態(tài)、動(dòng)作、獎(jiǎng)勵(lì)、策略、價(jià)值、優(yōu)勢(shì)1. 數(shù)據(jù)是怎么進(jìn)模型的字符 → token → id → 向量1.1 為什么機(jī)器不能直接讀文字計(jì)算機(jī)只能處理數(shù)字。你好世界這串字模型是不認(rèn)識(shí)的。所以第一步是把文字切成小塊、編上號(hào)再變成向量。1.2 tokenizer分詞器干的事tokenizer 文字 → 編號(hào)的轉(zhuǎn)換器。它做的事這本書真是好看 --分詞-- [這,本,書,真,是,好,看] --查詞表-- [6821, 1726, 1210, 2682, 1878, 2619, 3554]token詞元被切出來的最小單位。中文里通常一個(gè)字或一個(gè)詞就是一個(gè) token。詞表vocab所有 token 的清單。本項(xiàng)目詞表大小 21128每個(gè) token 有個(gè)唯一編號(hào) id0~21127。id編號(hào)token 在詞表中的位置。tokenizer.encode(這本書)返回的就是一串 id。1.3 embedding嵌入干的事id 是整數(shù)但模型需要的是向量。Embedding 就是一張查表字典id6821 → 查表 → 一個(gè) 768 維的向量一堆小數(shù)nn.Embedding(vocab_size, emb_dim)內(nèi)部是一張形狀(21128, 768)的大表。id 是幾就取第幾行。取出來這行向量就是該詞的意思語義相近的詞向量也相近。這張表是訓(xùn)練學(xué)出來的——一開始是隨機(jī)數(shù)訓(xùn)練后越來越好。對(duì)比 one-hot 編碼也可以把 id 編成一個(gè)只有一位是 1 的 21128 維向量one-hot但那又稀疏又浪費(fèi)而且看不出詞與詞的相似關(guān)系。Embedding 表等于把 21128 維壓縮到 768 維還能學(xué)出語義。1.4 一句話總結(jié)數(shù)據(jù)流文字 --tokenizer-- token id 列表 --embedding-- (B, T, 768) 向量 [6821, 1726, ...] 每個(gè) token 一個(gè) 768 維向量Bbatch一次喂幾條樣本。Tseq_len一條樣本里多少個(gè) token。形狀(B, T, 768)就是整個(gè)模型世界的主語——幾乎所有操作都在這個(gè)形狀上進(jìn)進(jìn)出出。2. 神經(jīng)網(wǎng)絡(luò)的最小零件2.1 nn.Linear線性層一句乘法 加法nn.Linear(in_features,out_features)數(shù)學(xué)定義y xW? b輸入 x(..., in_features)權(quán)重 W(out_features, in_features)偏置 b(out_features,)輸出 y(..., out_features)。通俗理解給輸入的每個(gè)分量配一個(gè)權(quán)重加權(quán)求和再加個(gè)偏置得到新的一組數(shù)。它只能學(xué)線性關(guān)系所以后面必須接激活函數(shù)。2.2 激活函數(shù)讓網(wǎng)絡(luò)能彎曲如果全是線性層那多少層疊加都等于一層線性函數(shù)套線性函數(shù)還是線性學(xué)不了復(fù)雜東西。激活函數(shù)如 GELU、ReLU、sigmoid是非線性的讓每一層的輸出扭曲一下網(wǎng)絡(luò)才有表達(dá)復(fù)雜規(guī)律的能力。線性層 --GELU-- 非線性 --線性層-- 非線性 ...2.3 Dropout隨機(jī)丟一部分防過擬合訓(xùn)練時(shí)Dropout隨機(jī)把一部分神經(jīng)元的輸出置 0比如 10%剩下的值放大一點(diǎn)。效果模型不能依賴某個(gè)特定的神經(jīng)元被迫學(xué)得更平均、更魯棒這就是為什么訓(xùn)練和推理要切換模式model.train()開 dropout、model.eval()關(guān) dropout——推理時(shí)不需要隨機(jī)丟。3. 概率與損失3.1 logits打分是什么模型最后一層輸出的原始分?jǐn)?shù)可以理解成模型認(rèn)為每個(gè)詞該被選中的熱度。形狀(B, T, 21128)——每個(gè)位置對(duì)詞表 21128 個(gè)詞各打一個(gè)分。分?jǐn)?shù)是任意實(shí)數(shù)可正可負(fù)可大。它還不是概率。3.2 softmax把分?jǐn)?shù)變成概率想讓分?jǐn)?shù)之和等于 1才能當(dāng)概率用就用 softmaxprobs[i] exp(z[i]) / Σ? exp(z[j])exp是指數(shù)函數(shù)e?把任意數(shù)變成正數(shù)除以總和保證所有詞的概率加起來 1分?jǐn)?shù)越高概率越大但不是線性高分差距會(huì)被放大。數(shù)值穩(wěn)定性技巧代碼里反復(fù)出現(xiàn)z z - z.max(dim-1, keepdimTrue) # 先減每行最大值 probs softmax(z) # 結(jié)果一樣但不會(huì)溢出為什么如果 z 里有很大的數(shù)比如 1000exp(1000)直接是inf算炸。先減去最大值最大的變成 0exp(0)1安全。softmax 對(duì)每個(gè)元素同時(shí)加/減同一個(gè)常數(shù)結(jié)果不變數(shù)學(xué)上等價(jià)。3.3 交叉熵?fù)p失cross entropy衡量猜得有多不準(zhǔn)一句話模型給正確答案的概率越低損失越大。loss -log(P(正確答案))模型猜正確詞的概率是 0.9 →-log(0.9) ≈ 0.105很小損失小 ?模型猜正確詞的概率是 0.0001 →-log(0.0001) ≈ 9.2很大損失大 ?訓(xùn)練目標(biāo)就是把這個(gè)損失降到最低也就是讓正確詞的概率越來越大。為什么要 log概率是 0~1 的乘數(shù)直接最小化損失時(shí)梯度很小取-log后概率越小損失增長越猛梯度更有推動(dòng)力。另外 log 把連乘變成連加方便數(shù)學(xué)推導(dǎo)。代碼里的標(biāo)準(zhǔn)用法PyTorchF.cross_entropy(logits,labels)# logits: (N, C)C 是類別數(shù)# labels: (N,)每個(gè)位置是正確答案的類別編號(hào)# 它內(nèi)部自動(dòng)做 softmax所以傳 logits分?jǐn)?shù)而不是概率注意F.cross_entropy內(nèi)部已經(jīng)帶 softmax 了所以傳原始 logits而不是 softmax 后的概率傳概率反而錯(cuò)。3.4 log 概率與 KL 散度RLHF 里反復(fù)出現(xiàn)log 概率log P(x)。P(x) 是 0~1所以 log P(x) 是負(fù)數(shù)或 0。log 概率越大 概率越大。KL 散度Kullback-Leibler divergence度量一個(gè)分布 P 偏離另一個(gè)分布 Q 有多遠(yuǎn)。值越大越偏離等于 0 表示完全相同。在 RLHF 里我們不想讓新策略偏離參考模型太多就在獎(jiǎng)勵(lì)里加一項(xiàng)偏離懲罰-β·(log π_θ ? log π_ref)。log 相減正好是逐 token 的 KL 貢獻(xiàn)——這就是 3-PPO.py 里rewards -beta * kl的由來。4. 訓(xùn)練到底在做什么4.1 一次訓(xùn)練的完整流程背下來1. 前向傳播喂數(shù)據(jù) → 模型算出預(yù)測(cè) → 算出損失衡量錯(cuò)多少 2. 反向傳播loss.backward() → 用鏈?zhǔn)椒▌t算出每個(gè)參數(shù)的梯度該往哪改 3. 參數(shù)更新optimizer.step() → 讓每個(gè)參數(shù)沿減小損失的方向走一小步 4. 清梯度optimizer.zero_grad() → 把上一步的梯度清零防止累加每一步對(duì)應(yīng)一行代碼optimizer.zero_grad()# 清梯度loss.backward()# 反傳optimizer.step()# 更新4.2 梯度下降與學(xué)習(xí)率梯度損失函數(shù)對(duì)每個(gè)參數(shù)的偏導(dǎo)告訴它往哪個(gè)方向改、損失會(huì)變小。更新公式θ θ ? lr × 梯度。學(xué)習(xí)率lr是每步走多遠(yuǎn)。lr 太大 → 步子太大容易跳過最優(yōu)點(diǎn)甚至發(fā)散lr 太小 → 走得慢訓(xùn)練半天不收斂。本項(xiàng)目預(yù)訓(xùn)練5e-4SFT5e-5PPO1e-5——越到后面越小因?yàn)樵降胶笃谠揭?xì)微調(diào)。4.3 epoch / batch / step 是什么詞含義例子樣本sample一條數(shù)據(jù)一條評(píng)論batch批一次喂給模型的樣本集合8 條評(píng)論step / iteration步處理完一個(gè) batch 并更新一次參數(shù)1 次optimizer.step()epoch輪把整個(gè)數(shù)據(jù)集完整過一遍全部評(píng)論過 1 遍 1 epoch關(guān)系1 epoch 數(shù)據(jù)條數(shù) ÷ batch_size 個(gè) step。本項(xiàng)目 SFTNUM_EPOCHS1表示只把數(shù)據(jù)過一遍防止災(zāi)難性遺忘。4.4 train() 和 eval() 的區(qū)別model.train()訓(xùn)練模式Dropout 開啟。model.eval()評(píng)估模式Dropout 關(guān)閉且不更新任何參數(shù)。忘記切換是新手常見 bug評(píng)估時(shí)忘了eval()結(jié)果每次輸出隨機(jī)抖動(dòng)。5. 張量操作速查讀代碼必備操作干什么例子x.shape看形狀(2, 4, 768).unsqueeze(0)加一個(gè)維度(4,) → (1, 4)補(bǔ) batch 維.squeeze(0)去掉一個(gè)維度(1, 4) → (4,).view(a,b,c)重排形狀總元素?cái)?shù)不變(2,4,768) → (2,4,12,64).reshape(a,b,c)同 view更寬容必要時(shí)復(fù)制同上.transpose(1,2)交換兩個(gè)維度的順序(2,4,12,64) → (2,12,4,64).flatten(0,1)把一段維度壓平成一維(8,256,21128) → (2048,21128).cat([a,b], dim1)拼接(1,5)(1,1) → (1,6).gather(dim, index)按索引取數(shù)從詞表維取出實(shí)際 token的分?jǐn)?shù).item()單元素張量 → Python 數(shù)取 loss 值.numel()元素總數(shù)8×2562048廣播broadcasting形狀對(duì)不上時(shí)自動(dòng)拉齊(4, 768) (2, 4, 768) (2, 4, 768)規(guī)則從右往左對(duì)齊維度能配得上相等或一個(gè)為 1就自動(dòng)擴(kuò)展。位置嵌入(T, 768)和詞嵌入(B, T, 768)相加靠的就是廣播——(T,768)被自動(dòng)復(fù)制到每個(gè) batch。維數(shù)對(duì)不上會(huì)直接報(bào)錯(cuò)這是最常見的報(bào)錯(cuò)來源之一。view 為什么老報(bào)錯(cuò)requires contiguous[:, :-1, :]這類切片產(chǎn)生的結(jié)果內(nèi)存可能不連續(xù).view()要求連續(xù)內(nèi)存所以報(bào)錯(cuò).reshape()不報(bào)必要時(shí)自動(dòng)復(fù)制。所以代碼里錯(cuò)位后用.contiguous()或直接用view之前contiguous()一下。6. 強(qiáng)化學(xué)習(xí)一分鐘6.1 四件套術(shù)語通俗理解本項(xiàng)目里狀態(tài) S“現(xiàn)在寫到哪了”已生成的 token 序列動(dòng)作 a“下一步選什么”選下一個(gè) token策略 π(a|S)“在這種情況下選各種動(dòng)作的概率”GPT-2 輸出的概率分布獎(jiǎng)勵(lì) R“這一步做得好不好”KL 懲罰 RM 打分6.2 強(qiáng)化學(xué)習(xí)和監(jiān)督學(xué)習(xí)的本質(zhì)區(qū)別監(jiān)督學(xué)習(xí)有標(biāo)準(zhǔn)答案標(biāo)簽照答案學(xué)。比如 SFT 直接告訴模型下一個(gè)詞該是 X。強(qiáng)化學(xué)習(xí)沒有標(biāo)準(zhǔn)答案只有事后打分。模型自己試、被打分、再改進(jìn)。就像學(xué)騎自行車沒人告訴你往左 3 度只有摔了/沒摔。6.3 為什么 RL 訓(xùn)練不穩(wěn)定監(jiān)督學(xué)習(xí)一批數(shù)據(jù)固定梯度是確定性的。強(qiáng)化學(xué)習(xí)數(shù)據(jù)是策略自己采樣的——策略一變下一批數(shù)據(jù)的分布就變“自己給自己出題”。這就是 on-policy在軌的含義數(shù)據(jù)必須由當(dāng)前策略產(chǎn)生。數(shù)據(jù)分布一直在變 獎(jiǎng)勵(lì)有噪聲 → 訓(xùn)練容易來回震蕩。所以 PPO 才要用舊策略的數(shù)據(jù)、限制一次更新幅度裁剪、用價(jià)值網(wǎng)絡(luò)當(dāng)基線降方差。6.4 策略梯度的一行直覺想讓高分動(dòng)作更常出現(xiàn) 梯度 ∝ A_t × ?log π_θ(a_t|s_t) ↑ ↑ 這步多好 讓這步更容易出現(xiàn)的改動(dòng)方向優(yōu)勢(shì) A_t 0這步比預(yù)期好→ 往提高該動(dòng)作概率的方向更新A_t 0 → 往降低該動(dòng)作概率的方向更新。讀完這篇你應(yīng)該能回答tokenizer 把文字變成了什么為什么還要 embeddingF.cross_entropy為什么傳 logits 而不傳概率一次訓(xùn)練為什么要有zero_grad → backward → step三步model.train()和model.eval()差在哪強(qiáng)化學(xué)習(xí)和監(jiān)督學(xué)習(xí)最本質(zhì)的區(qū)別是什么答不上來的話回去再看對(duì)應(yīng)小節(jié)全答上來就可以開始讀gpt_model.md了。

相關(guān)新聞

深入解析MTK平臺(tái)scatter.txt分區(qū)表:從ptgen工具鏈到實(shí)戰(zhàn)定制

深入解析MTK平臺(tái)scatter.txt分區(qū)表:從ptgen工具鏈到實(shí)戰(zhàn)定制

1. 項(xiàng)目概述:從零理解MTK分區(qū)表的生成脈絡(luò)在MTK(聯(lián)發(fā)科)平臺(tái)的Android設(shè)備開發(fā)中,scatter.txt文件是一個(gè)繞不開的核心配置文件。無論是進(jìn)行固件燒錄、系統(tǒng)升級(jí),還是深度定制分區(qū)布局,都離不開它。很多剛接觸…

2026/8/1 4:39:45 閱讀更多
操作系統(tǒng)期末復(fù)習(xí):核心考點(diǎn)精講與高頻考題實(shí)戰(zhàn)指南

操作系統(tǒng)期末復(fù)習(xí):核心考點(diǎn)精講與高頻考題實(shí)戰(zhàn)指南

1. 項(xiàng)目概述:為什么我們需要一份“期末復(fù)習(xí)題”? 又到了學(xué)期末,看著操作系統(tǒng)這門課的教材和筆記,是不是感覺知識(shí)點(diǎn)又多又雜,像一團(tuán)亂麻?進(jìn)程、線程、死鎖、內(nèi)存管理、文件系統(tǒng)……每個(gè)概念都聽過&#xff0…

2026/8/1 8:09:55 閱讀更多
USB Type-C與USB 3.0/3.2/4協(xié)議全解析:從接口、協(xié)議到高速電路設(shè)計(jì)

USB Type-C與USB 3.0/3.2/4協(xié)議全解析:從接口、協(xié)議到高速電路設(shè)計(jì)

1. 項(xiàng)目概述:為什么我們需要重新認(rèn)識(shí)USB如果你最近幾年買過手機(jī)、筆記本,甚至是新款的游戲手柄,那你一定對(duì)那個(gè)正反都能插的小接口不陌生——沒錯(cuò),就是USB Type-C。但你可能也遇到過這樣的困惑:明明都是Type-C接口&…

2026/8/1 8:09:55 閱讀更多
CocosCreator DelayTime源碼解析:從動(dòng)作系統(tǒng)設(shè)計(jì)到性能優(yōu)化實(shí)戰(zhàn)

CocosCreator DelayTime源碼解析:從動(dòng)作系統(tǒng)設(shè)計(jì)到性能優(yōu)化實(shí)戰(zhàn)

1. 項(xiàng)目概述:為什么需要深挖一個(gè)簡單的延時(shí)動(dòng)作? 在CocosCreator的游戲開發(fā)中, cc.DelayTime 大概是每個(gè)開發(fā)者最早接觸、也最常使用的動(dòng)作之一。它的API簡單到令人發(fā)指—— node.runAction(cc.delayTime(2)) ,意思就是“等兩…

2026/8/1 8:09:55 閱讀更多
FANUC機(jī)器人系統(tǒng)變量全解析:從核心原理到工業(yè)自動(dòng)化實(shí)戰(zhàn)應(yīng)用

FANUC機(jī)器人系統(tǒng)變量全解析:從核心原理到工業(yè)自動(dòng)化實(shí)戰(zhàn)應(yīng)用

1. 項(xiàng)目概述:FANUC機(jī)器人系統(tǒng)變量的核心價(jià)值 在工業(yè)自動(dòng)化現(xiàn)場,尤其是汽車、3C、金屬加工這些對(duì)節(jié)拍和穩(wěn)定性要求極高的行業(yè),FANUC機(jī)器人是當(dāng)之無愧的主力軍。作為一名常年跟這些“鐵臂”打交道的工程師,我深知一個(gè)道理&#xff1…

2026/8/1 8:09:55 閱讀更多
芯片設(shè)計(jì)數(shù)字后仿與SDF文件:原理、流程與實(shí)戰(zhàn)調(diào)試指南

芯片設(shè)計(jì)數(shù)字后仿與SDF文件:原理、流程與實(shí)戰(zhàn)調(diào)試指南

1. 項(xiàng)目概述:從“紙上談兵”到“真刀真槍”的芯片驗(yàn)證 在芯片設(shè)計(jì)的漫長流程中,我們常常會(huì)聽到一個(gè)詞:“后仿真”,或者更專業(yè)的叫法——“數(shù)字后仿”。如果說前期的RTL功能仿真是在圖紙上推演建筑的力學(xué)結(jié)構(gòu),那么數(shù)字后…

2026/8/1 8:09:55 閱讀更多
Java安裝Selenium?動(dòng)化

Java安裝Selenium?動(dòng)化

Java如何安裝前提:Selenium?動(dòng)化 java版本最低要求為8 電腦?少已安裝?種瀏覽器,如:Chrome(推薦)、Edge、Firefox、IE、Safari提?:瀏覽器必須為官?下載的正版瀏覽器,根據(jù)以往經(jīng)驗(yàn)&#xff0…

2026/8/1 7:59:55 閱讀更多
AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O分配PCB板是應(yīng)用材料(Applied Materials)公司生產(chǎn)的一款用于半導(dǎo)體設(shè)備的I/O信號(hào)分配電路板。該型號(hào)(0100-02186)的核心特點(diǎn)如下:專用于Endura等半導(dǎo)體工藝腔室。集成信號(hào)路由與分配功能。連接控制…

2026/8/1 0:09:33 閱讀更多
Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)是日本日清(Nissei)品牌的一款工業(yè)用三相異步電機(jī),適用于自動(dòng)化設(shè)備及通用機(jī)械驅(qū)動(dòng)。該型號(hào)(FFMN-32L-10-T0 40AX)的核心特點(diǎn)如下:三相交流異步電動(dòng)機(jī)。額定…

2026/8/1 0:09:33 閱讀更多
AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O分配PCB板是應(yīng)用材料(Applied Materials)公司生產(chǎn)的一款用于半導(dǎo)體設(shè)備的I/O信號(hào)分配電路板。該型號(hào)(0100-02186)的核心特點(diǎn)如下:專用于Endura等半導(dǎo)體工藝腔室。集成信號(hào)路由與分配功能。連接控制…

2026/8/1 0:09:33 閱讀更多
Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)是日本日清(Nissei)品牌的一款工業(yè)用三相異步電機(jī),適用于自動(dòng)化設(shè)備及通用機(jī)械驅(qū)動(dòng)。該型號(hào)(FFMN-32L-10-T0 40AX)的核心特點(diǎn)如下:三相交流異步電動(dòng)機(jī)。額定…

2026/8/1 0:09:33 閱讀更多