slime 快速上手实战指南:一小时完成 RL 训练环境搭建、数据准备与脚本调参
2026/9/16 13:32:40 网站建设 项目流程

slime 快速上手实战指南:一小时完成 RL 训练环境搭建、数据准备与脚本调参

【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime

导读

本文是 slime(一个面向 RL Scaling 的 LLM 后训练框架)的完整快速上手指南,覆盖从环境配置、模型与数据集下载、权重格式转换,到训练脚本逐段参数解读,再到 Colocated 推理训练一体化、动态采样、Partial Rollout、bf16 训练 + fp8 推理、多轮 Agent 适配与多节点大规模 MoE 训练等核心特性的全流程实操。读完本文,你将能够独立在 NVIDIA GPU(B200 / H100 / H200 系列)上跑通一条基于 Megatron + SGLang 的 RL 训练链路,并具备自行修改模型配置、采样策略与自定义生成/奖励函数的能力。


一、基础环境搭建

1.1 硬件支持范围

slime支持多种 NVIDIA GPU 硬件平台:

  • B200 系列:完整支持,安装与启动步骤与 H 系列 GPU 完全一致;
  • H 系列(H100/H200):官方支持,拥有完善的 CI 测试覆盖,性能稳定。

重要说明

  • 最新的 Docker 镜像同时兼容 B 系列与 H 系列 GPU,无需额外配置;
  • H 系列上的 Megatron 后端有 CI 保护、经过充分验证,推荐用于生产环境;
  • B 系列基础功能稳定、适合开发与测试,但当前尚无 CI 保护;
  • 两个硬件平台使用完全相同的安装与启动流程。

由于 slime 可能包含针对 sglang/megatron 的临时补丁,为避免潜在的环境配置问题,官方强烈建议直接使用最新 Docker 镜像——其中已预配置全部依赖。

  • 对于不方便使用 Docker 的场景,可参考仓库根目录下的 build_conda.sh 用 conda 手动构建环境;
  • 对于 AMD GPU 支持,请参考 AMD 使用教程(npu/amd 相关补丁可参见仓库 docker/amd_patch 与 docker/npu_patch 目录)。

1.2 拉取并启动 Docker 容器

# 拉取最新镜像 docker pull slimerl/slime:latest # 启动交互式容器 docker run --rm --gpus all --ipc=host --shm-size=16g \ --ulimit memlock=-1 --ulimit stack=67108864 \ -it slimerl/slime:latest /bin/bash

参数说明:

  • --gpus all:将宿主机全部 GPU 暴露给容器;
  • --ipc=host --shm-size=16g:共享进程间通信并扩大共享内存,满足 Ray / NCCL 在多进程数据交换时的需求;
  • --ulimit memlock=-1:解除内存锁限制,避免大模型显存/内存分配失败;
  • --ulimit stack=67108864:扩大线程栈大小,防止深度递归与多线程场景下栈溢出。

1.3 安装/更新 slime

slime 已随 Docker 镜像安装。如需更新到最新版本:

# 路径可根据实际情况调整 cd /root/slime git pull pip install -e . --no-deps

使用pip install -e .以可编辑模式安装(源码位于当前工作目录下的 setup.py 与 pyproject.toml),并配合--no-deps跳过依赖重装——因为镜像中已内置了经过 slime 补丁匹配的 megatron / sglang 版本。


二、模型与数据集下载

可以从 Hugging Face、ModelScope 等平台下载所需模型与数据集。以下是通过huggingface_hub下载示例资源的命令:

# 下载模型权重(GLM-Z1-9B) hf download zai-org/GLM-Z1-9B-0414 --local-dir /root/GLM-Z1-9B-0414 # 下载训练数据集(dapo-math-17k) hf download --repo-type dataset zhuzilin/dapo-math-17k \ --local-dir /root/dapo-math-17k # 下载评估数据集(aime-2024) hf download --repo-type dataset zhuzilin/aime-2024 \ --local-dir /root/aime-2024

三、模型权重转换

3.1 Hugging Face 格式 → Megatron 格式

使用 Megatron 作为训练后端时,需要先将 Hugging Face 格式的模型权重转换为 Megatron 的torch_dist格式。

首先加载目标模型的配置文件。slime/scripts/models目录存放了已支持模型的配置脚本,需要通过source将配置参数注入当前 shell 环境。这里以 GLM4-9B 为例,Qwen3-4B、Qwen3.5、Qwen3.6、GLM-4.7-Flash、Qwen3-30B-A3B 等模型的操作方式相同:

cd /root/slime source scripts/models/glm4-9B.sh

