跳转到主要内容

Prefill Trace:Worker 供给、DSA/MLA 与 Chunked Prefill

用 GLM-5.2 Prefill Trace 区分 worker 供给、模型计算、KV 数据路径、通信与同步

· 约 4 分钟阅读

这篇不是 MLA 或 Chunked Prefill 的第二份教程,而是一张 trace 诊断清单:当 MessageQueue、模型 forward、KV gather/copy、NCCL 与同步同时出现时,怎样避免把它们都归成“模型计算慢”。

案例来自 GLM-5.2 Prefill profile;数值和符号只能约束该采集窗口,诊断顺序可以复用到其他 trace。

30 秒复习
  • 一句话:先把 Prefill trace 拆成 worker 供给、模型执行、KV 数据路径与通信同步,再用逐 step identity 验证因果。
  • 三个判断MessageQueue 长等待不等于 GPU 计算;Queue Length ≈ 22.94 是窗口聚合积压而非 batch size;prefix hit 应先换算成 effective prefill,再解释 scheduler chunk。
  • 核心模型request → scheduler/queue → worker → execute_model → attention/MoE/KV/collective,每层使用不同指标。
  • 边界:没有 request/chunk identity、Q/KQ/K shape 与时间相关性时,只能定位可疑层,不能给出百分比损失或单一根因。

1. 先按执行链分层

请求进入 engine / scheduler
  -> worker 从 MessageQueue 取得本轮工作
  -> GPUModelRunner.execute_model
  -> model.forward
  -> attention / MoE / KV / collective / sync
Trace 信号首先代表什么还不能证明什么
MessageQueue.dequeue/acquire_readworker 等待下一批工作或队列状态模型正在计算
GPUModelRunner.execute_model一轮模型执行包络内部哪个算子是根因
模型 forward模型路径总包络全部时间都是 GPU kernel
MLA / sparse attentionAttention 与 KV 访问路径压缩或稀疏一定带来净收益
KV gather/upconvert/copy布局、表示转换与搬运一定是远端 KV 或 P/D 传输
NCCL / stream sync通信或依赖等待通信本身而非上游迟到是根因

分析时先在时间线上标出这些层,再下钻。把 CPU queue wait 与 GPU model time 相加后直接归给“Prefill 算力”会混淆控制面和数据面。

2. MLA/DSA 只作数据路径解释

在该模型路径中,MLA/DSA 信号会出现在 Prefill,并非 Decode 专属。

  • MLA 主要改变 KV 的表示、缓存布局和访问方式;
  • DSA 类选择机制可能改变参与计算的历史范围;
  • causal 语义仍要求当前位置不能看未来 token。

Decode 对 KV 容量与读取带宽的收益通常更直观。Prefill 是否获益还取决于 QlenQ_{\text{len}}KlenK_{\text{len}}、prefix hit、chunk shape、gather/upconvert/copy 与 kernel 实现。这里不从 trace 名称推出“MLA 一定更快”。

MLA 机制见 DeepSeek MLA,稀疏/混合 Attention 的位置见 Attention 架构演化

3. Queue Length 不是 Batch Size

Queue Length ≈ 22.94 更像监控窗口中的平均积压,因此可以是小数;batch 则是某一轮真正交给模型的请求、序列或 token 集合。

指标正确问题
Queue Length等待执行的积压是否增长?
Running Requests同时服务多少请求?
Batch Sequences本轮包含多少序列?
Batched/Scheduled Tokens本轮实际推进多少 token?

若 Queue Length 高而 scheduled batch 小,应继续查 admission、worker 供给、token/KV budget 与资源配额,而不是把 22.94 当作请求 batch。

4. Prefix 与 Chunk 的解释顺序

用于调参与读 trace 的稳定心智模型是:

raw prompt
  -> 查找可复用 prefix / computed blocks
  -> 得到 effective uncached tokens
  -> scheduler 按 token budget 切 chunk
  -> 进入 Prefill forward

命中 prefix 后,suffix 不必重算前缀的 FFN/Attention 输出,但仍要把前缀 KV 当作历史:

Qlen=Nsuffix chunkQ_{\text{len}}=N_{\text{suffix chunk}} Klen=Ncached prefix+Nprevious suffix+Ncurrent chunkK_{\text{len}} =N_{\text{cached prefix}} +N_{\text{previous suffix}} +N_{\text{current chunk}}

所以 prefix hit 减少 effective prefill token,不代表 Attention 上下文归零。远端/分层 cache 还需单独记录 KV load latency。

5. 回到 GLM-5.2 P Trace

该 profile 中同时出现:

  • Python 侧 MessageQueue.dequeue/acquire_read 长等待;
  • GPUModelRunner.execute_model 与模型 forward 包络;
  • DSA/MLA、KV gather/upconvert/copy、NCCL 与 stream sync;
  • 约 256 token 的小块与数千到 16K 的大块。

可复用的调查顺序是:

  1. 供给:worker 是否持续拿到任务?等待是否与 queue/backlog 同时发生?
  2. 有效工作量:raw ISL 中有多少已被 prefix reuse?
  3. Chunk shape:小尾块是否对应更高的 launch、metadata 或小 GEMM 占比?
  4. Attention/KVQ/KQ/K、gather、upconvert 与 copy 是否随上下文变化?
  5. MoE/通信:expert token group、NCCL 与同步是否形成关键路径?

input_ids 只能描述本轮输入 token 规模。它不能独立解释 Attention 历史长度、MoE 路由、KV 布局或 worker 空洞。

6. 升级为因果结论所需证据

逐 step 至少补齐:

request_id, chunk_id, phase,
raw_input_tokens, prefix_hit_tokens, scheduled_tokens,
Q_len, K_len, expert_token_distribution,
queue_wait, execute_model_duration,
KV_copy/transform, collective, sync

再分别验证:

scheduled tokens -> forward duration
K_len -> attention / KV duration
expert tokens -> MoE duration
queue state -> worker idle gap

只有变量变化与目标指标稳定相关、且对照实验排除了共同上游等待,才能把“出现在哪里”升级为“造成了多少”。字段缺失时,应保留 unknown / unavailable,不要填零。

相关页面