ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

MiniCPM-o 4.5 如何以 1 秒分块流式输入实现实时语音对话并调节 length_penalty?

MiniCPM-o 4.5 如何以 1 秒分块流式输入实现实时语音对话并调节 length_penalty? MiniCPM-o 4.5 如何以 1 秒分块流式输入实现实时语音对话并调节 length_penalty【免费下载链接】MiniCPM-VA Pocket-Sized MLLM for Ultra-Efficient Image and Video Understanding on Your Phone项目地址: https://gitcode.com/GitHub_Trending/mi/MiniCPM-V本文的任务是在本地 GPU 上用 MiniCPM-o 4.5 跑通「实时语音对话」的半双工Half-Duplex Realtime Speech Conversation模式——把用户的整段语音按1 秒一个分块逐块喂给模型做流式 prefill降低首 token 延迟再流式生成带语音的输出并按文档建议在streaming_generate中设置length_penalty1.1提升回复内容质量。适用前提是 NVIDIA GPU 环境代码中执行model.eval().cuda()依赖按官方文档在 Python 3.10 下验证过。环境准备与依赖安装实时语音对话涉及 TTS 与流式推理必须安装带[all]扩展的minicpmo-utils文档中明确区分了「无 TTS/流式」与「有 TTS/流式」两种依赖本文属于后者pip install transformers4.51.0 accelerate torch2.3.0,2.8.0 torchaudio2.8.0 minicpmo-utils[all]1.0.5注意transformers被钉死在4.51.0文档说明其他版本可能存在兼容性问题under investigation不要自行升级。加载模型并初始化 TTS按文档的模型初始化代码加载openbmb/MiniCPM-o-4_5随后调用init_tts()启用语音输出import torch from transformers import AutoModel # Load omni model (default: init_visionTrue, init_audioTrue, init_ttsTrue) # For vision-only model: set init_audioFalse and init_ttsFalse # For audio-only model: set init_visionFalse model AutoModel.from_pretrained( openbmb/MiniCPM-o-4_5, trust_remote_codeTrue, attn_implementationsdpa, # sdpa or flash_attention_2 torch_dtypetorch.bfloat16, init_visionTrue, init_audioTrue, init_ttsTrue, ) model.eval().cuda() # Initialize TTS for audio output model.init_tts()attn_implementation文档给出sdpa或flash_attention_2两个取值按本机环境任选其一。预填系统轮并设定音色实时对话会话开始前先重置会话状态并可选地加载参考音频用于声音克隆然后 prefill 系统轮。下面以中文对话为例英文系统提示同样支持文档给出了 Clone the voice in the provided audio prompt. 版本的对照写法import librosa # Set reference audio for voice style ref_audio_path ref_audio_path # 替换为你自己的 16k 参考音频文件路径 ref_audio, _ librosa.load(ref_audio_path, sr16000, monoTrue) # Example system msg for Chinese Conversation sys_msg { role: system, content: [ 模仿输入音频中的声音特征。, ref_audio, 你的任务是用这种声音模式来当一个助手。请认真、高质量地回复用户的问题。请用高自然度的方式和用户聊天。你是由面壁智能开发的人工智能助手面壁小钢炮。 ] } # Reset state model.init_tts() model.reset_session(reset_token2wav_cacheTrue) model.init_token2wav_cache(prompt_speech_16kref_audio) session_id demo # First, prefill system turn model.streaming_prefill( session_idsession_id, msgs[sys_msg], omni_modeFalse, is_last_chunkTrue, )说明两点ref_audio_path在源文档中是占位写法读者需替换为自己的参考音频路径加载时固定sr16000, monoTrueomni_modeFalse表示纯语音对话链路。需要视频帧 音频的全双工流式交互是另一套接口model.as_duplex()model.prepare(...)不在本文这条操作路径内。将用户音频切分为 1 秒分块并逐块流式 prefill这是「实时」的关键不等待整段语音处理完毕而是把用户输入音频切成 1 秒16000 个采样点输入采样率固定 16000Hz的分块每块调用一次streaming_prefill。文档注释写明其目的是reduce first-token latency降低首 token 延迟。最后一个分块若不足 1 秒需补零到 16000 点并把is_last_chunk置为True# Here we simulate realtime speech conversation by splitting whole user input audio into chunks of 1s. user_audio, _ librosa.load(user_audio.wav, sr16000, monoTrue) # 替换为你的用户语音文件 IN_SAMPLE_RATE 16000 # input audio sample rate, fixed value CHUNK_SAMPLES IN_SAMPLE_RATE # sample OUT_SAMPLE_RATE 24000 # output audio sample rate, fixed value MIN_AUDIO_SAMPLES 16000 total_samples len(user_audio) num_chunks (total_samples CHUNK_SAMPLES - 1) // CHUNK_SAMPLES for chunk_idx in range(num_chunks): start chunk_idx * CHUNK_SAMPLES end min((chunk_idx 1) * CHUNK_SAMPLES, total_samples) chunk_audio user_audio[start:end] is_last_chunk (chunk_idx num_chunks - 1) if is_last_chunk and len(chunk_audio) MIN_AUDIO_SAMPLES: chunk_audio np.concatenate([chunk_audio, np.zeros(MIN_AUDIO_SAMPLES - len(chunk_audio), dtypechunk_audio.dtype)]) user_msg {role: user, content: [chunk_audio]} # For each 1s audio chunk, perform streaming_prefill once to reduce first-token latency model.streaming_prefill( session_idsession_id, msgs[user_msg], omni_modeFalse, is_last_chunkis_last_chunk, )执行前要引入numpyimport numpy as np。真实部署中这段循环对应「麦克风每采集满 1 秒就 prefill 一次」文档示例用离线加载的user_audio.wav模拟同样的分块节奏。流式生成回复并设置 length_penalty1.1所有分块 prefill 完成后调用streaming_generate流式产出文本与语音。文档对实时语音对话模式给出的建议参数是length_penalty1.1注释原文为For realtime speech conversation mode, we suggest length_penalty1.1 to improve response content。# Let model generate response in a streaming manner generate_audio True iter_gen model.streaming_generate( session_idsession_id, generate_audiogenerate_audio, use_tts_templateTrue, enable_thinkingFalse, do_sampleTrue, max_new_tokens512, length_penalty1.1, # For realtime speech conversation mode, we suggest length_penalty1.1 to improve response content ) audios [] text output_audio_path output.wav if generate_audio: for wav_chunk, text_chunk in iter_gen: audios.append(wav_chunk) text text_chunk generated_waveform torch.cat(audios, dim-1)[0] sf.write(output_audio_path, generated_waveform.cpu().numpy(), samplerate24000) print(Text:, text) print(Audio saved to output.wav) else: for text_chunk, is_finished in iter_gen: text text_chunk print(Text:, text)其中sf来自soundfile包依赖安装步骤已覆盖。length_penalty是文档明确给出的可调项建议值 1.1文档没有给出其他取值的对照效果如需实验请自行替换该数值后观察回复内容本文不代替文档给出结论。结果验证与多轮接续完成判据以文档代码的输出为准终端打印Text:后跟模型回复文本output.wav落盘采样率 24000HzOUT_SAMPLE_RATE为固定值即 TTS 生成的语音回复。多轮对话不需要重新加载模型同一session_id下把下一轮用户音频继续按 1 秒分块 prefill再调用streaming_generate即可——文档注释为Now we can prefill the following user turns and generate next turn response...。边界与限制本文路径是半双工语音对话输入分块 prefill 与输出生成是先后两个阶段。全双工边看视频边听语音、输入输出流互不阻塞走as_duplex()后的另一套接口参数如max_new_speak_tokens_per_chunk不同不要混用。输入音频采样率固定 16000Hz、输出 24000Hz这两个是文档标注的 fixed value切分逻辑中的CHUNK_SAMPLES依赖前者改动会破坏 1 秒分块约定。transformers4.51.0的版本锁定、torch2.3.0,2.8.0与torchaudio2.8.0的范围约束是文档明确给出的安装边界升级前请先核对官方文档是否已更新。相关入口模型初始化与半双工对话完整代码在 README.md 的 MiniCPM-o 4.5 Usages 章节Half-Duplex Omni Mode → Streaming Inference 与 Half-Duplex Realtime Speech Conversation Mode 小节如需以 Chat Completions API 方式调用同一模型可参考 docs/api.md。【免费下载链接】MiniCPM-VA Pocket-Sized MLLM for Ultra-Efficient Image and Video Understanding on Your Phone项目地址: https://gitcode.com/GitHub_Trending/mi/MiniCPM-V创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表