### 【realtime_ws】并发 streaming session 的vllm解码 测试中并发 streaming session 增多时,首条结果延迟明显上升,超过一定并发后结果趋于停滞。 在约 15+ 个并发 session 下,首字延迟 p50 从 10 个 session 时的 ~1.5s 涨到 ~2.2s(p95 到 ~66s),并随并发继续恶化。以上数值仅供参考,不代表精确基准。 似乎RealtimeBatchingEngine把并发 session 的请求统一汇到单个 worker 线程,底层调用同步 `LLM.generate。实时流式里每个 session 的 handle_client循环要等自己的 partial 返回之后才发下一帧(run_session_work → asyncio.to_thread →阻塞 generate),语音请求在vad处理后请求天然稀疏,batch_wait_ms=10ms的攒批窗口几乎凑不齐。于是请求稀疏 → 批凑不满 → 单条串行 → 客户端等更久 → 更稀疏,形成自锁,吞吐受限。这是我的推测解释,未必准确,供参考。 目前benchmark 文档只到 8 clients,若未来有意支持更高并发,是否可以考虑把解码器切到 AsyncLLMEngine(vLLM v1 的vllm.v1.engine.async_llm.AsyncLLM,同样 enable_prompt_embeds=True),每个 session 的partial / 锁句作独立 request_id提交:引擎按 step 在卡上合批、同时把每条结果返回给各自调用方,天然保住每个 session 的顺序与 partial 中间态,吞吐也随之恢复。是否值得,请各位大佬按定位评估;我这边物理条件有限,测试结果未必准确,也很难支持更高并发下的吞吐测试,若感兴趣可在高并发下尝试验证。
Activity
LauraGPT commentedon Sep 28, 2026
感谢提供具体的并发拐点,也感谢明确区分测量结果和推测。按当前 main
e1ceba0aa8ac4132df9e177c50000361fd2cc038核对源码后,这个方向值得评估,但需要拆开两层问题:RealtimeBatchingEngine用一个 worker 收集请求,再按解码参数分组,逐组调用同步generate();Nano 底层也是同步LLM.generate()。执行中的批次不会通过这个封装接纳新请求,后来的请求只能等下一轮。但下一轮也会收集已排队的请求,因此仅凭 10 ms 窗口,不能断言每次都只能单条解码,需要实际requests/samples日志确认。batcher 源码、Nano 调用handle_client等待当前 decode 后才继续消费下一条消息,这会造成接收侧积压;但不等于客户端协议要求等待 partial 才能发送下一帧。仓库压测客户端已经使用独立接收任务,同时持续发送音频。这里应区分客户端发送节奏、服务端消费进度和 GPU 解码队列。服务端、压测客户端另补充:当前benchmark 文档已有 H100 上 12/16 clients 的参考记录,并不只到示例命令中的 8 clients。16 路 batched candidate 的 final-after-STOP p95 仍约 10 s,不能视为低延迟容量保证。另外脚本的
first_update_ms统计首个结果消息,不要求非空文字,不一定等同于这里的“首字延迟”。不必先做更高并发测试。方便的话,请补充已有 10/15 路测试的这些信息:
--log-decode-profile后的慢时段日志,重点包括requests/samples、queue_ms_p50/max、engine_ms,以及相邻Audio encoding/vLLM generation日志;附已有客户端 JSONL。隐私音频不必公开,日志里的文本/热词也可脱敏。这些信息可以先区分批太小、音频编码/长段 final 太慢、引擎排队,以及 batcher 之前的消费积压。
queue_ms_*从进入 batcher 才开始计时,不能代表完整端到端排队。异步引擎可以作为独立改进方向,但不只是替换 API:还需验证指定 vLLM 版本的 prompt-embedding 路径、编码阶段调度、每 session 的结果顺序、过期 partial 丢弃、COMMIT/STOP 边界、断连取消和有界背压。唯一
request_id负责区分请求,并不会自动保证这些 session 语义或恢复吞吐。本次做的是源码核对,未复现所报 66 s 尾延迟,也未运行新 GPU 压测;issue 保持开放继续定位。补充(2026-09-28):#3734 已合入 main,现在这版压测脚本会分别导出
first_update_ms和首次非空白文本的first_text_ms,并提供clients_with_text覆盖数。无文本连接保持null,不会被记成零延迟;请同时保留连接总数和错误数。这是 main 中的脚本更新,不代表现有 pip 安装已包含。新增指标经 13 项本地及 GitHub CPU 测试验证,但没有更改解码器,也不代表本 issue 的高并发延迟已解决。