智谱(02513)首次披露GLM-5 Coding Agent推理工程实践
時間:2026-04-30 09:09:16
智譜
智通财经APP获悉,智谱(02513)公众号发文,首次系统披露GLM-5系列模型在超大规模Coding Agent调用场景下的底层推理技术突破。包括两个关键Bug的定位及修复、一项性能优化创新、以及一个意外的监控机制突破。针对Context Parallel策略中的KV Cache冗余存储问题,智谱设计实现了KV Cache分层存储方案 LayerSplit,这一优化直接大幅提升智谱在Coding场景下的服务能力上限。此外,公司推理优化还在进一步加速,大幅提升单位算力token吞吐效率,降低推理成本。
智谱表示,当智能真正进入高并发、长上下文的 Coding Agent 场景后,推理基础设施的挑战已经不只是吞吐、延迟和可用性,维护它的输出质量变得至关重要。每一次对 Scaling Law 的追求,都必须有同等强度的系统工程作为支撑。
经过数周的推演、排查与压测,公司最终定位并修复了几个相互独立的底层竞态 Bug,并对其中所反映的系统瓶颈进行了针对性优化,显著提高了推理系统的稳定性和效率。
本次披露的工程突破具备明确的技术深度——团队不仅在自有推理链路中定位并修复了PD分离架构下的KV Cache跨节点复用竞态,更进一步在主流开源推理框架SGLang的源代码层面发现并修复了HiCache模块的加载时序缺失(read-before-ready)问题,修复方案被SGLang开源社区采纳,其底层基础设施能力不仅服务于自身模型,也正在成为大模型行业的公共基础设施之一。
从线下复现到异常识别
自 3 月起,在 GLM-5 的线上监控和用户反馈中观察到三类异常现象:乱码(garbled output)、复读(repetition),以及生僻字(rare character)。这些现象在表面上与长上下文场景下常见的“降智”相似,但由于智谱并没有上线任何降低模型精度的优化,一个更关键的问题是:异常究竟源于模型本身,还是源于推理链路?如果源于模型,异常会表现为针对特定输入的稳定、可重复行为;反之,若异常与系统压力或运行时状态相关,则更可能指向推理基础设施中的链路或状态管理问题。
排查初期,公司先对用户反馈的 bad cases 做本地回放,并将同一批请求重复推理数百次,但始终未能复现异常,说明大概率不是模型本身的问题。为进一步模拟线上环境的压力,公司对线上日志做脱敏处理,并尽可能保留原始并发分布与请求时序,在本地进行全量回放。起初仍未复现异常,直到进一步调整 PD 分离比例并持续提高系统负载,模拟高峰期的 Prefill 堆积和 Decode 侧 KV Cache 压力后,才在约每万次请求中稳定复现 3-5 次异常。这种“与请求内容无关、与系统压力相关”的特征,说明问题可能来自高负载下的推理状态管理。与此同时,线下复现的异常频率仍低于线上反馈的频率,说明现有检测方法可能存在漏检,或仍有部分触发场景尚未覆盖。
如何可靠识别异常输出成为了新的挑战。三类异常中,复读相对容易检测,而乱码与生僻字比较棘手。公司尝试过正则表达式、字符集匹配等启发式方法,也尝试过基于模型判别的方式,但前者存在明显的漏判与误伤,后者则难以满足大规模消融实验的效率要求。上述限制使异常检测本身成为定位流程中的一个瓶颈。

