Prhub

#22089 [Feature] Add chunk-based streaming ASR for Qwen3-ASR

sgl-project/sglang · 作者 SammLSH · 合并时间 2026-04-10 01:49

分析状态 已生成
文件变更 5提交数 5 · 评论 46
代码增减 +263 / -2
feature multimodal documentation run-ci

执行摘要

为 Qwen3-ASR 模型添加基于块的流式语音识别,通过 SSE 实时输出部分转录。

PR动机源于Issue #22025,旨在减少完整音频处理前的等待时间,实现实时转录。PR body指出:'reducing time-to-first-text compared to waiting for the full audio to be processed',并参考Qwen3-ASR论文的流式算法。

建议技术管理者和工程师精读此PR,关注 StreamingASRState 的设计和适配器扩展模式,这些决策为流式处理提供了可扩展框架。同时,注意跨块状态不共享的架构选择,这限制了性能优化但保持了最小变更原则。

讨论亮点

Review中JustinTong0323指出了多个问题:Critical级别的StopAsyncIteration逃逸、提示模板重复和输入验证缺失,SammLSH均修复;Important级别如前缀文本源错误(使用full_transcript而非confirmed_text)、CJK语言回退无效(str.split()对中文无效)、语言默认值None等,部分修复,CJK问题记录为已知限制;设计讨论包括API参数暴露(用户能否覆盖配置)和代码重构(硬编码if语句),SammLSH计划作为后续改进。最终所有Critical和Important问题解决,PR获批准。

实现拆解

实现分为四个关键部分:1) 新增 streaming_asr.py 包含 StreamingASRState 类和 split_audio_chunks 函数,管理流式状态和音频分块;2) 修改 serving_transcription.py 添加 _generate_chunked_asr_stream 方法,集成流式处理逻辑并检测客户端断开;3) 扩展转录适配器接口,在 base.py 中添加流式支持属性,在 qwen3_asr.py 中为Qwen3-ASR配置具体参数;4) 调整 multimodal/processors/qwen3_asr.py 中的提示模板常量,确保一致性。

文件 模块 状态 重要度
python/sglang/srt/entrypoints/openai/streaming_asr.py entrypoints/openai added 8.0
python/sglang/srt/entrypoints/openai/serving_transcription.py entrypoints/openai modified 7.0
python/sglang/srt/entrypoints/openai/transcription_adapters/qwen3_asr.py entrypoints/openai/transcription_adapters modified 6.0
python/sglang/srt/multimodal/processors/qwen3_asr.py multimodal/processors modified 5.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

StreamingASRState split_audio_chunks _generate_chunked_asr_stream supports_chunked_streaming chunked_streaming_config

评论区精华

StopAsyncIteration 异常处理 正确性

JustinTong0323 指出 __anext__() 可能导致 StopAsyncIteration 逃逸 except Exception 块

结论:SammLSH 修复为使用 async for...break 模式 · 已解决

提示模板重复 设计

提示模板在多个文件重复定义,有分歧风险

结论:SammLSH 提取常量并导入,确保单一来源 · 已解决

CJK 回退无效 正确性

str.split() 对中文无效,rollback 机制失效

结论:记录为已知限制,计划后续实现 token 级回退 · unresolved

API 参数暴露 设计

是否允许用户覆盖 chunk_size_sec 等配置

结论:暂不暴露,计划作为后续 PR · pending

空格缺失问题 正确性

流式输出中空格在块边界丢失

结论:SammLSH 修复,通过跟踪 first_word 标志 · 已解决

风险与影响

技术风险包括:1) 回归风险:修改了serving层逻辑,可能影响其他转录模型如Whisper,但通过适配器模式隔离;2) 性能风险:每个块重复编码累积音频,导致3倍计算开销,长音频可能成为瓶颈;3) 兼容性:仅针对Qwen3-ASR设计,其他ASR模型需适配;4) 正确性:CJK回退机制无效,影响中文转录质量;5) 安全:输入验证在修复后加强,但仍有异常处理broad catch的问题残留。

影响范围:1) 用户:提供实时转录体验,支持流式输出,改善交互性;2) 系统:新增流式处理能力,但增加计算负载和内存使用;3) 团队:引入流式ASR框架,为未来模型扩展提供基础,但需跟进后续改进如WebSocket支持和优化。

编码重复开销 跨块状态不共享 CJK 回退无效 缺少用户参数暴露

关联 Issue

#22073 [Feature] Adding Qwen3-asr Model Support
#35767 [Enhancement]: Qwen3-ASR realtime endpoint produces degraded output — stateless segments, no cross-segment context, raw format leaks
#35908 [RFC]: Model-specific realtime streaming abstraction

完整报告

执行摘要

本PR为SGLang的Qwen3-ASR模型添加了服务器端块流式转录功能,通过将音频分割为2秒块并应用前缀回退算法,实现了实时部分转录输出。该变更显著降低了首次文本延迟,但以编码重复计算为代价,为多模态流式处理奠定了基础。

功能与动机

基于Issue #22025的流式输入需求,旨在减少用户等待完整音频处理的时间。PR body引用Qwen3-ASR论文算法,目标是通过SSE提供逐词输出,提升实时交互体验。

实现拆解

  • 流式状态管理:新增 python/sglang/srt/entrypoints/openai/streaming_asr.py,定义 StreamingASRState 类管理前缀回退状态,参数如 chunk_size_sec=2.0
  • 音频分块split_audio_chunks 函数将音频分割为累积块,每块包含从起始到当前位置的音频。
  • 请求处理:在 python/sglang/srt/entrypoints/openai/serving_transcription.py 中,_generate_chunked_asr_stream 方法处理流式请求,每个块作为独立SGLang请求发送,检测客户端断开。
  • 适配器扩展:适配器接口新增流式支持属性,Qwen3-ASR适配器实现具体配置,提示模板从处理器导入确保一致性。

评论区精华

  • 关键修复:JustinTong0323指出 StopAsyncIteration 逃逸问题,SammLSH改用 async for...break 解决。
  • 设计权衡:针对提示模板重复,讨论后决定从处理器导入,平衡依赖关系。
  • 已知限制:CJK语言回退无效,因 str.split() 不适用于无空格文本,记录为TODO。
  • 未来方向:API参数暴露和代码重构被标记为后续任务,保持PR最小化。

风险与影响

  • 性能风险:编码重复导致线性增长开销,长音频处理效率低。
  • 正确性风险:CJK回退机制失效,可能影响转录质量。
  • 兼容性:仅支持Qwen3-ASR,需适配器扩展以支持其他模型。
  • 影响:为用户提供实时转录,但增加系统负载;为团队引入流式框架,促进后续优化。

关联脉络

本PR直接依赖PR #22073,后者添加了Qwen3-ASR模型支持。关联Issue #22025驱动流式设计,同时参考vLLM的流式实现讨论(Issue #35767和#35908),显示跨项目的最佳实践对齐。

参与讨论