基于 slime 框架的 128xH100 DeepSeek R1 大规模 RL 训练实战指南【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime本指南以 slime 开源仓库中的 DeepSeek R1 训练示例 为核心完整讲解如何在 128 张 H10016 节点 × 8 卡上复现 DeepSeek R1 的强化学习训练包括 fp8 检查点的 bf16 还原与 torch dist 格式转换、多机 Ray 集群搭建、以及 slime 在 Megatron训练与 sglang推理两侧的并行参数、CPU Adam 显存优化、dynamic sampling 数据筛选等核心配置。读完本文你将掌握一套可直接复制执行的超大模型 RL 训练配方并理解每个关键参数背后的源码级原理。一、示例概览128xH100 上的训练配方本示例在 128 张 H10016 个节点每节点 8 卡上对 DeepSeek R1 进行 RL 训练整体技术路线如下训练精度使用 bf16 训练推理精度使用 128x128 blockwise quant 的 fp8 格式进行推理直接复用 DeepSeek-R1 官方 fp8 检查点回复长度模型最大回复长度为 32k--rollout-max-response-len 32768数据筛选训练中使用 dynamic sampling 对数据进行筛选丢弃整组全对/全错的低质量样本并行方案sglang推理侧启用 ep64开启 dp attention 与 deepepMegatron训练侧tp8、pp4、ep32、cp4。显存策略为节省 GPU 显存示例使用 CPU Adam每个节点8xH100约占用 1.4~1.5B 内存。如果单机内存不够可以通过增加 GPU 数量、扩大并行度如加大 tp/ep 维度的方式摊薄内存开销。二、环境准备搭建环境与下载数据的方法可以参考同目录下的 示例Qwen3-4B其核心步骤包括拉取slimerl/slime:latest镜像进入容器后执行git clonepip install -e . --no-deps安装 slime准备训练数据如zhuzilin/dapo-math-17k与评估数据如zhuzilin/aime-2024。2.1 下载 DeepSeek-R1 检查点DeepSeek-R1 需要下载到一个多机均可访问的共享地址下文记为$BASE_DIRhf download deepseek-ai/DeepSeek-R1 --local-dir $BASE_DIR/DeepSeek-R12.2 fp8 检查点转 bf16DeepSeek-R1 的 HuggingFace 官方检查点是block-quant 的 fp8 格式而 Megatron 无法直接加载这种格式。要转换出一个 Megatron 可加载的 torch dist 格式第一步是先把它还原为 bf16 的 HuggingFace 检查点cd slime/ python tools/fp8_cast_bf16.py --input-fp8-hf-path $BASE_DIR/DeepSeek-R1 --output-bf16-hf-path $BASE_DIR/DeepSeek-R1-bf16/从 tools/fp8_cast_bf16.py 的源码可以看到该工具的实现细节使用 Triton 编写了 weight_dequant kernel以 128x128 的 block 为单位将 fp8 权重与其_scale_inv缩放因子做反量化y x * s这与示例采用的 128x128 blockwise quant 精度方案一一对应遍历全部*.safetensors文件跳过*_scale_inv张量将 fp8 权重weight.element_size() 1反量化为 bf16 后写出同时保留config.json、tokenizer、chat_template 等元文件并更新model.safetensors.index.json移除已消费的_scale_inv条目保证转换产物可直接被标准 HF 加载器读取。2.3 bf16 检查点转 torch dist 格式随后将 bf16 版 DeepSeek-R1 转换为 torch dist 格式。由于模型规模较大需要在4 台机器上分别执行每台 8 卡合计 32 卡并行转换cd slime/ source scripts/models/deepseek-v3.sh PYTHONPATH/root/Megatron-LM/ torchrun \ --nproc-per-node 8 \ --master-addr ${MASTER_ADDR} --master-port 12345 \ --nnodes4 --node-rank ${NODE_RANK} \ tools/convert_hf_to_torch_dist.py \ ${MODEL_ARGS[]} \ --tensor-model-parallel-size 1 \ --pipeline-model-parallel-size 8 \ --expert-tensor-parallel-size 1 \ --expert-model-parallel-size 4 \ --decoder-first-pipeline-num-layers 7 \ --decoder-last-pipeline-num-layers 6 \ --hf-checkpoint $BASE_DIR/DeepSeek-R1-bf16/ \ --save $BASE_DIR/DeepSeek-R1_torch_dist/其中MASTER_ADDR为 node0 的 IPNODE_RANK表示这是第几台机器两者与多机torchrun时的配置方式一致。--decoder-first/last-pipeline-num-layers用于处理层数无法被 pipeline 深度整除的情况61 层分 8 段保证转换与后续训练时的层切分完全对齐。三、执行训练多机 Ray 集群与训练脚本3.1 启动训练在 node0 上运行cd slime/ bash scripts/run-deepseek-r1.shscripts/run-deepseek-r1.sh 脚本本身已经完成了大量环境准备清理残留的 sglang / ray / python 进程、检测 NVLink 拓扑、source模型配置、启动 Ray head 节点ray start --head --node-ip-address ${MASTER_ADDR} --num-gpus 8最后通过ray job submit将 train.py 提交到集群训练与推理在 16 节点共 128 卡上**训推一体colocate**运行。3.2 其余节点加入 Ray 集群在其他节点需要通过如下指令加入 Ray 集群ray start --address${MASTER_ADDR}:6379 --num-gpus 8 --node-ip-address ${WORKER_IP} --disable-usage-stats如果能够获取到所有节点的 IP 列表例如有一份 mpi hostfile每行为ip slot8则可以在scripts/run-deepseek-r1.sh中ray start --head指令之后追加如下逻辑从而只需要从 node0 一键执行for WORKER_IP in $(awk {print $1} $BASE_DIR/mpi_hostfile); do if [[ $WORKER_IP $MASTER_ADDR ]]; then continue fi echo Starting Ray worker on ${WORKER_IP} ssh root${WORKER_IP} \ pkill -9 sglang ; ray stop --force ; pkill -9 python ; ray start --address${MASTER_ADDR}:6379 --num-gpus 8 --node-ip-address ${WORKER_IP} --disable-usage-stats done wait注意脚本通过export no_proxy127.0.0.1,${MASTER_ADDR}与 runtime-env 中的no_proxy环境变量规避代理对 Ray 内部通信的干扰并设置了CUDA_DEVICE_MAX_CONNECTIONS1、NVSHMEM_DISABLE_NCCL1等关键环境变量在多机大规模并行下不可省略。四、参数详解逐段拆解训练脚本run-deepseek-r1.sh将全部训练参数按职责分为 8 组MODEL / CKPT / ROLLOUT / EVAL / PERF / GRPO / OPTIMIZER / SGLANG / MISC下面逐组说明。4.1 MODEL_ARGS模型结构配置SCRIPT_DIR$(cd -- $(dirname -- ${BASH_SOURCE[0]}) /dev/null pwd) source ${SCRIPT_DIR}/models/deepseek-v3.sh脚本通过source scripts/models/deepseek-v3.sh读取模型 config。这些 config 全部是Megatron 参数在使用 Megatron 训练时Megatron 无法从 ckpt 中读取模型结构需要自行配置。slime 在 scripts/models 目录下为常见模型提供了开箱即用的样例。从 scripts/models/deepseek-v3.sh 可以看到 DeepSeek-R1 的完整结构定义其中几个关键点MLA 注意力--multi-latent-attention配合--q-lora-rank 1536、--kv-lora-rank 512、--qk-head-dim 128、--qk-pos-emb-head-dim 64、--v-head-dim 128、--qk-layernorm并设置--rotary-scaling-factor 40、--mscale 1.0、--mscale-all-dim 1.0MoE 结构--num-experts 256、--moe-layer-freq前 3 层为 dense其余 58 层为 MoE由脚本自动生成频率数组、--moe-ffn-hidden-size 2048、--moe-router-topk 8、--moe-shared-expert-intermediate-size 2048、--moe-router-group-topk 4、--moe-router-num-groups 8、--moe-router-topk-scaling-factor 2.5其他--num-layers 61、--hidden-size 7168、--vocab-size 129280、--swiglu、--untie-embeddings-and-output-weights、--no-rope-fusion等。⚠️ 注意DeepSeek-R1 与同结构的其他版本如 deepseek-v3在--rotary-base等超参上可能不同务必核对与所加载权重是否一致。4.2 CKPT_ARGS检查点与量化配置CKPT_ARGS( # sglang 需要的 hf ckpt我们也会从这里读 tokenizer --hf-checkpoint $BASE_DIR/DeepSeek-R1/ #--hf-checkpoint $BASE_DIR/DeepSeek-R1-bf16/ --ref-load $BASE_DIR/DeepSeek-R1_torch_dist/ # actor 的 load dir如果是空的会从 ref_load 里面读 --load $BASE_DIR/DeepSeek-R1_slime/ --save $BASE_DIR/DeepSeek-R1_slime/ --save-interval 20 )--hf-checkpointsglang 推理所需的 HF 检查点tokenizer 也从这里读取。示例直接使用官方的fp8 block-quant 版本--ref-loadreference modelKL 计算用加载的 torch dist 检查点--load/--saveactor 的加载与保存目录如果--load为空会从--ref-load读取初始权重--save-interval 20每 20 步保存一次检查点。在线量化机制slime 会根据--hf-checkpoint中的量化配置在训练中执行在线量化。例如本例使用 DeepSeek-R1 的 fp8 检查点那么在参数更新时slime 会首先将参数进行 blockwise quant128x128再传给 sglang 进行推理从而让 bf16 训练与 fp8 推理无缝衔接。4.3 ROLLOUT_ARGSrollout 与奖励设置ROLLOUT_ARGS( --prompt-data $BASE_DIR/dapo-math-17k/dapo-math-17k.jsonl --input-key prompt --label-key label --apply-chat-template --rollout-shuffle --rm-type deepscaler --num-rollout 3000 --rollout-batch-size 128 --n-samples-per-prompt 8 --rollout-max-response-len 32768 --rollout-temperature 1 --over-sampling-batch-size 256 --dynamic-sampling-filter-path slime.rollout.filter_hub.dynamic_sampling_filters.check_reward_nonzero_std --num-steps-per-rollout 4 --balance-data )--prompt-dataprompt 数据集每行一个 JSON配合--input-key prompt、--label-key label取字段--apply-chat-template会对 openai message 格式的输入应用tokenizer.apply_chat_template(...)--rm-type deepscaler使用 deepscaler 规则奖励模型--num-rollout 3000一共训练的 rollout 数--rollout-batch-size 128一个 rollout 包含的 prompt 数--n-samples-per-prompt 8每个 prompt 采样 8 条回复因此一个 rollout 共 128 × 8 条数据--rollout-max-response-len 32768对应 32k 最大回复长度--rollout-temperature 1为采样温度--num-steps-per-rollout 4一次 rollout 对应 4 个训练步dynamic sampling 相关--over-sampling-batch-size 256配合--dynamic-sampling-filter-path实现 DAPO 式数据筛选详见第五节--balance-data训练时平衡数据对吞吐有益。4.4 EVAL_ARGS评估配置EVAL_ARGS( --eval-interval 20 --eval-prompt-data aime $BASE_DIR/rl_data/aime-2024.jsonl --n-samples-per-eval-prompt 8 --eval-max-response-len 32768 --eval-top-p 1 )评估时会继承 rollout 的采样参数但允许通过--eval-*前缀的独立参数覆盖例如--eval-top-p 1与 rollout 的 temperature 不同实现训练与评估采用不同采样策略。--eval-interval 20与--save-interval 20对齐便于 checkpoint 与评估结果一一对应。4.5 PERF_ARGSMegatron 并行与动态 batchPERF_ARGS( --tensor-model-parallel-size 8 --sequence-parallel --pipeline-model-parallel-size 4 --context-parallel-size 4 --expert-model-parallel-size 32 --expert-tensor-parallel-size 1 --decoder-last-pipeline-num-layers 13 --recompute-granularity full --recompute-method uniform --recompute-num-layers 1 --use-dynamic-batch-size --max-tokens-per-gpu 16384 )这一组基本是 Megatron 原生并行参数只有--use-dynamic-batch-size与--max-tokens-per-gpu是 slime 新增的。由于 DeepSeek-R1 有 61 层、不能被 4 整除示例专门通过--decoder-last-pipeline-num-layers 13将最后一个 PP stage 配置为 13 层前 3 个 stage 各 16 层16×31361。dynamic batch size 原理--max-tokens-per-gpu指每张卡最多处理的 token 数。开启--use-dynamic-batch-size后slime 会尽可能把一个 batch 内长短不一的数据拼到max_tokens_per_gpu形成动态的 micro batch size。从 slime/utils/arguments.py 的参数帮助可以看出其行为示例3 条样本长度分别为 100/200/300、max_tokens_per_gpu300时会拆成[100,200]与[300]两个 micro batch。若某条数据长度超过上限则自成一条不会截断数据。开启 context parallelCP时CP 张卡共享总长为CP * max_tokens_per_gpu的 token对应实现见 slime/utils/dp_schedule.py。开启 dynamic batch size 后会忽略传统的micro_batch_size。⚠️ slime 始终通过 data packing 方式训练并严格保证 per sample loss / per token loss 的准确性因此开启 dynamic batch size 不会影响 loss 计算推荐开启。4.6 GRPO_ARGSRL 损失配置GRPO_ARGS( --advantage-estimator grpo --use-kl-loss --kl-loss-coef 0.00 --kl-loss-type low_var_kl --entropy-coef 0.00 --eps-clip 0.2 --eps-clip-high 0.28 )--advantage-estimator grpo使用 GRPO 优势估计器--use-kl-loss--kl-loss-coef 0.00--kl-loss-type low_var_kl启用低方差 KL 损失系数为 0 表示当前仅作为约束信号如果希望不加载 reference model需要去掉--use-kl-loss并设置--kl-coef 0.00默认值为 0--entropy-coef 0.00熵正则系数--eps-clip 0.2/--eps-clip-high 0.28PPO/GRPO 常用的非对称 clip 区间high 侧略放宽以允许模型适度探索。4.7 OPTIMIZER_ARGSCPU Adam 显存优化OPTIMIZER_ARGS( --optimizer adam --lr 1e-6 --lr-decay-style constant --weight-decay 0.1 --adam-beta1 0.9 --adam-beta2 0.98 --optimizer-cpu-offload --overlap-cpu-optimizer-d2h-h2d --use-precision-aware-optimizer )--optimizer adam配合--lr 1e-6constant 衰减、--weight-decay 0.1、--adam-beta1 0.9、--adam-beta2 0.98显存优化三件套--optimizer-cpu-offload将优化器状态卸载到 CPU 内存对应前文每个节点约占用 1.4~1.5B 内存--overlap-cpu-optimizer-d2h-h2d让 CPU 与 GPU 之间的状态拷贝与计算重叠隐藏传输开销--use-precision-aware-optimizer按精度感知方式管理优化器状态进一步压缩显存占用。4.8 SGLANG_ARGS推理引擎配置SGLANG_ARGS( --rollout-num-gpus-per-engine 64 --sglang-mem-fraction-static 0.7 --sglang-ep-size 64 # dp attention --sglang-enable-dp-attention --sglang-dp-size 8 --sglang-moe-dense-tp-size 1 --sglang-enable-dp-lm-head # enable deepep for sglang --sglang-moe-a2a-backend deepep --sglang-deepep-mode auto # mtp --sglang-speculative-algorithm EAGLE --sglang-speculative-num-steps 3 --sglang-speculative-eagle-topk 1 --sglang-speculative-num-draft-tokens 4 # make every dp rank has 128 concurrency --sglang-server-concurrency 1024 )--rollout-num-gpus-per-engine 64基本对应 sglang 的tp_size此处为 64 卡组成一个推理引擎其余 sglang 参数均通过添加--sglang-前缀传给 slime 后透传给 sglangep64--sglang-ep-size 64启用大专家并行充分利用 sglang 在大 MoE 模型上的 EP 推理能力dp attention--sglang-enable-dp-attention、--sglang-dp-size 8、--sglang-moe-dense-tp-size 1、--sglang-enable-dp-lm-head将注意力计算按 dp 维度拆分降低长序列32k下的显存与计算压力deepep--sglang-moe-a2a-backend deepep、--sglang-deepep-mode auto启用 deepep 作为 MoE all-to-all 后端自动选择最优模式EAGLE 投机解码--sglang-speculative-algorithm EAGLE 3 步 draft、4 个 draft token、topk 1显著加速 32k 长回复的生成--sglang-server-concurrencyslime 特有参数限制同时发往单个 sglang server 的最大并发请求数防止并发过大打爆 HTTP server默认值为 512见 slime/backends/sglang_utils/arguments.py。本例为 8 机共一个 server为保证每个 dp rank 有 128 的并发8 dp × 128 1024调整为 1024。其底层通过asyncio.Semaphore(args.sglang_server_concurrency * get_rollout_num_engines(args))实现并发控制见 slime/rollout/sglang_rollout.py。⚠️ slime 使用 sgl-router 调度多个 sglang server在不开启 dp attention 的情况下不支持--sglang-dp-size。4.9 MISC_ARGS训练细节与 Megatron deepepMISC_ARGS( # default dropout in megatron is 0.1 --attention-dropout 0.0 --hidden-dropout 0.0 # should be good for model performance --accumulate-allreduce-grads-in-fp32 --attention-softmax-in-fp32 --attention-backend flash # use deepep for megatron --moe-enable-deepep --moe-token-dispatcher-type flex )一些额外的 Megatron 配置显式将 dropout 置 0Megatron 默认 0.1RL 微调阶段通常无需 dropout梯度累加与 attention softmax 保持 fp32 以稳定数值使用 flash attention 后端。关键点是 Megatron 侧同样开启了 deepep--moe-enable-deepep--moe-token-dispatcher-type flex与 sglang 侧的 deepep 形成训练/推理两侧的 MoE 通信优化对齐。五、dynamic samplingDAPO 式数据筛选机制DeepSeek-R1 示例使用了 DAPO 论文提出的 dynamic sampling 策略。配置方式为--over-sampling-batch-size 256 \ --dynamic-sampling-filter-path \ slime.rollout.filter_hub.dynamic_sampling_filters.check_reward_nonzero_std其中over_sampling_batch_size必须大于rollout_batch_size本例 256 128。运行流程为sampling 直接采样 256 条 prompt每条 prompt 采样 8 次由于 slime 内部采用异步采样会先后收到每个 prompt 的 8 条回复每收到一组回复就用--dynamic-sampling-filter-path指定的函数筛选通过则保留这 8 条否则整组丢弃当收到足够 128 × 8 条数据时立即停止采样不等剩余数据完成若删除过多导致剩余不足 128 条 prompt则再补采 256 条 prompt。示例使用的筛选函数定义在 slime/rollout/filter_hub/dynamic_sampling_filters.pydef check_reward_nonzero_std(args, samples: list[Sample], **kwargs): rewards [sample.get_reward_value(args) for sample in samples] keep torch.tensor(rewards, dtypetorch.float64).std() 1e-6 return DynamicFilterOutput( keepkeep, reasonNone if keep else fzero_std_{round(rewards[0], 1)}, )即判断该组 8 条回复的奖励标准差是否大于阈值若整组全对或全错奖励方差为 0说明该 prompt 没有区分度直接丢弃从而把训练数据聚焦在有进步空间的样本上。同一文件中还提供了check_reward_nonzero_std_with_fallback丢弃不足时优先保留、避免触发额外采样轮供不同场景选用。需要注意的是dynamic sampling 会提前终止abort大量请求可配合--partial-rollout将生成到一半的请求存入 data buffer 并在下一个 rollout 继续生成可配置--buffer-filter-path自定义出队策略进一步优化吞吐具体用法可参考 示例Qwen3-4B 中的 partial rollout 一节。六、训练与评估的完整闭环汇总整个脚本训练侧的完整参数流为MODEL_ARGS模型结构→CKPT_ARGS检查点/量化→ROLLOUT_ARGS数据与采样→OPTIMIZER_ARGSCPU Adam→GRPO_ARGSRL 损失→PERF_ARGS并行与动态 batch→EVAL_ARGSAIME 评估→SGLANG_ARGS推理引擎→MISC_ARGS训练细节最后统一拼接到ray job submit的train.py入口ray job submit --addresshttp://127.0.0.1:8265 --runtime-env-json{...} \ -- python3 train.py \ --actor-num-nodes 16 \ --actor-num-gpus-per-node 8 \ --colocate \ ${MODEL_ARGS[]} ${CKPT_ARGS[]} ${ROLLOUT_ARGS[]} ${OPTIMIZER_ARGS[]} \ ${GRPO_ARGS[]} ${WANDB_ARGS[]} ${PERF_ARGS[]} ${EVAL_ARGS[]} \ ${SGLANG_ARGS[]} ${MISC_ARGS[]}其中--actor-num-nodes 16 --actor-num-gpus-per-node 8 --colocate表示 16 节点 128 卡训推一体Megatron 训练与 sglang 推理共享全部 128 张卡。每 20 步保存一次 checkpoint 并执行一次 AIME-2024 评估每 prompt 采样 8 条最大回复 32ktop_p1形成训练 → 评估 → 存档的完整闭环。若希望训练与推理分离如为推理单独划分 GPU可去掉--colocate并配置--rollout-num-gpus相关细节同样可参考 示例Qwen3-4B 的训推分离与异步训练两节异步训练仅需将 train.py 换成 train_async.py。七、总结本指南以 slime 官方 DeepSeek-R1 示例为蓝本给出了从 fp8 检查点转换、torch dist 格式落地、多机 Ray 集群启动到 Megatron 训练与 sglang 推理双端并行配置的完整实操链路。其核心方法论可概括为三点精度对齐训练用 bf16、推理用 128x128 blockwise fp8由 slime 在参数更新时完成在线量化实现显存与吞吐的最优平衡并行匹配训练侧 tp8/pp4/cp4/ep32推理侧 ep64 dp attention deepep两侧各取所长并通过动态 batch size 与 data packing 吃满每张卡的 token 吞吐数据提纯以 dynamic sampling 淘汰零奖励方差的低区分度样本配合 partial rollout 与异步训练把数据管线效率拉满。对于希望将 slime 扩展到其他模型如 Qwen、GLM 系列的读者可参考 scripts/models 下已有的模型配置样例与 docs/zh/examples 中的其他实战文档在保持本示例并行框架的基础上替换对应配置即可。【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考