©PaperWeekly 原創 · 作者 | 張逸驊
單位 | 密歇根州立大學博士生
研究方向 | 可信人工智慧
如果你對大語言模型(LLM)的強化學習(RLHF)感興趣,又想從最基礎的策略梯度最佳化一路瞭解、推匯出 PPO、GAE,再深入探討 DPO,那你就來對地方了。
本文將從最基礎的 Gradient Policy Optimization 開始,逐步介紹經典的 REINFORCE 演算法,再講解如何利用剪下目標實現近端策略最佳化(PPO),並透過廣義優勢估計(GAE)在偏差與方差之間找到最佳平衡。之後,我們還會從頭推導、討論離線訓練方法,如 DPO,幫助你瞭解不同訓練路線的優勢與挑戰。
線上(On-Policy)和離線(Off-Policy)強化學習
如今,LLM 中主流的 RLHF 方向分為兩大路線:
-
以 PPO 為代表的 On-Policy 路線
-
以 DPO 為代表的 Off-Policy 路線
那麼,什麼是 On-Policy,什麼是 Off-Policy 呢?可以用一個簡潔的判定方法:
-
On-Policy:訓練過程中,需要模型親自參與“生成”來收集新的資料樣本。
-
Off-Policy:訓練過程中,不需要“線上”生成,更多依賴事先收集到的(或由別的策略產生的)資料進行離線學習。
一般來說,On-Policy 的方法在訓練時會更“耗卡”、更耗時——最大的開銷主要是源自“模型生成”這一步,因為對一個生成式任務而言,模型需要逐 token 地輸出,這個過程極其耗費算力。
不過,儘管速度較慢,On-Policy 在理論上擁有更高的效果上限,因為它能夠不斷根據當前模型狀態進行探索和更新,這一點將在後續討論 PPO時更加凸顯。
我們首先來談談 On-Policy 路線。On-Policy 的核心思路是:讓模型自己產出答案,然後依據答案的優劣來打分,以此指導下一步的引數更新。簡而言之,最關鍵的一點是讓模型“親自下場”。
假設你是一個需要學會下象棋的模型,現在有兩種訓練方式:
-
方式一:讓你真刀真槍地下棋,每一步都有教練跟在你身邊打分。當你吃掉對手棋子時,教練會鼓勵你;當你因為衝動失誤被對面反殺時,教練會及時提醒你改進。
-
方式二:給你一堆職業選手的比賽錄影和一堆臭棋簍子的對局,用標註告訴你哪些操作是好招,哪些操作是壞招,然後你被動地學這些好操作、避免壞操作。
這兩種方式最大的區別就在於:你有沒有親自去“下棋”。方式一就是On-Policy,需要模型自己產出行為,然後學習;方式二就是 Off-Policy,只需根據已有對局資料進行模仿式學習。
Off-Policy 在訓練時通常更快,因為它用現成的資料就可以了,不需要模型時時線上生成並等待打分,但也很依賴這批資料與當前模型能力的“匹配度”。如果資料中操作難度和模型水平相差太大(過高或過低),學習效果就可能大打折扣;On-Policy 則可以避免這一問題,因為它所得到的訓練樣本 100% 來自於自己當前的水平和行動。
在語言模型場景中,一個典型的 On-Policy 演算法往往包含以下元件:
-
Actor:負責“生成”句子的模型(就像正在對弈的你)。 -
Critic:類似於“教練”,為每個生成結果提供即時指導;它本身也在訓練過程中隨 Actor 的能力變化而調整。 -
Reward Model:相當於“裁判”,給出最終分數或偏好評估。通常在訓練過程中是固定不動的。 -
Reference Model:PPO 在大模型裡的“獨有角色”,用來防止 Actor 過度偏離原有預訓練分佈,緩解 reward hacking 等問題。
由於在大型 LLM 上,這四個部分的引數量都可能非常龐大(往往需要同時載入多個 70B 引數規模的模型),所以 On-Policy 訓練往往帶來極高的算力需求,這也是為什麼人們通常說 PPO“非常耗卡”的原因。
下一步,我們將把目光聚焦在當前 On-Policy 路線最具代表性的方法——PPO 上,看看它究竟如何在實踐中平衡訓練開銷與學習效率。

PPO(近端策略最佳化)
2.1 從策略梯度最佳化(Policy Gradient Optimization)談起
想象一下,你是一名剛開始學習下象棋的新手。你的目標是透過不斷調整你的下棋策略(記作 ,其中 表示你的策略引數),來提高在一局棋中獲得勝利的機率,也就是最大化你的期望回報。我們可以將每一盤棋看作是一條軌跡 ,而你要做的,就是透過不斷最佳化你的策略來獲得更高的回報。
更一般得,強化學習的目標就是去最佳化一個策略,使得回報的期望最大:

形式上, 這個策略的回報被定義在所有可能的軌跡上:

所謂的軌跡,就是一連串狀態和對應動作的組合(state,action):

在下棋這個例子中,狀態 可以理解為當前棋盤落子的狀態,而動作 即為下一次落子的地方。而當前時間點的下一個狀態,則服從某種機率分佈,可以被看作是隨機的、不確定的(即對手落子):

那麼一個軌跡 的機率則為:

在強化學習中,我們會不斷提到回報會隨著時間不斷打折 (discount reward) 的概念:未來的回報總是不如當下的回報那麼重要。所以一個策略 的總回報可以被視作:

其中 是時間上的折扣因子,而 是 時刻的實際回報。
在深度學習中,我們通常採用最小化損失函式來更新引數,這正是隨機梯度下降(Stochastic Gradient Descent)的做法。但在這裡,我們的目標是最大化回報,因此我們使用隨機梯度上升(Stochastic Gradient Ascent)來更新策略:

