![]()
2026年9月的一个清晨,有一台由64块NVIDIA GB300 GPU组成的集群,正在训练一个总参数量744B、每次实际激活40B的超大模型GLM-5.2。它要学习的不是写诗或者聊天,而是在真实的命令行终端里完成编程任务,一步步敲代码、跑测试、看报错、再改。这活儿听起来就很难,而更难的是:这台集群要一边不停地"出题考试"(生成模型的操作轨迹),一边不停地"批改试卷"(训练更新参数),两件事还必须严丝合缝地对齐,中间不能有任何数据对不上号。
这就是这篇论文要讲的系统,叫Miles。它不是在做一个新的算法,而是在解决一个更朴素也更硬核的问题:怎么把强化学习训练大模型这件事,从"能跑通"做到"能在生产环境里稳定、高效、可信地跑"。
**这件事到底难在哪**
先说说背景。强化学习*(Reinforcement Learning,简称RL):一种让模型通过尝试和反馈来自我改进的训练方式,模型做出一个动作,获得一个奖励分数,再根据这个分数调整自己的行为倾向。
用来训练大语言模型,早已不是什么新鲜事,但过去几年,这个"生成-反馈-更新"的循环已经变得远比想象中复杂。以前可能就是让模型写一段话,打个分,更新一下权重,一轮就结束了。但现在的任务是多轮的:模型要在终端里连续操作几十步,中间要调用工具、读取环境反馈,还可能因为一次失误让整个任务前功尽弃。生成这类"轨迹"(也就是模型一次完整的任务尝试)往往需要几十秒到几十分钟不等,长短差异极大。
而承担生成任务的引擎,往往要伺候的是万亿参数级别的混合专家模型*(Mixture of Experts,简称MoE):一种模型架构,它不是让每个参数都参与每次计算,而是像开会一样,每次只挑选一部分"专家"模块来处理当前的输入,这样能在保持强大能力的同时省下大量算力。
这就带来了两个几乎所有做过大规模系统的人都会撞上的坑。第一个坑是效率:生成轨迹是个磨洋工的活儿,慢吞吞的;训练更新则讲究火力全开的吞吐量。两种节奏放在一起,稍不注意就会出现一边干瞪眼等着另一边干完活的情况,GPU利用率直接打对折。第二个坑更隐蔽,也更致命:生成轨迹的引擎和训练用的引擎,即便用的是同一套权重,算出来的概率也可能对不上。这个"对不上"如果没被发现和纠正,训练出来的梯度信号本质上就是在优化一个从没真实发生过的轨迹,整个训练目标可能就是错的,而且系统不会报错,它只会安静地把模型训废。
Miles这套系统,就是奔着把这两个坑填平去设计的,它建立在一个叫slime的项目基础上,围绕着"组件要经过验证、代码要干净、系统要可定制"这三条原则,把强化学习训练的每一个环节都重新梳理了一遍。
**生成引擎怎么又快又准:SGLang与请求路由的门道**
Miles的生成端建立在SGLang*(一种高效的大模型推理服务框架):可以理解为专门给大模型"接客"的服务系统,它决定了模型推理请求怎么被安排、怎么被处理。
之上,但真正决定吞吐量高低的,是一个听起来很技术但道理很朴素的东西:请求路由。
一次多轮对话里,每一轮都要用到前面所有轮次积累的上下文。如果处理第一轮的引擎,和处理第二轮的引擎是同一台机器,那这台机器的显存里其实已经缓存了前面的计算结果(这叫KV缓存),第二轮只需要算新增的那一小段就行。但如果路由把第二轮的请求随手甩给了另一台机器,那台机器对前面发生了什么一无所知,只能把整个历史重新算一遍。
这就好比你去医院复诊,如果每次都换一个新医生,医生就得把你的病历从头看一遍才能开始看病;但如果一直是同一个医生,他打开电脑,病历都在,直接接着上次的思路往下问。如果不做这个"绑定",每一轮对话都相当于让医生重新读一遍病历,轮次越多,浪费的时间呈线性甚至更快地增长。
Miles管这种绑定叫"亲和性",用SGLang的按键路由,给每个多轮会话贴一个稳定的路由标签,路由器看到这个标签就知道该送到哪台引擎去。同时,Miles还有个叫"会话服务器"的组件专门负责管理这些多轮对话的身份和路由标签,如果一个请求没带这个标签,Miles会直接报错,而不是偷偷按负载均衡随便扔一个引擎,因为那样虽然不会崩溃,但会悄悄拉低缓存命中率,出了问题还查不到原因。
但只做亲和性绑定还不够,因为不同轨迹的长度天差地别,一台机器如果分到好几个特别长的任务,就会被拖着走,而分到短任务的机器很快就闲下来了。所以Miles还加了一条规则:新会话开始时,交给当前活跃请求最少的那台引擎。两条规则叠加起来,在论文的实测数据里,这套组合拳能让缓存命中率维持在96%。
**让生成和训练同时跑起来:全异步强化学习**
传统的做法,是生成和训练轮流上场,训练等生成的批次全部完成再开始,生成也等训练算完新权重才能继续。这种做法有个致命伤:只要一个批次里有一条轨迹特别慢(比如那种要跑三十轮工具调用的任务),整个批次就得死等它,其它GPU全部闲置。
Miles的解法是全异步调度*(Fully Asynchronous RL):让生成引擎持续不断地产出轨迹,训练器则随时从已经完成的轨迹里挑一批出来训练,两边互不等待。
这个设计要求生成和训练必须使用两组独立的GPU资源,Miles甚至明确拒绝在同一批GPU上同时跑生成和训练时启用全异步模式,因为共享GPU意味着两边天然要抢资源,异步就没了意义。
这就像一个自助餐厅,如果所有顾客必须排成一队,等前面那个人磨磨蹭蹭挑完菜、结完账才能轮到下一个,队伍效率完全被最慢的那个人拖累。而如果餐厅开了多个取餐口和结账口,顾客各取所需,谁快谁先走,整体效率立刻上去了。如果不做这种拆分,长上下文和调用工具的任务会让大量批次陷入等待,GPU利用率被死死摁在低位。
生成端为了保持稳定的产出速度,还设计了一个"补位规则":一条轨迹一完成,它占用的生成名额立刻空出来,新的任务马上补上,而不是非要等整组任务全部完成才补位。这个"按条补位"是全异步模式下的默认策略,能让并发生成的轨迹数量始终贴近上限,即便轨迹长度相差一个数量级也不受影响。
生成完的轨迹放进一个有容量上限的数据缓冲区里,等训练器来取。这个缓冲区还承担了一个重要职责:判断一条轨迹是不是"过期"了。
新鲜度*(Staleness):指一条轨迹是用多久之前的模型权重生成的。如果轨迹在缓冲区里等了太久,训练器已经更新了好几轮权重,这条轨迹相对当前的模型就"过时"了,用它来算梯度可能会产生误导。
Miles的定义很保守,只要轨迹里有任何一个token是用最旧的权重生成的,整条轨迹的新鲜度就按这个最旧的算,绝不高估轨迹的"新鲜程度"。缓冲区还会实时上报队列长度、平均新鲜度等一堆指标,让人一眼就能看出到底是生成端跟不上,还是训练端在空等。
**多轮对话里,怎么保证模型看到的和生成时一模一样**
这是整篇论文里我觉得特别值得展开讲的一个设计,叫token级精确记录(TITO,Token-In-Token-Out)。
问题出在哪呢。一般的多轮对话流程是这样的:模型生成一段文字,这段文字经过消息解析、工具调用、模板渲染,才变成下一轮的输入。这中间每一步都有可能悄悄改变分词方式,比如把工具调用的参数重新序列化了一下,或者省略了推理过程的某些内容。这些变化通常不会报错,但它们会导致训练器最后看到的token序列,和模型实际采样出来的token序列不是同一个东西。
这就像你录了一段语音备忘录,结果转写软件在转文字的时候,自己悄悄改了几个词、删了几句话,你以为自己说的是A,系统记录下来的却是经过"美化"的B。等你之后根据这份文字记录去复盘自己当时的思路,复盘的其实是从来没发生过的对话。如果不精确记录原始token,训练器算出来的每一步概率,都是针对一个"从未真实存在过"的轨迹在计算,梯度更新自然是错的,而且这种错误是无声无息的。
Miles的解法是让"会话服务器"这个组件全权接管分词工作,而不是任由外部框架各自为政。第一轮对话时,服务器把消息渲染成token;每完成一轮,就把这轮的输入token、输出token、每个token的概率还有专家路由结果全部存成一个"检查点";后面每一轮,只需要在这个检查点基础上,对新增的部分做增量分词。这样最终拼出来的整条轨迹,是一份完全精确的、和实际推理过程逐字对应的记录。
针对不同的智能体框架,Miles还设计了两种延伸历史的规则,线性和分支。线性适合那种严格按顺序往前走的对话,一个会话只产生一条训练序列;分支则允许历史记录长成一棵树,适应像Claude Code这类会自己"折叠"或"分叉"上下文的智能体框架,一个会话可以产生多条训练轨迹。
**混合专家模型里的路由漂移问题**
这是个非常有意思的细节。在MoE模型里,每个token要被送到哪几个"专家"模块去处理,是由一个打分函数决定的,选分数最高的几个。问题是,如果生成引擎和训练引擎用的计算精度、算子实现有一丁点差异,同一个token在两边可能会被路由到不同的专家上。
假设生成时某个token被送去了2号和7号专家,但训练时因为精度差异,同一个token被路由到了2号和8号专家。这时候,训练更新打在了8号专家身上,但真正处理过这个token、需要被纠正的其实是7号专家,它却什么都没学到。论文里提到,这种路由错位如果任其发展,会在成千上万步的训练中不断累积,甚至导致训练彻底崩溃。
Miles的解决办法叫R3*(Rollout Routing Replay,生成路由重放):把生成阶段记录下来的专家路由结果,当作数据的一部分保存下来,训练时直接照搬这个路由结果,不再重新计算。
这就好比考试时老师已经把每道题该找哪位阅卷老师批改都标注好了,阅卷老师直接按标注去改,而不是自己重新判断这道题该归谁管,从根本上杜绝了张冠李戴的可能。当然,这个方案不是没有代价的,每条轨迹的路由信息本身要占用不少存储空间,一个3.2万token的长序列,60层网络,每层选8个专家,光路由数据就要占大约60MB,而且这个开销会随着序列长度线性增长。
**训练端怎么把万亿参数塞进有限的显存里**
这一部分讲的是Miles在低精度训练和内存管理上的功夫。
先说精度。GPU的算力会随着数值精度降低而翻倍提升,从16位浮点到8位再到4位。但强化学习训练里,如果生成端和训练端用不同的量化方式计算同一份权重,两边算出来的结果会一层一层地累积误差,最终导致灾难性的训练崩溃。
Miles的应对策略是建立"精度契约":生成和训练必须用完全一样的量化逻辑。目前跑通的格式有三种,FP8分块量化已经比较成熟,MXFP8和NVFP4还处于测试阶段。这里有个细节挺有意思,NVFP4这种格式要求"谁碰权重谁就必须量化",所以不能出现训练器留在BF16精度、但生成引擎用NVFP4的搭配,这种组合是不被支持的。
再说内存。一个超大模型的优化器状态(也就是训练过程中用来记录每个参数历史更新趋势的额外数据)往往比模型本身占用的显存还多。Miles设计了两套内存释放机制:一套是训练间隙把整个训练进程的状态挪到GPU之外,给同一批GPU上的生成引擎腾地方;另一套是把优化器状态干脆存到硬盘上,需要更新哪部分参数就临时加载对应的那一小块回显存,用完立刻释放。
这就像你搬家时,如果家里东西太多塞不下,一种办法是暂时把所有家具搬到楼道里给装修腾地方,装修完再搬回来;另一种办法是把不常用的东西直接存进附近的仓库,需要用的时候再去取。论文里提到,在Qwen3-30B-A3B这个模型上,用了硬盘流式加载优化器状态后,训练进程的暂停时间从24秒缩短到5.2秒,恢复时间从8.9秒缩短到1.3秒,效果相当直观。
在案例研究中,那台跑GLM-5.2的64卡集群,实际上正是靠着这套硬盘流式方案,才把一个每个数据并行副本要占279GB显存的优化器状态给塞进了GPU里,这个数字本身就已经超过了单张GPU的显存容量,硬盘流式在这里不是锦上添花,而是"不这样做根本跑不起来"的刚需。
**权重从训练器传到生成引擎,怎么传得又快又稳**
每次训练更新完权重,都得把新权重同步给正在生成的引擎,这个过程如果处理不好,会变成整条流水线里最大的堵点。论文里给了一个很直观的数字:Kimi K2这个1万亿参数的模型,用最普通的广播方式同步一次权重,要花将近一分钟。
Miles准备了三种传输方式。默认的广播方式,是用NCCL*(NVIDIA的一套GPU间通信加速库):让多张GPU卡之间能够高速交换数据的底层通信协议。
把权重一次性发给所有生成引擎,简单可靠,但当训练集群和生成集群规模都很大时,会成为瓶颈,因为每个发送方都要把完整数据发给每一个接收方,哪怕对方根本用不上那部分权重。
第二种是点对点传输,让多个训练节点同时直接往生成节点的显存里写数据,用的是RDMA*(远程直接内存访问,一种绕过CPU直接在两台机器的内存间传输数据的技术)。
这种方式的效率提升非常惊人:在16节点对16节点的GLM-5模型上,广播要58.3秒,点对点只要8.48秒,降幅85.5%;Kimi K2上更夸张,从53.28秒降到7.23秒。但论文也诚实地指出了这个方案的短板,在单机部署时点对点反而比广播慢了将近70%,因为单机场景下没有额外的聚合带宽可用,点对点还要额外承担主机端权重重排和内存暂存的开销。这提醒我们,没有一种传输方式是万能的,取决于你的集群到底是"又宽又扁"还是"又窄又深"。
第三种是磁盘增量更新,这个思路挺巧妙的:连续两步训练之间,模型权重变化的字节数往往只占很小一部分,那与其每次都把整个模型重新传一遍,不如只把变化的部分写到一个大家都能访问的共享文件系统里,各个生成节点自己去读取增量、打补丁。这种方式不需要训练端和生成端之间有直接的网络通道,只要有个共享文件系统就行,非常适合那些物理上分离、没有专用高速网络连接两边的部署场景。
**除了强化学习,Miles还能做什么**
Miles并没有把自己局限在"标准强化学习"这一件事上,它把生成引擎、训练器和权重同步这三大件当作可以自由组合的积木,搭出了另外几种训练范式。
低秩适配强化学习*(LoRA RL):不更新模型的全部参数,而是冻结原始权重,只训练一小对低秩矩阵作为"补丁"叠加在原模型上。
这样做的好处立竿见影:优化器状态只需要覆盖这一小撮新增参数,每一步训练算得更快,权重同步时也只需要传输这一小部分补丁,而不是整个模型。论文提到,Kimi K3和2.4万亿参数的Qwen3.8这两个模型,发布当天能立刻用上强化学习训练,靠的正是LoRA,因为完整参数微调这么大的模型,根本塞不进现有集群。
另一个很有意思的方向是在线蒸馏(On-Policy Distillation)。传统蒸馏是让学生模型去模仿老师写好的文字,但学生自己几乎不会主动生成那样的文字,学习效果打折扣。在线蒸馏反过来做:让学生自己生成,然后拿老师模型去给学生生成的每一个token打分,看看老师觉得这个token出现的概率有多高,学生和老师打分的差异就成了训练信号。
这就好比学写作文,与其让学生反复抄一篇范文,不如让学生自己写一篇,再请一位经验丰富的老师逐句点评"这句话你写得比我更自信,但其实这里应该更谨慎一点",这种基于学生自己产出的反馈,往往比单纯模仿更有针对性。论文里给了一个具体例子:Qwen3.5-35B-A3B模型经过五步蒸馏训练后,回答长度从14070个token压缩到6132个token,减少了56%,而准确率几乎没有变化(84.0%到85.2%,这个差距在统计误差范围内)。也就是说,模型学会了用更少的话说清楚同样的事,这本身就是一种进步,尽管论文很诚实地没有夸大成"准确率提升"。
还有一种叫"真正的同策略对齐"(True-On-Policy Alignment),这个设计的野心更大:让生成引擎和训练器对同一个token算出的概率完全一模一样,一个比特都不差。要做到这一点,得把两边用的注意力计算方式、矩阵乘法内核,甚至随机性来源全部锁死到位。这个方案目前只在Qwen3的0.6B和4B这两个较小的模型上验证过,代价是牺牲了一部分推理速度,毕竟为了追求"绝对确定性",很多原本能加速的优化手段都得关掉。
**这套系统跑起来到底什么样:GLM-5.2的真实案例**
论文最后给出了一个完整的实测案例,非常有参考价值。64块GB300 GPU,一半做生成一半做训练,训练GLM-5.2这个744B总参数、40B激活参数的模型,任务是在真实的终端环境里完成编程任务。
训练这边把32块GPU按张量并行、流水线并行、上下文并行、专家并行四个维度切分,用尽了所有能用的并行手段。生成这边跑着FP8精度的模型副本,配合多token预测技术,一次前向传播能吐出不止一个token,加快生成速度。
实测结果里有几个数字值得记一下。前30步训练的中位数耗时是263秒,第一步因为要做各种初始化和预热,花了1042秒,这个数字被单独排除在中位数统计之外,是合理的处理方式。训练和生成之间的对数概率偏差,平均值是0.0369,这个数字虽然不是零,但被截断式重要性采样这个纠偏机制稳稳地兜住了。原始任务奖励的九步滑动平均,从0.438爬升到0.556,论文很谨慎地说,单次实验没法把这个提升和随机波动完全区分开,所以只当作一个观察结果来报告,而不是一个确凿的结论。这种谨慎的表达方式,其实比夸大其词的宣传更值得信任。
论文还提到一点很实在的工程细节:整个系统在缓冲区队列长度、专家路由重放开销、权重传输耗时这些环节上都做了详细的可观测性设计,出了问题能快速定位到底是生成慢了还是训练慢了,而不是像个黑箱一样,出问题了只能干瞪眼。
写在后面
读完这篇论文,最让我意外的其实不是某个具体的算法创新,而是它把强化学习训练大模型这件事,从"研究实验"的语境彻底搬到了"生产系统"的语境。研究论文里常见的表述是"我们的方法在某个数据集上取得了最优结果",但Miles这篇论文里反复出现的却是"这个功能目前处于测试阶段""这个路径只覆盖某几个模型家族""这个结论的置信度不够,我们只作为观察报告"。这种克制感在工程系统的文档里其实挺少见的,大多数系统宣传都倾向于把能用的场景说满,把不能用的场景模糊带过。
另一个让我反复琢磨的细节是那个"路由重放"的设计。混合专家模型的路由机制本来是为了省算力而设计的巧思,结果在强化学习训练里反倒成了一个容易被忽视的坑,稍不注意就会让训练悄无声息地跑偏。这提醒我一件事:一个系统里某个模块的"优点",放到另一个应用场景里,完全可能变成"隐患",工程设计从来不是孤立地评判一个模块好不好,而是要看它和整个系统其它部分之间会不会产生意想不到的化学反应。
论文里没有解决的问题也挺明确的:视觉语言模型目前还接不进这套精确的token记录系统,量化格式还在往4位精度的边界摸索,点对点权重传输目前只支持几个特定的模型家族。这些"未完成"的部分,某种程度上比"已完成"的部分更真实地反映了这个领域现在所处的位置:不是已经解决了所有问题,而是刚刚把最难啃的几块骨头啃下来,剩下的还有很长的路要走。
那么下一次,当你在新闻里看到某个千亿或万亿参数的模型又完成了一轮强化学习训练,不妨想一想,在那句简短的公告背后,可能藏着几十个像"路由重放""磁盘增量更新""会话服务器"这样毫不起眼却缺一不可的工程细节,正是它们撑住了那个看起来轻描淡写的"训练完成"四个字。
Q&A
Q1:Miles是什么系统,主要用来做什么?
A:Miles是RadixArk开发的一套面向生产环境的大模型强化学习后训练系统,用于解决超大模型(如万亿参数混合专家模型)在做多轮智能体强化学习训练时的效率和数值一致性问题,支持全异步调度、多种精度格式和三种权重同步方式。
Q2:Miles为什么要设计token级精确记录(TITO)机制?
A:因为传统多轮对话流程中,消息解析、工具调用、模板渲染等环节会悄悄改变分词结果,导致训练器看到的token和模型实际生成的不一致,进而让梯度更新对着一个从未真实发生的轨迹计算,TITO通过让会话服务器统一控制分词来避免这个问题。
Q3:GLM-5.2案例里用了多少GPU,训练效果如何?
A:案例使用64块NVIDIA GB300 GPU,一半用于生成一半用于训练,前30步训练中位耗时263秒,训练与生成间的概率偏差平均0.0369,任务奖励九步滑动平均从0.438升至0.556,但论文说明单次实验无法排除随机波动。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.