在人工智能的浩瀚宇宙中,深度学习如同一颗璀璨的星星,吸引着无数研究者和开发者的目光。而在这片星空中,Open R1 项目无疑是一颗新崛起的星星,承载着重现和改进深度学习模型的使命。本文将带您深入了解 Open R1 的背景、目标、实施步骤以及如何参与这一激动人心的项目。
📜 项目概述:Open R1 的使命
Open R1 是一个旨在完全开放重现 DeepSeek-R1 的项目。其核心目标是构建 R1 流水线中缺失的部分,使每个人都能复现并在此基础上进行扩展。该项目的设计简洁明了,主要由以下几个部分组成:
- 源代码:包含训练和评估模型以及生成合成数据的脚本。
- Makefile:提供每个步骤的易于运行的命令,便于用户快速上手。
通过这些组件,Open R1 旨在为研究人员提供一个可重复的实验平台,推动深度学习领域的进一步发展。
🛠️ 攻击计划:逐步实施的蓝图
Open R1 的实施计划可以分为三个主要步骤:
- 模型复制:通过从 DeepSeek-R1 中提取高质量语料,复制 R1-Distill 模型。
- 纯强化学习流水线:重现 DeepSeek 用于创建 R1-Zero 的纯强化学习流水线,这可能涉及为数学、推理和代码等领域策划新的大规模数据集。
- 多阶段训练:展示如何从基础模型经过多阶段训练到达强化学习调优的效果。
这一计划的实施将为深度学习模型的训练和评估提供坚实的基础。
💻 安装指南:快速上手 Open R1
要运行 Open R1 项目的代码,您需要首先创建一个 Python 虚拟环境。以下是安装的步骤:
uv venv openr1 --python 3.11 && source openr1/bin/activate && uv pip install --upgrade pip
接下来,安装 vLLM 库:
uv pip install vllm==0.6.6.post1
# 对于 CUDA 12.1
pip install vllm==0.6.6.post1 --extra-index-url https://download.pytorch.org/whl/cu121
export LD_LIBRARY_PATH=$(python -c "import site; print(site.getsitepackages()[0] + '/nvidia/nvjitlink/lib')"):$LD_LIBRARY_PATH
确保安装 PyTorch 的版本为 v2.5.1
,这是 vLLM 二进制文件编译所需的版本。然后,您可以根据具体的使用场景安装剩余的依赖项。
🏋️♂️ 模型训练:从基础到强化学习
Open R1 支持使用 DDP 或 DeepSpeed(ZeRO-2 和 ZeRO-3)进行模型训练。您可以通过修改配置文件轻松切换训练方法。以下是两种主要训练方法的简介:
📈 SFT(监督微调)
要在从 DeepSeek-R1 中提取的带有推理轨迹的数据集上运行 SFT,您可以使用以下命令:
accelerate launch --config_file=configs/zero3.yaml src/open_r1/sft.py \
--model_name_or_path Qwen/Qwen2.5-Math-1.5B-Instruct \
--dataset_name HuggingFaceH4/Bespoke-Stratos-17k \
--learning_rate 2.0e-5 \
--num_train_epochs 1 \
--packing \
--max_seq_length 4096 \
--per_device_train_batch_size 4 \
--per_device_eval_batch_size 4 \
--gradient_accumulation_steps 4 \
--gradient_checkpointing \
--bf16 \
--logging_steps 5 \
--eval_strategy steps \
--eval_steps 100 \
--output_dir data/Qwen2.5-1.5B-Open-R1-Distill
🔄 GRPO(生成强化学习训练)
通过 GRPO 训练器进行训练时,您可以使用以下命令:
accelerate launch --config_file configs/zero3.yaml --num_processes=7 src/open_r1/grpo.py \
--output_dir DeepSeek-R1-Distill-Qwen-7B-GRPO \
--model_name_or_path deepseek-ai/DeepSeek-R1-Distill-Qwen-7B \
--dataset_name AI-MO/NuminaMath-TIR \
--max_prompt_length 512 \
--max_completion_length 1024 \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 16 \
--logging_steps 10 \
--bf16 \
--use_vllm \
--vllm_device auto \
--vllm_gpu_memory_utilization 0.7
通过这两种方法,您可以灵活选择最适合您需求的训练方式。
📊 模型评估:验证性能的关键
在 Open R1 中,模型评估是一个至关重要的环节。我们使用 lighteval
来评估模型,并在 src/open_r1/evaluate.py
中定义自定义任务。以下是一些评估模型的命令示例:
单 GPU 评估
MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
MODEL_ARGS="pretrained=$MODEL,dtype=float16,max_model_length=32768,gpu_memory_utilisation=0.8"
TASK=aime24
OUTPUT_DIR=data/evals/$MODEL
lighteval vllm $MODEL_ARGS "custom|$TASK|0|0" \
--custom-tasks src/open_r1/evaluate.py \
--use-chat-template \
--system-prompt="Please reason step by step, and put your final answer within \boxed{}." \
--output-dir $OUTPUT_DIR
多 GPU 评估
对于需要跨多个 GPU 的大模型,您可以使用张量并行:
NUM_GPUS=8
MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
MODEL_ARGS="pretrained=$MODEL,dtype=float16,tensor_parallel_size=$NUM_GPUS,max_model_length=32768,gpu_memory_utilisation=0.8"
TASK=aime24
OUTPUT_DIR=data/evals/$MODEL
export VLLM_WORKER_MULTIPROC_METHOD=spawn
lighteval vllm $MODEL_ARGS "custom|$TASK|0|0" \
--custom-tasks src/open_r1/evaluate.py \
--use-chat-template \
--system-prompt="Please reason step by step, and put your final answer within \boxed{}." \
--output-dir $OUTPUT_DIR
通过这些评估方式,您可以全面了解模型的性能表现,从而为后续的优化提供依据。
🔍 重现 DeepSeek 在 MATH-500 上的评估结果
Open R1 还能够重现 DeepSeek 在 MATH-500 基准测试中报告的结果。以下是一些模型在 MATH-500 上的表现:
模型 | MATH-500 (HF lighteval) | MATH-500 (DeepSeek 报告) |
---|---|---|
DeepSeek-R1-Distill-Qwen-1.5B | 81.6 | 83.9 |
DeepSeek-R1-Distill-Qwen-7B | 91.8 | 92.8 |
DeepSeek-R1-Distill-Qwen-14B | 94.2 | 93.9 |
DeepSeek-R1-Distill-Qwen-32B | 95.0 | 94.3 |
DeepSeek-R1-Distill-Llama-8B | 85.8 | 89.1 |
DeepSeek-R1-Distill-Llama-70B | 93.4 | 94.5 |
要重现这些结果,您可以使用以下命令:
sbatch slurm/evaluate.slurm deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B math_500
sbatch slurm/evaluate.slurm deepseek-ai/DeepSeek-R1-Distill-Qwen-7B math_500
sbatch slurm/evaluate.slurm deepseek-ai/DeepSeek-R1-Distill-Qwen-14B math_500
sbatch slurm/evaluate.slurm deepseek-ai/DeepSeek-R1-Distill-Qwen-32B math_500 tp
sbatch slurm/evaluate.slurm deepseek-ai/DeepSeek-R1-Distill-Llama-8B math_500
sbatch slurm/evaluate.slurm deepseek-ai/DeepSeek-R1-Distill-Llama-70B math_500 tp
通过这些命令,您可以轻松重现 DeepSeek 的评估结果,为您的研究提供有力支持。
📊 数据生成:丰富训练集的关键
在训练模型的过程中,数据的质量和多样性至关重要。Open R1 提供了生成合成数据的功能,以丰富训练集。
从小型 R1 模型生成数据
以下是一个示例,展示如何从小型 R1 模型生成数据:
from datasets import load_dataset
from distilabel.models import vLLM
from distilabel.pipeline import Pipeline
from distilabel.steps.tasks import TextGeneration
prompt_template = """\
You will be given a problem. Please reason step by step, and put your final answer within \boxed{}:
{{ instruction }}"""
dataset = load_dataset("AI-MO/NuminaMath-TIR", split="train").select(range(10))
model_id = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B" # 替换为其他小型 R1 模型
with Pipeline(
name="distill-qwen-7b-r1",
description="A pipeline to generate data from a distilled r1 model",
) as pipeline:
llm = vLLM(
model=model_id,
tokenizer=model_id,
extra_kwargs={
"tensor_parallel_size": 1,
"max_model_len": 8192,
},
generation_kwargs={
"temperature": 0.6,
"max_new_tokens": 8192,
},
)
prompt_column = "problem"
text_generation = TextGeneration(
llm=llm,
template=prompt_template,
num_generations=4,
input_mappings={"instruction": prompt_column} if prompt_column is not None else {}
)
if __name__ == "__main__":
distiset = pipeline.run(dataset=dataset)
distiset.push_to_hub(repo_id="username/numina-deepseek-r1-qwen-7b")
从 DeepSeek-R1 生成数据
对于更大的 DeepSeek-R1 模型,您可以使用以下命令生成数据:
sbatch slurm/generate.slurm \
--hf-dataset AI-MO/NuminaMath-TIR \
--temperature 0.6 \
--prompt-column problem \
--model deepseek-ai/DeepSeek-R1 \
--hf-output-dataset username/r1-dataset
通过这些数据生成方法,您可以为模型训练提供丰富的训练数据,提升模型的性能。
🤝 参与贡献:共同构建 Open R1
Open R1 项目欢迎所有对深度学习感兴趣的研究者和开发者参与贡献。无论是代码贡献、文档编写还是提出建议,您的参与都将为项目的发展注入新的活力。
您可以通过访问 Open R1 GitHub 页面 来了解更多信息并参与讨论。
📝 结语
Open R1 项目不仅是一个深度学习模型的重现平台,更是一个开放合作的社区。通过共同的努力,我们可以推动深度学习技术的进步,为未来的人工智能发展铺平道路。让我们一起探索这片未知的领域,共同书写深度学习的新篇章!