這裡的 就被稱為策略梯度(policy gradient)。換句話說,就好比每盤棋結束後,你會覆盤,評估自己每一步走法對最終勝負的貢獻,然後調整下一盤棋的策略。這樣的更新方法統稱為策略梯度演算法(policy gradient algorithms)。
然而,正如在下棋時要考慮所有可能的走法和局面一樣,精確計算這個梯度需要對所有可能棋局(軌跡)進行求和或積分,而這在實際中(除非棋盤極其簡單)是計算上不可行的,因為即使你擁有可導的 ,由於軌跡的步數太多,在使用 auto-differentiation 求導過程中會因為 memory 太大而使用非常受限。因此,我們需要仔細思考一下怎麼求這個策略梯度。
策略梯度的推導
為了得到一個可操作的策略梯度公式,就像在覆盤中總結經驗一樣,我們從目標函式的梯度開始推導。將每盤棋視為一條軌跡 ,目標函式梯度為:

第1步:展開期望(Expand the Expectation)
這一步相當於考慮所有可能的棋局,我們將期望展開為對所有軌跡的積分:

第2步:交換梯度與積分(Interchange Gradient and Integral)
就像把每一步棋的影響拆分出來,我們將梯度運算子移入積分內部:

第3步:使用對數導數技巧(Apply Log-Derivative Trick)
利用一個數學技巧(對數導數),類似於在覆盤中分解每一步的重要性,我們有:

第4步:回到期望形式(Return to Expectation Form)
最終,我們可以把上面的積分重新寫成期望的形式:

分解
在下棋的過程中,每盤棋的走法取決於你每一步的決策。假設一盤棋的軌跡 可表示為:

這裡 就是你在棋局某一時刻(狀態 )下選擇某一步棋(動作 )的機率。取對數後求梯度,我們得到:

(注意:棋局中對手的反應 由規則決定,與 無關,因此其梯度為零。也就是說,當 給定時, 也就定下來了。)
2.2 最終策略梯度公式(Final Policy Gradient Formula)
把上面的結果代入期望,我們最終得到的公式是:

在這條公式中,每一步棋的決策()決定了整盤棋的表現,而不依賴於對手的固定規則。實際操作中,我們通常使用蒙特卡洛抽樣來近似這個期望,就好比你透過大量實戰積累經驗來提升下棋水平。最後,基於取樣的策略梯度可以由以下式子近似:

如果你仔細觀察這個式子,你會發現很有意思的兩個地方。首先 直接出現在策略引數的梯度裡邊。
2.3 REINFORCE 演算法流程與實現步驟
下面介紹經典的策略梯度方法——REINFORCE 演算法,它就像你透過不斷下棋、覆盤總結經驗來不斷改進你的棋藝:
1. 策略網路構建
搭建一個神經網路來定義你的下棋策略 :
-
輸入:當前棋局狀態 -
輸出:根據當前棋局生成下一步棋的機率分佈
2. 軌跡取樣
用當前策略進行對局(取樣軌跡 ),並記錄每步棋得到的獎勵(例如贏棋後的獎勵分數)。
-
你可以設定每盤棋固定步數(比如 100 步),或直到比賽結束。
3. 梯度計算
根據收集到的對局資料集 計算梯度估計,就像總結每盤棋中各步對勝負的貢獻:

4. 引數更新
使用隨機梯度上升法更新你的策略引數,就好像根據覆盤結果調整你的下棋風格:

或者寫作:

5. 迴圈最佳化
重複“下棋-覆盤-調整”這一過程,直到你的策略收斂,即你能穩定地打出高水平的棋局。
核心公式說明
1. 梯度估計公式

-
這裡,我們利用大量實戰(蒙特卡洛抽樣)來近似整個期望。 -
軌跡總獎勵 就是整盤棋的勝負結果,用來衡量你所有決策的綜合效果。
2. 引數更新規則

-
表示學習率,相當於每盤棋覆盤後你調整策略的幅度;梯度的方向正是指向能夠提升勝率的方向。
3. 演算法特性
-
關鍵優勢:這種方法完全依靠你下棋的實戰經驗,不需要提前知道對手的策略(model-free)。 -
計算要求:需要大量的對局取樣以降低隨機性帶來的波動(方差)。 -
改進方向:後續方法(如 Actor-Critic)會引入價值函式參考線,使得策略更新更為穩定,就像在覆盤中加入專業教練的點評一樣,幫助你更快提高棋藝。
2.4 策略梯度最佳化面臨的問題
策略梯度最佳化一個核心的假設是:我們可以透過採用的方法來估計策略的梯度。但是當問題的規模變得非常大:比如每次軌跡 都非常長,又或者策略模型非常大,為了預估準確的梯度,我們就不得不採樣多次,否則就會面臨方差很高的問題。
策略梯度演算法中的梯度估計雖然在理論上是無偏的(即其期望值會收斂到真實梯度),但實際上它的方差非常高,該梯度估計可以寫成:

其中:
-
表示資料集 的大小, -
是當前策略(你的下棋策略), -
是整盤棋(軌跡 )的總回報, -
分別代表在時間步 你採取的動作和所處的狀態。想象你在下棋。
想象你在下棋。每一步你都希望知道自己的決策對最終勝負的貢獻,但問題在於,如果你試圖把整盤棋的輸贏都歸因於每一步決策,那麼這種評估就會變得非常不穩定——也就是方差很高。接下來,我們將採取不同的做法來減小這樣估計的方差。
2.5 減小方差:只關注未來
觀察上邊用於梯度估計得式子:無論當前在哪一步 , 總是會把整個軌跡中所有的 reward 都算進去。然後這麼做是不太合理的,當前的決策應該只需要考慮對未來產生的影響:過去的已經無法改變了,無需再加入到 的計算中。
回到下棋的例子:假如每一步的評分都把前面已經走過的好步或壞步也計入進去,那就會混淆你當前決策的真實價值。實際上,在評估當前走法時,你只需要關注從這一步開始直到局末的“後續表現”。這就是所謂的“rewards to go”,即只考慮從當前動作開始到比賽結束所獲得的獎勵。
用數學表達就是,我們將原來的梯度估計調整為:

