vLLM-Omni TTS 推理工程

vLLM-Omni TTS 推理工程

TL;DR

vLLM-Omni 透過解決 Talker 和 Code2Wav 階段中的特定瓶頸,為多個模型優化了 TTS 推理,在高併發情況下為 Qwen3-TTS 實現了高達 172% 的音訊吞吐量提升,並將端到端延遲降低了近一半。

TTS 推理與傳統 LLM 推理有何不同

TTS 推理使用自回歸模型,但由於其多階段流水線(Talker 和 Code2Wav)以及對串流音訊輸出嚴格的延遲預算,面臨著與純文本 LLM 不同的服務瓶頸;其中,分塊大小(chunk size)會同時影響首包延遲(first-packet latency)和跨分塊的音訊品質。

優化概述

vLLM-Omni 根據每個 TTS 模型的流水線結構、解碼狀態、批次形狀(batch shapes)和數值約束來選擇優化方案,而非採用固定配方,因為像階段分離、批次預處理、torch.compile 和 GPU 駐留狀態(GPU-resident state)等技術僅對特定架構有效。

Qwen3-TTS:完整的優化路徑

對於 Qwen3-TTS,將連接器分塊(connector chunks)與 Code2Wav 解碼窗口解耦、對 Stage 0 預處理進行批次處理、清理熱路徑(hot-path)開銷,並將數值精度對齊至 fp32,這在 H20 × 2 且 c=64 的情況下,將音訊吞吐量提升了 61.5%,並將 P99 端到端延遲降低了近一半。

1. 串流:將連接器分塊與 Code2Wav 解碼窗口解耦

將連接器串流分塊大小 (codec_chunk_frames) 與 Code2Wav 的內部解碼窗口 (decode_chunk_framesdecode_left_context_frames) 解耦,可以實現獨立調優:較小的連接器分塊可降低首包延遲,而 Code2Wav 則維持 300 幀的解碼窗口加上 25 幀的左上下文,以確保跨分塊的音訊連續性。

2. 吞吐量:Stage 0 解碼預處理

對 Talker 解碼預處理(說話者嵌入準備、trailing_text 維護、輸入嵌入構建)進行批次處理,消除了解碼熱路徑中的每個請求的 Python 開銷,減少了高併發下由小張量分配和內核啟動(kernel launches)引起的 GPU 空閒時間。

3. 熱路徑清理

將 O(N²) 的 req_id_to_index 查詢替換為字典、提前跳過非串流路徑、預計算 codec 不允許的遮罩(masks),並針對 Code2Wav 調優 CUDA Graph 捕獲,在不改變模型計算的情況下,減少了頻繁的 c=64 解碼循環中的 Python 開銷。

4. 數值精度:Code Predictor 的 fp32 對齊

透過 PyTorch 原生實現將 Talker code predictor 拆分,使 RMSNorm 方差、RoPE cos/sin、attention 和 QKV 投影保持在 fp32,防止了在短序列、高頻自回歸步驟中因 bfloat16 融合內核(fused kernels)導致的精度漂移。

5. 驗證

堆疊優化後,Qwen3-TTS 在 H20 × 2 上的音訊吞吐量從 26.55 增加到 42.88 audio-s/s (+61.5%),在 c=64 進行語音克隆時,P99 端到端延遲從 17.7s 降至 9.0s;隨著併發增加,由於固定成本的攤銷,端到端延遲呈現非線性增長。

VoxCPM2:單階段混合 TTS

對於 VoxCPM2,全前向 torch.compile 減少了 MiniCPM4 Talker 中的 Python-to-compiled 邊界,而在 c=64 情況下,跨請求對 CFM/LocDiT 解碼尾部進行批次處理,使 H20 × 1 上的音訊吞吐量提升了 172.0%。

探索 torch.compile

fullgraph=False 的情況下將整個 Model.forward 包裝在 torch.compile 中,讓 Dynamo 能夠優化 28 層的 MiniCPM4 循環(儘管存在 PagedAttention 中斷),將 cudaLaunchKernel 數量減少了約 71%,內核時間減少了約 27%;而僅對單層進行編譯則因無法解決邊界問題而未能降低啟動次數。

CFM/LocDiT 解碼尾部批次處理

在將結果散射回之前,對 CFM/LocDiT、feat_encoderstop_headlm_h、殘差輸出和前綴特徵條件進行跨請求批次處理,結合滑動窗口 VAE 解碼和融合操作,將微小的單請求擴散工作量轉化為高效的 GPU 批次,在 c=64 時將 H20 × 1 的吞吐量從 4.19 req/s 提升至 10.83 req/s (+158.8%),音訊吞吐量從 12.16 提升至 33.07 audio-s/s (+172.0%)。

