如何确保Azure文本转语音准确处理逐词翻译的发音问题
如何确保Azure文本转语音准确处理逐词翻译的发音问题
我来帮你解决这个Azure TTS处理逐词翻译发音不准的问题。首先咱们得先梳理清楚当前代码的核心问题,再一步步优化:
先说说当前代码的几个坑
- 逐词翻译的生成逻辑太粗糙:你现在的
_generate_word_by_word方法只是简单按空格拆分原词和译词,然后逐个对应。但像德语、英语到西班牙语的翻译,很多时候是多词对多词、语序完全不同的(比如英语的"looking for"对应西班牙语的"buscando"),硬拆的话肯定对应不上,TTS读出来自然不对。 - TTS服务只会用一种语音读完整段文本:你当前的TTS是检测整个文本的主语言,然后用对应语音读完全部内容。但逐词翻译的文本是混合两种语言的(比如"Ich (Yo)"),用单一种语音读另一种语言的单词,发音肯定不标准。
- Gemini的prompt指令不够明确:原来的prompt没有严格要求Gemini返回带语言标识的逐词对应,也没要求它处理好短语/多词对应的情况,导致输出的内容没法给TTS提供准确的语言信息。
接下来咱们一步步优化
第一步:给Gemini的翻译指令"打补丁",要求返回带语言标记的结构化内容
咱们得让Gemini输出三种明确格式的内容,用---分隔方便程序解析:
- 自然流畅的目标语言翻译(用于整体发音)
- 带语言标记的逐词翻译文本(比如
Ich[de] (Yo[es]),方便TTS识别语言) - 结构化的逐词映射JSON(方便程序处理对应关系)
修改TranslationService里的聊天会话初始化prompt:
self.chat_session = self.model.start_chat( history=[ { "role": "user", "parts": [ """ 你是专业的德西、英西翻译专家,处理单词/短语翻译时必须返回以下三种格式的内容,用---分隔: 1. 自然流畅的目标语言翻译(用于整体发音): <自然翻译文本> --- 2. 逐词/短语对应翻译(每个内容标注ISO 639-1语言代码): <原内容1[原语言码]> (<译内容1[目标语言码]>) <原内容2[原语言码]> (<译内容2[目标语言码]>) ... --- 3. 结构化逐词映射(合法JSON格式): { "word_mappings": [ {"original": "原内容", "original_lang": "原语言码", "translation": "译内容", "target_lang": "目标语言码", "pos": "词性"}, ... ] } 注意事项: - 语言码用de(德语)、es(西班牙语)、en(英语) - 短语要作为整体对应,比如英语"looking for"对应西班牙语"buscando",不能拆成单个单词 - 译词必须带正确的重音符号,比如西班牙语的á/é/í/ó/ú/ñ """ ] } ] )
然后在process_prompt方法里解析Gemini的返回内容:
async def process_prompt(self, text: str, source_lang: str, target_lang: str) -> Translation: try: # 构造带语言参数的查询 prompt = f""" 现在请处理以下文本的翻译,原语言是{source_lang},目标语言是{target_lang}: {text} """ response = self.chat_session.send_message(prompt) generated_text = response.text # 拆分Gemini返回的三个部分 parts = generated_text.split("---") if len(parts) != 3: raise ValueError("Gemini返回的格式不符合要求,请检查prompt指令") natural_translation = parts[0].strip() word_by_word_text = parts[1].strip() word_mappings_json = parts[2].strip() # 解析结构化映射 import json word_mappings = json.loads(word_mappings_json)["word_mappings"] # 生成自然翻译的音频(也可以额外生成逐词翻译的音频) audio_filename = await self.tts_service.text_to_speech(text=natural_translation) print(f"Generated natural translation: {natural_translation}") print(f"Generated word-by-word text: {word_by_word_text}") return Translation( original_text=text, translated_text=natural_translation, source_language=source_lang, target_language=target_lang, audio_path=audio_filename, translations={"main": natural_translation, "word_by_word": word_by_word_text}, word_by_word=word_mappings, grammar_explanations=self._generate_grammar_explanations(natural_translation) ) except Exception as e: print(f"Error in process_prompt: {str(e)}") raise Exception(f"Translation processing failed: {str(e)}")
第二步:改造Azure TTS服务,支持混合语言发音
现在要让TTS能识别带语言标记的文本,自动切换对应语音。修改EnhancedTTSService的代码:
def _parse_mixed_lang_text(self, text: str) -> str: # 匹配带语言标记的内容:支持单词和短语(包含空格) pattern = r'([\w\s]+)\[([a-z]{2})\]' def replace_match(match): content = match.group(1).strip() lang = match.group(2) # 获取对应语言的语音 voice_name = self.voice_mapping.get(lang, self.voice_mapping['en']) return f'<voice name="{voice_name}">{content}</voice>' # 替换所有匹配项,同时转义XML特殊字符 processed_text = re.sub(pattern, replace_match, text) processed_text = processed_text.replace('&', '&').replace('<', '<').replace('>', '>') return processed_text def _generate_ssml(self, text: str) -> str: # 先处理混合语言文本 processed_text = self._parse_mixed_lang_text(text) # 生成支持多语音的SSML ssml = f"""<?xml version='1.0'?> <speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis'> <prosody rate="0.95" pitch="0%"> {processed_text} </prosody> </speak>""" return ssml
这样处理后,比如逐词翻译文本是hallo[de] (hola[es]),生成的SSML会自动切换德语和西班牙语的语音,Azure TTS就能准确读出两种语言的发音了。
第三步:兜底保障译词的拼写正确性
你的_restore_accents方法已经做得很好了,一定要保留。它能确保译词的重音符号正确——毕竟Azure TTS的发音完全依赖输入的拼写,重音对西班牙语、德语的发音影响极大。
最后测试一下效果
比如输入德语的hallo,Gemini会返回:
- 自然翻译:
hola - 逐词翻译文本:
hallo[de] (hola[es]) - 结构化映射:
{"word_mappings": [{"original": "hallo", "original_lang": "de", "translation": "hola", "target_lang": "es", "pos": "感叹词"}]}
TTS处理逐词翻译文本时,会用德语语音读hallo,西班牙语语音读hola,发音完全标准;处理自然翻译文本时,直接用西班牙语语音读hola,也符合要求。
总结一下核心思路
- 把逐词对应的精准度交给Gemini,不要自己硬拆单词,避免语序、多词对应等低级错误;
- 给每个翻译内容加上语言标记,让TTS明确知道每个部分该用哪种语言的语音;
- 确保译词的拼写(尤其是重音)正确,给TTS提供最准确的输入。
备注:内容来源于stack exchange,提问作者pomoworko.com
相关产品推荐
相关产品推荐