這裡,就代表了從當前走法開始到局末的“獎勵總和”。這樣做就像你在覆盤時,只關注從某一步開始後續的變化,而不糾結於那一步之前已經發生的事情。
因此,當我們把這些“來自過去的”的冗餘項去除後,噪聲就自然而然會減少一些。
2.6 減小方差:參考線(Baseline)
為了進一步減少評估中的波動,我們可以為每一步的“後續獎勵”減去一個基準值。數學上,這個參考線通常記為 (在實際中,我們常用價值函式 來作為這個參考線),公式為:

其中 就是所謂的參考線,他不一定是一個常數,更多時候是另外一個狀態 的函式。這個參考顯得實際意義是,在當前的狀態下,回報的期望大概是什麼樣子。那麼所謂超出期望的部分 就是優勢(Advantage)。在實際訓練中,我們會用優勢代替原來的獎勵進行梯度估計,以減小方差。
在大語言模型的對齊訓練中,我們通常在語言模型(即策略 )的基礎上增加一個額外的線性層,用來估計在某個狀態下的預期回報 。這相當於為每個局面設定了一個標準分,幫助我們衡量當前決策的實際優勢。如果你想更直觀得了解為什麼需要這個參考線,可以閱讀我的上一篇文章。
2.7 減小方差:引入 和
在上邊,我們提到了 “rewards to go” 的概念,即 。這個項在強化學習中被稱為 Q 函式(),即在狀態 採取動作 後,未來獲得的總回報。然後,透過減去狀態價值 我們得到優勢函式:

用下棋的比喻,Q 函式描述的是你當前這個局面 在走了一步 後可能的輸贏,而狀態價值表示的是僅憑現在的局面,你還有多少老本兒可以吃。如果當前局面對你十分有利,但是你走了一步臭棋,儘管你最後贏面還是很大(相當於 的絕對大小還是很大),但是你相對於對方的“優勢”卻減弱了。
所以,你不僅應該關注某一步棋的絕對得分,還要和“老本兒”比較比較,看看這一步棋究竟為你增加了多少勝率。如果 為正,則說明這步棋明顯擴大了你的優勢;若為負,則表明你這一招不妙。
最終,我們可以將策略梯度寫為:

這公式正是衡量你在每個局面上,透過比對每一步棋與平均表現的差距,從而決定如何調整你的下棋策略。
2.8 優勢函式的解釋
簡單來說,優勢函式 就告訴你,在某個局面(狀態 )下,選擇某個特定走法(動作 )相比於平均走法能提升多少勝率。如果這步棋帶來的預期回報遠高於你當前的基準水平,那麼這步棋的優勢就是正的,說明它非常值得采用;反之,則說明不如平均水平。
總之,透過這些方法——只考慮“後續獎勵”、引入參考線以及使用優勢函式,我們就能在訓練中有效降低梯度估計的方差,就像你在下棋時只關注關鍵走法對局面轉變的影響,從而讓策略更新更穩定、更有針對性。
2.9 如何估計優勢項 – 使用基於迭代的 GAE 策略
我們可以用多種方式來估計優勢項。例如:

上邊的例子告訴我們,我們可以累加若干步來實現偏差和方差的權衡。
-
如果我們過早地停止累加真實的獎勵項:就會產生高偏差(high bias),因為只使用了對價值函式的小部分近似和極少的真實獎勵。 -
如果我們累加過多的獎勵項:則會引入高方差(high variance),因為依賴更多真實取樣會讓估計量不穩定。
為平衡這一偏差-方差問題,我們可以採用對這幾項進行加權求和的做法,也就是廣義優勢估計(Generalized Advantage Estimation, GAE):

-
這是一個遞迴公式。末端時刻的優勢估計可以看作第一種展開,而它的前一時刻會再加上一層衰減係數 。 -
透過在各時間步上不斷迭代累加,就可以平衡真實獎勵所帶來的高方差和使用價值函式所帶來的高偏差。
下一章會講述 GAE 的詳細推導。
在大語言模型對齊的場景中,這個結果會指示策略(語言模型)在給定某個提示(state)後,去提升那些在期望意義上“優於平均”獎勵的下一個 token 選取機率。換言之,模型將傾向於選擇那些更可能引導未來 token 合乎我們所希望的獎勵標準(即更“對齊”或更符合訓練資料分佈)之序列。
2.10 PPO 損失函式(The PPO Loss)
在 PPO(近端策略最佳化)中,為了防止更新時策略變化過大,我們會構造一套特殊的損失函式。它主要由以下幾部分構成:
策略損失(Policy Loss, )

這一部分就像是在下棋時,你不希望一次改變策略太多,而是希望微調每一步的選擇,保證既能改善局勢,又不會因冒險走出常規而導致局面混亂。
價值函式損失(Value Function Loss, )

這一項幫助我們確保對於每個局面,你的預期回報估計(就像預判棋局發展)與實際獲得的回報儘可能接近。
熵損失(Entropy Loss, )

熵損失鼓勵策略保持一定的探索性,就像一個優秀的棋手不僅熟練掌握定式,同時也敢於嘗試新變化,保持靈活應變的能力。
PPO 總損失(PPO Loss, )

將這些部分結合起來,就構成了 PPO 的總損失函式。這個損失函式旨在在更新策略時既提高勝率(獎勵),又防止策略偏離原有風格過遠,保持平穩而高效的改進。
2.11 使用 PPO 的優勢
-
穩定性:剪下操作(clipping)確保策略更新時步伐不會過大,就像你在下棋時不會突然改變風格,保證每一步都穩紮穩打。 -
樣本效率:PPO 能夠較好地利用收集到的對局資料,儘管在大型模型的場景下仍需大量取樣。 -
內在安全性:透過剪下更新和參考策略的 KL 懲罰,PPO 能有效防止模型在更新時出現劇烈偏差,從而確保生成結果不會與預訓練風格南轅北轍。
總體來說,就像一位經驗豐富的棋手在不斷下棋、覆盤、調整策略中不斷進步一樣,PPO 透過精細的梯度更新和對策略變化的限制,實現了穩健而高效的強化學習。

GAE(廣義優勢估計)理解及推導
想象一下你在參加一場國際象棋比賽。每一步棋不僅會直接影響當前局面,還可能對後續整個比賽產生深遠影響。為了判斷某一步棋到底給你帶來了多少優勢,你需要同時考慮這一步棋的即時得分和它對未來局勢的潛在貢獻。
廣義優勢估計(Generalized Advantage Estimation, GAE)正是為了解決這一問題而設計的,它幫助策略評估在某個狀態下采取某個動作比平均水平會帶來多少優勢,就像你在覆盤時會評估某一步棋是否為你贏得了更高的勝率。
GAE 的創新之處在於結合了多步估計和時間差分(TD)估計的思想,利用一系列過去的誤差來預測未來收益,從而在平衡偏差與方差之間達到最佳狀態。PPO 與 GAE 聯合使用時,就好比一位棋手在有了穩健的對局策略框架(PPO)的基礎上,又利用精確的局面評估(GAE)來不斷最佳化每一步的決策,使得整體表現更加穩定且高效。
3.1 引入殘差的概念
在下棋時,你往往無法一開始就知道一招棋的全部價值,而只能根據下一步的預判來估計其效果。這個預判與實際結果之間的差異就叫做時間差分(TD)殘差。
為什麼需要殘差?
設想在比賽中,你站在一個關鍵的分叉口,基於經驗認為向左走可能更有利,但實際走後發現局面並不如預期。這種實際體驗與原始預判之間的差異就是殘差,它幫助你修正對未來局面的估計,使你在後續對局中做出更明智的選擇。
殘差的數學表達
對於策略梯度方法,價值函式的梯度可以寫為:

其中 表示在狀態 下采取動作 能帶來的未來收益(經過 baseline 校正後的優勢),我們簡稱為 。如果簡單地定義:

那麼,為了更準確地反映從當前走法開始未來帶來的全部影響,我們引入 TD 殘差。具體來說,對於狀態 下采取動作 ,如果接下來的狀態是 並獲得獎勵 ,則定義 TD 殘差為:

-
就像你下完這一步棋後獲得的即時得分。 -
和 分別是你對當前局面和下一局面預期的整體評分,相當於教練對局面的評價。 -
是折扣因子,表示未來獎勵的重要性逐步減弱。
殘差的直覺解釋
假設你在下國際象棋,你當前的局面是 ,然後你選擇了某個動作 ,導致遊戲進入了新的局面 ,並且你獲得了即時獎勵 。你的目標是估計這一步對未來的影響。
-
你對當前狀態 的預估價值是 ,它代表你在這個狀態下按照當前策略繼續走下去能獲得的預期收益。 -
你對下一步 的預估價值是 ,它代表你在下一步之後能獲得的預期收益。
理想情況下,你的當前狀態的價值 應該等於:

也就是說,你的當前狀態的價值 應該等於你的即時獎勵 加上你折扣後的未來預期價值 (因為未來的收益隨著時間的推移會衰減,是衰減因子)。
但實際上,你的 可能並不等於這個理想的估計,而是有一定的誤差。因此,我們定義 TD 殘差來表示這個誤差。因此, 衡量了你當前走法與預期之間的差距,就好像你發現某步棋的實際效果比預期好或差,從而提供了調整策略的依據。
為了獲得更準確的評估,就像你在覆盤時不僅關注眼前一步,而是回顧接下來的幾步對局勢的影響,我們定義 表示從時刻 開始向前看 步的累計優勢:

當 趨於無窮時,有:

根據殘差的定義,這可以展開為:

這就好比你在下棋時,把從當前走法開始到比賽結束的所有實際得分都考慮在內。顯然,考慮的步數越多( 越大),你對局面的評估偏差越小,但同時可能受到更多偶然因素的影響,導致方差增大;反之,若只看眼前幾步,則偏差較大但方差較小。
3.2 偏差-方差的折衷(Bias-Variance Tradeoff)
在實際中,為了在偏差與方差之間找到最佳平衡,我們不會簡單地選擇某個固定的 來累加所有獎勵,而是採用指數加權的方式,這就是 GAE 的核心思想。
首先定義 TD 殘差:

然後,我們用遞迴公式來累計優勢:

這裡, 就像你在下棋時決定對未來幾步影響的重視程度:
-
當 時,你會盡可能考慮整盤棋的所有後續效果(偏差最小,但方差最大)。 -
當 時,你只關注當前一步(偏差最大,但方差最小)。
此外,我們也可以用加權求和的方式表示多步優勢。定義:

展開得:

假設我們只考慮前 項,根據等比數列求和公式,我們有:

當 時:

乘以 得:

令 ,最終我們得到:

這正展示瞭如何透過調節 來權衡短期與長期收益的影響。正如一位棋手既不會只看眼前一步,也不會試圖預判所有可能變化,而是用一個合適的比例權衡近遠期影響一樣:
-
當 時,優勢估計包含了整盤棋的所有觀察資訊(偏差最小,方差最大): -
當 時,只依賴於當前一步的資訊(偏差最大,方差最小):
綜上, 就是調節偏差和方差的重要超引數:
-
越大,考慮的後續觀察越多,偏差越小,但方差越大; -
越小,依賴當前預估越多,偏差越大,但方差越小。
這種方法就如同一位棋手在下棋時,不僅關注眼前一著的效果,同時用合理的權重考慮未來幾步的走向,從而做出最優決策。

用 PPO 訓練 LLM 的 Token-per-Token 過程
下面以一種直白、逐 token 的方式講解在使用 PPO 訓練一個 LLM 時到底發生了什麼,並說明其中涉及的引數( 與 )的角色以及第一次更新的過程。
4.1 用 PPO 對齊 LLM
-
(舊策略引數):這是用來生成資料(比如生成 token 序列)的模型引數。在一次 PPO 更新前,你會用這套引數來取樣(即生成 token),同時記錄下每個 token 的生成機率(通常以 log-probability 的形式記錄)。 -
(當前策略引數):這是正在被更新的模型引數。你透過 PPO 演算法根據之前取樣得到的資料來調整這組引數,使得模型生成的 token 更符合獎勵訊號。更新後, 就會和 不一樣。
可以把 想象成“老版模型”,而 則是“新版模型”,新版模型在一次訓練迭代後會比老版模型更好(或者更符合獎勵訊號)。在每次更新後,新版模型會成為下一輪迴圈中的“老版模型”。
2. “Token-per-Token” 的訓練過程
假設你已經有一個預訓練的 LLM,我們把它的引數設為 。下面是一個具體的過程說明:
(1)取樣階段
1. 給定一個提示(prompt)
你將一個 prompt 輸入 LLM(使用 的引數)生成文字。
2. 逐 token 生成
模型根據當前上下文(state)生成下一個 token(action)。例如,當生成第 t 個 token 時:
-
當前狀態 是 prompt 加上前面 t-1 個 token。 -
模型選擇了 token 的動作,並給出了一個機率 (通常記錄為 log-probability)。
3. 記錄資料
對於每個 token,你記錄:
-
狀態 (上下文) -
動作 (生成的 token) -
舊策略下的生成機率(或 log-prob) -
可能還會記錄獎勵資訊(比如透過一個獎勵模型計算出的分數)和估計的價值 。 -
這樣形成一條軌跡(sequence)——一系列 token 及其相關資料。
(2)計算優勢(Advantage)
在 PPO 中,我們需要計算每個 token 的優勢 (可以採用 GAE,多步或者單步的方式)。
-
舉例:對於第 t 個 token,我們可能計算:
-
其中 是單步時序差分誤差。 -
在實際操作中,由於軌跡有限,我們只計算到軌跡結束的位置。
(3)更新階段:從 到
在取樣得到一批 token 資料後,你開始用 PPO 演算法更新模型引數。這裡 “token-per-token” 的解釋如下:
1. 舊策略作為參照
你已經記錄了每個 token 在生成時(使用 )得到的 log-probability,即 。
2. 當前策略重新計算概
使用當前的模型引數 (最初初始時 和 是一樣的,但你會進行多次梯度更新後, 會發生變化),對同樣的狀態 計算生成相同 token at 的 log-probability,即 。
3. 計算機率比
對於每個 token,計算機率比:

這個比值表示“新版模型”與“舊版模型”在該 token 處的生成傾向發生了多大變化。
4. 構造 PPO Loss(每個 token 的損失)
PPO 的目標是限制新版和舊版的差異過大。對每個 token,根據優勢 和比值 計算損失:

直白理解:
-
如果當前策略與舊策略的機率比 和優勢 的乘積在可接受範圍內(在 內),就用這個值。 -
如果比值太大或者太小,就用限制後的值(clip 後的值),防止更新步長過大。
5. 對所有 token 取平均,更新引數
將所有 token 的損失 平均,得到整個批次的 loss。然後用梯度下降(或其他最佳化器)更新模型引數 。
-
這時, 開始和 不一樣了,也就是說新版模型已經從舊版模型上進行了“改進”。
6. 更新
在一次完整的 PPO 更新(通常經過多個 epoch 在同一批資料上訓練)後,你會把當前模型引數 賦值給 ,為下一輪取樣做好準備。
3. 虛擬碼
下面給出一個虛擬碼風格的演算法塊,幫助理解 token-per-token 的 PPO 更新過程:
# 初始化:預訓練 LLM 的引數設為 θ_old,同時複製給 θ
θ_old = PretrainedLLM.parameters
θ = copy(θ_old)
# 取樣階段:使用 θ_old 生成一批資料
for
each prompt
in
dataset:
trajectory = []
state = prompt
while
not end_of_sequence:
token, logpi_old = θ_old.generate_token(state)
# 記錄當前狀態、token 以及 θ_old 下的 log機率
trajectory.append( (state, token, logpi_old, reward, V(state)) )
state = state + token
# 更新狀態(追加 token)
store trajectory
# 計算優勢(例如採用 GAE)
for
each trajectory:
for
t from last token downto first:
δ_t = reward[t] + γ * V(state[t+1]) - V(state[t])
A_t = δ_t + γ * λ * A[t+1]
# 遞推計算
# PPO 更新階段:多輪 epoch
for
each PPO update epoch:
for
each token data (state s_t, token a_t, logpi_old, A_t)
in
batch:
# 1. 當前策略計算 log 機率
logpi_current = θ.log_probability(s_t, a_t)
# 2. 計算機率比
r_t = exp( logpi_current - logpi_old )
# 3. 計算未剪下與剪下目標
loss_unclipped = r_t * A_t
loss_clipped = clip(r_t, 1-ε, 1+ε) * A_t
# 4. 每個 token 的損失取較小值(並加上負號,因為我們是最小化 loss)
loss_token = -min(loss_unclipped, loss_clipped)
# 5. 平均所有 token 的 loss,進行一次梯度更新
θ = Update(θ, average(loss_token over batch))
# 更新完畢後,將 θ 複製給 θ_old,用於下一輪取樣
θ_old = copy(θ)
4.2 在第一次更新時,如果新模型和舊模型一模一樣,PPO Loss 是 0 嗎?
當然不會,下面是原因。
1. PPO Loss 的形式回顧
PPO 的目標函式通常寫成:

