寫點(diǎn)代碼 | 從頭編寫GRPO、DrGRPO、GSPO,800行代碼實(shí)現(xiàn)完整訓(xùn)練和驗(yàn)證流程
在大型語言模型(LLM)的強(qiáng)化學(xué)習(xí)(RL)領(lǐng)域,一個(gè)很有潛力的方向是利用可驗(yàn)證的獎勵(Verifiable Rewards)進(jìn)行模型優(yōu)化,即RLVR。傳統(tǒng)的強(qiáng)化學(xué)習(xí)依賴于人類反饋(RLHF)或者一個(gè)專屬的價(jià)值模型(Value Model),這可能主觀又昂貴。而RLVR通過程序化的、客觀的獎勵函數(shù)來指導(dǎo)模型學(xué)習(xí),例如,在數(shù)學(xué)問題上,答案是否正確是可以通過計(jì)算驗(yàn)證的。 這種方法為我們提供了一條更高效、可擴(kuò)展的路徑,來增強(qiáng)模型的推理等復(fù)雜能力。
在RLVR的核心思想指導(dǎo)下,涌現(xiàn)出了一系列優(yōu)秀的算法,其中有代表性的有GRPO、DrGRPO和GSPO。其中是GRPO是訓(xùn)練DeepSeek R1的核心算法,GSPO是訓(xùn)練Qwen 3的核心算法。它們都脫胎于經(jīng)典的PPO算法,但各自在尋求更高效率和穩(wěn)定性的道路上做出了不同的探索。
最近,我在思考如何通過強(qiáng)化訓(xùn)練,提升多模態(tài)工業(yè)大模型的性能。找遍全網(wǎng),沒發(fā)現(xiàn)有中意的實(shí)現(xiàn),干脆自己動手豐衣足食。我花了兩天時(shí)間,寫了一個(gè)Python腳本,800多行代碼,從頭實(shí)現(xiàn)了GRPO、GSPO、DrGRPO 3個(gè)算法和訓(xùn)練框架。 然后用同一個(gè)數(shù)據(jù)集,訓(xùn)練相同的步數(shù),比較他們3個(gè)的性能。整體還不錯(cuò),一次運(yùn)行,效果如下
方法 | 初始準(zhǔn)確率 | 最終準(zhǔn)確率 | 提升幅度 (Δ) |
GSPO | 12.00% | 72.00% | 60.00% |
GRPO | 12.00% | 72.00% | 60.00% |
DrGRPO | 12.00% | 58.00% | 46.00% |
你如果想試一下,參考下面的命令,或者訪問 https://github.com/zhangfaen/GRPO_DrGRPO_GSPO_from_scratch_and_benchmark
%git clone https://github.com/zhangfaen/GRPO_DrGRPO_GSPO_from_scratch_and_benchmark
%cd GRPO_DrGRPO_GSPO_from_scratch_and_benchmark
%conda create -n grpo_drgrpo_gspo python=3.12
%conda activate grpo_drgrpo_gspo
%pip install -r requirements.txt
%python GRPO_DrGRPO_GSPO_from_scratch_and_benchmark.py寫代碼的過程中,對這3個(gè)算法的理解也更深了,再分享一點(diǎn)對他們的理解。
GRPO、DrGRPO、GSPO:一脈相承,各有千秋
GRPO的核心思想是拋棄PPO中需要額外訓(xùn)練的價(jià)值模型(Value Model),從而大幅降低了計(jì)算和內(nèi)存的開銷。 它的做法非常巧妙:對于同一個(gè)問題(Prompt),讓模型生成一組(Group)答案,然后根據(jù)獎勵函數(shù)為每個(gè)答案打分。接著,它不再預(yù)測一個(gè)絕對的“價(jià)值”,而是計(jì)算每個(gè)答案相對于這組答案平均得分的“優(yōu)勢”(Advantage)。如果一個(gè)答案的得分高于平均分,它就獲得了正優(yōu)勢,模型就會被鼓勵學(xué)習(xí)生成類似答案的策略;反之亦然。 這種“組內(nèi)相對比較”的思想,就是GRPO名字的由來,它讓訓(xùn)練過程變得更加穩(wěn)定和高效。
然而,有研究者認(rèn)為GRPO的原始設(shè)計(jì)存在一些固有的偏見(Bias),它的損失函數(shù)計(jì)算方式會系統(tǒng)性地“偏袒”那些在錯(cuò)誤答案中更長的回復(fù),同時(shí)給予那些難度過高或過低的(即所有生成答案都對或都錯(cuò))問題過大的權(quán)重。
為了解決這些問題,DrGRPO(GRPO Done Right)應(yīng)運(yùn)而生。 它的改進(jìn)非常直接:移除導(dǎo)致偏見的操作。具體來說,DrGRPO去掉了GRPO優(yōu)勢計(jì)算中按標(biāo)準(zhǔn)差進(jìn)行歸一化的步驟,以及損失函數(shù)中按序列長度進(jìn)行歸一化的部分,從而實(shí)現(xiàn)了一個(gè)更加公平和無偏的優(yōu)化目標(biāo)。
GRPO和DrGRPO雖然高效,但有研究者認(rèn)為它們都存在一個(gè)更深層次的問題:獎勵和優(yōu)化的粒度不匹配。 獎勵是針對整個(gè)生成序列(Sequence)的(例如,最終答案是否正確),但優(yōu)化卻是在每個(gè)詞元(Token)上進(jìn)行的。 這種不匹配在高難度任務(wù)和更復(fù)雜的模型(如混合專家模型,MoE)中,會引入大量噪聲,導(dǎo)致訓(xùn)練非常不穩(wěn)定,甚至模型崩潰。
于是,GSPO(Group Sequence Policy Optimization)橫空出世,旨在從根本上解決這個(gè)問題。 GSPO的核心是將優(yōu)化的粒度從詞元級別提升到了序列級別。 它不再為每個(gè)詞元計(jì)算重要性權(quán)重,而是為整個(gè)序列計(jì)算一個(gè)統(tǒng)一的權(quán)重。 這樣一來,優(yōu)化目標(biāo)和獎勵機(jī)制就完全對齊了。 所有的更新操作,包括PPO中的裁剪(Clipping),都是在序列層面上完成的。 這一改動極大地增強(qiáng)了訓(xùn)練的穩(wěn)定性,尤其是在MoE模型的訓(xùn)練上,避免了GRPO需要的“路由回放(Routing Replay)”等復(fù)雜技巧,并顯著提升了訓(xùn)練效率和最終性能。