图1:投机采样指标可以作为异常检测的重要参考
在反复分析推理日志后,智谱发现了一个意想不到的切入点:投机采样(Speculative Decoding)指标可以作为异常检测的重要参考。投机采样原本是一个性能优化技术,先由草稿模型生成候选 token,再由目标模型校验并决定是否接受,从而在不改变最终输出分布的前提下提升 decode 效率。如图 1 所示,两个指标(spec_accept_length:目标模型连续接受的 draft token 前缀长度;spec_accept_rate:draft token 被接受的比例)在异常发生时呈现出稳定模式:
乱码和生僻字:通常伴随极低的 spec_accept_length,即草稿模型生成的候选 token 几乎全部被目标模型拒绝,表明目标模型所看到的 KV Cache 状态与草稿模型预期之间存在显著偏差。
复读:通常伴随偏高的 spec_accept_rate,表明损坏的 KV Cache 可能使注意力模式退化,并将生成过程推向高置信度的重复循环。
基于上述观察,公司进一步实现了一套在线异常监控策略:当 spec_accept_length 持续低于 1.4 且生成长度已超过 128 token,或 spec_accept_rate 超过 0.96 时,系统主动中止当前生成,并将请求交由负载均衡器重试。该策略使投机采样从单纯的性能优化技术,拓展为输出质量的实时监控信号,成为后续消融实验中的关键工具。
BugFix#1:PD分离架构下的KV Cache竞态
在观察到异常输出与并发压力具有明显相关性后,公司进一步分析其原因。通过对请求生命周期以及推理引擎中 PD 分离执行时序的分析,发现该问题源于请求生命周期与 KV Cache 回收与复用时序之间的不一致,从而引发的 KV Cache 复用冲突。
1.原因分析:异步 Abort 引发的 KV Cache 复用竞态
为限制尾延迟,公司在推理引擎中引入了基于超时的请求终止机制:当 Prefill 阶段未在规定时间内完成时,Decode 侧会对请求执行 Abort,并回收其占用的 KV Cache 资源。然而,该 Abort 信号未被正确传播至 Prefill 侧,同时 Decode 侧也缺乏判断 KV Cache 是否可安全回收与复用的充分信息。因此,在 Decode Abort 并将对应 KV Cache 空间分配给新请求之后,先前已发起的 RDMA 写入以及正在执行的 Prefill 计算仍持续执行,未被同步取消。

图2:PD 分离场景下 KV Cache 竞态示意图
图 2 中展示了在 PD 分离架构下,两个请求在 Prefill 与 Decode 之间交互的时序关系,以及由此引发的 KV Cache 竞态。
在初始阶段,Req1 被发送至 Prefill-1(P1)和 Decode(D)。由于调度或排队等原因,Req1 在 P1 侧经历了一段等待后才开始执行 Prefill Forward。与此同时,Decode 侧在一段时间内未收到对应的 KV Cache 数据,触发超时机制,并对 Req1 执行 Abort。
随后,Decode 侧回收 Req1 占用的 KV Cache 槽位,但没有正确通知 P1。紧接着,新请求 Req2 到达,并被分配至 Prefill-2(P2)和 Decode。由于内存复用策略,Req2 被分配到与 Req1 相同的 KV Cache 地址。P2 开始执行 Prefill Forward 并进行 KV Transfer,并在较短时间内完成,使 Decode 侧进入生成阶段。
与此同时,P1 侧针对 Req1 发起的 KV Cache 写入仍在继续,其数据会写入已被 Req2 复用的显存区域,从而覆盖 Req2 的部分 KV Cache。最终,Req2 在 Decode 阶段读取到被覆盖的数据,导致生成结果异常。
2.修复方案:KV Cache 释放的时序一致性保证
为消除上述竞态,在推理引擎中引入了更严格的时序约束,在请求终止与 KV Cache写入完成之间建立显式同步关系。
具体而言,Decode 在触发 Abort 后,会向 Prefill 侧发送通知。Prefill 仅在以下条件满足时返回“可释放”信号:相关 RDMA 写入尚未开始,或所有已提交写入均已完成。Decode 仅在收到该确认后,才允许回收并复用对应的 KV Cache 槽位。该机制确保 KV 写入不会跨越显存复用边界,从而避免跨请求的 KV Cache 覆盖。
修复效果:该修复上线后,异常输出的发生率由约万分之十几下降至万分之三以下。结果表明,在 PD 分离架构中,需要对跨节点的数据传输与显存复用建立明确的一致性约束,以避免类似问题。
BugFix#2: HiCache加载时序缺失
Coding Agent 场景显著提高了输入长度(平均超过 70K tokens),同时伴随较高的前缀复用率。这类负载使 HiCache(多级 KV Cache)成为线上服务中的关键优化手段。然而,在 KV Cache 换入与计算重叠执行的情况下,当前实现未能保证数据在使用前已完成加载,导致可能出现未就绪 KV Cache 被访问的情况。
1.原因分析:流水线同步缺失导致的 read-before-ready
通过对 HiCache 执行时序分析,公司将问题定位在 DSA HiCache 的缓存读取路径上。系统会从 CPU 内存异步换入(swap-in)历史前缀缓存,并通过 Load Stream 与 Forward Stream 的重叠执行来提高吞吐。
如图 3(a) 所示,Load Stream 负责加载 KV Cache 与 Indexer Cache,而 Forward Stream 依次执行 Index 计算与后续的 Sparse Attention。理论上,Forward Stream 中的 Indexer 计算应在对应的 Indexer Cache 完成加载后才能启动。然而,在原始实现中,该依赖未被显式表达。
具体而言,Indexer 算子在启动时未对 Load Indexer Cache 的完成建立同步约束(图 3 中红色虚线区域)。因此,Forward Stream 可能先于 Load Stream 完成数据加载而开始执行,从而出现 Read-before-Ready 的访问模式,即在数据尚未完成加载时即被读取。
该问题会导致 Index 计算基于不完整或未初始化的数据执行,进而影响后续 Sparse Attention 的计算结果,并最终反映为输出异常。