source之后,环境变量MODEL_ARGS中即保存了一组 Megatron 超参数。以 scripts/models/glm4-9B.sh 为例,其内容包含模型结构描述(层数、隐藏层大小、注意力头数、RoPE 配置等):

MODEL_ARGS=( --spec "slime_plugins.models.glm4" "get_glm_spec" --swiglu --num-layers 40 --hidden-size 4096 --ffn-hidden-size 13696 --num-attention-heads 32 --group-query-attention --num-query-groups 2 --use-rotary-position-embeddings --disable-bias-linear --add-qkv-bias --normalization "RMSNorm" --norm-epsilon 1e-5 --rotary-base 10000 --vocab-size 151552 --post-self-attn-layernorm --post-mlp-layernorm --rotary-interleaved --rotary-percent 0.5 --no-rope-fusion --untie-embeddings-and-output-weights )

然后运行转换脚本。注意以下参数:

  • --hf-checkpoint:指定已下载的 Hugging Face 模型权重路径;
  • --save:指定转换后torch_dist格式权重的保存路径。
PYTHONPATH=/root/Megatron-LM python tools/convert_hf_to_torch_dist.py \ ${MODEL_ARGS[@]} \ --hf-checkpoint /root/GLM-Z1-9B-0414 \ --save /root/GLM-Z1-9B-0414_torch_dist

从源码看转换流程的关键细节(对应 tools/convert_hf_to_torch_dist.py):

  • 并行切分自动推导:当pipeline_model_parallel_size == 1且 world size > 1 时,脚本会自动按 GPU 数量推导流水线并行切分,保证每张卡分配到的层数为正(decoder_last_pipeline_num_layers会随之修正);若找不到合法的流水线并行度(如层数不足以切分),会抛出ValueError。对于更大的模型,可直接使用torchrun多卡甚至多节点启动转换脚本;
  • AMD 平台约束:代码中明确断言,AMD GPU(torch.version.hip非空)转换时必须开启--use_cpu_initialization=True,即在 CPU 上完成权重转换;同时会为 ROCm 环境打上FileSystemWriterAsync兼容补丁(见 slime/utils/rocm_checkpoint_writer.py);
  • 校验约束:脚本断言 world size ≤ 层数,即"转换使用的 GPU 数不能超过模型层数";
  • 保存格式:通过 Megatron 的save_checkpoint保存,随后 rank 0 将 checkpoint tracker 标记为release,并把iter_1目录重命名为 release 目录,方便后续加载。

特别提示:转换 kimi-k2 模型权重时,需要打开模型路径下的config.json,将"model_type": "kimi_k2"改为"model_type": "deepseek_v3"

3.2 Megatron 格式 → Hugging Face 格式

使用以下脚本将训练保存的 Megatron checkpoint 转回 Hugging Face 格式:

PYTHONPATH=/root/Megatron-LM python tools/convert_torch_dist_to_hf.py \ --input-dir /path/to/torch_dist_ckpt/iter_xxx/ \ --output-dir /root/GLM-Z1-9B-0414-iter_xxx \ --origin-hf-dir /root/GLM-Z1-9B-0414

从源码看该脚本的实现(对应 tools/convert_torch_dist_to_hf.py):

  • 通过WrappedStorageReader读取 torch_dist 格式的.metadata(对 megatron/glm 模块的 pickle 反序列化做了兼容包装),并用EmptyStateDictLoadPlanner跳过优化器状态,仅加载模型权重;
  • 张量默认按 2GB 分块写入model-xxxxx-of-xxxxx.safetensors,并生成model.safetensors.index.json权重映射(--chunk-size可调);
  • 若传入--origin-hf-dir,会将其中的 tokenizer、config.json等非权重文件一并拷贝到输出目录,同时可通过--add-missing-from-origin-hf-a)把原 HF checkpoint 中缺失的权重补充进新 checkpoint;
  • 模型名可通过--model-name显式指定,否则会从origin_hf_dirAutoConfig自动推断(转换为小写类名),从而路由到 slime/backends/megatron_utils/megatron_to_hf 下对应的转换器(如qwen3_5.pyglm4moe.pydeepseekv3.py等)。

注意事项:由于 Megatron 为了性能会对 embedding 进行 padding(--vocab-size会被对齐到并行度整数倍),转换出来的 embedding 可能不正确。此时请在转换时手动设置--vocab-size(配合remove_padding逻辑去掉 padding)。


四、训练脚本与参数全景

完成上述准备工作后即可启动训练:

cd /root/slime bash scripts/run-glm4-9B.sh

