32B IOI奧賽擊敗DeepSeek-R1!Open R1開源復(fù)刻第三彈,下一步R1-Zero
Hugging Face的Open R1再度升級!
Hugging Face的Open R1是一個社區(qū)驅(qū)動的項目,目標(biāo)是創(chuàng)建一個完全開源的DeepSeek-R1版本。目前,已有模型如OlympicCoder-32B和數(shù)據(jù)集如codeforces發(fā)布,顯示了項目的進展。
最新發(fā)布的7B和32B OlympicCoder,在IOI挑戰(zhàn)上超越了一眾前沿模型,比Claude 3.7 Sonnet還猛。
OlympicCoder已經(jīng)成了代碼推理界的「肌肉猛男」,有些模型規(guī)模比它大100倍,結(jié)果還是被它按在地上摩擦……
模型在2024年國際信息學(xué)奧林匹克競賽(IOI)50次提交中的表現(xiàn)
而這一切,得感謝Open R1的一系列騷操作:
- CodeForces-CoTs數(shù)據(jù)集:近10萬個高質(zhì)量樣本,提煉自DeepSeek-R1,專門訓(xùn)練C++和Python代碼生成。
- IOI基準(zhǔn)測試:拿2024年國際信息學(xué)奧林匹克競賽(IOI)的難題來虐AI,看看誰是真正的「代碼戰(zhàn)神」。
- 提交策略優(yōu)化:模擬OpenAI的策略,讓模型最大化得分,像真正的選手一樣參加比賽。
我們來扒一扒它是怎么煉成的,以及Hugging Face團隊踩過的那些坑。
(小心,可能會讓你懷疑人生:AI連刷題都比你強了……)
CodeForces-CoTs數(shù)據(jù)集
CodeForces作為編程競賽的熱門平臺,其中的算法優(yōu)化問題極具挑戰(zhàn)性。
這使其成為一個有趣的數(shù)據(jù)集,用于提升和測試模型的代碼推理能力。
此次發(fā)布的open-r1/codeforces包含了超過1萬個問題,時間跨度從最初的競賽一直到2025年,其中約3000個問題是DeepMind和CodeContests中沒有的。
對于約60%的問題,數(shù)據(jù)集提供了競賽組織者撰寫的解題思路,這對理解原理至關(guān)重要。
同時,每個問題都從官方網(wǎng)站提取了3個正確解決方案。
open-r1/codeforces-cots數(shù)據(jù)集更是一大亮點,其中包含了DeepSeek-R1針對這些問題生成的近10萬個思維鏈(CoT)樣本,用C++和Python兩種語言呈現(xiàn)。
研究團隊在這個數(shù)據(jù)集上對Qwen2.5 Coder Instruct 7B和32B進行微調(diào),得到了OlympicCoder-7B和OlympicCoder-32B模型。
代碼可驗證性危機
雖然DeepMind和其他競賽數(shù)據(jù)集都包含測試用例,并聲稱是可驗證的,但這些通常只是競賽網(wǎng)站上全套測試用例的一小部分。
特別是CodeForces,顯示的測試用例上限約為500個字符,這意味著這些數(shù)據(jù)集只包含符合此限制的較短、較簡單的測試用例。
例如,研究者選取了7個問題,R1生成的解決方案通過了全部公開測試用例,并將它們提交到CodeForces平臺:
盡管這些方案通過了較短的測試,但均未通過完整測試集。這凸顯了對新的可驗證的編程競賽數(shù)據(jù)集的需求。
國際信息學(xué)奧林匹克競賽(IOI)
國際信息學(xué)奧林匹克競賽(IOI)是全球頂尖的編程競賽。
完整測試集遵循寬松的(CC-BY)許可發(fā)布,使其成為測試代碼推理能力的理想數(shù)據(jù)集。
如果你熟悉美國數(shù)學(xué)邀請賽(AIME),IOI就相當(dāng)于數(shù)學(xué)奧林匹克競賽(IMO)的編程版,參加AIME的最優(yōu)秀學(xué)生才有資格受邀參加IMO。
IOI的問題設(shè)計獨特,每個問題細分為多個子任務(wù),各子任務(wù)輸入約束不同。
參賽者要解決子任務(wù),提交的方案須在嚴(yán)格時限內(nèi)通過所有測試用例。
最后子任務(wù)通常是完整復(fù)雜問題,而前面子任務(wù)相對簡單、約束更多,參賽者常針對特定子任務(wù)拿部分分?jǐn)?shù),競賽中得滿分十分罕見。
團隊整理了2020-2024年的IOI問題,將它們拆分為子任務(wù),使每個提示都能解決一個特定的子任務(wù),便于有針對性地訓(xùn)練和評估。
他們還在open-r1/ioi和open-r1/ioi-test-cases中發(fā)布了處理后的問題陳述、評分檢查文件及測試用例,同時創(chuàng)建了自定義代碼,用于運行解決方案并按IOI規(guī)則評分,代碼可在https://github.com/huggingface/ioi上獲取。
研究者對2024年IOI上40多個領(lǐng)先的推理模型進行了全面評估。
每個問題的提交次數(shù)限制為50次,采用與OpenAI類似的選擇策略模擬得分。
評估結(jié)果顯示,OlympicCoder模型表現(xiàn)出色。
OlympicCoder-32B在50次提交限制下,超越了o1-mini、DeepSeek-R1、Claude-3.7-Sonnet-thinking等模型。
模型在2024年國際信息學(xué)奧林匹克競賽(IOI)50次提交中的表現(xiàn)
提交策略
這種提交策略可能不利于非推理模型,像OlympicCoder-32B-Instruct和Qwen-2.5-Coder-32B-Instruct。
為模擬真實競賽,團隊采用類似OpenAI用于o1-ioi的循環(huán)提交策略。
首先提交針對最后一個子任務(wù)的解決方案,然后是倒數(shù)第二個子任務(wù)的方案,以此類推,只有選定提交時才評估解決方案。
若子任務(wù)已被之前選定的提交解決,就跳過針對該子任務(wù)的提交。
在每個目標(biāo)子任務(wù)里,傾向于選擇更長的生成內(nèi)容,這對推理模型合理,對其他模型不太適用。
如果取消50次提交限制,并評估生成的所有提交,會得到以下結(jié)果:
國際信息學(xué)奧林匹克競賽(2024年)無提交限制時模型的表現(xiàn)
基于R1軌跡訓(xùn)練的經(jīng)驗教訓(xùn)
在創(chuàng)建OlympicCoder模型時,研究者進行了大量SFT實驗,以了解用于CodeForces數(shù)據(jù)集的各種篩選條件的作用。
發(fā)現(xiàn)open-r1/codeforces-cots的以下子集表現(xiàn)最佳:
solutions
:R1根據(jù)問題陳述生成的方案。solutions_w_editorials
:R1根據(jù)問題陳述和解釋正確解決方案的說明生成的方案。
請注意,這里只關(guān)注了C++解決方案,融入Python解決方案可能進一步提高性能。
用LiveCodeBench作為模型的測試平臺,然后將表現(xiàn)最佳的checkpoints用于更具挑戰(zhàn)性的IOI基準(zhǔn)測試。
研究者測試了各種超參數(shù)配置來訓(xùn)練模型,最終確定如下:
- 模型:Qwen2.5 Coder Instruct 7B和32B
- 輪數(shù):10
- 有效批大小:128
- 學(xué)習(xí)率:4e-5
- 調(diào)度器:余弦衰減至峰值學(xué)習(xí)率的10%
- 上下文長度:7B為32,768個token,32B為22,528個token
樣本打包會損害推理性能
樣本打包是一種在訓(xùn)練中常用的加速方法,它將訓(xùn)練樣本連接成大小相等的塊,無需填充token。
打包后,樣本可能會跨塊邊界重疊。不過,要是大部分樣本比塊小很多,這種重疊影響不大。
然而,對于從R1提取的推理軌跡,這可能會帶來負面影響。
因為很多軌跡長,答案被截斷的可能性高。這就導(dǎo)致訓(xùn)練時,它很難關(guān)注長上下文信息,尤其是問題和答案被分到不同塊的時候。
如下圖所示,打包會嚴(yán)重損害模型的性能。用打包時,模型幾乎解不出LiveCodebench里的題;不用打包,性能在幾個訓(xùn)練周期后趨于平穩(wěn)。
這種差異可能是由于訓(xùn)練集僅包含C++解決方案,而LiveCodeBench僅評估Python的性能。
盡管如此,在所有分析過的數(shù)據(jù)集里,打包的效果都更差。
用較大的學(xué)習(xí)率獲得最佳表現(xiàn)
在用Qwen進行的大多數(shù)SFT實驗中,2e-5的學(xué)習(xí)率通常足以獲得強大的性能。
但是,當(dāng)將帶有推理數(shù)據(jù)的SFT用于現(xiàn)有指令模型時,將學(xué)習(xí)率大幅提高到4e-5,性能會顯著提升。
如下圖所示,學(xué)習(xí)率每提高一倍,在LiveCodeBench上的得分就會提高近10分!
納入解題思路無助于提升性能
在創(chuàng)建open-r1/codeforces-cots數(shù)據(jù)集中的solutions_w_editorials子集時,原以為給R1輸入問題及解答,能獲得更好的推理軌跡。
但出人意料的是,結(jié)果并非如此。訓(xùn)練時,直接從問題描述采樣,反倒讓性能有了一定的持續(xù)提升。
用<think>預(yù)填充以持續(xù)生成長CoT
在測試模型時,發(fā)現(xiàn)個奇怪現(xiàn)象:拿領(lǐng)域內(nèi)問題(比如競技編程)提問,模型會在<think>和</think>標(biāo)簽里,輸出長長的CoT,然后給出答案。
可要是問領(lǐng)域外的問題,像「瑞士首都是哪」,模型就變回原來指令模型的回答方式了。
舉個例子,簡單問題「1+1等于幾」,模型正?;卮鹗沁@樣:
用戶:1+1等于多少?
模型回答:2。這是最基礎(chǔ)的數(shù)學(xué)加法題,1+1就是 2。這題常出現(xiàn)在面試或者在線測試?yán)铮脕砜疾齑痤}人能不能快速解決問題。雖說答案大家都知道,但雇主能通過這題,看看答題人有沒有批判性思維和解決問題的能力。而且,這也是數(shù)學(xué)里復(fù)雜運算的基礎(chǔ)。下次再有人問,你就放心答2就行!
這段代碼里,定義了add_numbers函數(shù),輸入兩個數(shù)返回它們的和。接著用1和1調(diào)用函數(shù),把結(jié)果存進result,再打印出來。
但要是預(yù)先在模型回答里加上<think>,情況就不一樣了:
用戶:1+1等于多少?
模型回答:<think>好的,我要回答「1+1等于多少」這個問題。1+1等于2。不過,會不會有別的考法?或者不同進制?十進制里是2,二進制就是10了。但這問題問得直接,用戶估計就想要個簡單答案,那就是2。直接說出來?</think>對,1+1等于2,你還有別的想了解的嗎?
這說明,將推理軌跡融入現(xiàn)有預(yù)訓(xùn)練模型時,得在最終模型的對話模板里,默認強制加上預(yù)填充。DeepSeek處理提煉模型用的也是這招,這可能就是原因所在。
把這些經(jīng)驗都用上,團隊做出了OlympicCoder-7B,性能和DeepSeek的提煉模型差不多,比基礎(chǔ)的Qwen2.5-Coder強多了。
巧用8位優(yōu)化器,拓展長上下文大模型
訓(xùn)練OlympicCoder-7B時,研究者發(fā)現(xiàn)DeepSpeed ZeRO-3在配有8個H100的單節(jié)點上,訓(xùn)練32k上下文長度的模型沒問題。
可一旦把訓(xùn)練方案用于32B模型,就遇到了一系列內(nèi)存問題。尤其是上下文長度超過20k token時,哪怕用16個節(jié)點,也會因內(nèi)存不足而崩潰。
這可不妙,CodeForces-CoTs里20%的軌跡長度都超過20k token,意味著它們會在訓(xùn)練期間被截斷。
問題的根源在于transformers
和trl
尚不支持上下文并行。
團隊嘗試了各種節(jié)省內(nèi)存的辦法,發(fā)現(xiàn)將FSDP與paged_adamw_8bit
優(yōu)化器結(jié)合起來,可以將上下文擴展到 22,528個token,但仍有9%的數(shù)據(jù)被截斷。
更新
最近,團隊在改進TRL中GRPO的實現(xiàn)方面取得了進展,帶來了一些提升,進一步提高了效率、可擴展性和資源利用率。
以下是這次更新最重要的變化概要:
生成重復(fù)使用
GRPO的主要瓶頸與其他在線方法相同:生成過程需要時間。
提高GRPO樣本效率的一個關(guān)鍵方法是在優(yōu)化過程中多次重用生成的樣本,而不是在單次使用后丟棄。這一技術(shù)實際上早在PPO中就已經(jīng)引入。
對于GRPO,樣本重用的次數(shù)用μ表示。
現(xiàn)在,可以多次重用生成的樣本,從而顯著加快處理速度。
from trl import GRPOConfig
training_args = GRPOConfig(..., num_iteratinotallow=...)
不過需要注意的是,如果μ過大,可能會對學(xué)習(xí)產(chǎn)生負面影響。根據(jù)他們的經(jīng)驗,2到4之間的值是一個較好的平衡點。
獎勵加權(quán)
在訓(xùn)練模型時,并非所有獎勵都同等重要。例如,可能希望模型優(yōu)先關(guān)注正確性而非格式,而不是平等對待兩者。
為了解決這個問題,現(xiàn)在可以為不同的獎勵分配不同的權(quán)重,從而更精細地控制優(yōu)化過程。通過調(diào)整這些權(quán)重,我們可以引導(dǎo)模型更加關(guān)注特定任務(wù)中最重要的方面。
下面代碼配置了一個GRPO訓(xùn)練器,通過GRPOConfig設(shè)置訓(xùn)練參數(shù),并為兩個獎勵函數(shù)(very_important_reward 和 less_important_reward)分配了不同的權(quán)重(0.9和0.1),以控制優(yōu)化過程中不同獎勵的重要性。
from trl import GRPOConfig, GRPOTrainer
def very_important_reward(completions, **kwargs):
...
def less_important_reward(completions, **kwargs):
...
training_args = GRPOConfig(
...,
reward_weights=[0.9, 0.1],
)
trainer = GRPOTrainer(
...,
reward_funcs=[very_important_reward, less_important_reward],
args=training_args,
)
其他改進
GRPO還進行了一些較小但影響深遠的改進:
- PEFT+vLLM集成:現(xiàn)在可以將PEFT(參數(shù)高效微調(diào))與vLLM結(jié)合使用,將高效微調(diào)與優(yōu)化的推理相結(jié)合,提升可擴展性。
- 梯度檢查點:通過重新計算某些激活值而非存儲它們來減少訓(xùn)練過程中的內(nèi)存消耗,從而支持訓(xùn)練更大的模型。
- 優(yōu)化的選擇性Log Softmax計算:引入了一種新的Log Softmax計算方法,降低了訓(xùn)練期間的內(nèi)存峰值。
接下來的工作
團隊當(dāng)前的重點集中在兩個關(guān)鍵領(lǐng)域:
- 提升生成速度:正在探索進一步的優(yōu)化(如靜態(tài)緩存),以使生成過程更快。
- 將GRPO擴展到多節(jié)點設(shè)置:正在努力使 GRPO 能夠在多節(jié)點上擴展,從而支持訓(xùn)練更大的模型。
Open R1 Math-Dataset更新
研究團隊還進一步豐富了之前發(fā)布的OpenR1-Math-Raw數(shù)據(jù)集,添加了新的元數(shù)據(jù),以在過濾和驗證過程中支持更明智的決策。具體來說,新增了以下列:
- reparsed_answers:注意到答案列中的許多條目要么LaTeX格式不正確,要么僅包含部分答案。此外,由于一些問題是多項選擇題,正確答案本身及其對應(yīng)的字母都應(yīng)視為有效響應(yīng)。
為此,他們使用Llama-3.3-70B-Instruct模型從解決方案列中重新提取了所有答案,確保reparsed_answers包含正確答案,并在多項選擇題中同時包含對應(yīng)的字母。
- correctness:基于模型的答案驗證可能需要大量資源。因此,團隊使用Llama-3.3-70B-Instruct作為評判模型,并結(jié)合math_verify對答案列和reparsed_answers列進行了評估。
訓(xùn)練與評估
在數(shù)據(jù)受限的過濾場景中,精確度和召回率都是重要的考慮因素。
因此,研究團隊沒有為每個實驗設(shè)定相同的token預(yù)算,而是對所有數(shù)據(jù)進行了單個周期的訓(xùn)練。
他們選擇了Qwen7B-Instruct模型,并通過RoPE擴展將其微調(diào)至32k的上下文長度,采用余弦調(diào)度。
為了跟蹤性能進展,每隔40步在AIME-24、AIME-25和MATH-500數(shù)據(jù)集上使用lighteval評估模型。
下圖展示了在AIME-24、AIME-25和MATH-500數(shù)據(jù)集上,不同方法(包括無限制、LLaMA驗證、math_verify等)對模型準(zhǔn)確率隨訓(xùn)練步數(shù)變化的影響。
結(jié)果顯示,驗證顯著影響了早期性能。過濾在前40步尤為重要。
在MATH-500數(shù)據(jù)集上,較嚴(yán)格的驗證方法在早期階段顯著提升了性能(例如,no_restrictions得分為 0.61,而LandMV 為0.72)。然而,隨著訓(xùn)練的進行,這種性能差距逐漸縮小,擁有更多樣本(即使其中包含錯誤)變得更有利。
使用math_verify過濾的數(shù)據(jù)集始終表現(xiàn)出較低的訓(xùn)練損失。
研究團隊推測math_verify能有效識別特定任務(wù)子集(主要是數(shù)值型任務(wù)),而基于Llama的驗證或未過濾的數(shù)據(jù)集則保持了更廣泛的數(shù)據(jù)多樣性。
不僅如此,還有個意外發(fā)現(xiàn),未過濾數(shù)據(jù)集并未嚴(yán)重退化。盡管包含錯誤樣本,no_restrictions數(shù)據(jù)集在長時間訓(xùn)練中仍保持了競爭力。
下一步是什么?
通過這次更新,團隊現(xiàn)已具備完成復(fù)刻DeepSeek-R1計劃第1步和第2步的主要組件:
在接下來的幾周,他們計劃重點關(guān)注:
- 完善蒸餾數(shù)據(jù)集的組合,以訓(xùn)練通用推理模型。
- 將GRPO擴展到更大的模型,如Qwen/Qwen2.5-Coder-32B-Instruct,從而推導(dǎo)出R1-Zero變體。
- 結(jié)合來自數(shù)學(xué)和代碼等多領(lǐng)域的獎勵信號,并引入獎勵模型來評分非推理數(shù)據(jù)。