RL 后训练 · LLM Post-Training
slime 深度解析:大规模 LLM 强化学习框架
清华 THUDM 出品的 SGLang-native RL 训练框架。GLM-5 全系列背后的引擎。从架构、算法到工程实践,一篇彻底搞懂 slime。
slime 是清华大学 THUDM 团队开源的大语言模型强化学习后训练框架,名字是 SGLang-native LLM post-training framework 的缩写,点明了它最核心的设计选择——以 SGLang 作为原生推理引擎。
一句话定位:slime 把 Megatron-LM(工业级训练引擎)和 SGLang(高吞吐推理引擎)焊接在一起,中间用 Ray 做分布式调度,解决了「超大模型 RL 训练时训练和推理两套系统各自为政、GPU 资源严重浪费」的工程难题。已在 GLM-4.5/4.6/4.7/5/5.1 全系列推理模型上得到生产验证。
图 0-1:slime 在 LLM 训练流水线中的位置。它是「SFT 之后、模型上线之前」的 RL 后训练环节的核心引擎。
🏆 生产验证
GLM-5 全系列均由 slime 训练,是目前规模最大的 RL 后训练开源框架之一。
⚡ 全异步模式
训练 GPU 不等推理,推理 GPU 不等训练,两者在时间轴上高度重叠,GPU 利用率最高可达 90%。
📐 规模上限
支持 744B+ MoE 模型,依托 Megatron 的张量/流水线并行,无理论规模上限。
1.1 RL 后训练是什么
预训练的 LLM 学会了语言,但不知道「什么样的回答是好的」。RL 后训练(RLHF / RLAIF / 规则奖励)的核心循环是:
图 1-1:RL 后训练的四步循环。这就是 DeepSeek-R1、OpenAI o1、GLM-Z1 背后的核心技术路线。
这个循环看起来简单,但每一步都有大量工程挑战。理解这些挑战,才能理解 slime 的设计取舍。
1.2 工程挑战:为什么难
双引擎矛盾
训练需要 Megatron(张量并行,优化器状态),推理需要 SGLang(KV Cache,高吞吐)。两者底层完全不同,权重格式、张量分片方式都要对齐。
显存资源冲突
推理要占满显存放 KV Cache(需要高 batch),训练要占满显存存梯度和优化器状态。两者无法在同一时刻共享 GPU。
长尾等待问题
同一 batch 里有些请求生成 10 tokens,有些生成 2000 tokens。同步模式下,所有训练 GPU 都要等最慢的那个请求完成才能开始训练。
权重同步开销
每轮训练完,新权重要从 Megatron 格式转换并广播给所有推理节点。对于 70B+ 模型,这个传输代价极大(数百 GB 数据)。
slime 的答案: 通过 Ray 把训练集群和推理集群分开调度;用 Data Buffer 解耦两者的数据流;用全异步模式消除长尾等待;用 vLLM-style 权重加载协议优化同步效率。
2.1 三大模块:Training / Rollout / Data Buffer
图 2-1:slime 整体架构。Training(Megatron)和 Rollout(SGLang)通过 Data Buffer 解耦,Ray 负责整个集群的资源调度和通信。
🧠 Training 模块
- 基于 Megatron-LM,支持 TP / PP / SP
- 同时管理 Actor / Critic / Reference 三个模型
- Actor 参数更新后推送给 Rollout
- 支持 FP8 训练(A100 节省约 50% 显存)
- 核心代码:
slime/trainer/
🗄 Data Buffer
- 训练和推理的唯一通信媒介
- 管理 Prompt 队列的采样与分发
- 全异步模式下追踪每条数据的「代龄」
- 支持自定义 DataPipeline
- 核心代码:
slime/data/
⚡ Rollout 模块
- 基于 SGLang,多实例 Router 负载均衡
- RadixAttention 自动复用 system prompt KV
- 生成回答后立即调用奖励函数打分
- 支持 PD 分离(Prefill/Decode 独立卡)
- 核心代码:
slime/rollout/
2.2 Ray 分布式调度
slime 用 Ray 的 Placement Group 机制把训练节点和推理节点组织成逻辑分组,支持两种部署拓扑:
分离部署(Separate)
训练 GPU 和推理 GPU 是不同的机器/节点。两者可以完全并行运行,互不干扰。适合有大型 GPU 集群的场景(如 16 卡训练 + 8 卡推理)。
共置部署(Colocate)
训练和推理共用同一批 GPU,通过时间分片交替服务。训练阶段 SGLang 权重 Offload 到 CPU,推理阶段从 CPU 加载回 GPU。适合资源受限(8 卡以内)场景。
# Ray 启动示例:分离部署(4 节点训练 + 2 节点推理)
ray start --head --node-ip-address=MASTER_IP
# slime 配置(yaml)
distributed:
training_nodes: 4 # 训练节点数
rollout_nodes: 2 # 推理节点数
tp_size: 8 # 张量并行度
pp_size: 2 # 流水线并行度(训练内部)
2.3 权重同步机制
每轮训练结束后,新权重需要从 Megatron 格式传给 SGLang。这是 slime 中最复杂的工程问题之一:
图 2-2:权重同步流程。Megatron TP 分片 → All-Gather → 格式转换 → SGLang 热加载。逐层流式传输减少峰值内存。
slime 不绑定某一个 RL 算法,而是提供了一套统一的数据结构和训练接口,支持 PPO、GRPO、REINFORCE++、GSPO、OPD 等主流算法。核心区别在于「如何利用多条生成回答计算策略梯度」。
4.1 PPO(Proximal Policy Optimization)
PPO 是最经典的 RLHF 算法,最早在 InstructGPT 中使用。slime 实现了完整的 PPO 四模型版本:
四个模型
- Actor:待训练的策略模型 $\pi_\theta$
- Critic:价值函数 $V_\phi(s)$,估计期望奖励
- Reference:冻结的参考模型 $\pi_{ref}$(SFT 权重)
- Reward Model:对回答打分的奖励函数
PPO Loss 组成
- Actor Loss:Clip 约束的策略梯度
- Critic Loss:TD Error / GAE
- KL Penalty:限制与 Reference 偏差
- Entropy Bonus(可选):鼓励探索
PPO 的 Actor Loss 公式:
$$\mathcal{L}^{PPO}(\theta) = -\mathbb{E}_{t}\left[\min\left(r_t(\theta)\hat{A}_t,\ \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)\hat{A}_t\right)\right]$$
其中 $r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)}$ 是策略比,$\hat{A}_t$ 是广义优势估计(GAE),$\epsilon$ 通常取 0.2。
PPO 的问题:Critic 模型本身也需要训练(和 Actor 一样大的模型)+ 需要 Reward Model,资源消耗是 GRPO 的 2-3 倍。这是 DeepSeek-R1 放弃 PPO 的主要原因。
4.2 GRPO(Group Relative Policy Optimization)
GRPO 是 DeepSeek 团队提出的算法,消除了对 Critic 模型的依赖。核心思想是:对同一个问题生成 $G$ 条回答,用这 $G$ 条回答内部的相对奖励作为优势估计。
图 4-1:GRPO 流程。同一问题生成 G 条回答,以组内相对奖励(归一化后)作为优势估计,无需单独的 Critic 模型。
GRPO 的 Loss 公式(带 KL 约束):
$$\mathcal{L}^{GRPO}(\theta) = -\mathbb{E}\left[\frac{1}{G}\sum_{i=1}^{G}\left(\min\left(r_i(\theta)\hat{A}_i, \text{clip}(r_i(\theta),1-\epsilon,1+\epsilon)\hat{A}_i\right) - \beta\, D_{KL}(\pi_\theta \| \pi_{ref})\right)\right]$$
其中 $\hat{A}_i = \frac{r_i - \text{mean}(r_{1..G})}{\text{std}(r_{1..G})}$,$\beta$ 控制 KL 惩罚强度。
GRPO vs PPO:GRPO 省掉了 Critic 模型,每次 rollout 需要 G 条回答(通常 G=8~16)。不需要 Critic 的代价是方差稍高;但省去的显存足以部署更大的模型或更多推理实例,综合吞吐更好。
4.3 REINFORCE++
REINFORCE++ 是 GRPO 的简化版,去掉了 clip 约束,直接用 REINFORCE 梯度:
$$\mathcal{L}^{REINFORCE++}(\theta) = -\mathbb{E}\left[\hat{A}_i \cdot \log\pi_\theta(a_i|s_i)\right] + \beta\, D_{KL}(\pi_\theta \| \pi_{ref})$$
因为没有 ratio clip,训练可能不稳定,但实现更简单,超参少。适合快速验证奖励函数的有效性。
4.4 GSPO & OPD
GSPO(Group Sequence Policy Optimization)
把 KL 惩罚从 token 级别提升到 sequence 级别,更稳定。GLM-Z1-Rumination 论文中用的主算法。序列级 KL 能更好地阻止模型输出风格大漂移。
OPD(Off-Policy Data)
全异步模式中,训练数据来自「旧版策略」生成(off-policy)。OPD 通过重要性采样权重修正偏差:$w_i = \frac{\pi_\theta(a_i)}{\pi_{\mu}(a_i)}$ 其中 $\pi_\mu$ 是生成时的策略。
4.5 KL 估计器:三种实现对比
所有算法都需要估计当前策略和参考策略的 KL 散度 $D_{KL}(\pi_\theta \| \pi_{ref})$,slime 提供三种实现:
| 类型 | 公式 | 计算量 | 偏差 | 适用场景 |
| kl_estimator_k1 |
$r - 1 - \log r$($r=\pi_\theta/\pi_{ref}$) |
低 |
有偏(近似) |
一般场景,默认 |
| kl_estimator_k3 |
$\frac{(r-1)^2}{2} + \frac{(r-1)^3}{3}$(三阶近似) |
中 |
更精确 |
稳定性要求高 |
| token_level_kl |
精确 per-token KL,在所有 vocab 上求和 |
高(vocab_size 倍) |
无偏 |
研究用,内存敏感 |
# slime 配置 KL 估计器(yaml)
algorithm:
name: grpo # ppo / grpo / reinforce++ / gspo
kl_type: kl_estimator_k1 # k1 / k3 / token_level_kl
kl_coef: 0.01 # β 系数,越大越保守(不偏离 reference)
clip_eps: 0.2 # PPO clip 系数
group_size: 8 # GRPO 每个 prompt 生成几条回答
奖励函数的质量直接决定 RL 训练的上限。slime 支持三大类奖励函数,可以组合使用(加权求和)。
5.1 三类奖励
① 规则验证器
最可靠、无偏,适合有标准答案的任务。
- 数学:sympy 验证 LaTeX 表达式等价
- 代码:沙盒运行单元测试,通过率作为奖励
- 格式:正则验证 JSON / XML 合法性
② 奖励模型(RM)
神经网络对输出打分,适合主观质量评估。
- 在 Rollout 结束后调用 RM forward
- 支持独立 RM 服务(HTTP API)
- 支持内嵌 RM(同卡,节省通信)
- Reward Hacking 风险较高
③ LLM-as-Judge
用强 LLM(GPT-4o / GLM-4)对输出打分。
- 适合主观对话质量、指令遵循
- 成本高,通常只用于 final eval
- 可作为在线 RM 的替代方案
5.2 自定义奖励函数实现
slime 的奖励函数接口非常简洁,只需继承 BaseRewardFn 实现一个方法:
# slime/reward/base.py(简化)
class BaseRewardFn:
"""所有奖励函数的基类"""
def __call__(
self,
prompts: list[str], # 输入 prompt
completions: list[str], # 模型生成的回答
metadata: dict, # 附加信息(ground truth 等)
) -> list[float]: # 每条回答的奖励值(0~1 或 -1~1)
raise NotImplementedError
# 示例:数学正确性奖励(sympy 验证)
class MathVerifyReward(BaseRewardFn):
def __call__(self, prompts, completions, metadata):
rewards = []
for comp, gt in zip(completions, metadata["ground_truth"]):
pred = extract_boxed_answer(comp) # 提取 \boxed{...}
try:
correct = sympy.simplify(sympy.parse_expr(pred) -
sympy.parse_expr(gt)) == 0
rewards.append(1.0 if correct else 0.0)
except:
rewards.append(0.0)
return rewards
# 示例:代码通过率奖励
class CodePassRateReward(BaseRewardFn):
def __call__(self, prompts, completions, metadata):
rewards = []
for comp, tests in zip(completions, metadata["test_cases"]):
code = extract_code_block(comp)
passed = run_sandbox(code, tests) # 沙盒执行
rewards.append(passed / len(tests)) # 通过率
return rewards
# 组合多个奖励(在 config 中配置权重)
class CompositeReward(BaseRewardFn):
def __init__(self, reward_fns, weights):
self.fns = reward_fns
self.w = weights
def __call__(self, prompts, completions, metadata):
total = [0.0] * len(completions)
for fn, w in zip(self.fns, self.w):
scores = fn(prompts, completions, metadata)
total = [t + w*s for t, s in zip(total, scores)]
return total
最佳实践:数学任务优先用 sympy 精确验证;代码任务用 E2B / Modal 沙盒运行测试;对话任务用 RM + 格式正则双重奖励。奖励稀疏(大部分为 0)时,考虑增加「过程奖励」(PRM)或「格式奖励」作为稠密引导。
3.1 同步模式(Sync)
默认的同步模式下,每个 rollout_id 严格按顺序执行五步:
1
初始化 & 权重推送
Ray Placement Group 分配好 GPU,Actor/Critic/Reference 模型加载完毕。第一次把训练权重推给 SGLang Engine(或从 checkpoint 恢复)。
2
Rollout 生成
rollout_manager.generate(rollout_id):SGLang 处理一批 Prompt,每个 Prompt 生成 N 条回答(GRPO 需要 N>1,PPO 通常 N=1)。生成完成后调用奖励函数打分,结果打包存入 Data Buffer。
3
训练更新
actor_model.async_train(rollout_id, rollout_data_ref):从 Data Buffer 取数据,计算 PPO / GRPO Loss,执行反向传播。如果启用了 Critic,同步进行 Critic 更新。
4
权重同步
actor_model.update_weights():把更新后的 Actor 权重传给所有 SGLang 实例。下一轮 Rollout 将使用最新策略。
5
Checkpoint & 评估
按 save_interval 保存 Megatron checkpoint(可选转 HF 格式);按 eval_interval 在 benchmark 上跑评估,记录 pass@1 / reward 指标。
# 简化版核心训练循环(train.py)
for rollout_id in range(args.start_rollout_id, args.num_rollout):
# ① 推理生成 + 奖励计算
rollout_data_ref = rollout_manager.generate(rollout_id)
# ② 训练更新(Actor + 可选 Critic)
actor_model.async_train(rollout_id, rollout_data_ref)
if critic_model:
critic_model.train(rollout_id, rollout_data_ref)
# ③ 新权重推给推理引擎
actor_model.update_weights()
# ④ 周期保存 / 评估
if rollout_id % args.save_interval == 0:
actor_model.save_checkpoint(rollout_id)
if rollout_id % args.eval_interval == 0:
actor_model.eval(rollout_id)
3.2 全异步模式(Fully Async)
全异步模式是 slime 的核心技术创新之一。同步模式中,训练 GPU 必须等最后一个推理请求完成才能开始训练(长尾问题)。全异步打破了这个约束。
图 3-1:同步 vs 全异步模式对比。异步模式中推理和训练在时间轴上高度重叠,GPU 利用率从 ~40% 提升至 ~85%。
# fully_async_rollout.py 核心逻辑(简化)
class AsyncRolloutWorker:
"""后台 asyncio 线程,持续从 data_buffer 取 Prompt 生成"""
def __init__(self, args, data_buffer, concurrency=10):
# concurrency = sglang_server_concurrency × num_engines
# 始终保持固定数量的「在途推理」请求
self.semaphore = asyncio.Semaphore(concurrency)
async def run(self):
while not self.done:
async with self.semaphore:
prompt = await self.data_buffer.get_prompt()
result = await self.sglang_engine.generate(prompt)
await self.data_buffer.put_result(result)
# 权重同步时,正在进行的请求标记 ABORTED
# ABORTED 样本自动重入 buffer,不丢失计算
# 训练侧:只要 buffer 里有足够数据就开始训练,不等推理
while not training_done:
batch = data_buffer.sample(batch_size) # 不阻塞,有多少取多少
if len(batch) >= min_batch_size:
actor.train_step(batch)
3.3 Colocate 模式(GPU 共用)
当没有足够 GPU 做分离部署时,Colocate 模式让训练和推理共用同一批卡,通过显存 Offload 分时复用:
图 3-2:Colocate 模式分时复用 GPU。训练时 SGLang 权重 Offload 到 CPU,推理时 Megatron 状态 Offload,两个阶段交替使用同一批显存。
| 模型架构 | 典型代表 | 规模 | 训练并行 | 备注 |
| Dense LLM |
GLM-4 / LLaMA / Qwen |
7B–70B |
TP + SP |
最成熟,默认配置即可 |
| Dense LLM (大) |
Qwen3-72B / DeepSeek-7B |
70B+ |
TP + PP + SP |
需要开启 PP 流水线并行 |
| MoE |
GLM-4.6 MoE / DeepSeek-MoE |
100B–744B |
TP + EP + SP |
Expert Parallel (EP) 分布专家层 |
| VLM(视觉) |
InternVL / GLM-4V |
任意 |
视觉编码器单独处理 |
支持多模态奖励(需要 VLM RM) |
支持的 GPU 架构
- NVIDIA H100 / H800:首选,FP8 训练
- NVIDIA A100 / A800:完全支持 BF16
- NVIDIA A10 / RTX 系列:小规模测试
- AMD MI300X:实验性支持
精度 / 量化支持
- BF16:默认训练精度
- FP8:Megatron FP8,节省 ~50% 显存
- INT4 推理:AWQ / GPTQ(仅推理阶段)
- FP8 推理:SGLang FP8 kv cache
7.1 配置文件详解
slime 使用 YAML 配置文件,核心字段说明:
# ── examples/grpo_math_7b.yaml 注释版 ──
# ① 模型路径
actor_rollout_ref:
model:
path: /path/to/qwen2.5-7b-instruct # HuggingFace 格式权重
# ② 训练超参
training:
total_epochs: 2
rollout_batch_size: 512 # 每次 rollout 的 prompt 数量
train_batch_size: 256 # 每次梯度更新的 prompt 数量
ppo_mini_batch_size: 64 # PPO/GRPO clip 的 mini-batch 大小
gradient_accumulation: 4 # 梯度累积步数
lr: 1e-6 # Actor 学习率(RL 用极小学习率)
weight_decay: 0.01
save_interval: 100 # 每 N 个 rollout 保存一次 checkpoint
eval_interval: 50 # 每 N 个 rollout 评估一次
# ③ RL 算法
algorithm:
name: grpo
group_size: 8 # 每 prompt 生成 8 条回答
kl_type: kl_estimator_k1
kl_coef: 0.001 # 轻 KL 约束(数学任务可以更自由)
clip_eps: 0.2
entropy_coef: 0.0 # 不加 entropy bonus
# ④ 推理引擎
rollout:
num_engines: 4 # 4 个 SGLang 实例
gpu_per_engine: 2 # 每个实例用 2 张 GPU(TP=2)
max_new_tokens: 4096 # 数学题允许长链
temperature: 0.8 # 采样温度(探索用)
top_p: 0.95
# ⑤ 分布式
distributed:
training_nodes: 4 # 4 个训练节点(共 32 张 H100)
tp_size: 4 # 张量并行
pp_size: 2 # 流水线并行(7B 模型可以不用)
use_colocate: false # 分离部署
# ⑥ 全异步(可选)
async_rollout:
enabled: true # 开启全异步模式(推荐大规模场景)
concurrency: 40 # 同时在途的推理请求数
max_staleness: 3 # 允许数据落后最多 3 轮权重
# ⑦ 奖励函数
reward:
- type: math_verify # 数学正确性(sympy)
weight: 1.0
- type: format_check # 格式(有 think + answer block)
weight: 0.1
7.2 启动命令
# 前提:激活 venv,确认 Ray head 已启动
source /path/to/slime-env/bin/activate
ray status # 确认所有节点已加入集群
# 启动训练(单命令,Ray 自动分配资源)
python -m slime.train \
--config examples/grpo_math_7b.yaml \
--experiment_name "qwen7b_math_grpo_v1" \
--output_dir /checkpoint/grpo_math_7b
# 从 checkpoint 恢复
python -m slime.train \
--config examples/grpo_math_7b.yaml \
--resume_from /checkpoint/grpo_math_7b/rollout_100
# 仅导出 HuggingFace 格式(不训练)
python -m slime.export_hf \
--megatron_ckpt /checkpoint/grpo_math_7b/rollout_200 \
--output_dir /models/qwen7b_math_grpo_hf
关键调参经验:
- 学习率用
1e-6 ~ 5e-6,比 SFT 小 10 倍以上,防止遗忘
- 数学任务
kl_coef=0.001~0.01,对话任务 kl_coef=0.1~0.5
group_size(GRPO)越大越稳定,但显存和推理时间成比例增长,8~16 较常见
- 全异步模式
max_staleness=3 足够;超过 5 效果可能下降
| 项目 | 核心亮点 | RL 算法 | 奖励来源 |
| GLM-Z1-Rumination |
长思维链推理,单次生成 8k+ tokens,MATH 达到 SOTA |
GSPO |
数学验证 + 代码执行 |
| GLM-4.5 Air |
小参数高效推理模型,消费级 GPU 可运行 |
GRPO |
数学 + 指令遵循 RM |
| Math-RLVR |
纯数学 RL 从 scratch,研究"RL 能做什么 SFT 做不到" |
REINFORCE++ |
sympy 精确验证 |
| CodeRL-slime |
代码生成 RL,LeetCode 通过率 +40% |
GRPO |
单元测试通过率 |
| MultiModal-RL |
图文 VLM 的 RL 对齐,视觉问答准确率提升 |
PPO |
VLM RM + 格式奖励 |
技术趋势:从结果来看,纯规则验证奖励(数学/代码)比 RM 打分稳定得多,且没有 Reward Hacking 问题。「有标准答案的领域 + 规则验证器」是目前 RL 后训练最有效的组合。
| 框架 |
训练引擎 |
推理引擎 |
最大规模 |
异步训练 |
算法支持 |
特点 |
| slime |
Megatron-LM |
SGLang(原生) |
744B+ MoE |
✅ 全异步 |
PPO/GRPO/REINFORCE++/GSPO/OPD |
生产级大规模,GLM-5 背后引擎 |
| verl |
Megatron / FSDP |
vLLM / SGLang |
数十 B |
❌ |
PPO / GRPO |
字节出品,学术研究友好 |
| OpenRLHF |
DeepSpeed |
vLLM |
70B |
❌ |
PPO / GRPO / DPO |
最早开源 RLHF 框架,易用 |
| TRL |
HuggingFace Trainer |
内嵌 |
≤13B |
❌ |
PPO / DPO / GRPO |
最简单,适合入门 |
| NeMo-Aligner |
Megatron-LM |
TensorRT-LLM |
数千 B |
❌ |
PPO / SteerLM |
NVIDIA 出品,硬件强绑定 |
图 9-1:选型决策树。70B+ 以上模型或需要全异步模式时,slime 是目前最成熟的开源选择。
选 slime 的理由
- 模型规模 ≥ 30B,需要 Megatron TP+PP
- 需要全异步模式(GPU 数量多、训练时间敏感)
- 已有 SGLang 推理基础设施
- 想用 GSPO / OPD 等前沿算法
- 参考 GLM 系列训练方式
不选 slime 的场景
- 快速验证想法(≤7B),TRL 更简单
- HuggingFace 生态深度绑定,verl 更适合
- NVIDIA 专有硬件 + TensorRT 优化,用 NeMo
- 需要 DPO / IPO / SimPO 等 offline 算法
一句话总结:slime 是「面向生产、面向规模、面向超大 MoE」的 RL 后训练引擎。Megatron 兜底了大规模训练能力,SGLang 提供了最高效的推理吞吐,全异步模式解决了长尾等待。代价是部署复杂度高(需要 Ray 集群 + Megatron 环境),小规模实验时杀鸡用牛刀。