UC伯克利華人開源14B「o3-mini」,代碼版R1突襲OpenAI王座!
OpenAI o1/o3-mini級的推理模型,竟被搶先開源了?
剛剛,來自UC伯克利和Together AI的聯合團隊,重磅推出了一款完全開源的代碼推理模型——DeepCoder-14B-Preview。
現在,只需要14B就可以擁有一個媲美o3-mini的本地模型,并且完全免費!
DeepCoder-14B-Preview通過分布式RL從Deepseek-R1-Distilled-Qwen-14B微調得來。
在LiveCodeBench基準測試中,它的單次通過率(Pass@1)達到了60.6%,提升幅度高達8%。
至此,又見證了強化學習的勝利。
DeepCoder在訓練過程中的LiveCodeBench (LCB) 得分:訓練到第180步的時候,上下文長度擴展到了32K;用32K時最佳的檢查點來做推理,并且把上下文擴展到64K,這時LCB得分能達到60.6%,和o3-mini性能相當
同時,團隊還開源了verl-pipe,這是verl后訓練系統的擴展,集成了多項系統優化,能讓端到端的訓練速度提高2倍。
對此網友們稱贊:這是完全開源的勝利,不僅僅是模型,數據集、代碼、訓練日志也開放。
值得一提的是,DeepCoder-14B-Preview基于24K個可驗證的編程問題,在32個H100 GPU上訓練了2.5周。
數據集構建
數學領域的研究發現,強化學習要是有可驗證的獎勵機制,能顯著提升模型的推理能力。
在數學領域,網上能找到好多高質量、可驗證的數據,編程則相對稀缺。
在早期實驗中,團隊評估了幾個常見的代碼數據集,像APPS、TACO、CodeContests、KodCode和LeetCode。
結果發現,有些數據集對模型來說太簡單了,如KodCode和LeetCode;還有些數據集有噪聲,或者里面的測試用例有缺陷、不完整,不可驗證。這會給出錯誤的獎勵信號,讓RL訓練無法穩定進行。
為解決這些問題,研究者整理出一個高質量的訓練集,包括:
- TACO里已驗證過的問題。
- PrimeIntellect的SYNTHETIC-1數據集中經驗證的問題。
- 2023年5月1日到2024年7月31日提交的LiveCodeBench問題。
為保證數據質量,讓RL訓練能順利開展,有一套嚴格的過濾流程:
- 程序化驗證:每個問題都會用外部官方的解法自動檢查一遍,只保留官方解法能通過所有單元測試的問題,檢查過程在tests/rewards/test_code_batch.py腳本中自動完成。
- 測試過濾:每個問題至少包含5個單元測試。測試用例少的問題容易讓模型鉆空子,模型通過識別常見測試用例,學會簡單地輸出記憶的答案,即「獎勵黑客」。
- 去重:研究者會把數據集中重復的問題都去掉,防止互相干擾。他們對Taco Verified、PrimeIntellect SYNTHETIC-1和LCB(2023年5月1日-2024年7月31日)這三個訓練數據集做了去重處理,還檢查了測試數據集LCB(2024年8月1日-2025年2月1日)和Codeforces的57個競賽數據集。
過濾后,得到24K個高質量的編程問題,用于RL訓練,其中7.5K個來自TACO Verified,16K個來自PrimeIntellect SYNTHETIC-1,600個來自LiveCodeBench。
代碼沙盒環境
為了計算代碼RL訓練的獎勵,得在代碼沙盒里,對模型生成的代碼進行單元測試。
每個RL迭代過程,用1024個問題來評估訓練效果,每個問題至少有5個單元測試。
這么多測試任務,就得靠100多個代碼沙盒一起并行運行,才能在合理的時間內,準確驗證模型生成的代碼。
目前,研究者用了兩種沙盒:Together代碼解釋器和本地代碼沙盒。
Together代碼解釋器
這個環境速度快、效率高,能直接用在RL訓練上,每個問題的成本僅3美分。
Together代碼解釋器已支持100多個沙盒同時運行,每分鐘能執行1000多次沙盒操作。
這些沙盒能訪問標準輸出(stdout)、標準輸入(stdin),還能評估代碼最后一行輸出的結果。
同時,它能把代碼運行的環境和主機系統隔離開,保證安全。
本地代碼沙盒
本地代碼沙盒是通過啟動一個獨立的、有防護的Python子進程來運行的。它從標準輸入(stdin)接收測試用例的輸入,然后把答案輸出到標準輸入(stdout)。
本地沙盒用的是LiveCodeBench官方代碼庫里的評估代碼,確保測試結果和現有排行榜一致。
獎勵函數
有些獎勵方式容易讓模型作弊,比如給思維鏈(CoT)懲罰,或者N個測試中有K個通過就給K/N獎勵。
獎勵函數采用稀疏結果獎勵模型(ORM),具體獎勵規則是這樣的:
- 獎勵為「1」:生成的代碼必須通過所有抽選的單元測試。有些問題有幾百個測試用例,全部驗證不太現實,所以會根據輸入字符串的長度,每個問題挑出15個最難的測試(根據輸入字符串的長度來判斷)。
- 獎勵為「0」:要是模型生成的代碼有一個測試用例沒通過,或者答案格式不對(比如缺少python[CODE]標記),就沒有獎勵。每個測試用例都有6-12秒的時間限制。
訓練方法
GRPO+
研究者參考了DAPO的關鍵思路,改進了GRPO算法,讓訓練過程更穩定:
GRPO+和GRPO在16K上下文訓練中的平均訓練獎勵:GRPO的獎勵曲線最后會崩潰,GRPO+因為有Clip High機制,獎勵曲線保持穩定
- 無熵損失:加上熵損失項,很容易讓訓練不穩定,熵值指數級增長,導致訓練崩潰。因此移除了熵損失項。
- 無KL損失(源自DAPO):去掉KL散度損失,LLM就不會被限制在原來監督微調(SFT)模型的置信區域內。還能省掉為參考策略計算對數概率,訓練速度也就更快了。
- 超長過濾(源自DAPO):為保留長上下文推理能力,對超出長度而被截斷的序列做了特殊處理。這項技術使DeepCoder即使在32K上下文環境中訓練,在64K上下文下也能推理。這種過濾方法允許響應長度自然增長,而不會因截斷而受到懲罰。
由于采用超長過濾機制,GRPO+的響應長度隨訓練時間穩步增長
- Clip High(源自DAPO):通過提高GRPO/PPO代理損失的上限,鼓勵模型嘗試更多不同的可能,熵值也更穩定。這樣調整后,訓練更穩定,模型性能也有提升。
Clip High機制和沒有熵損失,能保證GRPO+的token級熵不會崩潰,鼓勵模型充分探索
迭代式上下文擴展
在DeepScaleR的介紹中,提到過迭代式上下文擴展技術。它能讓模型先在短一點的上下文里學會有效思考,然后再應用到更長的上下文。
這個方法曾讓1.5B參數模型的下游任務性能穩步提升,隨著上下文窗口從8K擴大到16K,再到24K的過程中,在AIME測試里的準確率從33%提高到38%,最后到了43%,最終達到了o1-preview的水平。
不過,將這個技術用在14B參數模型的時候,遇到了新問題:
- 14B參數模型本身推理能力就很強,想要再提升,就得解決更難的問題。
- 這些更難的問題往往需要比8K更長的上下文窗口,而8K是之前小模型訓練的起始上下文長度。
如果一開始用短上下文訓練,模型輸出超出這個長度就懲罰它,這樣做效果不好。模型的初始性能會下降,輸出的內容也會變短,長上下文的推理能力也會變弱。
為了在保證訓練效率的同時,讓模型能處理長上下文推理,研究者引入了DAPO的超長過濾技術。在訓練的時候,會忽略那些因為太長被截斷的序列,這樣模型就算生成的內容長一點,也不會被懲罰。
因此,模型即使在較短的上下文中訓練,也能「想得長遠」。
研究者把迭代上下文擴展用在DeepCoder-14B-Preview上,把訓練的上下文窗口從16K擴大到32K,LiveCodeBench基準測試中,模型表現如下:
- 在16K和32K上下文長度下,準確率從54%提升至58%。
- 在64K上下文長度評估時,達到了60.6%。
這說明模型的泛化能力很強,超出了訓練時的上下文范圍也能表現得很好。
和DeepSeek-R1-Distill-Qwen-14B這種基礎蒸餾模型比起來,DeepCoder-14B-Preview的泛化能力就更突出了。
基礎蒸餾模型一旦超出訓練時的上下文長度,性能就很難提升了。
雖然DeepCoder因為平均響應長度較長,在16K上下文長度下的原始性能低一些,會因為截斷和格式問題扣分,但它在長上下文的推理能力很強,最終在64K上下文長度的評估中超越了其他模型。
DeepCoder在訓練過程中的平均響應長度和訓練獎勵:平均響應長度從8K增長到17.5K
DeepCoder的成功,正是把迭代上下文擴展和超長過濾技術結合起來了。
從圖中可以看到,在訓練過程中,模型的平均響應長度從8K增長到17.5K,平均獎勵也從0.6提高到 0.7。說明隨著時間推移,模型學會了更厲害、更有條理的思考方式。
關鍵技術改進
在多種編程基準上對 Deepcoder-14B-Preview 進行了評估,包括LiveCodeBench (LCB)、Codeforces、HumanEval+以及AIME2024數學競賽。
憑借14B的參數量,模型在所有編程基準上均展現出強勁性能:在LiveCodeBench上實現了60.6%的Pass@1準確率,在Codeforces上獲得了1936的評分,其表現可與o3-mini (low) 和o1模型相媲美。
訓練耗時太長?系統優化來幫忙
使用長上下文對LLM進行強化學習(RL)訓練非常耗時,需要在長上下文環境中反復進行采樣和訓練。
若無系統層面的優化,完整的訓練流程可能耗費數周乃至數月。14B參數編程模型訓練,每一步就得花1200至2500秒,總訓練時長達到2.5周!
團隊引入并開源了verl-pipeline。它是開源RLHF庫verl的一個優化版本,用了多項系統級改進措施,旨在加速端到端的RL訓練過程。
相較于基準的verl實現,verl-pipeline實現了高達2.5倍的速度提升。
運用這些新的系統優化來訓練DeepCoder-1.5B-Preview模型,該模型在LiveCodeBench上的準確率達到了25%,相比Deepseek-R1-Distill-Qwen-1.5B提升了8%。
采樣器是瓶頸
在后訓練中,采樣往往是拖慢整體進度的關鍵因素。這是因為用vLLM和SGLang這類推理引擎生成32K token的長序列時,會產生延遲。
Verl的PPO/GRPO訓練流程:每次RL迭代都包含采樣、獎勵函數計算和訓練這三個階段;其中,采樣是整個訓練流程的瓶頸,訓練速度受限于那些生成較長序列的掉隊采樣器(straggler samplers)
RL訓練系統通常受限于采樣時間——上圖展示了Verl的PPO/GRPO流水線,其中響應長度的不一致性導致部分采樣器成為掉隊者。
這些掉隊者會拖慢訓練進度,而先完成任務的采樣器則處于空閑狀態,從而導致GPU利用率低下。
樸素解決方案:小批流水線化
為了減少RL訓練過程中的空閑時間,研究者將采樣和訓練過程流水線化(Minibatch Pipelining)。
如此一來,訓練器在采樣器繼續生成后續數據批次的同時,就會開始利用較早到達的小批數據進行模型更新。這種重疊執行有助于減少采樣帶來的延遲。
小批流水線:采樣器和訓練器分別在不同的工作機組中運行;當完成采樣并釋放小批量數據(用于PPO/GRPO訓練)后,訓練器會異步處理這些數據;在一次迭代結束時,訓練器會將更新后的權重給采樣器
然而,這種方法存在三個關鍵的局限性:
- 小批數據的平均序列長度往往隨訓練進展而增長,這增加了處理后續小批的訓練時間。結果就是,最后幾個小批數據常常在采樣階段結束后才能處理完畢,從而限制了流水線化帶來的實際效益。
- 流水線化需要在采樣器和訓練器之間靜態劃分GPU資源,這減少了可用采樣器的數量。不同于Verl可以在同一個GPU池中動態地切換采樣器和訓練器角色,這種靜態劃分因采樣器數量減少,可能反而會延長端到端的總采樣時間。
- 獎勵函數的計算可能耗時很長,特別是對于編程類任務,每個RL迭代都需要運行數千個單元測試。在Verl的默認設置中,獎勵計算是在所有采樣任務完成后,在頭節點(head node)上集中進行的。
盡管存在這些約束,團隊在代碼庫的ray_trainer_pipeline.py文件中實現了小批流水線化,并且需要指出的是,這種流水線技術可以通過引入微批處理(microbatching)來進一步優化。
DeepCoder的解決方案:一次性流水線化
為實現訓練、獎勵計算和采樣的完全流水線化,研究者引入了一次性流水線化(One-Off Pipelining)。
一次性流水線:采樣器會提前一個迭代周期生成一批數據,而訓練器則使用上一次迭代的數據來更新梯度;此外,獎勵函數的計算與采樣過程是交錯進行的;這種方法不會為GRPO/PPO的策略算法引入異步離策略樣本
其思路非常簡單:犧牲第一個RL迭代,僅執行采樣任務,然后利用這個采樣得到的數據批次在下一個迭代中進行訓練。
這樣一來,采樣和訓練就能并行處理,徹底消除了采樣完成后訓練器的等待空閑時間。
其次,獎勵計算被嵌入到采樣流程中,與之交錯執行。
一旦某個采樣請求完成,其對應的獎勵會立即被計算出來——這有效減少了獎勵評估環節的開銷,特別是對于計算密集型任務(例如編程任務中的測試用例執行)而言效果顯著。
團隊在代碼庫verl分支(fork)中的ray_trainer_async.py文件里實現了一次性流水線化。
端到端性能
一次性流水線完全掩蓋了訓練器和獎勵計算的時間,數學任務訓練時間縮短1.4倍,編程任務縮短2倍
上圖展示了對verl、小批流水線化和一次性流水線化在兩種工作負載(數學和編程)下的評估結果。
為確保公平性,所有基準方法都利用Python線程池并行計算獎勵;而verl官方實現是串行計算每個樣本的獎勵,這種方式對于編程任務來說耗時過長,難以實際應用。
在8塊A100 GPU上對Deepcoder-1.5B-Preview進行了評估,并細致調整了采樣器與訓練器的資源配比,旨在更好地平衡兩者所需的時間開銷。
- 對于數學任務:一次性流水線化將每次RL迭代所需時間縮短了1.4倍。值得注意的是,數學任務的獎勵計算時間幾乎為零,因為它僅涉及基礎的Sympy檢查。特別之處在于,一次性流水線化能夠完全掩蓋(mask away)訓練器所需的時間,這與小批流水線化中最后一個小批會「溢出」(spill over)導致延遲的情況形成了對比。
- 對于編程任務:計算獎勵需要在每次RL迭代中運行數千個單元測試,這是一個非常耗時的過程。一次性流水線化能夠同時掩蓋訓練器時間和獎勵計算時間,從而將端到端的訓練總時長縮短了2倍。
最關鍵的是,一次性流水線化不僅切實有效,而且能成功擴展應用于復雜的編程任務。
DeepCoder使用ray_trainer_async.py(采用一次性流水線化)訓練了DeepCoder-1.5B-Preview,其在 LiveCodeBench (LCB) 上的得分相較于基礎的蒸餾模型提升了8%。
作者介紹
Sijun Tan(譚嗣俊)
譚嗣俊是UC伯克利計算機科學專業的三年級博士生,導師是Raluca Ada Popa。隸屬于伯克利的Sky Computing Lab。
此前,他在弗吉尼亞大學獲得計算機科學和數學雙學士學位,導師是David Wu和Yuan Tian。
他曾在Facebook AI Research(FAIR)實習過一段時間,并在螞蟻集團擔任過高級算法工程師。
他的研究領域涵蓋機器學習、計算機安全和應用密碼學。目前,其研究重點是增強通用型AI智能體的能力和魯棒性。
Michael Luo
Michael Luo目前是UC伯克利電氣工程與計算機科學系(EECS)的博士生,導師是Ion Stoica教授。
在此之前,他獲得了UC伯克利電氣工程與計算機科學碩士和工商管理雙學士學位。
他的研究興趣主要在人工智能和系統領域。目前,其研究主要是為機器學習從業者構建可擴展的系統,以實現Sky Computing的愿景。
Roy Huang
Roy Huang目前是UC伯克利計算機科學專業的大四學生,對CV和NLP領域的研究感興趣。