在 2025 年云栖大会的现场演示里,Qwen3-Omni-Flash 用 234 ms 的冷启动首包延迟完成了一次 “边看视频边对话” 的交互。观众肉眼几乎察觉不到停顿,但很多人忽略了背后的工程细节:多模态链路的新瓶颈早已不是 LLM 本身,而是 “编码 + prefill” 的串行耦合。
过去我们优化纯文本模型时,只要把 decode 阶段调度好,就能让 TTFT(Time to First Token)降到 150 ms 以内。可当输入变成 3 fps 的视频流、16 kHz 音频与 768 px 图像的混合体,encode 阶段产生的 token 数量会瞬间膨胀 5–10 倍,直接把 prefill 拖进内存墙。下面把我们在 Qwen3-Omni-Flash 上的实测步骤拆成 5 个可直接落地的参数,方便你在任意 MoE 多模态模型上复现。
1. encode-prefill 重叠窗口:256 token
受 RServe 论文启发,我们把视觉编码器与 LLM prefill 做成 ** intra-request 流水线 **:每当编码器产出 256 个连续 token,就立即触发一次 chunked prefill,而不必等整张图或整段音频完全编码完毕。实现方式是在 vLLM 的 MultiModalProcessor 里加一条 callback_queue,256 token 就 torch.cuda.Event 通知一次。
- 实测收益:TTFT 从 420 ms → 180 ms(−57%)
- 副作用:batch 调度复杂度 +15%,需要把
max_num_seqs从 128 调到 96 以避免显存碎片
2. chunked-prefill size:512
Omni-7B 的注意力头维度 128,在 A100 上实测 FlashAttention-2 的最佳 tile 是 512。继续放大到 1024 收益递减,反而因 SRAM 装不下导致回退到 HBM。512 是吞吐与延迟的甜点,同时把 num_pipeline_stages 设为 2,可以让 encode 与 prefill 的 GPU 利用率都 >90%。
3. decode batch=32
当首 token 发出后,真正的实时感来自 decode 阶段稳态延迟。我们用连续批处理(continuous batching)把 decode batch 拉到 32,配合 gated KV-cache pool,每 50 ms 刷新一次。此时
- 每输出 token 的平均延迟(TPOT)= 38 ms
- P99 延迟 < 65 ms,仍低于人类 200 ms 感知阈值
如果业务对语音流更敏感,可把 batch 降到 16,TPOT 会进一步压到 28 ms,但 QPS 下降 40%,需要横向扩容补偿。
4. INT8 显存预算:4 GB
端侧场景(Orin-Nano 8 GB)我们直接用 INT8 权重量化 + KV-cache FP16 的混合方案:
- 7B 权重从 14 GB → 3.5 GB
- 32 k 上下文 KV-cache 占用 2.2 GB
- 留 2 GB 给图像 / 音频临时激活,系统总显存 7.7 GB,仍在安全余量内
注意:INT4 虽然能把权重再砍一半,但在 ASR 任务上 WER 会回退 0.8%,除非你的应用对精度极不敏感,否则不建议。
5. MoE 路由剪枝阈值:0.27
Qwen3-Omni-Flash 的 Thinker 部分有 128 个专家,默认 top-8 激活。我们通过 类别感知路由 把专家按模态先切成 6 组(文本 / 图像 / 音频 / 视频 / 通用 / 空闲),再在组内做 top-k。实验发现,当路由门控分数 < 0.27 时直接置零,可以无损剪掉 1.8 个专家,单 token 延迟从 1.2 ms 降到 0.9 ms,累积到 512 token 的 prefill 阶段就是 150 ms 的净收益。
端侧实测:Orin-Nano 30 fps 视频对话
把以上 5 个参数打包进 TensorRT 引擎后,我们在 Orin-Nano 上跑 30 fps、480 p 的视频流对话,连续 10 分钟,监控数据如下:
- 平均端到端延迟:234 ms(冷启动)→ 稳态 190 ms
- 整机功耗:18 W,比 FP16 方案下降 42%
- 显存峰值:7.1 GB,无 OOM
- 视频帧丢失:0(30 fps 全保持)
小结:一张表带走
| 参数 | 推荐值 | 收益 | 副作用 |
|---|---|---|---|
| encode-prefill 重叠窗口 | 256 token | TTFT −57% | 调度复杂度 ↑ |
| chunked-prefill size | 512 | 吞吐甜点 | 无 |
| decode batch | 32 | TPOT 38 ms | QPS 受限 |
| INT8 权重 | 4 GB 预算 | 显存 ↓ 60% | 精度需验证 |
| MoE 剪枝阈值 | 0.27 | 延迟 −25% | 需重新校准 |
把这些数值直接写进你的 config.json 或 trtexec 启动脚本,就能在任意 Ampere 及以上 GPU 复现 234 ms 首包。如果后续想继续往下压,把 encode 阶段搬到 DLA(Deep Learning Accelerator) 是下一波 30 ms 级别的空间,但那是另一篇笔记的故事了。
参考资料
- CSDN《Qwen3-8B:轻量级大模型中的延迟王者》2025-11-27
- RServe: Overlapping Encoding and Prefill for Efficient LMM Inference, ArXiv 2509.24381
- EPD Disaggregation: Efficiently Serving Large Multimodal Models, ArXiv 2501.05460