[MiniCPM-o-4.5] tts_bound 在当前语音被截断时选择历史回转的 <|tts_eos|>, 导致 TTS 范围为空
作者: jaminmei创建于 2026年9月17日更新于 2026年9月17日
Hi! 在 openbmb/MiniCPM-o-4_5 的 modeling_minicpmo.py 中,在测试多回合对话时,我遇到了一个特殊情况。chat() 会取出最后一个 <|tts_bos|>,但会将提示 + 生成的 token 中的 最后一个 <|tts_eos|> 传递给 generate_speech_non_streaming 函数:
tts_bos_idx = tts_bos_indices[-1] if tts_bos_indices else -1
tts_eos_idx = tts_eos_indices[-1] if tts_eos_indices else None如果历史中包含一个完成的语音回合(提示中包含一个旧的 <|tts_eos|>),并且当前回复在自己的标记之前停止(例如,最大新 token 很小),则结束索引位于开始索引之前,full_sequences[0][start:end] 为空,并且说话者获得了一个空条件 - 没有音频,尽管回合中包含可发音的 token。在 _generate_speech_non_streaming 中的 bare except 会隐藏失败,因此您只会得到没有 wav 的文本。None 回退只涵盖 "任何地方都没有 <|tts_eos|>";它无法帮助当一个旧标记位于最后一个 <|tts_bos|> 之前。同一个文件中的文本侧提取已经正确地执行了此操作(text.split("<|tts_bos|>")[-1].split("<|tts_eos|>")[0]),因此也许只需要以同样的方式定义 token 路径:
start = tts_bos_indices[-1] + 1
eos_in_segment = [i for i in tts_eos_indices if i >= start]
tts_eos_idx = eos_in_segment[0] if eos_in_segment else None
tts_bound = (start, tts_eos_idx)单回合和完成回合的行为保持不变。
内容来源: OpenBMB/MiniCPM-V