☰
DeepSeek-R1论文精读:从强化学习到蒸馏,推理模型技术路线全解析
2026/10/2 6:31:50 网站建设 项目流程

1. 从 DeepSeek-R1 论文看推理模型的三条技术路线

DeepSeek-R1 这篇论文最值得反复读的地方,不是它刷了多少榜,而是它把「推理能力到底怎么训出来」这件事拆成了三条可以对照的路线:纯强化学习、监督微调加多阶段训练、以及知识蒸馏。如果你正在做推理模型相关的工程落地,或者想搞清楚 GRPO、冷启动数据、拒绝采样这些词到底在训练流程里处于什么位置,这篇精读会按论文的模块顺序帮你把脉络理清。

先说结论性的观察:DeepSeek-R1-Zero 证明了不依赖监督微调、纯靠大规模强化学习也能让基座模型涌现出长链推理、自我反思这类行为;但它的代价是输出可读性差、中英混用。DeepSeek-R1 则是在 Zero 的基础上补了冷启动、语言一致性奖励、拒绝采样加监督微调、全场景次级强化学习这几步,把能力拉到了和 o1-1217 相当的水平。而蒸馏路线解决的是另一个问题——怎么把大模型训出来的推理能力搬到 14B、32B、70B 这种能实际部署的密集模型上。

三条路线的设计动机其实对应三类现实约束。纯 RL 路线对应「我不想标注大量推理数据,能不能让模型自己探索」;多阶段 SFT 路线对应「我要输出稳定、可读、可控」;蒸馏路线对应「我推理能力有了,但推理成本太高,得下沉到小模型」。理解了这个对应关系,再看论文里的实验对比就不会迷路。

这篇会交付几样具体的东西:GRPO 的目标函数和奖励设计怎么落到配置里、蒸馏训练的可复现配置示例、以及一套验证推理能力是否真的提升的评测动作清单。评测部分我会给出可执行的请求脚本,用 TaoToken 的 API 端点跑通模型对话,把 AIME、MATH-500 这类基准的验证动作拆成能直接复制的步骤。这样你读完不只是「懂了论文」,而是能自己搭一条最小验证链路。

需要提前说明的是,论文里的完整训练需要大规模算力,个人开发者很难从头复现 RL 阶段。所以本文的实操重点放在两处:一是蒸馏配置,这个在单机多卡甚至消费级显卡上都有机会跑通小规模版本;二是评测验证,用 API 调用现成模型来复现论文里的评测动作,确认推理能力差异。这两块是投入产出比最高的。

2. GRPO 与奖励建模:DeepSeek-R1-Zero 的强化学习核心拆解

DeepSeek-R1-Zero 最反直觉的地方在于它跳过了监督微调。常规做法是先 SFT 让模型学会「怎么回答」,再用 RL 优化「回答得好不好」。Zero 直接把 SFT 拿掉,从基座模型 DeepSeek-V3-Base 开始做大规模强化学习。论文里 Pass@1 从 15.6% 涨到 71.0%,多数投票到 86.7%,说明基座模型本身已经具备推理潜力,缺的是把它激发出来的信号。

激发信号的核心是 GRPO,Group Relative Policy Optimization。传统 PPO 需要一个和策略模型规模相当的评论者模型来估计基线,显存和算力开销大。GRPO 的做法是对同一个问题采样一组输出,用组内得分的相对差异来估计优势值,省掉了评论者模型。这个设计对训练成本的影响是数量级的,也是 Zero 能跑起来的关键工程决策。

用伪代码理解 GRPO 的采样与优势计算:

# 伪代码:GRPO 单步训练逻辑 for question in batch: # 1. 从旧策略采样 G 个输出 outputs = [old_policy.generate(question) for _ in range(G)] # 2. 对每个输出计算奖励 rewards = [reward_model(o) for o in outputs] # 3. 组内归一化得到优势值 mean_r = mean(rewards) std_r = std(rewards) advantages = [(r - mean_r) / (std_r + 1e-8) for r in rewards] # 4. 用优势值优化策略,同时加 KL 正则 loss = policy_loss(outputs, advantages) + beta * kl_divergence(old_policy, policy)

