AWS发布vLLM-Omni DLC,在SageMaker上流式输出TTS语音
AWS机器学习博客发布教程,介绍如何使用vLLM-Omni深度学习容器在SageMaker AI上部署Qwen3-TTS模型,通过双向流式连接在模型还在生成时就开始播放语音。
AI解读:这条新闻面向的是做语音代理、互动教学或客服助手的人:他们最怕的就是说完话后那段漫长的沉默。AWS给出的解法是把文本转语音(TTS)模型部署在SageMaker AI上,并用vLLM-Omni容器让音频在模型还没生成完时就开始往外流。换句话说,不是等整段话合成完毕再播放,而是边说边生成。
关键机制是SageMaker的双向流式传输:客户端通过HTTP/2 WebSocket连到SageMaker Runtime端点,推理边车把连接转给容器里的vLLM-Omni原生WebSocket路由。文字事件进去,24 kHz PCM音频块从同一条连接回来,Gradio客户端收到一块播一块。
但这不是开箱即用的产品。你需要AWS账号、SageMaker执行角色、端点配额,以及至少一种符合条件的GPU实例(ml.g6.xlarge、ml.g6e.xlarge、ml.g5.xlarge或ml.g4dn.xlarge),还要装boto3 1.40.0以上和HTTP/2 Python客户端0.4.0。教程明确说首次部署要等实例下载镜像和模型,而且运行中的GPU端点会持续计费。
对普通读者来说,现在不需要做任何事。对真在做实时语音应用的人来说,这个例子的价值在于给出了输入和输出两条互补路径:上一篇用Voxtral把麦克风音频转成文字,这一篇把应用返回的文字再流式合成语音,中间怎么编排对话逻辑仍然要自己补上。
AWS机器学习博客发布一篇教程,介绍如何在Amazon SageMaker AI上部署文本转语音(TTS)模型Qwen3-TTS,并让语音在模型完成整段生成之前就开始播放。
教程使用AWS vLLM-Omni深度学习容器(DLC),通过一条持久双向连接把文字流进去、把音频流出来,并提供一个Gradio应用供试用。
这是该系列的第一部分,聚焦实时语音应用的流式语音;第二部分将把同一DLC用于图像和视频生成。
vLLM-Omni DLC做了什么
vLLM-Omni项目将vLLM从文本生成扩展到处理或生成文本、音频、图像和视频的模型。AWS的vLLM-Omni DLC把受跟踪的vLLM-Omni发布版打包进AWS镜像,并为SageMaker AI增加路由中间件。
该运行时支持的模型类型包括统一全模态模型、自动语音识别(ASR)、TTS、音频生成、图像生成和视频生成。这篇教程选择Qwen3-TTS作为具体示例,因为流式语音能直接演示双向音频输出。
此前一篇vLLM相关文章覆盖了输入侧:把麦克风音频流式送入Voxtral-Mini-4B Realtime语音转文字模型并返回转写事件。这篇教程补充输出侧:把文字发送给Qwen3-TTS,再通过vLLM-Omni DLC流式返回生成的语音。两端之间的编排逻辑不在本次演练范围内。
- vLLM-Omni扩展了vLLM的模态范围,异构流水线抽象可协调多阶段模型工作流,包括自回归和扩散阶段
- 它提供流式输出和OpenAI兼容API
- vLLM-Omni DLC打包运行时及其框架依赖和部署配置,提供到AWS计算和托管推理服务的一致镜像路径
连接如何建立
完整示例位于仓库的03-features/bidirectional-streaming-vLLM-Omni目录。SageMaker双向流式传输暴露一个通过HTTP/2承载的全双工WebSocket,客户端连接SageMaker Runtime端点的8443端口,SageMaker推理边车把连接转发到容器内的vLLM-Omni原生WebSocket路由。
客户端发送会话配置和文本事件,Qwen3-TTS通过同一条连接返回音频生命周期事件和音频块事件。示例使用v1/audio/speech/stream,这是vLLM-Omni暴露的原生WebSocket路由之一。
Gradio客户端在收到每个24 kHz PCM音频块时立即播放,状态字段报告块数量和音频总字节数。
- vLLM-Omni v1.5 DLC增加了SageMaker AI所需的双向流式传输能力标签和路由中间件
- 客户端先发送session.config,设置voice、language、response_format为pcm、stream_audio为true
- 再发送input.text和input.done
部署条件与实例池
端点配置使用SageMaker实例池。一个实例池为一个生产变体定义按优先级排序的兼容实例类型列表。SageMaker会先尝试ml.g6.xlarge,容量不可用时再回退到ml.g6e.xlarge、ml.g5.xlarge或ml.g4dn.xlarge。
SageMaker仍然只配置一个实例,而不是每个池条目一个实例。但创建端点时会校验每个已配置池条目的配额,因此需要为每个包含的类型都留出可用配额。如果SageMaker选了不同实例类型,每小时成本也可能变化。
教程建议用--instance-types把池限制在满足配额、价格和性能要求的类型上。
- 需要AWS账号并配置好AWS CLI或AWS SDK凭据
- 需要Git、Python 3.12或更新版本
- 需要SageMaker AI执行角色、创建和调用SageMaker AI端点的权限
- 需要至少一种池内实例类型的端点配额
- 要求boto3版本1.40.0或更新,以及SageMaker Runtime HTTP/2 Python客户端0.4.0
- 演练使用美国东部(弗吉尼亚北部)区域
部署步骤与清理
克隆示例仓库后,进入双向流式vLLM-Omni示例目录,创建Python 3.12虚拟环境并按requirements.txt安装依赖。设置SAGEMAKER_EXECUTION_ROLE_ARN环境变量,示例默认使用us-east-1,可用--region切换到其他受支持区域。
运行python deploy_bidi_stream.py并传入端点名称、区域和--keep-endpoint,示例会从DLC创建SageMaker模型、端点配置和实时端点。环境变量SM_VLLM_MODEL告诉容器加载哪个模型,脚本还会运行一次流式冒烟测试并把结果保存为validation-output.wav。
等待端点达到InService,首次部署因为实例要下载DLC镜像和模型文件而耗时较长。之后运行sagemaker_bidi_tts_client.py,在浏览器打开127.0.0.1:6006即可输入文字、选择音色和语言并生成语音。--share选项会创建Gradio公开链接,除非确实需要否则不要启用。
清理时先停止Gradio进程,再用--delete-endpoint运行部署脚本删除端点、端点配置和模型。如果进程在中途停止,可通过SageMaker AI控制台或API删除资源。运行中的GPU端点会持续产生费用。
教程感谢Zhuofu Bai、Ayush Sharma、Christian Kamwangala和Jon Chua对解决方案和发布流程的贡献。