再介紹一下這個(gè)Python腳本,方便理解
這個(gè)Python腳本旨在提供一個(gè)清晰、可運(yùn)行的環(huán)境,讓感興趣的同學(xué)能親手實(shí)踐并比較這幾種前沿的RL算法。注:代碼以學(xué)習(xí)和理解為主要目的,實(shí)際使用中請根據(jù)實(shí)際情況進(jìn)行修改和優(yōu)化。
這個(gè)腳本主要包含以下幾個(gè)部分:
- **一個(gè)統(tǒng)一的訓(xùn)練器 RLVRTrainer?**:為了公平比較,我將三種算法的通用訓(xùn)練流程封裝在一個(gè)統(tǒng)一的?RLVRTrainer?類中。它涵蓋了模型和分詞器的加載、數(shù)據(jù)處理、日志記錄、模型評估以及最終模型的保存等所有必要環(huán)節(jié)。
- 清晰的算法實(shí)現(xiàn):在_compute_loss?方法中,可以通過?loss_type?參數(shù)(可選"grpo", "dr_grpo", "gspo")清晰地看到三種算法在計(jì)算損失函數(shù)時(shí)的核心差異。對于GSPO,還通過?importance_sampling_level?參數(shù)區(qū)分了其序列級別重要性采樣的實(shí)現(xiàn)。代碼邏輯力求與算法的原始思想保持一致,方便對照論文進(jìn)行理解。
- 標(biāo)準(zhǔn)化的實(shí)驗(yàn)設(shè)置:腳本使用公開的openai/gsm8k?數(shù)據(jù)集進(jìn)行數(shù)學(xué)推理任務(wù)的訓(xùn)練和評測。在?main?函數(shù)中,可以看到一個(gè)標(biāo)準(zhǔn)化的實(shí)驗(yàn)流程:
加載和準(zhǔn)備數(shù)據(jù):一次性加載數(shù)據(jù)集,并劃分為訓(xùn)練集和評估集。
統(tǒng)一起始點(diǎn):所有算法都從同一個(gè)預(yù)訓(xùn)練模型(Qwen/Qwen2.5-1.5B-Instruct)開始訓(xùn)練,并進(jìn)行初始性能評估,確保比較的起點(diǎn)公平。
相同的訓(xùn)練資源:所有算法都使用相同的超參數(shù)(如學(xué)習(xí)率、批次大小等)和訓(xùn)練步數(shù)(num_steps)進(jìn)行訓(xùn)練。
端到端的比較:腳本會自動依次運(yùn)行GSPO、GRPO和DrGRPO的訓(xùn)練和評估流程,并在最后打印出清晰的性能對比結(jié)果,包括初始準(zhǔn)確率、最終準(zhǔn)確率以及提升幅度。
通過閱讀和運(yùn)行這個(gè)腳本,應(yīng)該可以加深對GRPO、DrGRPO和GSPO核心思想的理解,還能直觀地看到“序列級別優(yōu)化”相比“詞元級別優(yōu)化”所帶來的顯著優(yōu)勢。
我運(yùn)行上述腳本的一個(gè)的結(jié)果
在一張A800 GPU卡上,運(yùn)行上述腳本,大約花費(fèi)5個(gè)小時(shí)左右,產(chǎn)生如下結(jié)果。
方法 | 初始準(zhǔn)確率 | 最終準(zhǔn)確率 | 提升幅度 (Δ) |
GSPO | 12.00% | 72.00% | 60.00% |
GRPO | 12.00% | 72.00% | 60.00% |
DrGRPO | 12.00% | 58.00% | 46.00% |
可以看到,沒有經(jīng)過強(qiáng)化訓(xùn)練的Qwen/Qwen2.5-1.5B-Instruct,在數(shù)學(xué)推理任務(wù)中(基于openai/gsm8k數(shù)據(jù)集評測),準(zhǔn)確率約為12.00%。經(jīng)過GSPO和GRPO算法的強(qiáng)化訓(xùn)練,準(zhǔn)確率分別提升至72.00%和72.00%,而經(jīng)過DrGRPO算法的強(qiáng)化訓(xùn)練,則提升至58.00%。GSPO和GRPO的提升幅度為60.00%和60.00%,而DrGRPO的提升幅度為46.00%。需要說明的是,這次運(yùn)行使用的數(shù)據(jù)集openai/gsm8k是小學(xué)水平的數(shù)學(xué)應(yīng)用題,數(shù)據(jù)集規(guī)模小,推理難度較低,訓(xùn)練過程只訓(xùn)練了200步,結(jié)果參考就好,不代表DrGRPO在大規(guī)模生產(chǎn)環(huán)境中比GRPO和GSPO差。
附錄
- GSPO: https://arxiv.org/abs/2507.18071
- GRPO: https://arxiv.org/abs/2402.03300
- Dr.GRPO: ?https://arxiv.org/pdf/2503.20783
本文轉(zhuǎn)載自???后向傳播???,作者: 張發(fā)恩

