下面以 scripts/run-glm4-9B.sh 为例,逐段分析主要参数组。完整的参数定义可在 slime/utils/arguments.py 中查到。

4.1 MODEL_ARGS:模型配置参数

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" source "${SCRIPT_DIR}/models/glm4-9B.sh"

该段通过sourcescripts/models/glm4-9B.sh加载模型配置。这些配置全部是 Megatron 所需的超参数——因为Megatron 无法直接从 checkpoint 读取模型结构,必须人工指定。我们在scripts/models/目录中为一些常用模型提供了配置示例(如 scripts/models/qwen3-4B.sh、scripts/models/qwen3-30B-A3B.sh、scripts/models/glm4.7-30B-A3B.sh 等)。

⚠️注意: 请务必核对模型配置文件中的参数(如--rotary-base)是否与当前使用的模型完全一致。同一模型结构的不同版本可能使用不同的配置值。如需修改,可在source之后直接覆盖,例如:

source "${SCRIPT_DIR}/models/glm4-9B.sh" MODEL_ARGS+=(--rotary-base 10000)

4.2 CKPT_ARGS:Checkpoint 与路径参数

CKPT_ARGS=( # 用于加载 tokenizer 等信息,不会实际使用 hf 路径中的模型权重参数 --hf-checkpoint /root/GLM-Z1-9B-0414 # Reference Model 的 Megatron 格式 checkpoint --ref-load /root/GLM-Z1-9B-0414_torch_dist # Actor 模型加载路径。通常应与 --save 保持一致以便断点续训 # 若为空或不含有效 checkpoint,则回退到 --ref-load 加载 --load /root/GLM-Z1-9B-0414_slime/ # 训练过程中的模型保存路径 --save /root/GLM-Z1-9B-0414_slime/ # 模型保存间隔(步数) --save-interval 20 )

各参数含义:

  • --hf-checkpoint:仅用于加载 tokenizer / 处理器等元信息,不读取其中权重;
  • --ref-load:Reference Model 的 Megatron 格式 checkpoint,用于 KL 散度等参考;
  • --load:Actor 模型的加载路径(与--save一致可实现断点续训);为空或没有有效 checkpoint 时自动从--ref-load加载;
  • --save:训练时模型保存路径;--save-interval:每 N 步保存一次。

4.3 ROLLOUT_ARGS:数据生成(Rollout)参数

整个训练过程可以看作"数据采样 → 权重更新"的闭环:

阶段一:数据采样(Rollout)

  • --rollout-batch-size:每一轮采样的Prompt 数量
  • --n-samples-per-prompt:每个 Prompt 生成的回复数量(用于 GRPO 类算法)。

两者乘积决定单轮采样生成的总样本数

阶段二:模型训练(Training)

  • --global-batch-size:执行一次参数更新(optimizer.step)所需的样本数量
  • --num-steps-per-rollout:用当前采样的数据执行多少次参数更新(默认 1,即 on-policy 训练)。

两者乘积决定单轮训练消耗的总样本数

⚠️ 这里的参数更新指训练阶段的optimizer.step(),与训练引擎向推理引擎发起的权重同步(Weight Sync)不是一回事。

闭环约束:每一轮的"产出"与"消耗"必须相等,即满足:

(rollout-batch-size × n-samples-per-prompt) = (global-batch-size × num-steps-per-rollout)

  • 在 slime 中,若设置了--num-steps-per-rollout,则--global-batch-size未设置时会自动计算,设置了则会按上述公式校验。

训练轮次控制

  • --num-rollout:控制整个"采样→训练"循环的总执行轮数。
ROLLOUT_ARGS=( # Prompt 数据集,JSONL 格式 --prompt-data /root/dapo-math-17k/dapo-math-17k.jsonl --input-key prompt --label-key label # 若 Prompt 的 input_key 是 OpenAI message 格式,则应用 Chat Template --apply-chat-template # 是否在 Rollout 阶段打乱数据 --rollout-shuffle # Reward Model 类型。slime 内置多种,也支持通过 --custom-rm-path 自定义 --rm-type deepscaler # 这五个参数控制 rollout 与 train 之间的关系 --num-rollout 3000 --rollout-batch-size 16 --n-samples-per-prompt 8 --num-steps-per-rollout 1 --global-batch-size 128 # Rollout 采样参数 --rollout-max-response-len 8192 --rollout-temperature 1 # 对 rollout 阶段收集的数据做负载均衡,使每个训练进程(DP rank)分配到的 # 计算负载大致相等,可能有利于训练速度 --balance-data )

内置的奖励模型实现位于 slime/rollout/rm_hub,包括deepscalerf1gpqaifbenchmath(含 DAPO 数学奖励)等。

4.4 EVAL_ARGS:评估参数

评估流程继承大部分 Rollout 参数,但可用以下参数覆盖,实现与训练不同的评估策略:

EVAL_ARGS=( # 评估间隔(按 Rollout 轮数计) --eval-interval 5 # 评估用 Prompt 数据集 --eval-prompt-data aime /root/aime-2024/aime-2024.jsonl # 每个评估 Prompt 的采样数量 --n-samples-per-eval-prompt 16 # 评估时的最大回复长度 --eval-max-response-len 16384 # 评估时的采样参数 --eval-top-p 1 )

(在 scripts/run-glm4-9B.sh 中实际示例为--eval-interval 20,可结合任务规模调整。)

4.5 PERF_ARGS:性能与并行参数

该部分主要是 Megatron 的并行配置。--use-dynamic-batch-size--max-tokens-per-gpu是 slime 特有的优化:

  • --max-tokens-per-gpu:每张 GPU 处理的最大 token 数。启用动态批处理(use_dynamic_batch_size)后,系统会智能地将不同长度的样本打包,使每个 micro-batch 的总 token 数逼近该上限,从而提升训练效率。若单个样本长度超过该值,则单独形成一个 batch。在上下文并行(CP)模式下,N 张 CP 卡共享N * max_tokens_per_gpu的总长度;
  • --use-dynamic-batch-size:启用动态批处理,此时--micro-batch-size会被忽略。

💡提示: slime 始终通过数据打包(data packing)方式训练模型,并严格保证每个样本的 loss / 每个 token 的 loss 计算正确。因此启用动态 batch size 不会影响 loss 计算,强烈建议开启。

PERF_ARGS=( --tensor-model-parallel-size 2 --sequence-parallel --pipeline-model-parallel-size 1 --context-parallel-size 2 --expert-model-parallel-size 1 --expert-tensor-parallel-size 1 --recompute-granularity full --recompute-method uniform --recompute-num-layers 1 # --micro-batch-size 1 # 启用动态批处理后该项被忽略 --use-dynamic-batch-size --max-tokens-per-gpu 4608 )

关于"启用动态批处理不影响 loss 正确性"这一点,仓库中有对应测试佐证,例如 tests/test_loss_cp_invariance.py(CP 下 loss 不变性)与 tests/test_loss_mask_type_qwen35.py(不同 loss mask 类型的处理)。

4.6 GRPO_ARGS:GRPO 算法参数

  • --use-kl-loss:启用该选项会加载参考模型,并计算当前模型与参考模型的 KL 散度作为监控指标。KL 散度是否计入最终训练 loss 取决于--kl-loss-coef:若该系数为 0,KL 散度仅作为观测指标展示,不参与 loss 计算。
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 外,slime 还支持 GSPO、Reinforce++、Reinforce++ Baseline 以及 PPO 等多种训练算法,按需切换该参数即可;
  • --calculate-per-token-loss:默认 slime 按每样本计算 loss,即mean(sum(sample_i) / len(sample_i));开启该 flag 后改为按每 token计算,即sum(sum(sample_i)) / sum(len(sample_i))
  • --use-tis:启用 TIS(Truncated Importance Sampling,截断重要性采样),用于 off-policy RL 场景(相关实现可参见 slime/utils/ppo_utils.py 等训练工具模块)。

4.7 OPTIMIZER_ARGS:优化器参数

OPTIMIZER_ARGS=( --optimizer adam --lr 1e-6 --lr-decay-style constant --weight-decay 0.1 --adam-beta1 0.9 --adam-beta2 0.98 )

RL 训练通常使用很小的恒定学习率(如1e-6)配合constant衰减策略,以避免破坏预训练权重。

4.8 SGLANG_ARGS:SGLang 服务参数

该组参数用于配置 SGLang 推理服务:

  • --rollout-num-gpus-per-engine:基本等价于 SGLang 的tp_size
  • 其他 SGLang 参数可以通过添加--sglang-前缀传给 slime,slime 会自动转发给 SGLang。例如设置 SGLang 的--log-level INFO参数,只需使用--sglang-log-level INFO

⚠️注意: slime 使用sgl-router调度多个 SGLang Server。未启用 DP Attention 时,dp_size会通过rollout-num-gpus / rollout-num-gpus-per-engine计算。

SGLANG_ARGS=( --rollout-num-gpus-per-engine 2 )

4.9 补充参数组:MISC_ARGS 与 WANDB_ARGS

完整的 scripts/run-glm4-9B.sh 还包含两类参数,值得了解:

WANDB_ARGS=( #--use-wandb # --wandb-project slime-dev # --wandb-group qwen3-4B-test # --wandb-key ${WANDB_KEY} ) MISC_ARGS=( # megatron 默认 dropout 为 0.1 --attention-dropout 0.0 --hidden-dropout 0.0 # 有利于模型性能 --accumulate-allreduce-grads-in-fp32 --attention-softmax-in-fp32 # 使用 MLA 的模型需要注释掉该行 --attention-backend flash )

脚本随后会在容器内启动 Ray 主节点并提交训练任务:

export MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"} ray start --head --node-ip-address ${MASTER_ADDR} --num-gpus 8 --disable-usage-stats --dashboard-host=0.0.0.0 --dashboard-port=8265 RUNTIME_ENV_JSON='{ "env_vars": { "PYTHONPATH": "/root/Megatron-LM/", "CUDA_DEVICE_MAX_CONNECTIONS": "1", "NCCL_NVLS_ENABLE": "'${HAS_NVLINK}'" } }' ray job submit --address="http://127.0.0.1:8265" \ --runtime-env-json="${RUNTIME_ENV_JSON}" \ -- python3 train.py \ --actor-num-nodes 1 \ --actor-num-gpus-per-node 4 \ --rollout-num-gpus 4 \ ${MODEL_ARGS[@]} ${CKPT_ARGS[@]} ${ROLLOUT_ARGS[@]} \ ${OPTIMIZER_ARGS[@]} ${GRPO_ARGS[@]} ${WANDB_ARGS[@]} \ ${PERF_ARGS[@]} ${EVAL_ARGS[@]} ${SGLANG_ARGS[@]} ${MISC_ARGS[@]}

其中HAS_NVLINK由脚本在启动时根据nvidia-smi topo -m检测结果自动设置,用于开启NCCL_NVLS_ENABLE(NVLink Sharp)。


五、核心特性详解

5.1 Colocated Actor 与 Rollout(训练推理一体化)

默认配置下,训练(Actor)与推理(Rollout)资源是分开指定的:Ray 为训练部分分配actor_num_nodes * actor_num_gpus_per_node张 GPU,为推理部分分配rollout_num_gpus张 GPU。当显式设置--rollout-num-gpus 0时,slime 仍会解析 SGLang 参数并启动 router,但不启动本地 SGLang Server。

标准(分离式)配置

ray job submit ... \ -- python3 train.py \ --actor-num-nodes 1 \ --actor-num-gpus-per-node 4 \ --rollout-num-gpus 4 \ ...

上述配置中 Actor 使用 4 卡、Rollout 使用 4 卡,并行运行。

训练推理一体化(Colocated)配置: 要让训练与推理部署在同一组 GPU 上,请添加--colocate参数。默认情况下这会使训练与推理的卡数相等;也可以显式设置一个不同的正数--rollout-num-gpus,例如使用比 Actor 更多的 rollout GPU——多出的 GPU 仅作为 rollout 资源使用。若显式设置--rollout-num-gpus 0,则 slime 只启动 router、不启动本地 SGLang Server(对应参数定义见 slime/utils/arguments.py 中--colocate--rollout-num-gpus的说明)。

ray job submit ... \ -- python3 train.py \ --actor-num-nodes 1 \ --actor-num-gpus-per-node 8 \ --colocate \ ...

此时训练与推理将共享全部 8 张 GPU。

⚠️注意: 在训练推理一体化模式下,Megatron 初始化后会占用一定显存,且在完成 offload 之前不会释放。你需要调整--sglang-mem-fraction-static参数来降低 SGLang 的显存占用比例,避免显存不足。通常建议设置为 0.8。

5.2 动态采样(Dynamic Sampling)

slime 支持更复杂的采样策略,例如 DAPO 中使用的动态采样。启用该特性需要配置:

--over-sampling-batch-size 64 \ --dynamic-sampling-filter-path \ slime.rollout.filter_hub.dynamic_sampling_filters.check_reward_nonzero_std

这里over_sampling_batch_size必须大于rollout_batch_size,例如:

--rollout-batch-size 32 \ --n-samples-per-prompt 8 \ --over-sampling-batch-size 64 \

每次采样将直接采样 64 个 prompt,每个 prompt 采样 8 次。由于 slime 内部采用异步采样,会陆续收到每个 prompt 的 8 条回复;收到回复时,会用dynamic_sampling_filter_path对应的函数进行过滤:通过则保留这 8 条数据,否则丢弃。

示例中的过滤函数check_reward_nonzero_std会检查一组样本奖励的标准差是否大于零,确保保留的每组样本的奖励分数存在差异,从而避免数据过于同质、提升数据多样性。仓库中的实际实现位于 slime/rollout/filter_hub/dynamic_sampling_filters.py:

def check_reward_nonzero_std(args, samples: list[Sample], **kwargs): rewards = [sample.get_reward_value(args) for sample in samples] keep = torch.tensor(rewards, dtype=torch.float64).std() > 1e-6 return DynamicFilterOutput( keep=keep, reason=None if keep else f"zero_std_{round(rewards[0], 1)}", )

注:原文档中该函数判据写作std() > 0.0,仓库实际实现为torch.float64精度下std() > 1e-6(同一目录还提供了check_reward_nonzero_std_with_fallback,它在过滤失败时倾向于保留该组而非触发新一轮采样)。DynamicFilterOutput等基础类型定义在 slime/rollout/filter_hub/base_types.py。

如果过滤函数非常严格、导致大量 prompt 组被丢弃,系统会监控remaining_batch_size中的待处理任务数:一旦因丢弃过多导致待处理任务数低于目标数量(32),系统会自动触发新一轮过采样,再次请求over_sampling_batch_size(64)个新 prompt,重复上述过程。

5.3 Partial Rollout(部分回复续采)

动态采样期间会有大量请求被提前中止,造成算力浪费。启用--partial-rollout参数后,这些只生成了一半的样本会被缓存,并在下一轮 Rollout 阶段继续生成,从而提升性能。对应参数定义在 slime/utils/arguments.py 中:未完成的样本在动态采样期间会被回收回数据缓冲区(data buffer),这对长回复场景尤其有用。

你也可以通过--buffer-filter-path自定义从缓存提取数据的策略,默认策略为pop_first——按先进先出顺序提取所需数量的样本。其实现位于 slime/rollout/data_source.py:

def pop_first(args, rollout_id, buffer: list[list[Sample]], num_samples: int) -> list[list[Sample]]: num_to_pop = min(len(buffer), num_samples) samples = buffer[:num_to_pop] del buffer[:num_to_pop] return samples

即每次取出前num_samples个 prompt 对应的num_samples * n_samples_per_prompt条数据。数据源层面对应RolloutDataSourceWithBuffer类:get_samples会先尝试从 buffer 中按自定义策略取样本,不足部分再向原始数据源补齐;同时校验每个样本组的长度必须等于n_samples_per_prompt

💡提示: 每个 partial rollout 样本的sample.metadata中保存了首次生成的 rollout id,可用于数据过滤。

5.4 bf16 训练 + fp8 推理

slime 直接支持 bf16 训练与 fp8 推理。以 Qwen3-4B 为例,只需下载以下模型:

hf download Qwen/Qwen3-4B-FP8 --local-dir /root/Qwen3-4B-FP8

并将--hf-checkpoint替换为:

# 用于加载 tokenizer 等信息,实际上不会使用 hf 路径中的模型权重参数 --hf-checkpoint /root/Qwen3-4B-FP8 # megatron checkpoint 仍须是开始时由 bf16 huggingface 转换而来的 dist 权重,不因 fp8 rollout 而改变 --ref-load /root/Qwen3-4B_torch_dist

这即会触发 fp8 推理。目前实现会直接将 bf16 权重强转(cast)为 fp8,未来会逐步加入对精度影响更小的量化方案。fp8 相关核函数与工具见 slime/backends/megatron_utils/kernels/fp8_kernel.py 与 tools/convert_hf_to_fp8.py。

对于长上下文 rollout,还可以在 SGLang 中启用 FP8 KV cache 以提升有效 KV cache 容量:

--sglang-kv-cache-dtype fp8_e4m3

⚠️ 训练用的 megatron checkpoint 仍须是开始时由 bf16 huggingface 转换而来的那个。


六、多轮交互(Multiturn)适配

slime 框架高度可扩展,支持复杂的 Agent 场景(如多轮交互、工具调用)。其核心机制是通过自定义函数改写默认的数据生成(Rollout)与奖励计算(Reward)逻辑。本节以基于 Search-R1 的实现为例,说明如何将 slime 适配为支持多轮交互。仓库中可直接参考的完整实现见 examples/search-r1/generate_with_search.py(本地检索与 Google 搜索双后端,支持日志概率采集)。

6.1 适配策略总览

将 slime 适配为支持多轮交互主要包含三步:

  1. 数据准备:将多轮交互数据集适配为 slime 的Sample对象。把对话历史、真实标签等映射到promptlabel字段,并将工具定义、中间状态等附加信息存入metadata字段,供后续函数调用;
  2. 实现自定义生成函数:编写模拟"模型生成动作 → 执行工具 → 拼接观察结果"交互循环的函数,并正确处理 Loss Masking;
  3. 实现自定义奖励函数:编写评估完整交互轨迹并返回最终奖励分数的函数。

6.2 数据准备与映射

要向自定义函数传递复杂的上下文信息,需要在数据预处理阶段将所有相关附加字段聚合起来。

核心思路:把数据集中除promptlabel之外的所有附加信息(如session_iduser_profiletool_code等)合并成一个单一结构化字段(例如一列名为metadata的 JSON 字符串)。

第一步:在数据集中构造metadata字段

训练开始前需要处理原始数据集。例如原始数据形如:

questionfinal_answersession_idtool_code
"...""...""sess_123""code_A"

需要转换为:

questionfinal_answermetadata
"...""..."{"session_id": "sess_123", "tool_code": "code_A"}

第二步:在训练脚本中指定映射

数据准备完成后,在训练脚本中通过ROLLOUT_ARGS将预处理好的metadata列映射到 slime 的Sample.metadata字段:

ROLLOUT_ARGS=( # 1. 指定预处理后的数据集文件 --prompt-data /root/nq_search/train_processed.json # 2. 将 "question" 列映射为输入 prompt --input-key question # 3. 将 "final_answer" 列映射为评估标签 --label-key final_answer # 4. 将预先构造的 "metadata" 列加载到 Sample.metadata # slime 会自动将其解析为 Python 字典 --metadata-key metadata )

底层实现上,Dataset的构建(见 slime/rollout/data_source.py)会把prompt_keylabel_keymetadata_keytool_key等分别填入Samplepromptlabelmetadata等字段(Sample数据类定义见 slime/utils/types.py,其metadata字段默认为 dict)。通过这种方式,你可以在自定义generatereward函数中方便地用sample.metadata['session_id']访问所有预先准备好的结构化信息。

6.3 编写自定义生成函数

首先通过--custom-generate-function-path参数指定一个自定义异步 Python 函数。

函数签名async def generate(args, sample: Sample, sampling_params) -> Sample:

核心实现要点

  1. 构建交互循环:创建控制最大交互轮数的循环(如for _ in range(max_turns):);
  2. 调用模型生成动作:每轮循环中调用 SGLang 服务,让模型基于当前对话历史生成下一个动作(如<search>query</search>);
  3. 解析并执行动作:解析模型输出、识别动作与参数,调用外部工具或 API(如 Google 搜索);
  4. 构建观察结果:将工具返回的结果格式化后追加到对话历史中,作为下一轮输入;
  5. 处理 Loss Masking:这是 Agent 训练的关键。
    • 注意:loss_mask的长度应与response一致,需要计算 loss 的 token 为 1,被掩码的为 0;
    • 模型生成的 token(如思考、动作指令)→loss_mask设为1,参与 loss 计算;
    • 工具或环境返回的 token(如 API 结果)→loss_mask设为0,不参与 loss 计算;
  6. 终止条件:当模型生成终止标签(如<answer>...)或达到最大轮数时结束循环;
  7. 封装返回:将完整交互历史、token id 与loss_masks填入Sample对象并返回。

代码示例(伪代码)

async def generate(args, sample: Sample, sampling_params) -> Sample: # ... initialization ... prompt, full_response, loss_masks = sample.prompt, "", [] for _ in range(max_turns): # 1. Model generates action model_output = await call_sglang(prompt + full_response, ...) # ... tokenization and appending ... loss_masks += [1] * len(model_tokens) # loss_mask = 1 full_response += model_output # 2. Parse and execute action action, content = parse_action(model_output) if action == "search": # 3 & 4. Get and append observation results tool_output = await google_search(content) # ... tokenization and appending ... loss_masks += [0] * len(tool_tokens) # loss_mask = 0 full_response += tool_output elif action == "answer": break # end loop # 7. Fill and return Sample object sample.response = full_response sample.tokens = ... sample.loss_mask = loss_masks return sample

对照仓库中的真实实现(examples/search-r1/generate_with_search.py),可以看到更多工程细节:例如通过GenerateState复用 tokenizer、通过 HTTP 调用sglang_router/generate接口、把</search></answer>等标签注入sampling_params["stop"]避免模型输出越界垃圾内容、通过output_token_logprobs采集日志概率以支持 TIS、并在生成过程中维护sample.tokenssample.loss_masksample.rollout_log_probs的逐 token 对齐等。

6.4 编写自定义奖励函数

类似地,通过--custom-rm-path指定自定义奖励函数。

函数签名async def reward_func(args, sample: Sample, **kwargs) -> float:

该函数接收完整的Sample对象,根据最终交互结果计算分数。你可以在此实现自定义打分逻辑,或调用外部 Reward Model 服务。内置奖励模型的加载逻辑见 slime/rollout/rm_hub/init.py:每个Sample还可携带custom_rm_path(来自数据集配置)实现样本级奖励函数覆盖,优先级高于全局args.custom_rm_path

6.5 在训练脚本中配置

最后,在训练脚本中通过以下参数启用上述自定义函数:

CUSTOM_ARGS=( # 指定自定义生成函数路径(格式:path.to.your.file:function_name) --custom-generate-function-path your_module.multiturn_logic.generate # 指定自定义奖励函数路径 --custom-rm-path your_module.multiturn_logic.reward_func )

仓库中另有大量 Agent 场景示例可供参考:多智能体系统 examples/multi_agent/agent_system.py、带工具沙箱的 RE-Tool examples/retool/tool_sandbox.py、多轮 VLM 评测 examples/geo3k_vlm_multi_turn/env_geo3k.py、tau-bench 工具调用 examples/tau-bench/generate_with_tau.py 等,均基于--custom-generate-function-path/--custom-rm-path机制实现。


七、大规模 MoE 模型的多节点训练

启动多节点任务前,需要先启动 Ray 集群。在节点 0 上执行:

# Node0 (HEAD) ray start --head --node-ip-address ${MASTER_ADDR} \ --num-gpus 8 --disable-usage-stats # 其他节点 ray start --address=${MASTER_ADDR}:6379 --num-gpus 8

Ray 集群启动后,从节点 0 提交任务,例如:

ray job submit --address="http://127.0.0.1:8265" \ --runtime-env-json='{ "env_vars": { "PYTHONPATH": "/root/Megatron-LM/", ... # e.g., no_proxy, API variables, etc. } }' \ -- python3 train.py \ --... # 其他 Megatron/SGLang/slime 参数

可选地,根据你的环境可能需要设置以下环境变量。例如在 Docker 或 SLURM 环境下存在多个 IP、而系统选择了错误的 IP 时,可参考下面的 SLURM + enroot 多节点示例:

export SLIME_HOST_IP=$(hostname -I | awk '{print $1}') export GLOO_SOCKET_IFNAME=$(ip -o -4 addr show | awk '$4 ~ /^10\\./ {print $2}') export NCCL_SOCKET_IFNAME=$(ip -o -4 addr show | awk '$4 ~ /^10\\./ {print $2}') export NVSHMEM_BOOTSTRAP_UID_SOCK_IFNAME=$(ip -o -4 addr show | awk '$4 ~ /^10\./ {print $2}')

slime 针对大规模 Mixture of Experts(MoE)模型的分布式训练做了深度优化(包括专家并行、上下文并行与负载均衡等,可参考 slime/backends/megatron_utils/cp_utils.py、slime/backends/megatron_utils/alignment 等模块)。我们提供了以下端到端训练案例供参考:

  • 示例:8xH100 训练 GLM-4.7-Flash
  • 示例:32xH100 训练 GLM-5.2
  • 示例:64xH100 训练 GLM-4.7
  • 示例:128xH100 训练 DeepSeek-R1

另外,scripts/目录下的模型脚本(如 scripts/models/qwen3-30B-A3B.sh、scripts/models/glm4.7-355B-A32B.sh 等)以及 scripts/run-glm4.7-355B-A32B.sh 等训练脚本同样支持多节点训练,相关文档仍在持续扩充中。


八、小结与下一步

本文从零到一完整走通了 slime 的一条 RL 训练链路:通过官方 Docker 镜像搭建环境,下载模型与数据,完成 HF ↔ Megatron 双向权重转换,逐段读懂训练脚本中的八组核心参数,并深入讲解了 Colocated 训练推理一体化、动态采样、Partial Rollout、bf16 训练 + fp8 推理、多轮 Agent 适配与多节点 MoE 训练等进阶能力。每个特性均有仓库源码级实现可查证。

下一步建议:

  • 阅读 docs/en/get_started/usage.md 了解日常使用细节,或 docs/en/get_started/customization.md 深入了解自定义扩展机制;
  • 按需查阅 docs/en/advanced 下的进阶主题(如 Megatron 配置、SGLang 配置、低精度训练、PD 分离、容错、可复现性等);
  • 参考 docs/en/examples 中不同模型的端到端案例,将本文流程迁移到你的目标模型上。

【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询