其中
-
是新模型(引數 )與舊模型(引數 )在相同狀態下生成同一 token 的機率比, -
是優勢估計,反映了該 token 相對於基準(baseline)的“好壞”。
這個 Loss 的目的是引導模型朝著使得生成動作得到更高優勢(獎勵)的方向更新,而不是直接衡量新舊模型的引數差異。
2. 如果新模型和舊模型一模一樣,損失是不是為零?
-
在第一次更新之前,我們通常將新模型引數 初始化為舊模型引數 。因此,對於每個 token, -
代入 PPO 目標函式,兩項都會變為: 並且剪下操作對 1 沒有影響(因為 ),結果仍然是 。 -
因此,每個 token 的目標函式就是 ,而 Loss 是加上負號,即:
關鍵在於:優勢 並不必然為零。
優勢 是透過環境獎勵和價值函式估計計算得到的,它反映了“這個 token 產生的結果比預期要好還是差”。即使新模型與舊模型完全一致,環境反饋(獎勵)和價值函式的估計通常會使得 非零。
3. 直觀解釋
-
取樣階段
當你用舊模型()生成 token 時,會記錄每個 token 的生成機率、對應的獎勵以及基於價值函式的估計。假設某個 token 在環境中獲得了較高獎勵,但模型當時對該 token 的預估不夠樂觀,那麼它的優勢 就是正的;反之,如果獎勵低於預期,優勢 就可能為負。 -
第一次更新 儘管初始時 與 完全一致(所以機率比 ),PPO Loss 的計算主要依賴於優勢 。因此,Loss 為: 如果 為正,則負號意味著 Loss 為負,反向傳播時會鼓勵模型增加生成這個 token 的機率;如果 為負,則模型會減少生成該 token 的機率。 -
梯度更新的作用 這樣,儘管新舊策略當前一致,優勢 的非零值會透過梯度計算推動模型調整生成策略,從而在下一次生成時更傾向於產生正優勢的 token。
4.總結
-
PPO Loss 的核心目標:
不是直接對比新舊模型引數的差異,而是基於舊策略取樣資料上每個 token 的優勢來指導模型更新。 -
即使在第一次更新時:
由於優勢 通常不為零,PPO Loss 會產生非零梯度,從而促使模型在更新過程中調整策略,使其生成結果更符合獎勵訊號。
這就是為什麼即使在第一次更新前,新模型與舊模型完全一致,PPO Loss 也不會為零的原因。

DPO:看著棋譜學下棋
前面我們提到,PPO 很像你在真實棋盤上有一位教練隨時指導,邊對弈邊在真實環境中改進策略(線上學習);而 DPO 則更像你坐在家裡研究一本棋譜(離線資料),透過已有的勝負對照來推斷如何改進走法。
本節就來具體推導 DPO(Direct Preference Optimization)的數學原理,解釋它在和 PPO(或更一般的 RLHF 思路)對比時有何長處與不足。
在此之前,請先牢記下面 3 個關鍵的目標函式: 表示獎勵模型(Reward Model), 是我們需要訓練的對齊模型(策略), 則是參考模型(無論是 PPO 還是 DPO,都需要它來保證策略別跑得太偏)。這 3 個目標函式分別是:
-
ward Model Loss:

-
PPO Loss:

-
DPO Loss:

其中 KL 散度定義為:

5.1 從最佳化目標中直接求解最優對齊模型
讓我們先從 PPO 的損失函數出發,對其進行數學變換。就像在真實棋盤上下棋時,教練(Reward Model)即時給你反饋、並用 KL 散度懲罰讓你的策略別偏離參考模型太遠。
1. 代入 KL-散度公式:

2. 提取常數 並進行恆等變換:

3. 繼續變換:

4. 得到:

在這裡我們構造了一個新的分佈 :

其中,這個 就像一個歸一化常數,保證 是一個真正的機率分佈(機率和為 1)。

在上式中,分子代表了在給定某個輸入對 時,模型獲得獎勵的期望值;而分母則彙總了在相同輸入 下,所有可能輸出 的獎勵期望之和。這樣的結構實際上實現了一個歸一化操作,使得整個表示式的值被限制在 的區間內,從而滿足我們構造機率分佈的基本要求。
雖然我們並不清楚 的具體形式,但由於我們已經知道參考分佈 的精確表達,我們可以利用這一資訊:只需將輸入 傳入參考模型,然後對所有可能的 進行遍歷(或者抽取足夠多的 樣本),便可以近似估計出 的分佈。
不過,需要注意的是,這種方法在實際操作中存在計算上的挑戰,我們將在後續進一步討論這些問題。
1. 繼續對 PPO Loss 等價變換:

2. 化簡:

3. 忽略掉與 無關的 ,得到:

4. 寫成 KL 散度的形式(左下⻆的 沒有了):

現在,我們的目標就簡化為關注 KL 散度那一部分。由於 KL 散度總是非負的,並且當兩個分佈完全一致時其值為 ,因此最優情況正是在 與 完全相等時達到的。這就給我們提供了一個顯式解:PPO 的最優機率分佈正好就是 。
換句話說,如果獎勵模型的引數 已經確定,那麼 PPO 的最優解就是

然而,在實際對齊訓練中,我們使用的獎勵函式 並不是隨便設定的,而是透過資料訓練得到的最優獎勵模型。也就是說,我們首先利用資料訓練出一個理想的獎勵模型 (相當於教練給棋局打分),然後在這個最優獎勵模型的基礎上,再進一步訓練出真正能“下好棋”的對齊模型。
由此,最優獎勵模型 與它訓練出的最優對齊模型 依然滿足上面那個關係,即

總結
首先,我們定義了一個整體的最佳化目標,用於對齊人類偏好。這個目標函式假設我們已經有了一個獎勵函式,並旨在找到一個能最大化該目標的對齊模型。可以將其理解為,在下棋時,你希望根據教練(獎勵函式)的評分,找到一種策略(下棋方法)使得你的勝率最高。數學上,這個目標寫為:

接著,我們從這個最佳化目標出發,推匯出在固定獎勵函式 情況下,對齊模型 的顯式解。類似於在棋譜中找到一條最優走法,這個顯式解為:

其中 是歸一化的 Partition Function,定義為

最後,在實際訓練中,我們通常不會單獨訓練獎勵模型,而是在最優獎勵模型 的指導下,直接訓練出最優的對齊模型。換句話說,就像你透過不斷實戰和教練點評,最終掌握了真正能下出好棋的策略一樣,我們將上面的公式稍作調整,得到:

這三個步驟展示了從整體對齊目標出發,到推匯出最優策略,再到將獎勵模型和對齊模型關聯起來的全過程。整個流程就像是:首先確定比賽的勝負標準(最佳化目標),接著從棋譜中總結出最佳走法(顯式策略解),最後透過不斷實戰驗證和反饋(獎勵模型訓練),最終獲得一套既能正確評估也能實際應用的下棋策略。
5.2 跳過獎勵模型的訓練
雖然我們形式上得到了

