资讯动态

DeepSeek-R1技术报告解读:纯RL训练推理模型与GRPO实战指南

发布时间:2026/10/19 3:29:05 来源:尧图企业网站定制
简介这份资源是DeepSeek-R1技术报告的中文翻译版PDF面向大模型研究者、算法工程师及对强化学习推理感兴趣的进阶学习者帮助突破英文原文的阅读门槛系统理解推理模型的设计思路。压缩包内仅含1个PDF文件约1.9MB轻量便于随时查阅与打印。报告完整覆盖DeepSeek-R1-Zero与DeepSeek-R1的研发脉络包括基础模型上的强化学习、冷启动数据、多阶段训练、奖励建模与训练模板并深入探讨自我进化过程与顿悟时刻实验部分对比了AIME 2024、Codeforces、GPQA Diamond、MATH-500等基准表现还给出基于Qwen与Llama蒸馏的1.5B至70B六个密集模型方案。目前已有1523人学习适合希望掌握大规模RL训练推理能力、复现或改进相关工作的读者作为核心参考资料。1. 推理模型技术报告怎么读从一份中文版 PDF 说起很多人拿到一份推理模型的技术报告第一反应是从头读到尾结果读到第三页就被各种符号和公式劝退。我见过太多人把这类文档当成论文来啃最后只记住了几个名词真到要复现或者调参的时候还是两眼一抹黑。这份 DeepSeek-R1 技术报告的中文版价值不在于让你读完而在于让你能从中提取出可落地的训练流程、奖励设计和评测方法。它解决的核心问题是一个纯强化学习驱动的推理模型到底是怎么从基座模型一步步训出来的中间用了哪些奖励信号、哪些数据、哪些约束。适合谁看适合已经跑过 SFT、做过 RLHF 微调、想搞清楚推理能力能不能不靠大量标注数据冷启动的工程师。如果你连 PPO 和 GRPO 的区别都还没搞明白建议先把基础打一打再回来。2. 纯 RL 训练推理能力的核心机制拆解2.1 为什么不用 SFT 冷启动也能出推理能力传统做法是先收集大量带推理链的标注数据做 SFT再用 RL 微调。这份报告里最反直觉的结论是不做 SFT直接在基座模型上跑 RL模型自己就能涌现出长链推理行为。背后的逻辑是当奖励信号足够明确答案对错可验证模型在探索过程中会自发地延长思考步骤来提高答对概率。这就像让一个学生只告诉他答案对不对不教他解题步骤他自己会摸索出一套解题方法。但这里有个关键前提基座模型本身要有足够的语言理解和生成能力。如果基座太弱RL 阶段根本探索不到正确的推理路径梯度信号全是噪声。常见做法是选一个已经在大量语料上预训练过的模型作为起点而不是从随机初始化开始。2.2 GRPO 与 PPO 在推理任务上的选型差异报告里用的是 GRPOGroup Relative Policy Optimization不是 PPO。两者的核心区别在于优势函数的估计方式。PPO 需要一个独立的 Critic 网络来估计状态价值而 GRPO 直接用一组采样输出的平均奖励作为基线省掉了 Critic 网络。# GRPO 优势估计的简化逻辑伪代码 def grpo_advantage(rewards, group_size): # rewards: 同一 prompt 下采样 group_size 个输出的奖励列表 # 例如 rewards [1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0] mean_reward sum(rewards) / len(rewards) std_reward (sum((r - mean_reward) ** 2 for r in rewards) / len(rewards)) ** 0.5 advantages [(r - mean_reward) / (std_reward 1e-8) for r in rewards] return advantages这段代码说明 GRPO 的核心对同一个问题采样多个回答用这组回答的奖励均值做基线标准差做归一化。参数group_size一般设 4 到 16太小方差大太大显存吃不消。相比 PPO 需要额外训练一个和策略网络同等规模的 CriticGRPO 在显存和训练稳定性上都更友好。我一般会在推理任务上优先试 GRPO除非任务对状态价值估计特别敏感。2.3 规则奖励与格式奖励的组合策略报告里奖励信号分两部分准确性奖励和格式奖励。准确性奖励靠规则验证比如数学题比对最终答案、代码题跑测试用例。格式奖励要求模型把推理过程放在指定标签内比如thinking...和answer.../answer。import re def format_reward(output_text): 检查输出是否符合 thinking 和 answer 标签格式 think_pattern r thinking.*? answer_pattern ranswer.*?/answer has_think bool(re.search(think_pattern, output_text, re.DOTALL)) has_answer bool(re.search(answer_pattern, output_text, re.DOTALL)) if has_think and has_answer: return 1.0 elif has_think or has_answer: return 0.5 else: return 0.0 def accuracy_reward(output_text, ground_truth): 从 answer 标签中提取答案并与标准答案比对 match re.search(ranswer(.*?)/answer, output_text, re.DOTALL) if not match: return 0.0 predicted match.group(1).strip() return 1.0 if predicted ground_truth.strip() else 0.0格式奖励的权重不能太高否则模型会学会只输出标签不认真推理。我一般把格式奖励权重设在 0.1 到 0.3 之间准确性奖励占主导。如果发现训练后期模型输出全是空标签说明格式奖励给多了得往下调。2.4 训练流程的关键阶段划分整个训练分几个阶段先在基座上跑纯 RL 让推理能力涌现然后收集 RL 阶段的高质量输出做 SFT 数据再对模型做一轮 SFT 和 RL 的混合训练。这个顺序很重要反过来先做 SFT 再做 RL模型容易陷入模仿标注数据的模式反而限制探索。每个阶段的步数控制也有讲究。纯 RL 阶段一般跑几千步就能看到推理链变长但跑太久会出现重复输出和语言混杂。我一般会在验证集准确率连续几百步不涨的时候停下来而不是死磕固定步数。3. 从报告到本地复现环境、数据与训练配置3.1 本地复现的最小环境搭建要复现报告里的训练流程硬件上至少需要多卡 A100 或同级别显卡。单卡不是不能跑但 group_size 得压到 2 以下训练效果会打折扣。软件栈方面常见做法是基于开源的 RL 训练框架改比如在 HuggingFace Transformers 基础上自己写训练循环或者用已有的 RLHF 框架改奖励函数。# 创建环境并安装核心依赖版本号按实际可用版本调整 conda create -n reasoning_rl python3.10 -y conda activate reasoning_rl pip install torch2.1.0 transformers4.40.0 accelerate0.29.0 pip install datasets2.18.0 wandb0.16.0 pip install flash-attn --no-build-isolation这里flash-attn不是必须的但开了之后长序列训练显存能省不少。wandb用来记录奖励曲线和输出样本排查问题时比看 loss 有用得多。装完之后先跑一个单步前向确认模型能加载别等训练脚本写完了才发现环境有问题。3.2 训练数据的准备与格式要求数据格式很简单每条样本一个 prompt 加一个标准答案。prompt 是问题文本标准答案是用于规则验证的字符串。数学题的话标准答案就是最终数值代码题的话标准答案是测试用例的预期输出。from datasets import Dataset raw_data [ {prompt: 计算 3x 7 22 中 x 的值, answer: 5}, {prompt: 一个长方形长 8 宽 5面积是多少, answer: 40}, # ... 更多样本 ] def format_sample(example): return { prompt: example[prompt], answer: example[answer], } dataset Dataset.from_list(raw_data).map(format_sample) dataset dataset.train_test_split(test_size0.05, seed42)数据量不需要像 SFT 那么大几千到几万条就能看到效果。关键是答案必须能自动验证如果答案本身有歧义奖励信号就是错的训练必然翻车。我一般会先写一个验证脚本把数据集里所有答案跑一遍规则验证确认没有解析失败的样本再开始训练。3.3 训练超参数的具体设置与调整逻辑学习率是第一个要调的。纯 RL 阶段学习率一般设在 1e-6 到 5e-6 之间比 SFT 阶段小一个数量级。太大模型输出会崩太小推理能力涌现不出来。KL 散度系数控制在 0.01 到 0.1用来约束模型不要偏离基座太远。training_args { learning_rate: 2e-6, kl_coef: 0.04, group_size: 8, max_new_tokens: 2048, temperature: 1.0, top_p: 0.95, batch_size_per_device: 2, gradient_accumulation_steps: 8, num_train_epochs: 2, save_steps: 200, logging_steps: 10, }temperature在采样阶段设 1.0 是为了保证探索多样性太低的话 group 内输出几乎一样优势估计全是零。max_new_tokens设 2048 是给推理链留足空间但也不能太大否则显存爆炸。group_size设 8 是显存和效果之间的折中显存够的话可以往上加到 16。3.4 训练过程中的监控指标与早停判断重点盯三个指标验证集准确率、平均输出长度、KL 散度。准确率涨说明推理能力在提升输出长度涨说明模型在学会展开推理KL 散度涨太快说明模型偏离基座太远可能要崩。# 训练循环中的关键监控逻辑伪代码 for step, batch in enumerate(dataloader): outputs model.generate(batch[prompts], temperature1.0, max_new_tokens2048) rewards [compute_reward(o, a) for o, a in zip(outputs, batch[answers])] advantages grpo_advantage(rewards, group_size8) loss policy_loss(outputs, advantages) kl_coef * kl_divergence(model, ref_model) loss.backward() optimizer.step() if step % 10 0: avg_len sum(len(o) for o in outputs) / len(outputs) avg_reward sum(rewards) / len(rewards) print(fstep{step} reward{avg_reward:.3f} len{avg_len:.0f} kl{kl:.4f})如果平均输出长度突然从几百跳到几千同时准确率没涨说明模型学会了刷长度骗格式奖励这时候要么降格式奖励权重要么加长度惩罚。如果 KL 散度超过 0.5 还在涨建议回滚到上一个 checkpoint 重新调学习率。4. 避坑与排查训练推理模型时最容易翻车的五个地方4.1 奖励信号全是零导致梯度消失现象训练跑了几百步奖励一直是零loss 不降模型输出和基座一模一样。原因通常是任务太难基座模型在 group_size 次采样里一次都没答对优势估计全是零梯度信号消失。解决方法是先用简单任务热身比如两位数加减法等模型开始有正确输出后再逐步加难度。或者把 group_size 临时调大增加采样到正确答案的概率。4.2 格式奖励过高导致模型只输出标签不推理现象模型输出变成thinkinganswer42/answerthink 标签里是空的但格式奖励照样给满分。原因是格式奖励权重设太高模型发现不推理也能拿分。解决办法是把格式奖励权重降到 0.1 以下同时加一条规则think 标签内字符数少于一定阈值时格式奖励归零。4.3 训练后期语言混杂和重复输出现象模型开始中英文混着说或者反复输出同一句话。这是 RL 训练后期的常见退化原因是 KL 约束太松模型跑偏了。解决办法是提高 KL 系数或者降低学习率。我一般会在发现重复输出的第一个 checkpoint 就停下来用上一个 checkpoint 继续训而不是等它自己恢复。4.4 验证集准确率和训练奖励脱节现象训练奖励一直在涨但验证集准确率不涨甚至下降。这通常是奖励函数被 hack 了模型找到了规则验证的漏洞。比如数学题答案比对时没做归一化模型输出5.0而标准答案是5规则判错但模型觉得委屈。解决办法是把奖励函数写得更鲁棒数值比对做类型转换和精度截断代码题用多组测试用例而不是单组。4.5 显存溢出和训练中断恢复现象训练跑了几百步突然 OOM或者机器重启后不知道怎么接着训。原因是长序列生成时显存峰值波动大或者 checkpoint 保存间隔太长。解决办法是把max_new_tokens设一个合理上限同时在生成时用past_key_values缓存。checkpoint 保存间隔不要超过 200 步恢复训练时除了模型权重还要加载优化器状态和 scheduler否则学习率会从头开始。5. 进阶技巧用少量样本验证推理能力是否真的涌现5.1 设计一个最小验证集来快速判断训练是否有效不用等训练跑完准备 20 到 50 道有标准答案的题覆盖不同难度。每 100 步跑一次验证看准确率和输出长度的变化趋势。如果 500 步内准确率没动说明奖励设计或数据有问题继续跑也是浪费时间。def quick_eval(model, tokenizer, eval_set, max_new_tokens1024): correct 0 total_len 0 for item in eval_set: inputs tokenizer(item[prompt], return_tensorspt).to(model.device) with torch.no_grad(): outputs model.generate(**inputs, max_new_tokensmax_new_tokens, temperature0.6, do_sampleTrue) text tokenizer.decode(outputs[0], skip_special_tokensTrue) total_len len(text) if extract_answer(text) item[answer]: correct 1 return correct / len(eval_set), total_len / len(eval_set)这个函数返回准确率和平均输出长度两个值。准确率涨、长度也涨说明模型在学会推理。准确率不涨但长度涨说明模型在学会废话。准确率涨、长度不涨说明模型在学会直接给答案推理链没展开这时候要检查格式奖励是不是没生效。5.2 对比不同 group_size 对推理链质量的影响group_size 直接影响优势估计的方差。我做过一组对比group_size 设 4 时训练前期准确率波动很大因为组内样本太少均值估计不准设 8 时波动明显减小设 16 时效果最好但显存占用翻倍。如果显存有限建议设 8 并配合梯度累积来稳定训练。group_size显存占用训练稳定性推理链质量4低波动大一般8中较稳定较好16高稳定好5.3 用输出长度分布判断模型是否在真正推理把验证集上所有输出长度画成直方图。如果分布集中在很短的区间说明模型没展开推理如果分布很宽且有明显的长尾说明模型在根据题目难度自适应地调整推理步数。我一般会对比训练前后两个 checkpoint 的长度分布如果分布右移且准确率同步提升基本可以确认推理能力在涌现。5.4 一个我踩过的坑别在训练中途改奖励函数有一次训练到一半发现格式奖励给太高我直接在训练循环里改了权重结果模型行为突变准确率掉了一大截。后来才明白奖励函数一变之前积累的优化方向全乱了。正确做法是停下来用新奖励函数从头训或者至少回滚到改之前的 checkpoint。奖励函数的设计要在训练开始前就想清楚中途改代价很大。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