批判性思維能力將變得至關重要,要學會對接觸到的信息保持理性質疑。
——達里奧·阿莫迪 Anthropic CEO
這是向DeepSeek深度求索的第三篇思考,也是前一篇《》的信息補遺,我覺得這三篇看下來,基本能對DeepSeek的底層原理“祛魅”了。
寫這篇的原因,來自對自己的批判性質疑。
在解讀DeepSeek-R1論文的過程中,我一直擔心對著文字倒推流程,會丟失一些實現細節,并為此做了聲明:
由于原文在某些地方的描述過于簡略和抽象,圖中的部分模塊是我基于自己的理解完成的。 申悅,公眾號:互聯網悅讀筆記
我的推演會不會有問題?有沒有什么辦法來驗證我的思考是正確的呢?恰好這時候,我有看到新智元的一篇文章:
其中有提到,全球最大的開源平臺HuggingFace團隊,官宣復刻了DeepSeek R1的所有pipeline。并開源了訓練數據和訓練腳本。
![]()
看到這兒我可就不困了,簡直是及時雨!如果有能復現R1的完整代碼和語料庫,就能很大程度驗證我的猜想,同時還能從代碼層進一步搞懂R1的實現邏輯。
于是按圖索驥,我下載了這個叫Open R1的代碼庫(項目地址:https://github.com/huggingface/open-r1)。
![]()
Open R1的首頁,詳細介紹了這套代碼庫的文檔結構,尤其是他們如何依據DeepSeek-R1技術報告來復刻還原的,其核心流程有三個步驟:
![]()
第一步:通過從DeepSeek-R1中蒸餾高質量語料庫來復現R1-Distill模型。對應第1張圖,核心思路是利用蒸餾R1后的推理數據,來微調一個小模型,讓這個小模型達到R1-Distill的效果。而這個流程,和是類似的。
第二步:復現DeepSeek創建R1-Zero所使用的純強化學習(RL)流程。對應第2張圖,關鍵動作就是實現了GRPO的獎勵模型,最終訓出了Open R1-Zero,這其中獎勵函數如何設計,也是我非常感興趣的。
第三步:展示如何通過多階段訓練,從基礎模型進化到RL調優的模型。對應第3張圖,本質就上是把前兩張圖的流程串起來。相比我梳理的流程,這第三步顯得簡單的多,沒有分別準備Reasoning和非Reasoning數據,也沒有增加“語言一致性”獎勵這樣的細節描述,甚至只經歷了一個階段的2次訓練。而且看完代碼后我發現,這個開源項目也并沒有實現這第三步的代碼。
當然,人家在首頁也明說了:
This repo is a work in progress, let's build it together!
(此倉庫正在開發中,讓我們一起構建它吧!)
看起來還處于未完成狀態,不過也沒關系,光學習第一和第二步,對我而言就已經很有價值了。好,那接下來,我們就來從代碼層詳細解讀一下Open R1是如何做SFT(監督微調)和GRPO(分組相對策略優化)的。
在數據集上對模型執行簡單SFT
代碼庫中,所有和SFT相關的代碼,都放在sft.py里。源碼讀起來不難,算上注釋也就202行,也順便刷新了我的認知——原來做大模型開發,也沒有想象中那么復雜。
通讀完代碼后發現,實際的訓練過程,會比示意圖中要復雜一些。為方便理解,我把原圖做了擴展,順著代碼執行邏輯,重新梳理了這樣一張圖:
![]()
可以看到,在代碼中,已經為微調準備好了一組訓練數據,不需要經由DeepSeek-R1重新蒸餾了,這組數據就是圖中黃框部分的:HuggingFaceH4/Bespoke-Stratos-17k(地址:https://huggingface.co/datasets/bespokelabs/Bespoke-Stratos-17k)
這是由Bespoke Labs創建的推理數據集,這個數據集改進了伯克利的Sky - T1項目,包含問題、推理軌跡和答案。數據的類型由:代碼、數學和科學謎題組成,格式如上圖所示,分:system和conversations兩列數據,我分別取了其中的一組實例放在圖上,幫大家理解。
system代表系統提示詞,每一行都是一樣的,目的是指定模型輸出的格式和要求,conversations則把用戶提示詞和模型返回的帶推理信息的答案合并到了一起。其中的推理軌跡內容,就來自對DeepSeek-R1的SFT蒸餾。因此也確實可以認為,這是由DeepSeek-R1蒸餾過的帶推理信息的數據集。
這里我特地標紅了一塊區域,代表這個數據集,只有訓練數據(train split),并未找到驗證數據集(test split)。這會導致模型訓練過程不穩定,難以達到理想性能,同時代碼執行也會出錯,后面我會再詳細說明。
接下來進入正式監督微調環節,從左向右看,用來被訓練的基座模型,是阿里的Qwen2.5-1.5B-Instruct,這也是Qwen大語言模型的最新系列。
完整的監督微調過程,會先讀取數據集,再初始化模型參數和SFT訓練器參數,之后執行循環訓練,直到損失函數收斂到可接受程度,對模型保存輸出,命名新模型為:Qwen2.5-1.5B-Open-R1-Distill。其核心代碼如下圖,我對關鍵位置都做了箭頭指示:
![]()
圖中標問號的那行代碼,對應著上文提到的驗證數據集缺失的問題:代碼運行時,會判斷是否包含驗證測試集,如果不包含,但同時又要求在訓練過程中做評估(training_args.eval_strategy=steps),那這行代碼會拋異常報錯,也不知道官方有沒有發現這個Bug……
當然,這問題的解法也很簡單——換個有測試數據的數據集就可以了,或者切分原有訓練數據的一部分放到測試集中,都是可以的。修復這問題后,一個簡單的SFT訓練過程就完成了。
在這個過程中,我感覺花時間最多的,不是寫代碼,而是準備數據、選擇合適的預訓練模型、明確參數、打好日志記錄,再根據評估結果持續優化模型結構和訓練策略。光參數配置就有幾十項,要搞清楚這不同參數值會如何影響最終訓練結果,也是非常需要經驗和判斷力的,怪不得算法研究員這么貴呢。
在給定數據集上使用GRPO訓練模型
GRPO的訓練過程是在grpo.py中實現的,其流程會比SFT復雜些,但代碼總長度仍舊只有兩百多行,同樣我也畫出了它的流程圖:
![]()
首先是數據部分。從代碼上看,用來做GRPO訓練的推理數據,也是提前準備好的,這是huggingface上的一套叫AI-MO/NuminaMath-TIR的數據集(地址:https://huggingface.co/datasets/AI-MO/NuminaMath-TIR)。主要用于推理任務,特別是涉及數值輸出的數學問題。
有意思的是,我查了它的出處,相比其他推理數據,這套數據集的推理軌跡,是用GPT-4o來撰寫python代碼,把解題的源代碼作為推理數據,因此叫TIR(Tool Integrated Reasoning工具集成推理)。最終能得到比普通數學解題思維鏈效果更好的推理軌跡,方法極其巧妙,如下圖:
![]()
貢獻數據集的團隊叫Numina,他們用上述思路訓出的數學模型,直接在人工智能數學奧林匹克競賽(AIMO)中獲得了第1名,有興趣的讀者可以到項目的github主頁去看看(地址:https://github.com/project-numina/aimo-progress-prize)。更讓我驚訝的是,他們在構建數據集時,廣泛參考了DeepSeek Math的方法,所以繞了一圈,還是逃不開DeepSeek的“魔爪”。
相比SFT的Bespoke-Stratos-17k,AI-MO/NuminaMath-TIR倒是完整包含了訓練數據集(train split)和測試數據集(test split),二者的格式相同,都由:problem(問題)、solution(解題推理過程和答案)、messages(問題+推理答案合集),如下圖:
![]()
其中messages中包含冗余的solution信息,而獎勵規則只需判斷solution中的結果即可,為避免干擾訓練過程,會在后續處理中刪掉messages列,因此圖中我做了劃線標記,大家只需關注前兩列即可,具體的示例我也放在了圖上。
數據準備好后,回到GRPO的訓練流程,從左往右看,這次用的預訓練模型,是蒸餾DeepSeek-R1訓出的Qwen-1.5B模型,相比SFT所用的Qwen2.5-1.5B-Instruct,會有更好的長思維鏈推理能力。完整訓練流程見下圖藍色部分:
![]()
先讀取數據集。由于該數據集中并不包含system提示詞,因此要將數據集中的樣本重新格式化,增加system prompt,在其中指定好輸出要求,并把原數據集中的problem作為user prompt放入代碼的提示詞框架中。
接下來和我上文提到的一樣,要移除干擾項messages列。
之后初始化GRPO的各項訓練參數,就可以執行兩個獎勵函數進行訓練了。主流程和SFT訓練過程差不多。
在源碼中,完整還原了準確性獎勵函數accuracy_reward和格式獎勵函數format_reward的實現流程。方法也并不復雜,抽象來看就3步。
準確性獎勵
第一步調用模型,根據訓練集中每個樣本的problem,生成多個答案,如上圖,可能會生成:
The answer is28
The result is21
這2個答案;
第二步,將這多個答案,和訓練集中的正確答案:28做對比;
第三步,如果相等,獎勵1分,如果不等,獎勵0分,其實現細節如下圖,關鍵代碼就一行:
![]()
格式獎勵
第一步調用模型,仍由每個problem生成多個答案;
第二步,對這些答案,不去對比solution中的結果,而是只看正則是否匹配 xxx xxx 這樣的格式;
第三步,如果匹配,獎勵1分,如果不匹配,給0分。代碼如下圖,也不過就4行:
![]()
之后的流程就還是循環執行訓練,直到符合要求,輸出名為Qwen2.5-1.5B-Open-R1-GRPO的模型。
總結
到這里,我就算基本搞懂HuggingFace是怎么還原DeepSeek R1核心訓練算法的了(其中有不對的地方,也歡迎隨時指正)。整體回看下來,結合前2篇對DeepSeek從論文層面的解構,在這里特別想給大家再分享我的三點底層思考:
模型訓練,數據為王
AI圈一直有個共識,如今要進一步提升模型性能,數據是瓶頸,之前還不太理解,這次深扒代碼后才真正意識到:訓模型的關鍵,不是代碼該怎么寫,也不是參數該設置成多少,而是數據對訓好一個模型的重要性。
可以看到,無論SFT,還是GRPO,訓練數據集都是精心篩選過的。
用來做SFT的Bespoke-Stratos-17k,包含1.67w行,125MB大小,每一行都有著上千個單詞詳細描述其推理過程。為GRPO提供數據的Numina團隊,也在AI-MO/NuminaMath-TIR的首頁提到:
However, collecting and annotating such data is both costly and time-consuming. (收集和標注此類數據既昂貴又耗時)
而對模型推理能力而言,訓練數據的詳細程度直接決定了推理能力訓練的好壞,這其中包括數據的多樣性、覆蓋范圍、對推理步驟描述的詳盡程度等等,甚至還可以衍生出創新的數據生成思路(比如Numina用代碼描述數學運算的過程)。如果在看這篇文章的你正在思考如何切入大模型領域,我覺得這就是未來涌現新機遇的方向。
用思考過程反推模型能力
模型再強大,也要可落地,對我們普通人而言,又不需要去訓模型或者做標注,可以如何從豐富的推理數據中獲益呢?
我覺得一方面,越是強大的推理模型,其推理過程數據肯定是越有價值的。因此可以通過觀察模型的思考軌跡,大致推斷這款模型在推理能力上的強弱。舉個例子,同樣問一個問題:
訓練數據和模型推理能力相關這個道理,對普通人有什么啟發?
Kimi的思考過程,只從“做事”的角度,把模型訓練和日常生活做了關聯。
而DeepSeek,除了考慮到“做事”,還關聯了“做人”,會從不同人群的角度對這個問題做拆解。二者高下,一看便知。
![]()
把模型當人,反思自我
就像我在《》這篇文章中提到的,普通人完全可以學習模型的推理思路,像訓練AI一樣訓練自己、審視自己。
借「AI見識群」里群友的一句話:
DeepSeek的價值,特別在于它能讓用戶認為,不是AI不夠聰明,而是自己不會表達。當看完AI的思考過程,就會自審,是自己膚淺了,問的不夠好。
之前的模型,只會讓人覺得答非所問,是模型蠢。而當用戶看到了模型的推理過程,就會把它當做一個“人”,感受到這個“人”的想法,從而極大提升人類對AI的認同感,而不是危機感。
此外,DeepSeek拆解問題、多角度分析問題的方法,尤其對產品經理、投資人和創業者特別有幫助,因為這類角色每天要做的事,就是擴展視野、洞察機會、解構問題。
具體的使用方法,可以先從一個模糊的問題開始,讓AI幫自己打開思路,再針對其中的細節進行反復對話和批判性探討(簡單來講就是不斷追問“為什么”),可以極大程度鍛煉慢思考能力。都說所有行業,都值得用AI做一遍,我想再加一句,所有行業的方法論,都值得用DeepSeek再梳理一遍!
知道了這一點,下次當用戶提出“我想要一匹更快的馬”的時候,何不試試先問問AI,看它是不是能推理出用戶真正想要的是什么?
我是申悅,前360產品總監、36氪產品負責人,目前AII in AI,瘋狂鉆研中。歡迎加我好友互相交流
回復“ 微信 ”,加我 個人微信
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.