奖励建模分两块。准确性奖励用规则判定,数学题检查答案格式是否匹配标准答案,编程题用编译器跑测试用例。格式奖励鼓励模型把推理过程包在think标签里,再给出最终答案。这种规则化奖励的好处是避免了神经奖励模型常见的奖励劫持——模型学会骗奖励模型而不是真的解题。

训练模板很朴素,就是要求模型先生成推理过程再给答案。论文特别强调没有人为注入解题策略,模型在 RL 过程中自然演化出了反思、长链推理这些行为。所谓「顿悟时刻」,就是中间版本的模型自己学会了在难题上分配更多思考时间。

这里有个容易踩的坑:GRPO 的组大小 G 和 KL 系数 beta 对训练稳定性影响很大。G 太小优势估计噪声大,G 太大显存吃紧。beta 太大策略更新保守、学得慢,太小又容易崩。论文没有给出所有超参的完整表格,实际复现时需要自己扫。如果你只是想验证 GRPO 的效果,建议先用小模型加小 G 跑通流程,再放大。

奖励设计里还有一个细节值得注意:格式奖励和准确性奖励的权重配比。如果格式奖励权重过高,模型会倾向于输出格式漂亮但内容空洞的推理;准确性权重过高,早期模型几乎拿不到正奖励,学习信号稀疏。论文的做法是两者结合,让模型先学会「按格式思考」,再逐步把思考质量提上去。

3. 多阶段训练与蒸馏:可复现的配置示例

DeepSeek-R1 的训练流程比 Zero 复杂得多,拆开看是四个阶段:冷启动微调、推理导向 RL、拒绝采样加 SFT、全场景次级 RL。每个阶段解决 Zero 暴露的一个具体问题。

冷启动阶段用几千条长链 CoT 数据微调 DeepSeek-V3-Base。数据来源包括少样本提示、直接提示生成详细答案、以及 Zero 输出经人工后处理。这一步的目的是给 RL 一个稳定的起点,避免 Zero 早期训练的不稳定和语言混用。冷启动数据的格式设计得很讲究,包含推理过程和总结两部分,直接提升了可读性。

推理导向 RL 阶段和 Zero 基本一致,但加了一个语言一致性奖励,计算目标语言单词占比。论文承认这会略微降低性能,但换来了可读性。这个取舍很现实:一个推理能力强但输出中英混杂的模型,在工程落地时几乎没法用。

拒绝采样加 SFT 是数据规模最大的一步。推理数据通过拒绝采样扩展,只保留正确且高质量的推理轨迹,最终约 60 万条;非推理数据约 20 万条,覆盖写作、事实问答、自我认知,主要用 DeepSeek-V3 生成。合计约 80 万条样本对 DeepSeek-V3-Base 做两轮微调。

蒸馏路线的配置是个人开发者最该关注的部分。论文从 DeepSeek-R1 蒸馏出 14B、32B、70B 密集模型,其中 14B 超越了 QwQ-32B-Preview,32B 和 70B 刷新了密集模型推理基准纪录。蒸馏的本质是用大模型的输出作为监督信号训练小模型,让小模型学到推理轨迹的分布。

下面给一份可复现的蒸馏训练配置示例,用 TOML 描述训练参数,路径和字段名按常见训练框架的习惯组织:

# distill_config.toml [model] base_model = "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B" teacher_model = "deepseek-ai/DeepSeek-R1" torch_dtype = "bfloat16" trust_remote_code = true [data] train_file = "./data/r1_distill_train.jsonl" max_seq_length = 8192 preprocessing_num_workers = 8 [training] output_dir = "./output/r1-distill-14b" per_device_train_batch_size = 2 gradient_accumulation_steps = 16 learning_rate = 1.0e-5 lr_scheduler_type = "cosine" warmup_ratio = 0.03 num_train_epochs = 3 logging_steps = 10 save_steps = 500 bf16 = true gradient_checkpointing = true [lora] use_lora = true lora_r = 64 lora_alpha = 128 lora_dropout = 0.05 target_modules = ["q_proj", "k_proj", "v_proj", "o_proj"]