但在實際中,這個顯式解不太容易直接用,因為:
-
很難估計:它需要對給定 prompt 下的所有回答 進行窮舉或採樣,計算 並累計,代價十分高昂。 -
我們最初目標是想繞過“先訓練獎勵模型”這一步,直接一步到位地學出一個對齊模型。然而 仍需已知 ,離我們想要的“直接學好棋”(而不是先學打分)還有距離。
於是,我們反向思考:如果我們有 ,能否推匯出它對應的獎勵函式 ?答案是可以的。由

可等價變形為:

這樣,就能把 表達成 的函式,從而把“訓練獎勵模型”與“訓練對齊模型”之間的關係打通。
總結這一部分:
既然我們已經能夠用最優的對齊模型 表示出最優獎勵模型 (就好比你透過反覆對局和覆盤,總結出了一套最佳下棋策略,並由此推匯出最準確的棋局評價標準),那麼我們只需將 直接代入獎勵模型的訓練目標中。
換句話說,這就意味著,你可以看似在訓練獎勵模型,實際上卻一步到位地得到了最優的對齊模型。這樣一來,就實現了我們最初“讓模型既會評估又能下好棋”的目標。
接下來,問題便回到瞭如何訓練獎勵模型上。通常,我們採用“偏好排序”的資料標註方法來訓練獎勵模型,這在棋譜分析中就好比有人事先標註了哪幾步棋更佳。一般來說,有兩種主要方法:
1. 只生成 2 個回答
對於一個給定的提示 (或一個棋局),只生成兩個回答(走法):例如 <prompt x, chosen y1, reject y2> 。此時,人工標註會告訴我們哪一個走法更好。我們的目標是讓獎勵模型對被選中的回答(chosen)打出更高的分數,而對拒絕的回答(reject)打出較低的分數。
2. 生成 K 個(K>2)回答
對於同一個提示 ,生成多個回答(走法):例如 <prompt x, y1, …, yK> 。假設人工標註給出了一種偏好排序 ,比如認為從高到低依次為 y2 > y3 > y1 > … > yK 。我們希望獎勵模型能夠對這個真實排序 賦予最高的總分,而任何其他可能的排序得分都較低。
在一些訓練框架(例如 ChatGPT 的實現)中,當生成的回答超過 2 個時,系統會將這些回答拆分成兩兩比較,從而使得目標函式與只生成 2 個回答時的目標保持一致。
但在更一般的場景下,我們會將所有可能的回答偏好排序看作一個整體資料,並期望真實排序 的得分最高。DPO 的推導正是基於這種整體偏好排序的思路,因此在接下來的部分,我們會分別針對 K=2 和 K>2 的情況,詳細推匯出 DPO 最終的目標函式形式。
BT 模型:只生成 2 個回答
想象你在下棋時,教練只給你展示兩種走法——一種被標記為“好招”(chosen),另一種為“壞招”(reject)。在這種情況下,你的目標就是讓你的“打分系統”(獎勵模型)儘可能高地評估好招,而低地評估壞招,也就是說,希望“好招打敗壞招”的機率儘可能大。
為此,我們可以藉助經典的 Bradley-Terry (BT) 模型進行建模。BT 模型最初在 1952 年提出,用於分析成對資料間的相對優勢,廣泛應用於體育比賽、市場調查等領域。對於一對資料 和 (在這裡分別代表 chosen 和 reject 回答),BT 模型將“ 打敗 ”的機率表示為:

其中, 和 分別代表了兩者的強度引數,就像在棋賽中,我們可以用過往勝率來衡量兩位棋手的實力。類似地,當 和 分別代表 chosen 和 reject 回答時,這裡的強度引數可以被視為獎勵模型對這兩個回答打出的分數。
我們的目標是讓 打敗 的機率儘可能大,也就是說,在整個標註資料集 中,我們希望 chosen 回答的表現遠遠優於 reject 回答。因此,獎勵函式的總體最佳化目標可以設計為:

這裡的最後一行正是 ChatGPT 等系統中使用的獎勵模型最佳化目標。直觀上講,這個目標函式鼓勵獎勵模型輸出的分數使得 chosen 回答比 reject 回答更具有優勢。我們可以認為,這一步就類似於教練給棋譜中的兩個走法打分,並要求好招的分數明顯高於壞招。
假設我們找到了最優的獎勵模型,其形式為

將這一最優獎勵函式代入前面的目標函式中,我們得到:

這一結果說明,我們已經將獎勵模型的訓練目標轉化為只依賴於對齊模型 的最佳化。也就是說,透過這種方法,我們可以在實際操作中繞過單獨訓練獎勵模型的步驟,直接使用標註好的“成對”偏好資料,就像你直接從棋譜中學習最佳走法一樣,從而一步到位地訓練出對齊模型 。
因此,我們對上述式子再稍加調整,將待訓練的對齊模型設為 ,最終目標寫作:

PT 模型:生成 K (K>2) 個回答
想象一下,在一盤國際象棋比賽中,你不僅僅在考慮兩個備選走法,而是一次性評估多種可能的走法。例如,在關鍵時刻,你的教練給你展示了 K 個不同的走法,並要求你根據每一步可能帶來的局面變化來排序這些走法,確定哪一種走法最有可能帶來勝利。這種情形對應於我們在 RLHF 中使用的“生成 K 個回答並進行偏好排序”的場景。
與只生成兩個回答的 BT 模型不同(BT 模型只關注一對走法之間的對比),這裡我們使用的是一種基於統計的 PT 模型(Plackett-Luce 模型),它可以對多個候選走法進行排序。
假設 表示人工標註出的真實偏好排序,換句話說,就是教練根據局勢給出了一份理想的走法排名。我們希望這個真實排序 能夠擊敗所有其他可能的排序。為此,我們定義“真實排序 擊敗其他任何排序”的機率為:

在這裡, 表示真實排序 中第 k 個走法(比如 是最受青睞的走法, 是第二受青睞的,以此類推),而 則代表當前棋局(或 prompt)。直觀上,我們希望在真實排序中,最受偏好的走法()在所有候選走法中獲得最高的得分;第二好的走法()在剩餘走法中也應獲得相對高分;依此類推。
接下來,我們將最優獎勵函式 代入上式。首先,將 表示為