Higgs Audio V3:動態批次與多 Codebook 狀態

對於 Higgs Audio V3,將多 codebook 解碼狀態移至 GPU 駐留的批次張量,並使用本地 MLP CUDA Graph(而非 PIECEWISE),避免了 Python 開銷和同步,在 c=16 時於單個 H20 上實現了 35.26 audio-s/s 的吞吐量。

將解碼狀態移至 GPU

將每個請求的 Python 字典狀態(_decode_last_codes_decode_has_codes、延遲計數、EOC 計數等)轉換為 GPU 駐留的批次張量,消除了解碼熱路徑中的 Python 循環和 D2H 同步,狀態更新現在發生在批次 GPU 軌跡上。

使 CUDA Graph 適應動態批次形狀

使用統一的單 token 解碼批次進行 CUDA Graph 捕獲(其中 decode_mask 全為 True),避免了音訊回饋機制布林遮罩導致的形狀不匹配,確保了在調度器進行動態批次處理時具有穩定的圖形形狀。

本地 MLP CUDA Graph vs. PIECEWISE

涵蓋 post_attention_layernorm + mlp 的本地 MLP CUDA Graph 在 Higgs v3 上的表現優於 PIECEWISE 圖,因為該模型的多 codebook 延遲模式會導致數據依賴的嵌入查找和 pre-attention 索引操作,這會破壞較大的圖或需要昂貴的同步。

一個被拒絕的階段重疊設計

為了隱藏 D2H 複製而設計的單步音訊階段重疊設計被拒絕了,因為在動態批次下結構上不安全,因為調度器引起的請求重排序或完成可能會破壞游標與請求的映射,若沒有請求 ID 鍵值和 drain hooks,該方法是不可靠的。

Fish Speech S2 Pro:當通用 Attention 成為瓶頸

對於 Fish Speech S2 Pro,針對特定模型的 q_len=1 attention kernel 和 Fast AR 緩衝區重用解決了來自通用 Attention 開銷和重複分配的 GPU 端瓶頸,在 H20 上於 c=64 時實現了 23.72 audio-s/s 的吞吐量。

特定模型 Attention Kernel

一個針對 SlowAR 解碼 Attention 的 Fish 特定 Triton kernel(處理 q_len=1, fp16/bf16, head_dim=128, block size 16, GQA layout)取代了純解碼步驟中的通用 paged/varlen attention,並針對長序列採用 split-partial-combine 策略,並在 CPU 端設置上限以避免路徑選擇期間的同步。

Fast AR 緩衝區重用與編譯

為 Fast AR 預分配並重用 _embed_buf_k_cache_v_cache 張量,消除了短序列解碼步驟中的重複分配,而 torch.compile(使用 fullgraph=Falsedynamic=True)則為四層 Transformer 緩存了子圖,儘管存在 SDPA 內部中斷。

DAC 與運行時優化

將 codec 負載傳輸從 Python list[int] 切換到張量序列化,啟用 fp16 DAC 支援,實現了幀數批次 DAC 批次處理,並透過非同步分塊處理將連接器傳輸與 DAC 計算重疊,在高併發下減少了分配、GC 壓力和阻塞。

性能數據

優化在各個模型中都帶來了可衡量的增益,這已在 vLLM-Omni cookbook 基準測試中得到驗證。

Qwen3-TTS (c=64, p=512, H20 × 2, 語音克隆)

指標 優化前 優化後 變化
音訊吞吐量 26.55 audio-s/s 42.88 audio-s/s +61.5%
中位數 E2EL 9654ms 5699ms −41.0%
P99 E2EL 17686ms 8956ms −49.4%
P99 TTFP 7558ms 5563ms −26.4%

VoxCPM2 (c=64, H20 × 1, CFM 批次處理前後)

指標 優化前 優化後 變化
請求吞吐量 4.19 req/s 10.83 req/s +158.8%
音訊吞吐量 12.16 audio-s/s 33.07 audio-s/s +172.0%

Fish Speech S2 Pro (H20, 單 GPU, c=64, Triton KV cache + 張量負載)

指標 數值
音訊吞吐量 23.72 audio-s/s
請求吞吐量 5.95 req/s
平均 TTFP 899.67 ms
平均 E2EL 10.47 s

Higgs Audio V3 (H20, 單 GPU, c=16, eager + 本地 MLP 圖)

指標 數值
請求吞吐量 5.18 req/s
音訊吞吐量 35.26 audio-s/s
Wall time 96.5s
相對於基準的加速比 2.70×

Sources