OA0
OA0 是一个探索 AI 的社区
现在注册
已注册用户请  登录
OA0  ›  代码  ›  Open-R1 — 社区复现推理模型训练流程的开源项目

Open-R1 — 社区复现推理模型训练流程的开源项目

 
  accord ·  2026-04-01 11:00:28 · 5 次点击  · 0 条评论  

Open R1

一个完全开源的 DeepSeek-R1 复现项目。此仓库仍在开发中,让我们一起构建它!

目录
1. 概述
2. 实施计划
3. 安装
4. 训练模型
- SFT
- GRPO
5. 评估模型
6. 复现 DeepSeek 的评估结果
7. 数据生成
- 从小型蒸馏 R1 模型生成数据
- 从 DeepSeek-R1 生成数据
8. 贡献

概述

本仓库的目标是构建 R1 流程中缺失的环节,使每个人都能复现并在此基础上进行开发。项目设计简洁,主要包含:

  • src/open_r1:包含训练模型以及生成合成数据的脚本:
    • grpo.py:在给定数据集上使用 GRPO 训练模型。
    • sft.py:在数据集上对模型进行简单的监督微调(SFT)。
    • generate.py:使用 Distilabel 从模型生成合成数据。
  • Makefile:包含易于运行的命令,用于执行上述脚本支持的 R1 流程中的每个步骤。

实施计划

我们将以 DeepSeek-R1 的技术报告为指南,大致可分为三个主要步骤:

  • 步骤 1:通过从 DeepSeek-R1 蒸馏高质量语料库,复现 R1-Distill 模型。
  • 步骤 2:复现 DeepSeek 用于创建 R1-Zero 的纯强化学习(RL)流程。这可能涉及为数学、推理和代码任务策划新的大规模数据集。
  • 步骤 3:展示通过多阶段训练,可以从基础模型演进到 RL 调优模型。



