
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),僅供參考