图 3:HiCache 读取流水线时序异常与修复示意图
2.修复方案:重构算子流水线的原子性
为解决上述问题,公司对 HiCache 的读取流水线进行了修改(如图 3(b) 所示),在数据加载与计算之间引入显式的同步约束:
显式同步约束:在 Indexer 算子启动前引入与 Load Stream 的同步点,确保对应层级的 Indexer Cache 已完成加载。Forward Stream 仅在数据就绪后才启动计算,从而避免 read-before-ready 的访问。
该修复上线后,在相同负载条件下,由执行时序不一致引起的异常完全消失,系统行为趋于稳定。该修复已通过 Pull Request #22811 提交至 SGLang 社区。
优化:KV Cache分层存储LayerSplit
上述两个竞态问题揭示了一个共同的系统瓶颈:在长上下文的 Coding Agent Serving 场景中,Prefill 阶段主导了系统性能。
为了控制 Prefill 排队带来的 TTFT,智谱引入了超时 Abort;为了缓解 Prefill 侧 KV Cache 容量压力,引入了 HiCache。在修复这些状态一致性问题后,进一步回到瓶颈本身:如何提升 Prefill 吞吐、降低 Prefill 侧 KV Cache 显存压力。为此,公司设计并实现了 KV Cache 分层存储方案 LayerSplit。
Coding Agent 负载通常呈现出上下文长度较长、Prefix Cache 命中率较高的特征。在这一场景下,Prefill 阶段往往成为系统的主要性能瓶颈,因此 Context Parallel(CP)成为线上 Prefill 节点的主要并行策略。然而,现有的 SGLang 开源实现存在 KV Cache 冗余存储的问题,导致有限的 KV Cache 容量成为 GPU 计算资源利用率的限制因素。

图 4:LayerSplit、KV Cache 分层存储方案
针对这一问题,公司设计并实现了一种 KV Cache 分层存储方案(LayerSplit)。在该方案中,每张 GPU 不再保存全部层的 KV Cache,而是仅持有部分层的 KV Cache(如图 4(a) 所示),从而显著降低单卡的显存占用。
在计算过程中,不同 CP rank 按照图 4(b) 所示的方式协同完成 Prefill:具体而言,持有某一层 KV Cache 的 rank 会在执行 Attention 计算前,将该层 Cache 广播给其他相关 rank。为降低通信开销,进一步设计了 KV Cache 广播与 indexer 计算的重叠机制,使二者在时间上相互掩盖。最终,整个流程中仅引入了 Indexer Cache 广播的额外开销,其规模约为 KV Cache 的 1/8,因此整体通信成本较低,对性能影响可以忽略。

图 5:GLM-5.1 + LayerSplit 在不同长度下的吞吐提升
图 5 展示了在 Cache 命中率达到 90% 的条件下,该优化在请求长度从 40k 到 120k 区间内带来的性能提升。实验结果表明,系统吞吐量提升幅度在 10% 至 132% 之间,且随着上下文长度的增加,收益更加显著。整体来看,该优化显著提升了系统在 Coding Agent 场景下的处理能力。
免責聲明:本資訊不構成建議或操作邀約,市場有風險,投資需謹慎!