新闻 🗞️

  • 🧑‍🍳 [2025/05/26] (步骤 1 已完成!) 我们发布了 Mixture-of-Thoughts——一个包含 35 万条从 R1 蒸馏并经过验证的推理轨迹的精选数据集。该数据集涵盖数学、编程和科学任务,旨在教导语言模型进行逐步推理。我们还提供了训练 OpenR1-Distill-7B 的配方,该模型复现了 deepseek-ai/DeepSeek-R1-Distill-Qwen-7B 的推理能力,标志着 Open R1 项目步骤 1 的完成。
  • ⚡️ [2025/03/11] (更新 #3): 我们发布了 CodeForces-CoTs 数据集,包含 1 万个竞赛编程问题和 10 万个从 R1 蒸馏的解决方案。我们还发布了 IOI24:一个包含国际奥林匹克竞赛中非常困难问题的新基准。在 CodeForces-CoTs 上训练的 7B Qwen 模型在 IOI24 上可以超越 Claude 3.7 Sonnet,而 32B 模型甚至可以超越 R1 本身。
  • ∞ [2025/02/10] (更新 #2): 我们发布了 OpenR1-Math-220k 数据集,包含 22 万条从 R1 在新版 NuminaMath 上蒸馏的推理轨迹。在此数据集上训练的模型与 DeepSeek 蒸馏模型的性能相当。
  • 🔥 [2025/02/02] (更新 #1): 我们实现了训练推理评估流程的首批组件。开始吧!

安装

[!CAUTION]
相关库依赖 CUDA 12.4。如果遇到与段错误相关的错误,请使用 nvcc --version 仔细检查系统运行的版本。

要运行本项目中的代码,首先使用例如 uv 创建一个 Python 虚拟环境。
安装 uv,请遵循 UV 安装指南

[!NOTE]
作为快捷方式,可以运行 make install 来设置开发库(具体如下)。之后,如果一切设置正确,你可以尝试 Open-R1 模型。

uv venv openr1 --python 3.11 && source openr1/bin/activate && uv pip install --upgrade pip

[!TIP]
对于 Hugging Face 集群用户,请将 export UV_LINK_MODE=copy 添加到你的 .bashrc 中,以抑制来自 uv 的缓存警告。

接下来,安装 vLLM 和 FlashAttention:

uv pip install vllm==0.8.5.post1
uv pip install setuptools && uv pip install flash-attn --no-build-isolation

这将同时安装 PyTorch v2.6.0,使用此版本非常重要,因为 vLLM 二进制文件是针对此版本编译的。然后,你可以通过 pip install -e .[LIST OF MODES] 为你的特定用例安装剩余的依赖项。对于大多数贡献者,我们推荐:

GIT_LFS_SKIP_SMUDGE=1 uv pip install -e ".[dev]"

接下来,登录你的 Hugging Face 和 Weights and Biases 账户:

huggingface-cli login
wandb login

最后,检查你的系统是否安装了 Git LFS,以便能够加载模型/数据集并将其推送到 Hugging Face Hub:

git-lfs --version

如果未安装,请运行:

sudo apt-get install git-lfs

训练模型

[!NOTE]
下面的训练命令配置适用于 8 x H100s (80GB) 的节点。对于不同的硬件和拓扑结构,你可能需要调整批次大小和梯度累积步数。

我们支持使用 DDP 或 DeepSpeed(ZeRO-2 和 ZeRO-3)训练模型。例如,要在从 DeepSeek-R1 蒸馏的包含推理轨迹的数据集(如 open-r1/Mixture-of-Thoughts)上进行 SFT,请运行:

# 通过命令行训练
accelerate launch --config_file=recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --model_name_or_path open-r1/Qwen2.5-Math-7B-RoPE-300k \
    --dataset_name open-r1/Mixture-of-Thoughts \
    --dataset_config all \
    --eos_token '<|im_end|>' \
    --learning_rate 4.0e-5 \
    --num_train_epochs 5 \
    --max_seq_length 32768 \
    --per_device_train_batch_size 2 \
    --gradient_checkpointing \
    --bf16 \
    --use_liger_kernel \
    --output_dir data/OpenR1-Distill-7B

# 通过 YAML 配置文件训练
accelerate launch --config_file recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --config recipes/OpenR1-Distill-7B/sft/config_distill.yaml

目前支持以下任务:

  • 监督微调 sft
  • 组相对策略优化 grpo

[!TIP]
如果你增加/减少了 GPU 数量,我们建议同时调整每个设备的批次大小或梯度累积步数,以保持全局批次大小不变。

默认情况下,这些脚本会将每个模型推送到你的 Hugging Face Hub 用户名下,即 {username}/{model_name}-{task}。你可以通过以下方式在命令行中附加参数来覆盖每个 YAML 配置文件中的参数:

# 将基础模型更改为更小的变体
accelerate launch --config_file recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --config recipes/OpenR1-Distill-7B/sft/config_distill.yaml \
    --model_name_or_path Qwen/Qwen3-0.6B-Base \
    --hub_model_id OpenR1-Distill-0.6B \
    --output_dir data/OpenR1-Distill-0.6B

如果你还希望覆盖 Weights and Biases 的默认设置,可以按如下方式操作:

accelerate launch --config_file recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --config recipes/OpenR1-Distill-7B/sft/config_distill.yaml
    --wandb_entity huggingface --wandb_project open-r1 --run_name Qwen2.5-1.5B-GRPO

🚨 警告 🚨

大多数基础模型如 meta-llama/Llama-3.2-1B 没有聊天模板,因此我们在训练期间将 ChatML 设置为默认模板。然而,对于像 Qwen/Qwen2.5-1.5B 这样的 Qwen 基础模型,分词器中预定义了聊天模板,因此必须相应地设置 EOS 令牌,例如:

# 为 Qwen 基础模型对齐 EOS 令牌与聊天模板
accelerate launch --config_file=recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --model_name_or_path Qwen/Qwen2.5-1.5B \
+   --eos_token '<|im_end|>'
    --dataset_name open-r1/Mixture-of-Thoughts \
    --dataset_config all \
    --learning_rate 4.0e-5 \
    --num_train_epochs 1 \
    --max_seq_length 32768 \
    --per_device_train_batch_size 16 \
    --gradient_checkpointing \
    --bf16 \
    --use_liger_kernel \
    --output_dir data/Qwen2.5-1.5B-Open-R1-Distill

如果你希望使用自定义聊天模板(例如 Llama 或 Gemma),则必须提供聊天模板和相应的 EOS 令牌:

# 将 EOS 令牌与自定义聊天模板对齐
accelerate launch --config_file=recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --model_name_or_path meta-llama/Llama-3.2-1B \
+   --chat_template "$(cat llama_chat_template.jinja)" \
+   --eos_token '<|eot_id|>' \
    --dataset_name open-r1/Mixture-of-Thoughts \
    --dataset_config all \
    --learning_rate 4.0e-5 \
    --num_train_epochs 1 \
    --max_seq_length 32768 \
    --per_device_train_batch_size 16 \
    --gradient_checkpointing \
    --bf16 \
    --use_liger_kernel \
    --output_dir data/Llama-3.2-1B-Open-R1-Distill

SFT 蒸馏

我们提供了一个配方,用于从相同的基础模型开始,复现 deepseek-ai/DeepSeek-R1-Distill-Qwen-7B 的推理能力。为此,请运行:

ACCELERATE_LOG_LEVEL=info accelerate launch --config_file recipes/accelerate_configs/zero3.yaml \
    src/open_r1/sft.py \
    --config recipes/OpenR1-Distill-7B/sft/config_distill.yaml

结果将是一个类似 open-r1/OpenR1-Distill-7B 的模型,其下游性能如下:

模型 AIME 2024 MATH-500 GPQA Diamond LiveCodeBench v5
OpenR1-Distill-7B 52.7 89.0 52.8 39.4
DeepSeek-R1-Distill-Qwen-7B 51.3 93.5 52.4 37.4

你可以调整 YAML 配置,以在不同的基础模型或数据集上进行训练。

GRPO

我们使用 TRL 的 vLLM 后端来扩展训练,以支持跨多个节点的大型模型。对于在 8 个 GPU 上跨单个节点训练小型模型,使用 vllm_mode="colocate" 在与训练脚本相同的进程中运行 vLLM:

ACCELERATE_LOG_LEVEL=info \
    accelerate launch --config_file recipes/accelerate_configs/zero3.yaml \
    src/open_r1/grpo.py --config recipes/DeepSeek-R1-Distill-Qwen-1.5B/grpo/config_demo.yaml \
    --vllm_mode colocate

[!WARNING]
蒸馏的 DeepSeek 模型中使用的聊天模板省略了 <think></think> 标签内推理块的内容。它还用 <think> 预填充了助手响应,这会干扰格式奖励函数。为了处理这个问题,重要的是覆盖聊天模板,如 recipes/DeepSeek-R1-Distill-Qwen-1.5B/grpo/config_demo.yaml 中所做的那样。

对于在 N+1 个节点上进行多节点训练,其中 1 个节点运行 vLLM 服务器,N 个节点运行训练,我们提供了一个示例 Slurm 脚本。例如,要在 1+1 个节点上使用数据并行运行上述示例,请运行:

sbatch --nodes=2 slurm/train.slurm --model Qwen2.5-1.5B-Instruct --task grpo --config demo --accelerator zero2 --dp 8 --tp 1

更多详情请参见在 Slurm 集群上启动作业部分。

GRPO 数据集过滤

我们支持通过生成和计算可验证任务的通过率来过滤数据集,请参阅此 README

👨‍💻 使用代码解释器进行训练

我们提供了一个 code 奖励函数,用于执行训练期间策略生成的代码。目前,此奖励函数针对像 Codeforces 这样的代码竞赛,其中解决方案针对一组测试用例执行,并将整体成功率作为最终奖励返回。为确保安全执行,我们支持多种沙箱提供商:

  1. E2B - 快速、基于云的沙箱,专注于 Python 执行。
  2. Morph - 基于云的沙箱,支持更广泛的语言 - Python/JS/C++/Rust。

要使用代码奖励函数,首先安装必要的依赖项:

uv pip install -e '.[code]'
E2B 提供商

要使用 E2B 沙箱,创建一个 .env 文件并添加你的 E2B API 令牌:

E2B_API_KEY="e2b_xxx"
Morph 提供商

要使用 Morph,首先安装 morphcloud 包:

pip install morphcloud

然后将你的 Morph API 令牌添加到 .env 文件:

MORPH_API_KEY="YOUR_MORPH_API_KEY"

要指定使用哪个提供商,请在配置中添加 provider_type 参数:

# 对于 E2B
provider_type: e2b

# 对于 Morph
provider_type: morph
数据集要求

确保你的数据集包含一个 verification_info 列,其模式如下(改编自 PrimeIntellect 优秀的数据集):

{
    "language": "python",  # Morph 支持更多语言,包括 C++、Java 等。
    "test_cases": [
        {
            "input": "4\n4\n0001\n1000\n0011\n0111\n3\n010\n101\n0\n2\n00000\n00001\n4\n01\n001\n0001\n00001\n",
            "output": "1\n3 \n-1\n0\n\n2\n1 2 \n",
            "type": "stdin_stdout",
        }
    ],
}

例如,要在 Python 问题上训练一个小型模型,启动 vLLM 服务器:

```shell
CUDA_VISIBLE_DEVICES=0 trl vllm-serve --model Qwen/Qwen2.5-1.5

5 次点击  ∙  0 人收藏  
登录后收藏  
0 条回复
关于 ·  帮助 ·  PING ·  隐私 ·  条款   
OA0 - Omni AI 0 一个探索 AI 的社区
沪ICP备2024103595号-2
耗时 38 ms
Developed with Cursor