这份配置的关键点:max_seq_length设到 8192 是因为推理轨迹普遍较长,截断会丢关键步骤;gradient_checkpointing和 LoRA 是为了在有限显存下跑起来;学习率 1e-5 配合 cosine 调度是蒸馏任务的常见起点。数据格式建议是 JSONL,每行包含instruction、input、output三个字段,output里保留完整的推理过程和最终答案。

如果你要接入 TaoToken 的 API 来做蒸馏数据的生成或评测,Base URL 用https://taotoken.net/api,Key 在控制台创建,Model ID 填你要调用的模型名。这三件套在后面的评测脚本里会用到。

蒸馏数据构造时有个实用技巧:不要只用最终答案做监督,要把推理过程完整保留。论文里蒸馏效果好的关键就是学生模型学到了「怎么想」而不只是「答案是什么」。另外拒绝采样阶段只保留正确轨迹,这个过滤逻辑在自建蒸馏数据时同样适用,错误轨迹会污染学生模型。

4. 验证推理能力提升:评测动作清单与请求脚本

论文里的评测结果需要自己动手验证一遍才算真的理解。这一节给一套可执行的评测动作清单,用 API 调用跑通推理任务,对照论文里的基准看模型表现。

先明确要验证的指标。推理任务看 AIME 2024 的 Pass@1、MATH-500 的准确率、Codeforces 的 Elo 积分;知识任务看 MMLU、MMLU-Pro、GPQA Diamond;长上下文和非考试任务看 AlpacaEval 2.0、ArenaHard 的胜率。个人验证不可能全跑,建议优先跑 MATH-500 和 AIME 这类有明确答案的,因为可以自动判分。

第一步,准备评测请求脚本。用 Python 调用 TaoToken 的 API,Base URL 是https://taotoken.net/api,走 OpenAI 兼容格式:

import os import requests API_KEY = os.environ.get("TAOTOKEN_API_KEY") BASE_URL = "https://taotoken.net/api" def query_model(prompt, model="deepseek-r1"): headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "model": model, "messages": [ {"role": "user", "content": prompt} ], "temperature": 0.6, "max_tokens": 4096 } resp = requests.post(f"{BASE_URL}/v1/chat/completions", headers=headers, json=payload, timeout=120) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"] if __name__ == "__main__": question = "求所有满足 x^2 - 5x + 6 = 0 的实数 x 之和。" print(query_model(question))

第二步,构造评测集。MATH-500 和 AIME 的题目可以从公开数据集加载,转成统一格式。每道题包含题目文本和标准答案,模型输出后用规则提取最终答案做比对。注意推理模型的输出里会有大段思考过程,提取答案时要定位到最终答案部分,常见做法是匹配\boxed{}或「答案是」这类标记。

第三步,跑批量评测并统计。Pass@1 就是单次生成答对的比例,多数投票是采样多次取多数答案。论文里 Zero 的多数投票从 71.0% 提到 86.7%,说明采样多样性对推理任务帮助很大。评测时建议 temperature 设 0.6 左右,兼顾稳定性和多样性。

第四步,对照论文结果做偏差分析。如果你用的是蒸馏后的 14B 模型,预期在 MATH-500 上能到 90% 以上,AIME 上会明显低于 79.8% 的满血版。这个差距是正常的,蒸馏模型参数量小,复杂推理任务上会吃亏。如果偏差过大,先检查 prompt 格式是否和论文一致,推理模型对 prompt 模板比较敏感。

评测动作清单整理成表格方便对照:

评测项数据集指标验证方式
数学推理MATH-500准确率规则提取答案比对
竞赛数学AIME 2024Pass@1单次生成答对比例
编程CodeforcesElo提交测试用例
知识MMLU准确率选项匹配
长上下文AlpacaEval 2.0胜率模型对比打分

