ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何在 TTS 中实现新语言的 phonemizer?

如何在 TTS 中实现新语言的 phonemizer? 如何在 TTS 中实现新语言的 phonemizer【免费下载链接】TTS - a deep learning toolkit for Text-to-Speech, battle-tested in research and production项目地址: https://gitcode.com/GitHub_Trending/tt/TTS如果你的 TTS 任务要朗读一种新的语言而工具包内置的 phonemizer文本转音素/字母覆盖不到它就需要按 docs/source/implementing_a_new_language_frontend.md 描述的流程扩展一个新语言的 phonemizer。完成后的效果是模型配置里的config.phoneme_language可以直接映射到你实现的 phonemizer 类训练和推理时文本会被自动转换成音素不需要每次手动初始化。先确认是否真的需要自己实现在动手前先看目标语言是否已经被 espeak 覆盖。TTS/tts/utils/text/phonemizers/init.py 中的ESpeak包装类通过espeak/espeak-ng --voices动态读取支持的语言列表ESPEAK_LANGS并已经把这些语言写进了DEF_LANG_TO_PHONEMIZER映射。只要目标语言代码在 espeak 的支持列表里直接用ESpeak即可例如 docstring 给出的用法from TTS.tts.utils.text.phonemizers import ESpeak phonemizer ESpeak(tr) phonemizer.phonemize(Bu Türkçe, bir örnektir., separator|) # 文档示例输出: # b|ʊ t|ˈø|r|k|tʃ|ɛ, b|ɪ|r œ|r|n|ˈɛ|c|t|ɪ|r.注意ESpeak依赖系统中安装了espeak或espeak-ng可执行程序is_available()用shutil.which检查找不到时构造会抛出No espeak backend found。只有当语言不在 espeak 覆盖范围内或你需要自定义 G2Pgrapheme-to-phoneme行为时才走下面的自建路径。代码结构新语言放在哪里按照文档说明语言前端language frontend的组织方式是语言前端代码位于TTS.tts.utils.text模块下每种语言一个独立文件夹文件夹里放该语言处理文本输入所需的全部工具函数主 phonemizer 类放在 TTS/tts/utils/text/phonemizers 中它调用上一步的工具函数把文本转成音素或字母实现完成后必须把新类注册进 TTS/tts/utils/text/phonemizers/init.py才能把config.phoneme_language的语言代码映射到类上并自动初始化。文档建议参考现有实现。仓库中最完整的自建样例是白俄罗斯语be工具函数在 TTS/tts/utils/text/belarusian/phonemizer.pyphonemizer 类在 TTS/tts/utils/text/phonemizers/belarusian_phonemizer.py。所有自建 phonemizer 都继承 TTS/tts/utils/text/phonemizers/base.py 中的BasePhonemizer。基类把 phonemize 分成三步预处理去空格、按keep_puncs决定保留标点、调用子类的_phonemize做转换、后处理恢复标点。公开入口是phonemize(text, separator|)。基类__init__还会做两项检查is_available()为 False 时抛出RuntimeError(xx not installed on your system)_init_language中若语言不在supported_languages()内抛出language xx is not supported by the ... backend。第一步新建语言工具文件夹按白俄罗斯语的范例在TTS/tts/utils/text/下新建语言文件夹下文用lang表示你的语言代码如be在文件夹里实现把文本转成音素的函数。如果你的 G2P 依赖外部库在这里处理依赖。白俄罗斯语的 phonemizer.py 是一个典型的带依赖示例它要求pip install jpype1并读取环境变量BEL_FANETYKA_JAR指向fanetyka.jar文件缺少任一项都会抛出带明确提示的ModuleNotFoundError/KeyError。第二步实现继承 BasePhonemizer 的类在 TTS/tts/utils/text/phonemizers 下新建lang_phonemizer.py。对照 base.py 的抽象定义必须提供这些成员name()后端名称注册和按名查找都靠它is_available()后端依赖是否已安装version()后端版本supported_languages()返回{语言代码: 语言名}的字典_phonemize(text, separator)真正调用你第一步实现的 G2P 函数。以BEL_Phonemizer为参考骨架如下lang、LANG、Language name、lang_text_to_phonemes均需替换为你自己的语言代码、类名前缀、语言名和 G2P 函数from typing import Dict from TTS.tts.utils.text.lang.phonemizer import lang_text_to_phonemes from TTS.tts.utils.text.phonemizers.base import BasePhonemizer _DEF_LANG_PUNCS ,.! # 参考 _DEF_BE_PUNCS按语言调整需要保留的标点 class LANG_Phonemizer(BasePhonemizer): language lang def __init__(self, punctuations_DEF_LANG_PUNCS, keep_puncsTrue, **kwargs): super().__init__(self.language, punctuationspunctuations, keep_puncskeep_puncs) staticmethod def name(): return lang_phonemizer def _phonemize(self, text, separator): return lang_text_to_phonemes(text) staticmethod def supported_languages() - Dict: return {lang: Language name} def version(self) - str: return 0.0.1 def is_available(self) - bool: # 若 G2P 依赖外部库这里检查依赖是否已安装 return Truepunctuations和keep_puncs两个参数决定是否在 phonemize 后恢复标点参考实现中白俄罗斯语用了,!.并开启keep_puncsTrue可按目标语言调整。第三步在 phonemizers/init.py 中注册打开 TTS/tts/utils/text/phonemizers/init.py需要改三处。顶部导入你的类from TTS.tts.utils.text.phonemizers.lang_phonemizer import LANG_Phonemizer在“Force default for some languages”一带添加语言代码到 phonemizer 名称的映射参考已有的DEF_LANG_TO_PHONEMIZER[be] BEL_Phonemizer.name()DEF_LANG_TO_PHONEMIZER[lang] LANG_Phonemizer.name()在get_phonemizer_by_name的 if 分支中补一条参考if name be_phonemizer:的写法if name lang_phonemizer: return LANG_Phonemizer(**kwargs)为什么这三处缺一不可TTS/tts/utils/text/tokenizer.py 在构建 tokenizer 时的解析逻辑是——若配置里显式设置了config.phonemizer调用get_phonemizer_by_name(config.phonemizer, languageconfig.phoneme_language)否则用DEF_LANG_TO_PHONEMIZER[config.phoneme_language]查表再按名实例化。查不到会抛出No phonemizer found for language {config.phoneme_language}. You may need to install a third party library for this language.。缺映射会导致查表失败缺get_phonemizer_by_name分支会导致按名实例化失败。第四步在模型配置中使用按 TTS/tts/configs/shared_configs.py 中 phoneme 相关字段的说明config.use_phonemes True config.phoneme_language lang # 你注册的語言代码 # 可选显式指定 phonemizer 名称优先级高于 phoneme_language 查表 # config.phonemizer lang_phonemizerphonemizer字段留空时会自动按phoneme_language从DEF_LANG_TO_PHONEMIZER选择并把选中的名字写回new_config.phonemizer显式指定时则以get_phonemizer_by_name按名初始化。验证注册是否生效按从独立到集成的顺序做三个检查直接运行你的 phonemizer 文件。BEL_Phonemizer文件末尾的__main__就是现成的验证模式输出supported_languages()、version()、language、name()、is_available()和对样例文本тэст的phonemize结果。照此给自己的文件加一段__main__运行后确认能打印出音素序列。检查语言映射表。TTS/tts/configs/shared_configs.py 的 docstring 指出查看支持语言列表的方式是运行python TTS/tts/utils/text/phonemizers/__init__.py该文件的__main__会打印整个DEF_LANG_TO_PHONEMIZER。确认输出里出现你的语言代码及其名称。跑单测。如果要提交 PR文档要求把测试加到 tests/text_tests。参考 test_belarusian_phonemizer.py它维护一组文本/音素用例如Фанетычны канвертар/fanʲɛˈtɨt͡ʂnɨ kanˈvʲɛrtar逐行断言 G2P 函数输出与期望音素一致若 G2P 依赖环境变量如BEL_FANETYKA_JAR测试中用warnings.warn提示并跳过。如果模型初始化时仍报No phonemizer found for language ...说明第三步的DEF_LANG_TO_PHONEMIZER或导入没生效报xx not installed on your system则说明is_available()返回了 False需要先装好 G2P 依赖。可选分支phonemizer 依赖较重时的条件注册如果你的 G2P 依赖很难安装例如有系统级依赖可以参考日语 phonemizer 的处理方式在init.py 中用try: ... except ImportError:包裹导入失败时把类设为None只在导入成功时才写入PHONEMIZERS和DEF_LANG_TO_PHONEMIZER[ja-jp]。同时get_phonemizer_by_name里对name ja_jp_phonemizer且未安装的情况抛出带安装指引的错误如pip install TTS[ja]。这样主包在未装可选依赖时仍可用用户误配语言时才得到明确提示。最后再提醒两条限制ESpeak的可用语言列表依赖系统上的 espeak 可执行程序每个自建 phonemizer 的supported_languages()只写自己真正支持的语言代码基类会用它拒绝不受支持的语言。完成上述步骤并验证通过后你的语言就可以通过use_phonemesTruephoneme_language参与训练和推理了。【免费下载链接】TTS - a deep learning toolkit for Text-to-Speech, battle-tested in research and production项目地址: https://gitcode.com/GitHub_Trending/tt/TTS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表