ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

vllm-omni 中 Higgs-Audio v2 在线 TTS 服务实战:两阶段流水线、部署配置与声音克隆

vllm-omni 中 Higgs-Audio v2 在线 TTS 服务实战:两阶段流水线、部署配置与声音克隆 vllm-omni 中 Higgs-Audio v2 在线 TTS 服务实战两阶段流水线、部署配置与声音克隆【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni本指南围绕 vllm-omni 仓库中 higgs_audio_v2 在线服务示例 展开介绍 boson-ai Higgs-Audio v2 在 vllm-omni 中以「两阶段 TTS 流水线」形态落地的完整方案Llama-3.2-3B 规模的 Talker 语言模型带 DualFFN 音频专家生成 8 码书音频 codec再由 HiggsAudio codec 解码器Code2Wav还原为 24 kHz 单声道语音。读完本文你将掌握如何在本地 GPU 上启动该在线服务、通过/v1/audio/speech接口完成普通文本合成与浅层声音克隆shallow voice clone并理解async_chunk与codec_streaming背后的跨阶段流式实现原理。一、Higgs-Audio v2 的两阶段 TTS 架构Higgs-Audio v2 在 vllm-omni 中被组织为一条两阶段流水线其定义位于 pipeline.pyStage 0Talker模型架构HiggsAudioV2ForConditionalGeneration一个基于 Llama-3.2-3B 的自回归语言模型通过 DualFFN 音频专家将文本 token 逐步采样为8 码书num_codebooks8的音频 codec 序列。执行类型为LLM_AR引擎输出类型为latent即它只产出离散音频码不直接产出波形。Stage 1Code2Wav模型架构HiggsAudioV2Code2WavForConditionalGenerationHiggsAudio 码本解码器RVQ DAC 权重把 Stage 0 输出的 codec 码逐帧还原为24 kHz 单声道 PCM。执行类型为LLM_GENERATION最终输出类型为audio。Stage 0 有两个停止信号128009标准 LM 的eos_token_id序列级停止与128012audio_eos_token_id由 Talker 在音频 ramp 完成时强制施加行为对齐上游HiggsAudioModel._sample_audio_tokens的重写逻辑。Stage 1 则配置为detokenize: True将 codec 直接映射为波形输出。两阶段之间通过共享内存连接器SharedMemoryConnector传递数据stage 配置见仓库自带的部署文件 higgs_audio_v2.yaml。Stage 0 输出的每个 codec 帧对应hop_length960个 24 kHz 采样即25 fps × 960 24000见 higgs_audio_v2_code2wav.py 中的注释因此约 1 秒语音对应 25 个 codec 帧。二、前置条件与模型资源准备2.1 依赖版本示例要求较新的 transformers 版本以提供HiggsAudioV2TokenizerModel类pip install -U transformers5.3.0该依赖只在声音克隆路径需要在线编码参考音频时是强制的纯文本路径在 prompt 构造上不依赖此新类。客户端脚本还需要httpxpip install httpx。2.2 声音克隆所需的 codec 权重来源文档明确指出一个容易踩坑的细节声音克隆使用的编码器来自 HF 的HiggsAudioV2TokenizerModel权重从k2-fsa/OmniVoice/audio_tokenizer/子目录加载而不是 boson-ai 的独立 tokenizer 仓库。原因在 higgs_audio_v2_tokenizer.py 的_load_audio_tokenizer注释中有详细说明bosonai/higgs-audio-v2-tokenizer独立仓库里的model.safetensors实际是 3B Talker LM 的副本而非 codec若直接用它做from_pretrained得到的编码器/解码器是随机初始化的结构权重编码时会产出噪声码。k2-fsa OmniVoice 仓库则把同一套 codec 权重重新打包在audio_tokenizer/{config.json, model.safetensors, preprocessor_config.json}下键名与HiggsAudioV2TokenizerModel的类结构acoustic_encoder.*/acoustic_decoder.*/quantizer.quantizers.*/fc/fc2/semantic_model.*对齐HF 可直接加载。整个加载过程只会下载约 806 MB 的audio_tokenizer/子目录。同时源码支持通过环境变量HIGGS_AUDIO_TOKENIZER_PATH或HIGGS_AUDIO_V2_TOKENIZER_PATH指定本地 codec 目录在离线生产环境如 H20 任务下优先解析本地目录与已填充的 HF 缓存最后才回退到snapshot_download从而避免在线访问 HF。三、启动在线服务3.1 一键启动脚本使用示例目录下的run_server.sh即可拉起服务GPUS6,7 PORT8094 bash examples/online_serving/text_to_speech/higgs_audio_v2/run_server.sh脚本本质是执行vllm-omni serve并以--deploy-config vllm_omni/deploy/higgs_audio_v2.yaml指定两阶段部署配置同时开启--omni多模态一体化入口与--trust-remote-code。完整启动命令见 run_server.sh。3.2 环境变量覆盖项变量含义默认值MODELTalker 的 HF 模型 idbosonai/higgs-audio-v2-generation-3B-basePORT服务监听端口8094GPUSCUDA_VISIBLE_DEVICES的取值6,7GPU_UTIL--gpu-memory-utilization0.4脚本还会导出VLLM_USE_DEEP_GEMM0与VLLM_MOE_USE_DEEP_GEMM0以屏蔽可选的 DeepGEMM FP8 内核在未安装deep_gemm后端的镜像上该内核会在 warmup 阶段报错。如果你的环境已安装deep_gemm可以通过同样的两个环境变量手动重新开启。四、部署配置逐项解读higgs_audio_v2.yaml 是整条流水线的核心配置值得逐项理解4.1 顶层与连接器async_chunk: false connectors: connector_of_shared_memory: name: SharedMemoryConnector extra: codec_streaming: true connector_get_sleep_s: 0.01 connector_get_max_wait_first_chunk: 5000 connector_get_max_wait: 500 codec_chunk_frames: 25 codec_left_context_frames: 25 initial_codec_chunk_frames: 1async_chunk: false表示 Stage 0先把全部 codec 帧生成完毕再一次性交给 Stage 1 解码codec_streaming: true表示 Stage 1 解码出的 WAV/PCM 字节会按块流式推送给客户端codec_chunk_frames: 25与codec_left_context_frames: 25是 codec 分块与左上下文重叠的尺寸25 帧正好对应 1 秒语音25 fpsStage 1 每解码一段就会带上上一段的左上下文进行重叠拼接避免块边界出现音频断裂。流式传输链路由三部分共同完成stage-input processor 的 async-chunk 回调、共享内存连接器的codec_streaming标志以及serving_speech.py中约定的 WAV/PCM 流式输出。若要做严格非流式的冒烟测试把codec_streaming改为false即可。4.2 Stage 0Talker参数stages: - stage_id: 0 max_num_seqs: 4 gpu_memory_utilization: 0.6 enforce_eager: true trust_remote_code: true enable_prefix_caching: false async_scheduling: false max_num_batched_tokens: 2048 max_model_len: 4096 devices: 0 output_connectors: to_stage_1: connector_of_shared_memory default_sampling_params: temperature: 1.0 top_p: 0.95 top_k: 50 max_tokens: 1024 seed: 42 repetition_penalty: 1.0enforce_eager: true关闭 CUDA Graph 捕获——实时音频采样器的调度仍在迭代中且该镜像上 flash-attn-hopper 的 graph 路径在捕获期间触发过 CUDA driver/runtime 不匹配。max_model_len: 4096需覆盖 prompt max_new_tokens约 1500 个 codec 帧可舒适放入。采样参数特意采用非贪心策略temperature: 1.0, top_p: 0.95, top_k: 50对齐上游serve_engine默认值。若贪心解码temperature0音频码本 argmax 会在几步之后坍缩为固定值语音将失去自然度。max_tokens: 1024把 Stage 0 的音频帧数上限设为 1024约 40 秒按 25 fps 计。实际生成通常会被音频 EOS128012Talker 在 ramp 完成时强制施加提前截断该值只是兜底上限。4.3 Stage 1Code2Wav参数- stage_id: 1 max_num_seqs: 4 gpu_memory_utilization: 0.25 enforce_eager: true trust_remote_code: true enable_prefix_caching: false async_scheduling: false max_num_batched_tokens: 65536 max_model_len: 65536 devices: 0 input_connectors: from_stage_0: connector_of_shared_memory default_sampling_params: temperature: 0.0 top_p: 1.0 top_k: -1 max_tokens: 65536 seed: 42 repetition_penalty: 1.0Stage 1 的 prefill 长度为num_codebooks × num_frames8 × 8192 65536已覆盖 Stage 0 单请求 250 帧上限实际为 1024 帧兜底下的合理余量加上多请求 batch 的 headroom。Stage 1 是确定性解码temperature: 0.0, top_p: 1.0, top_k: -1因为 codec 码到波形的映射无需随机性。4.4 阶段输入处理器同步与流式两条路径Stage 0 到 Stage 1 的数据转换由 stage_input_processors/higgs_audio_v2.py 承担talker2code2wav同步Stage 0 全部结束后一次性收集所有音频帧经过「反转 delay pattern_revert_delay_pattern对应上游boson_multimodal的revert_delay_pattern→ 裁剪到真实码范围[0, 1023]→ 去掉首尾 BOS/EOS 边缘帧」的处理再以码书优先的扁平布局[Q × num_frames]交给 Stage 1。talker2code2wav_async_chunk流式每个产出的 codec 帧触发一次在请求级缓冲区累积帧凑满一个 chunk默认 25 帧就冲刷一个OmniPayloadStruct并携带MetaStruct(left_context_size, finished)让 Stage 1 按左上下文重叠拼接。Stage 1 严格拒绝任何 1024的码audio_stream_bos_id因此处理器会过滤掉仍带有 stream 特殊标记的帧保证 codec 只看到真实码。五、驱动服务普通文本合成使用示例自带的批量客户端 batch_speech_client.pypython examples/online_serving/text_to_speech/higgs_audio_v2/batch_speech_client.py \ --base-url http://localhost:8094 \ --model bosonai/higgs-audio-v2-generation-3B-base \ --output-dir /tmp/higgs_audio_v2_batch \ --prompts Hello world. \ The quick brown fox jumps over the lazy dog.客户端会逐个 prompt 向POST /v1/audio/speech发送请求并把返回的 WAV或--format pcm时的裸 PCM字节写入--output-dir文件名由 prompt 内容 slug 化生成。完整参数如下参数默认值说明--base-urlhttp://localhost:8094服务地址--modelhiggs_audio_v2请求体中的模型 id--prompts4 条内置示例句可传多个文本--output-dir/tmp/higgs_audio_v2_batch结果保存目录--formatwavwav或pcm--max-new-tokens300生成上限--seed42随机种子--timeout-s120.0HTTP 超时--ref-audio无声音克隆参考音频WAV 路径--ref-text无参考音频的逐字转写每个请求的 JSON 载荷包含model、input、response_format、max_new_tokens、seed声音克隆时额外附加ref_audiobase64 data URL与ref_text。--ref-audio与--ref-text必须成对提供否则客户端以退出码 2 报错。六、声音克隆浅层克隆6.1 使用方式python examples/online_serving/text_to_speech/higgs_audio_v2/batch_speech_client.py \ --base-url http://localhost:8094 \ --model bosonai/higgs-audio-v2-generation-3B-base \ --output-dir /tmp/higgs_audio_v2_clone \ --ref-audio /path/to/reference.wav \ --ref-text Exact transcript spoken in reference.wav. \ --prompts Hello, this is a cloned voice.6.2 底层实现链路声音克隆的 prompt 构建走 higgs_audio_v2_tokenizer.py 的build_voice_clone_prompt编码参考音频通过 HFHiggsAudioV2TokenizerModel权重来自 k2-fsa/OmniVoice 的audio_tokenizer/子目录按需重采样到 24 kHz把--ref-audio编码为[num_codebooks, T_raw]的 codec 码delay pattern 包装_build_delay_pattern仿照上游HiggsAudioV2Processor.build_delay_pattern在码序列前补 BOS、后补 EOS并按三角形延迟布局拉伸序列使第 k 个码书从第 k 帧才开始输出真实码模板渲染与占位符展开构造 ChatML 会话system 提示 参考转写 user 轮 无真实音频内容的 assistant 音频占位轮 目标文本 user 轮把单个|AUDIO_OUT|标记展开为与参考片段帧数匹配的N × audio_token (Q-1) × delay_token占位块tokenize 与张量附加生成的prompt_token_ids与编码码张量audio_input_ids[T_frames, num_codebooks]及audio_input_ids_mask全 True 布尔掩码一同返回。服务端适配器 tts_adapters/higgs_audio_v2.py 会把这几个张量放在additional_information的顶层不是列表包裹——只有顶层裸torch.Tensor才会被data_entry_keys.serialize_payload的_serialize_tensor正确序列化若放进 list 字段msgspec 无法序列化张量会在进程边界被静默丢弃导致克隆无声失败。Talker 随后在 prompt 侧的音频占位符处替换这些码对应HiggsAudioV2TalkerForConditionalGeneration._maybe_apply_ref_audio_substitution。注意--ref-text必须是--ref-audio的真实逐字转写转写不匹配会明显降低克隆音质。七、请求校验边界v1 范围当前 v1 示例只开放「纯文本 → 24 kHz 语音」与「浅层声音克隆」两条路径。以下请求会被请求校验器以明确的 4xx 拒绝见 serving_speech.py 与 higgs_audio_v2.py 的validate方法input中包含多说话人[SPEAKERn]标签profile:纯文本说话人描述ref_audio_in_system_message系统块变体分块长文本生成chunked long-form按请求指定voice内置预设声音/instructions风格情感控制/task_type/language模型从输入文本自行推断语言/speed ! 1.0音频以 24 kHz 原生速率渲染/x_vector_only_mode/speaker_embedding。其中voice若已通过POST /v1/audio/voices上传过说话人带ref_audio/ref_text则可在请求中直接以voicename引用已上传声音见serving_speech.py的_apply_uploaded_speaker与_resolve_ref_audio缓存逻辑。多说话人标签的拦截同时发生在 tokenizer 边界validate_plain_text_input保证离线pipeline与在线serving两条代码路径行为一致。八、流式输出与 WAV/PCM 约定服务端对response_formatwav的流式响应使用占位长度0xFFFFFFFF的 WAV 头_create_wav_header24 kHz 单声道 16-bit对齐 OpenAI 的流式 WAV 实现先发头再流式发 PCM 块客户端按块写入即可得到完整 WAVresponse_formatpcm则直接输出裸 PCM 字节。服务端还通过observe_audio_first_packet/observe_audio_streaming_finalize上报首个音频包延迟与流式完成等指标便于观测首包时延。九、测试与验证仓库为 higgs-audio v2 提供了端到端与单元级验证tests/e2e/online_serving/test_higgs_audio_v2_expansion.py覆盖纯文本 WAV、纯文本 PCM 流式、max_new_tokens限制、并发请求、基本声音克隆与克隆 PCM 流式等场景并对流式输出做字节量阈值断言如约 0.5 秒 24 kHz 单声道 PCM_16 ≈ 24 KiBtests/e2e/offline_inference/test_higgs_audio_v2_expansion.py覆盖离线推理路径含 prompt 占位符展开模型层HiggsAudioV2Code2Wav等同时暴露直接解码 APIdecode_codes/forward_chunk/forward供单元测试调用与 vLLM stage runtime APIembed_input_ids/compute_logitsNone 运行时forward共享同一套 RVQ DAC 权重。十、注意事项小结codec 权重来源克隆必须依赖 k2-fsa/OmniVoice 的audio_tokenizer/子目录约 806 MB切勿直接使用 boson-ai 独立 tokenizer 仓库的model.safetensors那是 Talker LM 副本克隆转写要真实--ref-text与--ref-audio内容必须严格一致且两者必须成对出现采样需多样性Stage 0 保持temperature1.0 / top_p0.95 / top_k50贪心解码会破坏语音自然度流式语义默认async_chunk: false codec_streaming: true即「Stage 0 整段生成、Stage 1 边解码边推流」想验证非流式可改codec_streaming: falseDeepGEMM 开关脚本默认关闭 FP8 内核以兼容无deep_gemm后端的镜像可自行重开张量序列化坑声音克隆的audio_input_ids必须放在additional_information顶层避免被 msgspec 丢弃。【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表