批判性思维能力将变得至关重要,要学会对接触到的信息保持理性质疑。
——达里奥·阿莫迪 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.