然後,上式中的機率就變為

接著,我們利用 來表達 (注意:在這裡 可以被看作是一個與 無關的歸一化常數,可以在後續處理中省略),從而將表示式寫成:

最後,對於整個資料集,我們希望真實排序 的平均機率儘可能大,也就是說,我們的目標是最大化整個資料集中真實排序的機率。因此,針對多回答情況下的 DPO 目標函式可以寫為:

參考資料:
Fine-tune LLaMA2 with DPO
https://huggingface.co/blog/DPO-trl
Fine-tune LLaMA3 with DPO
https://github.com/brevdev/notebooks/blob/main/llama3DPO.ipynb
5.3 DPO 的侷限性
經過上面的推導,我們已經看到了 DPO 的數學基礎。然而,就像在國際象棋中,只靠閱讀棋譜而不親自下棋,雖然你可能學到很多評價走法的技巧,但卻無法保證你在實際對局中能下出好棋。
DPO 的核心目標是讓模型學會以獎勵模型的方式去評估回答的好壞,而它對標的並不是 PPO 本身,而是那個獎勵模型。這意味著 DPO 在訓練時,所用的資料和損失函式與獎勵模型是完全一致的。
這就引出了一個關鍵問題:模型是否具備同時提升“評估能力”和“生成能力”的能力。換句話說,DPO 的訓練流程只專注於讓模型學會如何“打分”,就像你透過閱讀棋譜來學習如何評價不同走法一樣。但這並沒有直接保證模型在實際下棋時能夠做出最優決策——也就是說,它並沒有證明“評價能力”能夠直接轉化為“下棋能力”。
如果這種假設不成立,那麼 DPO 的訓練過程就失去了意義。正如我們不會認為只看棋譜就一定能下好棋一樣,這個前提的成立與否也直接關係到其他類似 SPIN、self-reward 等方法的合理性。
另外,由於 DPO 的最佳化目標僅依賴於獎勵模型的打分,它只關心模型生成的回答在相對於參考模型的分數變化上是否符合預期,而並不關心模型實際生成出的句子是否通順、有吸引力。
也就是說,DPO 更在意 loss margin 是否變大,而不在乎模型能否在實際對局中下出一手好棋。這就導致在訓練 DPO 時,我們經常會遇到一個尷尬的現象:無論是好回答還是壞回答的 loss 都會上升,迫使我們不得不透過調整超引數或加入其他約束來穩定訓練。
從另一個角度來看,DPO 的侷限性還可以歸納為以下幾點:
評價與生成的脫節:DPO 的訓練過程只讓模型學會“評價”,即像一個靜態的棋譜評分系統,忽略了實際對局中需要的線上生成(generate)過程。PPO 則不同,它透過線上生成不斷試錯,即時獲得反饋,從而將“評價能力”轉化為“生成能力”。缺少了這種線上探索,DPO 訓練出的模型雖然可能在離線資料上評分準確,但在實際生成時往往表現不佳。
離線訓練的侷限:RLHF 本質上是一種線上學習方法,因為它需要不斷修正模型當前已有的知識,就像棋手需要不斷實戰來磨鍊技藝。而 DPO 則是完全離線的,它強迫模型僅僅依賴於訓練者認為“正確”的回答(比如棋譜中的好招),沿著一條預設的正確路線走下去,缺少了必要的探索(explore)的空間。
實際上,我們常用一些技巧,比如先讓模型對偏好資料中的好回答做一次監督微調(SFT),再進行 DPO 訓練;或者利用模型自己生成的一些多樣化結果構成偏好對,這些都試圖在一定程度上引入線上和探索的元素。
資料質量要求高:由於 DPO 的訓練完全依賴於離線的偏好資料,其效果對資料的質量和覆蓋範圍要求極高。如果訓練資料不夠全面或與實際生成分佈不匹配,就可能出現這種情況:模型在生成正負樣本時相對比例雖符合要求,但絕對生成的機率被稀釋,甚至可能產生訓練資料之外的奇怪回答。
比如,在一個問答場景中,資料集正樣本是“義大利麵應該拌番茄肉醬”,負樣本是“義大利麵應該拌油潑辣子”,但 DPO 最佳化後模型可能會輸出“義大利麵應該拌 42 號混凝土”,這種偏差正說明了資料質量的重要性。
總的來說,DPO 的侷限性在於它只關注於將獎勵模型的“打分”能力傳遞給對齊模型,而沒有包含實際的線上生成和探索過程。
這就類似於你只看棋譜來學習走法,而沒有親自上棋練習;結果,即便你在理論上能準確評價每一步的好壞,也無法保證在實戰中做出最佳選擇。因此,雖然 DPO 能夠一步到位訓練出對齊模型,但如果缺少線上生成和探索的補充,其效果往往不如完整的 RLHF(即 Reward Model + PPO)體系。
更多閱讀

#投 稿 通 道#
讓你的文字被更多人看到
如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢?答案就是:你不認識的人。
總有一些你不認識的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋樑,促使不同背景、不同方向的學者和學術靈感相互碰撞,迸發出更多的可能性。
PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是最新論文解讀,也可以是學術熱點剖析、科研心得或競賽經驗講解等。我們的目的只有一個,讓知識真正流動起來。
• 文章確係個人原創作品,未曾在公開渠道發表,如為其他平臺已發表或待發表的文章,請明確標註
• 稿件建議以 markdown 格式撰寫,文中配圖以附件形式傳送,要求圖片清晰,無版權問題
• PaperWeekly 尊重原作者署名權,並將為每篇被採納的原創首發稿件,提供業內具有競爭力稿酬,具體依據文章閱讀量和文章質量階梯制結算
• 投稿郵箱:[email protected]
• 來稿請備註即時聯絡方式(微信),以便我們在稿件選用的第一時間聯絡作者
• 您也可以直接新增小編微信(pwbot02)快速投稿,備註:姓名-投稿

△長按新增PaperWeekly小編
現在,在「知乎」也能找到我們了
進入知乎首頁搜尋「PaperWeekly」
點選「關注」訂閱我們的專欄吧
·
·
·