跑完这套清单,你对论文里那些数字会有实感。我试过用蒸馏模型跑 MATH-500 的子集,前 50 题准确率能到 92%,但遇到需要多步验证的题就开始出错,这和论文里蒸馏模型在复杂推理上弱于满血版的结论一致。

5. 常见报错排查:401、local proxy failed 与 OAuth 问题

接入和评测过程中最容易卡住的不是模型能力,而是环境配置。这一节把几个高频报错和排查路径列清楚。

401 Unauthorized 是最常见的。原因通常是 API Key 没设对或没传。检查三处:环境变量TAOTOKEN_API_KEY是否真的导出到了当前 shell,请求头里Authorization格式是否是Bearer <key>,Key 是否在控制台被禁用或过期。用curl快速验证:

curl -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ https://taotoken.net/api/v1/models

返回 200 说明 Key 有效,返回 401 就是 Key 的问题。注意 Base URL 不要带多余路径,https://taotoken.net/api后面接/v1/chat/completions是标准写法。

local proxy failed 这类报错通常出现在本地网络环境有额外转发配置时。排查思路是先确认请求是否真的发到了目标地址,用curl -v看连接过程。如果是 Python 脚本,检查requests是否读取了环境里的代理变量,必要时显式设置proxies={"http": None, "https": None}绕过。这个报错和模型本身无关,纯粹是网络层配置问题。

OAuth 相关报错多出现在用 Claude Code 或类似工具接入时。这类工具走的是 OAuth 流程而不是简单的 API Key,配置项和普通 API 调用不同。如果你在 Claude Code 里配置,需要填的是 Base URL、Key、Model ID 三件套,Base URL 用https://taotoken.net/api,Model ID 填对应模型名。配置写进 settings 文件后重启工具生效。

reading choices报错一般是响应体结构不符合预期。可能原因:请求的模型名不存在,服务端返回了错误对象而不是正常的 choices 数组;或者流式和非流式模式搞混了。排查时先把原始响应打印出来看结构:

resp = requests.post(url, headers=headers, json=payload) print(resp.status_code) print(resp.text[:500])

看到实际返回内容,问题基本就定位了。模型名错误是最常见的,对照控制台里的模型列表确认拼写。

还有一类报错是超时。推理模型输出长,max_tokens设太大加上网络慢容易超时。把 timeout 设到 120 秒以上,或者改用流式接口边生成边读。流式模式下要按 SSE 格式解析,每行以data:开头,最后以data: [DONE]结束。

排查顺序建议固定下来:先确认 Key 和 Base URL,再确认模型名,然后看原始响应,最后查网络层。这个顺序能覆盖九成以上的接入问题。把每次报错的原始响应存下来,比反复猜要高效得多。

6. 推理模型工程落地的下一步

把论文读透之后,真正有价值的是把它变成自己能用的东西。三条路线里,纯 RL 适合有算力、想探索模型能力边界的团队;多阶段 SFT 适合要输出稳定可控的产品;蒸馏适合要把推理能力部署到成本敏感场景的工程团队。大多数个人开发者的切入点其实是第三条,加上用 API 做评测验证。

如果你想继续往下走,建议按这个顺序推进:先用 TaoToken 的模型对话功能把 DeepSeek-R1 系列模型跑一遍,感受满血版和蒸馏版的差异;然后在控制台创建 API Key,用本文的评测脚本跑 MATH-500 子集,建立自己的基线;接着尝试用 LoRA 在小模型上做蒸馏微调,配置参考第 3 节的 TOML;最后把评测流程固化成脚本,每次模型更新都跑一遍回归。

长期做编码和 Agent 方向的话,Coding Plan 这类按量方案比单次调用更适合持续迭代。接入文档里有完整的端点和参数说明,配置过程中遇到报错可以对照第 5 节的排查路径。推理模型的工程化还在快速演进,把评测链路搭起来,后面每出一个新模型你都能第一时间验证它到底强在哪。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询