Arganzheng's Blog

stay hungry, stay foolish

RL 后训练基础设施(06):Agentic rollout——多轮、工具、沙箱与环境服务

Agentic Rollout: Multi-Turn Trajectories, Tools, Sandboxes and Environment Services

前五篇的 rollout 是一件事:推理引擎批量生成。Agent 训练里它变成了一个分布式系统:模型生成一段,解析出工具调用,某个容器里跑一次测试(几十秒),结果追加进上下文,再生成——重复二十轮;同一时刻几千条这样的轨迹在跑,每条占着一个有状态的沙箱;reward 不是一个规则函数,是”测试通过了几个”。500 个代码任务 × \(G = 8\) × 20 轮是 8 万次容器执行,每次 30 秒就是 670 个 CPU·小时——与模型侧这一步的十几个 GPU·小时按价格算是同一量级;要在 30 分钟内跑完,需要 1300 到 1800 个并发沙箱,取决于沙箱能否在两轮之间释放。 GPU 这一侧在这 30 分钟里做了什么,是这篇更想回答的问题。答案不太好看:dec...

RL 后训练基础设施(05):异步与 off-policy——把同步的墙拆掉之后要补什么

Asynchrony and Off-Policy: What You Owe After Tearing Down the Synchronization Wall

第二篇的结论是异步把长尾吞掉、把一步的墙钟从 12 分钟压到 5 分钟。代价写得很轻:”样本过期”。这一篇把这个代价展开——它其实是三个不同的东西,各有各的机制、各有各的信号,混在一起时 reward 曲线只会告诉你”变缓了”,不会告诉你为什么。 第一个是 staleness:训练用第 \(t\) 步的权重更新,样本由第 \(t - k\) 步的权重生成,重要性比 \(\pi_\theta / \pi_{old}\) 偏离 1,PPO 的 clip 开始大量触发;更隐蔽的是,过期程度与回答长度相关——长回答生成得慢、更容易过期——所以”丢弃过期样本”这个看似中性的策略会系统性地丢掉长回答,改变训练数据的长度分布。第二个是训推不一致:推理引擎(vLLM,可能 FP8...

RL 后训练基础设施(04):权重同步——从训练分片到推理分片

Weight Synchronization: From Training Shards to Inference Shards

每一步训练结束,优化器改完了参数,推理引擎里的那份权重就旧了。把新权重送过去听起来是一次拷贝——8B 模型 16 GB,NVLink 一秒、InfiniBand 几秒。但两边的权重不是同一个形状的东西:训练器里它是 FSDP 按第 0 维切成 64 份的 DTensor,或者 Megatron 的 TP = 4 × PP = 2 × EP = 8 分片,QKV 三个矩阵融合成一个、专家堆叠成一个大张量、名字是 decoder.layers.3.self_attention.linear_qkv.weight;推理引擎里它是 vLLM 按 TP = 8 切的列、专家按 EP = 4 分组、可能是 FP8 加一组 128 × 128 的块缩放、名字是 model.lay...

RL 后训练基础设施(03):共置——训练器与推理引擎在同一组 GPU 上共存

Colocation: Handing GPU Memory Back and Forth Between Trainer and Rollout Engine

一个 32B 的模型在 8 张 H100 上做共置的 GRPO。训练时每张卡上要有 66 GB 的训练状态(16 字节 / 参数均分到 8 卡)加 8 GB 的参考模型;生成时每张卡上要有 8 GB 的推理权重副本(TP = 8)加尽量大的 KV 池。两样东西加起来 150 GB,卡只有 80 GB——所以每一步里显存要换两次主人:生成前训练状态搬到 CPU、推理引擎的权重与 KV 池挂回 GPU;训练前反过来。按 PCIe 的带宽算,一步两次切换搬 130 GB 左右、约 6 秒;步时间 5 分钟时是 2%。 2% 不值得写一篇。值得写的是这 6 秒之外的东西:推理引擎的 KV 池释放再建回来,里面的 prefix cache 全部作废;CUDA graph 捕...

RL 后训练基础设施(02):系统形态——共置、分离与异步

RL System Topologies: Colocated, Disaggregated and Asynchronous

上一篇算出的三段时间——生成 602 秒(其中长尾 196 秒)、前向 72 秒、训练 136 秒——是在”64 张卡先全部做生成、再全部做训练”的前提下算的。这只是三种可能之一。同样 64 张卡,也可以 46 张只做生成、18 张只做训练,两边同时跑;还可以更进一步,让训练不等生成、生成不等训练,各自按自己的节奏走。三种安排下,一步的墙钟分别是 810 秒、约 750 秒、约 610 秒,全步 MFU 分别是 13%、14%、17%——差别看起来不大,但那是因为上一篇的长尾假设(\(L_{max} / \bar L = 4\))相当温和。把长尾放到推理模型训练里常见的程度,或者把 Agent 环境的等待加进来,第三种安排会比第一种快两到三倍,而 verl 的公开实...

RL 后训练基础设施(01):负载画像——一步 RL 里发生什么

Anatomy of an RL Step: Rollout, Reward and Train

一个 8B 的策略模型做 GRPO:512 个 prompt、每个采 16 条回答、回答平均 8K token。这一步要生成 6700 万个 token,参考模型与旧策略要再各过一遍 7100 万个 token 的前向,训练要对同样多的 token 做前向加反向。合计 6.8×10¹⁸ FLOP,其中训练占一半、生成只占六分之一。但在 64 张 H100 上,生成要 600 秒、训练 135 秒——按时间生成占四分之三。整步下来,64 张卡的算力只用到了 13%。 这几个数字是本系列后面七篇的全部起点。系统形态(共置 / 分离 / 异步)要解决的是”生成的 600 秒里训练器在做什么、训练的 135 秒里推理引擎在做什么”;显存切换要解决的是”同一张卡上训练状态与...

RL 后训练基础设施:rollout 与训练如何共享一组 GPU(总纲)

RL Post-Training Infrastructure: How Rollout and Training Share the Same GPUs

内容简介 《RL 后训练基础设施:rollout 与训练如何共享一组 GPU》是一组共八篇的系列文章,面向已经理解大规模训练引擎(并行策略、FSDP / Megatron、checkpoint)和 LLM 推理引擎(vLLM 的调度、KV cache、权重加载)的工程师,系统讲解 RLHF / GRPO 一类在线强化学习后训练的系统是如何组织的:一个 RL 训练步里的生成(rollout)、打分(reward)、更新(train)三段各花多少算力与显存,训练框架与推理引擎怎样在同一组 GPU 上共存或分离,每一步的新权重怎样从训练器的分片布局搬进推理引擎,异步与 off-policy 怎样把 GPU 的等待压掉,Agent 训练的沙箱集群与长尾轨迹怎样调度,以及 ...

大模型推理系统揭秘(16):系列总结与通关自测

Deep Dive into vLLM: Series Recap and Final Self-Test

十五篇正文回答了一个问题:一个文本生成请求,为什么会演化成一个涉及计算、显存、调度、通信与状态管理的复杂系统——vLLM 又是怎样把它组织起来的。前三篇定义问题、立尺子、画全景;第四到第七篇是单机上的三个战场(调度、KV Cache、GPU 执行)加上解码这一步的三种扩展;第八到第九篇沿规模线扩到多卡与多实例(PD 分离),第十到第十二篇看模型生态、请求形态、异构硬件三种变化各停在哪一层;第十三篇望向集群级的系统,第十四篇回到源码把每个抽象落到对象、状态变化与调用链上,第十五篇用同一套框架对照 SGLang。十五篇反复回到同一个请求算账:Llama-3-70B、8×H100、TP=8、2050 token prompt、生成 300 token。 本文不讲新内容,...

大模型推理系统揭秘(15):vLLM 与 SGLang:同一个请求穿过两套 Serving 系统

vLLM vs SGLang: One Request Through Two LLM Serving Systems

NOTE 本文对照 vLLM v0.27.1(tag 6e448d0,2026-08-11)与 SGLang v0.5.18(tag 71de97b,2026-08-20)的源码。文中文件路径、类名、默认值均以这两个版本为准;两个项目都以周为单位迭代,阅读时请以你手上的版本对照。SGLang 的路径省略前缀 python/sglang/srt/,vLLM 的路径省略前缀 vllm/。 前十四篇只拿一个系统做标本。读者最自然的追问是:SGLang 呢? 它和 vLLM 一样是今天最常被部署的开源 LLM Serving 引擎,大规模 DeepSeek 部署、Agent 多轮会话、长 system prompt 的场景里经常是它被选中。两边的社区各有一组 be...

大模型推理系统揭秘(14):回到源码:一次请求在 vLLM 内部的真实旅程

NOTE 本文基于 vLLM v0.27.1(tag 6e448d0, 2026-08-11)源码剖析。文中文件路径、类名和函数名均以该版本为准;vLLM 迭代很快,阅读时请以你手上的版本对照。 前十三篇回答了「是什么」和「为什么」,这一篇回答「怎么实现」。 现在你已经知道 Scheduler 为什么要按 token 预算调度、KV Cache 为什么要分块、Attention Backend 为什么要按 batch 形态分派。带着这些「为什么」回头看数据结构,它们就不再是需要背的字段列表,而是每一个都能对应到一个设计约束。 这一篇刻意放在最后:如果它出现在系列的第二篇,你只会看到一堆 class;出现在这里,你会看到设计决策留下的痕迹。 本...

×