Skip to content

关于实时模式的vllm解码并发问题 #3732

Open

Description

@Ostarsion

【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

  1. added
    questionFurther information is requested
    needs triageNeeds maintainer triage and routing
    on Sep 28, 2026
  2. LauraGPT commented on Sep 28, 2026

    @LauraGPT
    Collaborator

    感谢提供具体的并发拐点,也感谢明确区分测量结果和推测。按当前 main e1ceba0aa8ac4132df9e177c50000361fd2cc038 核对源码后,这个方向值得评估,但需要拆开两层问题:

    1. 同步批处理确实存在批间等待。 RealtimeBatchingEngine 用一个 worker 收集请求,再按解码参数分组,逐组调用同步 generate();Nano 底层也是同步 LLM.generate()。执行中的批次不会通过这个封装接纳新请求,后来的请求只能等下一轮。但下一轮也会收集已排队的请求,因此仅凭 10 ms 窗口,不能断言每次都只能单条解码,需要实际 requests/samples 日志确认。batcher 源码、Nano 调用
    2. 同一连接的消息消费与推理串行。 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 路测试的这些信息:

    • FunASR commit/安装版本、模型版本、vLLM/PyTorch 版本、GPU 型号,以及完整服务端和客户端命令。
    • 首字延迟的统计定义,是否使用本仓压测客户端;音频时长/停顿分布、是否同一文件同步回放、是否开启说话人识别。
    • 在原配置增加 --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 的高并发延迟已解决。

  3. added
    benchmarkPerformance, accuracy, migration, or benchmark report
    needs feedbackWaiting for reporter feedback or retest results
    and removed
    needs triageNeeds maintainer triage and routing
    on Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    benchmarkPerformance, accuracy, migration, or benchmark reportneeds feedbackWaiting for reporter feedback or retest resultsquestionFurther information is requested

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions