资讯动态

使用 vLLM-Omni 离线运行 MiMo-Audio:TTS、语音理解与多轮对话的端到端推理实战

发布时间:2026/9/17 23:33:10 来源:尧图企业网站定制
使用 vLLM-Omni 离线运行 MiMo-AudioTTS、语音理解与多轮对话的端到端推理实战【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni本文基于 vLLM-Omni 仓库中的离线推理示例examples/offline_inference/mimo_audio/README.md展开系统讲解如何在本机用一条命令完成 MiMo-Audio 模型的文本转语音TTS、语音克隆、语音转文本ASR、音频理解与多轮口语对话等十类任务。读完本文你将掌握示例脚本end2end.py的完整用法、每个任务的输入构造方式以及底层两阶段thinkertalker → code2wav流水线的配置原理与常见坑位排查方法。一、示例背景MiMo-Audio 是什么MiMo-Audio 是小米 MiMo 系列的开源全模态音频模型仓库内对应模型名为XiaomiMiMo/MiMo-Audio-7B-Instruct。它用一个统一的模型同时支持音频理解与音频生成既能听懂语音内容并回答问题也能根据文本、风格指令甚至参考音频生成语音。在 vLLM-Omni 中它通过离线脚本在本地完成推理最终产出WAV 音频文件或文本输出。1.1 任务变体总览示例脚本支持十种任务变体--query-type的合法取值覆盖了音频理解和生成的主要场景query-type任务说明tts_sft基础文本转语音text-to-speechtts_sft_with_instruct带显式嗓音风格指令的 TTStts_sft_with_audio带音频参考的 TTS语音克隆tts_sft_with_natural_instruction文本中内嵌自然语言嗓音描述的 TTSaudio_trancribing_sft音频转文本语音识别注意上游任务名拼写为trancribing不要修正audio_understanding_sft结合文本查询理解并分析音频内容audio_understanding_sft_with_thinking带推理链reasoning chain的音频理解spoken_dialogue_sft_multiturn音频输入/输出的多轮口语对话speech2text_dialogue_sft_multiturn语音转文本的多轮对话text_dialogue_sft_multiturn纯文本多轮对话这些取值在 end2end.py 的query_map字典中注册每个取值映射到对应的 prompt 构造函数--query-type参数通过choicesquery_map.keys()校验传错会直接报参数错误。1.2 两阶段推理流水线MiMo-Audio 不是单个自回归模型而是两阶段结构这在 vllm_omni/model_executor/models/mimo_audio/pipeline.py 中定义得十分清晰Stage 0fused_thinker_talker融合的 thinker talker 模型负责多模态理解、文本生成并输出 RVQ 语音码codesfinal_output_type为textStage 1code2wav把 Stage 0 产出的语音码解码为波形final_output_type为audio。因此运行脚本后每个请求可能同时得到两类产物.txt解码文本和.wav生成的音频。默认部署模式下两阶段通过SharedMemoryConnector在同一张 GPU 上以异步分块async-chunk方式流转见 vllm_omni/deploy/mimo_audio.yaml 顶部注释。二、环境准备与依赖2.1 显存分配与部署配置MiMo-Audio 需要为两阶段流水线分配显存具体分配方案取决于你的硬件。仓库提供了两份可直接参考的部署配置vllm_omni/deploy/mimo_audio.yaml通用单卡配置Stage 0 显存利用率0.5、Stage 1 为0.3max_model_len均为 8192vllm_omni/deploy/mimo_audio_5090d.yaml针对 32GB 消费级 BlackwellRTX 5090 / 5090D调优的配置Stage 0 显存利用率0.78、Stage 1 为0.12并使用TRITON_ATTN规避 Blackwell 上 FlashAttention-2 的 PTX/工具链问题。内存分配相关的通用说明可参考仓库文档 docs/configuration/stage_configs.md。end2end.py的--deploy-config参数可以覆盖部署配置路径不传时脚本会根据 HFmodel_type自动加载vllm_omni/deploy/mimo_audio.yaml见 end2end.py。2.2 环境变量MIMO_AUDIO_TOKENIZER_PATH必填由于 MiMo-Audio 使用了专门的音频 tokenizer 架构MIMO_AUDIO_TOKENIZER_PATH环境变量是强制要求的export MIMO_AUDIO_TOKENIZER_PATHXiaomiMiMo/MiMo-Audio-Tokenizer在 32GB 消费级显卡上仓库食谱 recipes/XiaomiMiMo/MiMo-Audio.md 还建议追加以下环境变量以降低显存压力并规避采样器问题export MIMO_AUDIO_TOKENIZER_PATH${MIMO_AUDIO_TOKENIZER_PATH:-XiaomiMiMo/MiMo-Audio-Tokenizer} export MIMO_AUDIO_TOKENIZER_DEVICEcpu export MIMO_AUDIO_TOKENIZER_CUDA_GRAPH0 export VLLM_USE_FLASHINFER_SAMPLER0 export PYTORCH_CUDA_ALLOC_CONFexpandable_segments:True其中MIMO_AUDIO_TOKENIZER_DEVICEcpu将音频 tokenizer 放到 CPU 上以节省 Stage 1 的显存。2.3 FlashAttention音频生成任务的必装项对于音频生成类任务如各 TTS 变体、带音频输出的多轮口语对话需要安装与你的CUDA 和 PyTorch 版本匹配的flash-attn包。在 GPU 上缺少flash-attn会导致生成的音频变成纯噪声或不可用。请参考 FlashAttention 项目主页获取安装选项与预编译 wheel。顺带一提在 Blackwell 消费卡上即使安装了 flash-attnrecipes/XiaomiMiMo/MiMo-Audio.md 也提示未安装可用 flash-attn 构建时音频质量可能略微金属感该平台更推荐在部署配置中设置attention_backend: TRITON_ATTN。三、快速开始3.1 单个样本基础 TTSpython3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type tts_sft3.2 批量样本基础 TTSpython3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type tts_sft \ --num-prompts {batch_size}3.3 批量的重要约束max_model_len与max_position_embeddings启用多批量--num-prompts处理时如果传给下一阶段的 token 总数超过mimo_audio.yaml配置中的max_model_len值你必须同步修改MiMo-Audio-7B-Instruct/config.json中的max_position_embeddings使其与修改后的max_model_len一致。这一点同时被部署配置注释和代码双重印证mimo_audio.yaml 中 Stage 0 的max_model_len: 8192、max_num_batched_tokens: 8192stage_input_processors/mimo_audio.py 中的常量MAX_CODE2WAV_TOKENS 18192明确注释Stage 1code2wav收到的拍平语音码序列不能超过该值否则add_request在拷贝prompt_token_ids时会发生广播错误该常量必须与 Stage 1 的max_model_len、离线示例end2end.py保持同步。3.4 输出位置生成的音频文件默认保存在output_audio/目录下并会进一步按--query-type分子目录存放如output_audio/tts_sft/同时为每个请求写入同名.txt文本文件。--num-prompts参数同样适用于下面的所有任务。四、任务用法详解10 类任务全命令以下所有命令均以--model-name XiaomiMiMo/MiMo-Audio-7B-Instruct为基础仅在--query-type及附加参数上有差异。若本地模型缓存路径不同请调整--model-name。4.1 tts_sft基础文本转语音由文本生成语音python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type tts_sft \ --text The weather is so nice today.从源码看tts_sft走的是get_tts_sft(text..., read_text_onlyTrue)分支end2end.py即纯文本朗读模式脚本会用message_convert.py中的中英文 TTS 模板随机包装文本例如英文模板Please convert this text to speech、中文模板请将这段文字转换为语音等再拼出带|sostm|streaming output start token的 assistant 开头。4.2 tts_sft_with_instruct带嗓音指令的 TTS按显式嗓音风格指令生成语音python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type tts_sft_with_instruct \ --text The weather is so nice today. \ --instruct Speak happily in a childs voice该分支将instruct指令以(指令)形式拼入 user 轮次{template}: {text}({instruct})并使用带think\n开头的 assistant 片段create_assistant_start_with_think()见 message_convert.py。4.3 tts_sft_with_audio带音频参考的 TTS / 语音克隆用一段参考音频做声音克隆python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type tts_sft_with_audio \ --text The weather is so nice today. \ --audio-path ./spoken_dialogue_assistant_turn_1.wav代码中该分支把参考音频同时作为prompt_speech与multi_modal_data传入end2end.py。在 prompt 构造时_build_tts_system_prompt(has_voice_promptTrue, ...)会生成一个 system 轮次其中写明你的音色应该是并内嵌该音频对应的 token 占位message_convert.py从而让模型模仿参考音色。4.4 tts_sft_with_natural_instruction自然语言描述 TTS从文本中内嵌的自然语言嗓音描述生成语音python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type tts_sft_with_natural_instruction \ --text In a panting young male voice, he said: I cant run anymore, wait for me!该分支使用read_text_onlyFalse即文本本身即模板模式end2end.py系统提示中要求根据指定风格指令与文本内容生成语音用户文本直接按template:text格式拼入assistant 段以think开头message_convert.py。4.5 audio_trancribing_sft语音转文本将音频转写成文本python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type audio_trancribing_sft \ --audio-path ./spoken_dialogue_assistant_turn_1.wav源码中该分支会覆盖--text为固定的Please transcribe this audio and repeat it once.并设置use_sostmTrueend2end.py即 assistant 段使用|sostm|流式输出起始标记message_convert.py中还内置了 10 个中文 ASR 模板如请将这段语音转换为文字与 12 个英文 ASR 模板供随机选用。4.6 audio_understanding_sft音频理解结合文本查询理解并分析音频python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type audio_understanding_sft \ --text Summarize the audio. \ --audio-path ./spoken_dialogue_assistant_turn_1.wav4.7 audio_understanding_sft_with_thinking带推理链的音频理解带推理链reasoning chain的音频理解python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type audio_understanding_sft_with_thinking \ --text Summarize the audio. \ --audio-path ./spoken_dialogue_assistant_turn_1.wav与上一任务的区别仅在thinkingTrueget_audio_understanding_sft_prompt会通过append_assistant_ending(lm_prompt, thinkingTrue)使用开放的think\n标记让模型先生成推理链再给结论message_convert.py。4.8 spoken_dialogue_sft_multiturn多轮口语对话音频输入与输出的多轮对话python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type spoken_dialogue_sft_multiturn \ --audio-path ./prompt_speech_zh_m.wav注意此任务在脚本中使用了硬编码的音频文件。示例中使用的音频文件可在 MiMo-Audio 官方示例目录获取。代码中该分支构造了一个三回合 message_list用户轮次引用weather_of_today.mp3与beijing.mp3助手轮次则包含一段中文天气回复文本与spoken_dialogue_assistant_turn_1.wav并内置 system 级音色 promptend2end.py。多轮口语对话的 prompt 由get_spoken_dialogue_sft_multiturn_prompt构建助手轮次会使用StreamingInputSegment把文本与音频按块交错排列再包上|sostm|…|eostm|标记message_convert.py。4.9 speech2text_dialogue_sft_multiturn语音转文本对话多轮对话且输出为文本python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type speech2text_dialogue_sft_multiturn注意此任务在脚本中使用了硬编码的音频文件与消息列表。代码中该分支内置了两段音频weather_of_today.mp3、beijing.mp3与一轮助手文本回复并以thinkingTrue开启推理链end2end.py。4.10 text_dialogue_sft_multiturn纯文本对话纯文本多轮对话python3 -u end2end.py \ --model-name XiaomiMiMo/MiMo-Audio-7B-Instruct \ --query-type text_dialogue_sft_multiturn注意此任务在脚本中使用了硬编码的消息列表示例为一段推荐中国旅游景点 / 想去的城市 / 北京的三轮对话end2end.py。五、深入源码Prompt 与多模态输入是如何构造的为了让读者能自行改造脚本这里梳理示例目录中几个关键文件的职责文件职责end2end.py主入口解析参数 → 按query_type构造 query → 创建Omni引擎 → 生成并保存.txt/.wavmessage_convert.py全部 prompt 构造函数get_*_prompt、分段InputSegment与文本模板process_speechdata.pyInputSegment/StreamingInputSegment的底层定义与to_input_id编码逻辑message_base64_wav.jsonbase64 编码的示例 WAV 消息数据message_convert.py 配套的get_audio_data读取本地/data:协议的音频重采样到 24kHz 并返回(float32 信号, 采样率)元组5.1 特殊 token 体系MiMo-Audio 使用了一套专门的聊天/流式标记全部由 message_convert.py 中的create_*_segment系列函数生成|im_start|/|im_end|角色轮次起止user / assistant / system|sosp|/|eosp|音频输入段的起止标记|sostm|/|eostm|流式输出段起止标记凡是要输出语音的请求assistant 段都会以|sostm|开头|eot|文本段结束标记用于流式分段|empty|文本侧的占位空 tokenthink//think推理链开关thinkingTrue时使用开放的think\n。5.2 音频-文本交错编码process_speechdata.py 中的InputSegment.to_input_id()揭示了多模态输入的核心机制纯文本段文本经 tokenizer 编码后每隔group_size - 1个 token 插入-100占位insert_between音频通道全部填充speech_zeroemb_idx默认 1024最终拼接为[audio_channels 1, seqlen]的输入张量音频段先 reshape 为[audio_channels, seqlen]两侧补上|sosp|/|eosp|对应的 group 大小零嵌入文本侧用empty_token填充StreamingInputSegment用于多轮口语对话的助手轮次会把文本按text_segment_size、音频按audio_segment_size * group_size * audio_channels切块后逐对交错模拟流式边说边生成的结构。MiMoAudioConfigvllm_omni/model_executor/models/mimo_audio/config_mimo_audio.py中定义了group_size4、audio_channels8等默认值以及TALKER_CODEC_PAD_TOKEN_ID 151667talker 码流 pad token即message_convert.py中的speech_zeroemb_idx。5.3 生成结果的两类输出end2end.py遍历omni_outputs时按final_output_type分流end2end.pytext 类型保存{request_id}.txt内容含 Prompt 与vllm_text_output并会剔除输出文本中的chinese/english标签audio 类型从outputs[0].multimodal_output[audio]取张量转为 numpy 后以24kHz、WAV 格式写入{request_id}.wav。六、部署配置速览两阶段如何协同默认部署配置 vllm_omni/deploy/mimo_audio.yaml 的关键字段async_chunk: true # 启用异步分块流式传输 dtype: bfloat16 connectors: connector_of_shared_memory: name: SharedMemoryConnector # 共享内存连接器 extra: codec_streaming: true # 码流流式 codec_chunk_frames: 30 # 每块码帧数 codec_left_context_frames: 40 # 左侧上下文帧数须覆盖声码器注意力窗口 stages: - stage_id: 0 # thinkertalker max_num_seqs: 1 gpu_memory_utilization: 0.5 max_num_batched_tokens: 8192 max_model_len: 8192 devices: 0 default_sampling_params: temperature: 0.6 top_p: 0.95 top_k: 50 max_tokens: 18192 # 与 MAX_CODE2WAV_TOKENS 对齐 seed: 42 repetition_penalty: 1.1 - stage_id: 1 # code2wav gpu_memory_utilization: 0.3 max_num_batched_tokens: 8192 max_model_len: 8192 devices: 0 default_sampling_params: temperature: 0.0 # 解码阶段用确定性采样 max_tokens: 18192其中两个连接器参数在源码中有明确的校验逻辑vllm_omni/model_executor/stage_input_processors/mimo_audio.pycodec_chunk_frames最小值 3低于最小值会回退到默认值 10codec_left_context_frames最小值 40必须覆盖声码器注意力窗口vocoder_attn_window_size默认[40, 10]低于最小值会导致分块边界处声学状态重置使输出音频出现多说话人/音色漂移等不稳定现象。Stage 0 通过llm2code2wav_async_chunk把每步生成的[B,1,8,4]码张量按列优先拍平并前置 pad 向量累积到codec_chunk_frames满块或请求结束时再发给 Stage 1stage_input_processors/mimo_audio.py。如果只想在 5090D 上跑通离线 TTS可直接复用 mimo_audio_5090d.yaml 并通过--deploy-config指定。七、故障排查7.1 Tokenizer 路径问题MIMO_AUDIO_TOKENIZER_PATH未设置或模型找不到 tokenizer运行前先导出 tokenizer 路径export MIMO_AUDIO_TOKENIZER_PATHXiaomiMiMo/MiMo-Audio-Tokenizer该环境变量为必填项见本文环境变量一节。7.2 其他常见问题模型或部署配置加载失败检查 docs/configuration/stage_configs.md 中关于显存与 GPU 设置的说明确认gpu_memory_utilization、devices等字段与你的硬件匹配读写 WAV 报错如不支持的格式确保输入文件是标准 WAV/MP3且soundfile正确链接到了可用的libsndfile生成的音频为噪声/不可用确认已安装与 CUDA、PyTorch 匹配的flash-attn构建音频生成任务必需多批量时报 token 超限/广播错误检查 Stage 1 的max_model_len18192 上限与模型config.json中max_position_embeddings是否同步调整见快速开始一节。八、注意事项与参数速查脚本使用end2end.py中内置的默认模型路径和音频文件若本地缓存路径不同请自行更新使用--output-dir更改输出目录默认./output_audio使用--num-prompts一次生成多个 prompt默认 1多轮对话示例所用音频文件可在 MiMo-Audio 官方示例目录获取脚本支持初始化休眠时间--init-sleep-seconds默认 20 秒、批处理超时--batch-timeout默认 5 秒、初始化超时--init-timeout默认 5000 秒、共享内存阈值--shm-threshold-bytes默认 65536 字节等配置详见python3 -u end2end.py --help采样参数方面thinker 使用temperature0.0, max_tokens2048code2wav 使用temperature0.0, max_tokens4096*16, detokenizeTrue二者均固定seed42、repetition_penalty1.1end2end.py--output-wav参数已标记为 deprecated请使用--output-dir。九、延伸阅读在线服务版示例OpenAI 兼容接口 聊天模板examples/online_serving/mimo_audio/单卡 32GB BlackwellRTX 5090/5090D完整部署食谱recipes/XiaomiMiMo/MiMo-Audio.md两阶段流水线拓扑定义vllm_omni/model_executor/models/mimo_audio/pipeline.py音频 tokenizer 模型实现vllm_omni/model_executor/models/mimo_audio/modeling_audio_tokenizer.py部署配置vllm_omni/deploy/mimo_audio.yaml、vllm_omni/deploy/mimo_audio_5090d.yaml【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价