
Coqui-TTS Mary-TTS 兼容 API用 /locales、/voices 与 /process 三个端点替换经典 TTS 服务【免费下载链接】TTS - a deep learning toolkit for Text-to-Speech, battle-tested in research and production项目地址: https://gitcode.com/GitHub_Trending/tt/TTS本篇围绕 Coqui-TTS 仓库中的 Mary-TTS 兼容层文档 marytts.md 展开它说明 Coqui-TTS 的 Flask 演示服务器如何通过三个 Mary-TTS 风格 HTTP 端点/locales、/voices、/process兼容旧有 Mary-TTS 客户端并逐一拆解 server.py 中各端点的源码实现、参数解析细节与已知限制帮助读者把 Coqui-TTS 作为传统 Mary-TTS 服务的“即插即用”替换项接入屏幕阅读器、智能家居或语音助手类工具链。一、Mary-TTS 是什么为什么值得做兼容MaryModular Architecture for Research in sYnthesisText-to-Speech 是一个用 Java 编写的开源GNU LGPL多语言 TTS 平台最初由德国 DFKI 语言技术实验室与萨尔兰大学语音学研究所合作开发后由 MMCI 卓越集群与 DFKI 的语音处理小组维护。该项目的历史相当悠久3.0 版本可追溯到 2006 年远早于深度学习成为通用术语的时代最后一个官方版本 5.2 发布于 2016 年。正是由于开源、音质尚可、合成速度快Mary-TTS 在过去十年被大量工具集成形成了稳定的 HTTP API 调用习惯。原文档列举的典型集成方包括屏幕阅读器NVDA SpeechHub智能家居中心openHAB、Home Assistant语音助手Rhasspy、Mycroft、SEPIA。这些工具多年只对接 Mary-TTS 的 HTTP 接口。Coqui-TTS 提供兼容层后上述工具无需修改代码即可把服务端指向 Coqui-TTS直接获得更高质量的深度学习语音——这是本文讨论的兼容性层存在的根本意义。二、Mary-TTS HTTP API 的三个最小可用端点Mary-TTS 本身提供大量端点加载 style、音频效果、示例等但据原文档总结大多数兼容工具只需要其中 3 个即可正常工作。Coqui-TTS 的兼容层正是按这个“最小集合”实现的1./localesGET——返回受支持的语言环境返回格式为每行一个 locale 的纯文本例如en_US、de_DE或简写的en行以\n分隔。2./voicesGET——返回可用语音列表返回格式为每行名称 语言环境 性别例如glow-tts en u。其中名称不能包含空格Mary-TTS 约定性别字段传统上取f女或m男。3./processGET/POST——核心合成端点完整示例 URL经典 Mary-TTS 参数风格/process?INPUT_TEXT[my text]INPUT_TYPETEXTLOCALE[locale]VOICE[name]OUTPUT_TYPEAUDIOAUDIOWAVE_FILE服务端处理输入文本并返回一个 WAV 文件。INPUT_TYPE、OUTPUT_TYPE、AUDIO等参数虽然支持其他取值但在兼容工具中通常是固定值。三、启动服务器并用 curl 验证兼容端点兼容层构建在 Coqui-TTS 自带的 Flask 演示服务器之上。服务器入口为 TTS/server/server.pypip 安装后还可以直接使用tts-server命令见 setup.py 中的entry_points定义tts-server TTS.server.server:main。要获得“经典 Mary-TTS 兼容”体验关键点在于端口文档建议监听59125这是 Mary-TTS 客户端的默认端口习惯值而非 Coqui-TTS 演示服务器默认的5002。以官方预训练模型为例python TTS/server/server.py \ --model_name tts_models/en/ljspeech/tacotron2-DDC \ --port 59125--model_name的取值格式为language/dataset/model_name在 server.py 的 argparse 定义中可见默认值即tts_models/en/ljspeech/tacotron2-DDC。也可以用自定义 checkpoint 启动各参数的说明可参考 TTS/server/README.md。服务器启动后按文档给出的三条 curl 命令逐一验证返回当前活跃语音的 locale例如encurl http://localhost:59125/locales返回当前活跃语音的名称例如glow-tts en ucurl http://localhost:59125/voices对输入文本进行合成保存为 wav 文件curl http://localhost:59125/process?INPUT_TEXTthisisatest test.wav注意原文档中第三条命令未加引号curl http://localhost:59125/process?INPUT_TEXTthisisatest test.wav在多数 shell 中?与无需转义可以原样执行但一旦文本中包含空格之外的特殊字符建议用引号包裹 URL。也可以把这些 URL 直接粘贴到浏览器中查看结果。四、源码解析三个端点如何把“单模型服务器”伪装成“Mary-TTS 服务器”兼容层的全部实现集中在 TTS/server/server.py 的# Basic MaryTTS compatibility layer区块。以下逐一对照源码说明其设计。/locales从 model_name 拆出语言段app.route(/locales, methods[GET]) def mary_tts_api_locales(): MaryTTS-compatible /locales endpoint # NOTE: We currently assume there is only one model active at the same time if args.model_name is not None: model_details args.model_name.split(/) else: model_details [, en, , default] return render_template_string({{ locale }}\n, localemodel_details[1])实现方式是把--model_name按/切分tts_models/en/ljspeech/tacotron2-DDC切分后下标 1 恰为语言码en于是返回en\n。若未指定model_name则回退为[, en, , default]同样返回en。源码注释明确承认前提同一时间只有一个模型处于活跃状态因此无法像真正的 Mary-TTS 服务器那样枚举全部已安装 locale。/voices模型名充当“voice”性别固定为ureturn render_template_string( {{ name }} {{ locale }} {{ gender }}\n, namemodel_details[3], localemodel_details[1], genderu )voice 名称取自 model_name 的最后一段下标 3如tacotron2-DDC——注意 Mary-TTS 要求名称不含空格官方模型名天然满足locale与/locales相同取切分后的第 2 段性别固定返回uundefined因为 Coqui-TTS 的模型体系没有“男声/女声”这一元数据概念。对tts_models/en/ljspeech/tacotron2-DDC该端点实际输出tacotron2-DDC en u\n。/process只取INPUT_TEXT其余参数全部忽略app.route(/process, methods[GET, POST]) def mary_tts_api_process(): MaryTTS-compatible /process endpoint with lock: if request.method POST: data parse_qs(request.get_data(as_textTrue)) # NOTE: we ignore param. LOCALE and VOICE for now since we have only one active model text data.get(INPUT_TEXT, [])[0] else: text request.args.get(INPUT_TEXT, ) print(f Model input: {text}) wavs synthesizer.tts(text) out io.BytesIO() synthesizer.save_wav(wavs, out) return send_file(out, mimetypeaudio/wav)几个值得注意的实现细节GET 与 POST 双支持GET 请求从 URL 查询串取INPUT_TEXTPOST 请求用urllib.parse.parse_qs解析请求体文本后取INPUT_TEXT。这覆盖了不同工具对 Mary-TTS 的两种调用习惯。只读INPUT_TEXTLOCALE、VOICE、INPUT_TYPE、OUTPUT_TYPE、AUDIO等参数全部忽略——因为服务器只有一个活跃模型且永远返回 WAV其余参数没有实际作用。源码注释直接写明了忽略LOCALE/VOICE的原因。with lock:串行化模块级lock Lock()定义于 server.py保证同一时刻只有一路合成在跑避免多线程并发推理产生竞争。这对单模型演示服务器是合理的取舍但也意味着 Mary-TTS 兼容端点不是并发服务高吞吐场景需要自行扩展。输出格式synthesizer.tts(text)得到波形列表后写入内存BytesIO以mimetypeaudio/wav通过 Flasksend_file流式返回正好匹配 Mary-TTS 客户端对AUDIOWAVE_FILE的预期。合成链路Synthesizer.tts内部做了什么synthesizer.tts(text)实现在 TTS/utils/synthesizer.py。Mary-TTS 端点传入的只有text因此实际执行路径是用pysbd.Segmenter(languageen)把输入文本按英文断句切分为句子列表split_sentencesTrue为默认逐句调用 TTS 模型的synthesize或通用synthesis函数生成波形若配置了独立声码器将 mel 频谱反归一化TTS 音频配置、再按声码器配置归一化、必要时对采样率不匹配做插值最后走声码器inference还原波形未配置声码器时回退 Griffin-Lim各句波形拼接句间插入 10000 个采样点的静音返回。由此可得两个与兼容层相关的实践结论文本按英文断句Segmenter在服务器初始化时硬编码为en见 synthesizer.py 的self._get_segmenter(en)。也就是说/process端点的断句行为面向英文文本用其他语言的model_name如de、fr启动时端点本身仍可返回正确 locale但断句器仍按英文规则切分——这是源码结构可见的局限。Mary-TTS 端点不传 speaker/language 参数与同一服务器里的/api/tts端点支持speaker-id、language-id、style-wav见 server.py不同/process只调用synthesizer.tts(text)。因此若加载的是多说话人/多语言模型经 Mary 兼容端点合成时不会指定说话人与语言可能触发Synthesizer内部的参数校验异常例如要求提供speaker_idx的报错见 synthesizer.py。对单说话人模型如 LJSpeech 系列则无此问题。五、与经典 Mary-TTS 服务器的行为差异及取舍原文档“How it works and limitations”一节可以归纳为下表维度经典 Mary-TTS 服务器Coqui-TTS 兼容端点/locales列出全部已安装 locale只返回当前活跃模型的单一 locale/voices列出全部已安装语音只返回当前模型名作为唯一 voice/process参数接受LOCALE、VOICE等并据此选择资源仅使用INPUT_TEXT其余参数忽略性别字段传统f/m固定uCoqui-TTS 模型无性别定义输出格式按OUTPUT_TYPE/AUDIO参数恒定 WAV作者的结论是这属于可接受的折中——大多数用户本来就只关心某一个特定语音兼容层足以让存量工具直接切换过来API 未来可能扩展为同时支持多语言、多语音。这一判断也与源码中两处NOTE: We currently assume there is only one model active at the same time注释完全一致。六、验证与延伸阅读兼容端点源码TTS/server/server.py演示服务器启动方式与参数TTS/server/README.md推理主链路断句、合成、声码器、实时率统计TTS/utils/synthesizer.py主题原始文档docs/source/marytts.md。需要说明的适用前提Mary-TTS 端点与/api/tts一样运行在演示服务器上受全局锁串行化约束定位为“兼容替换”而非高并发生产网关/locales与/voices的信息仅反映启动时通过--model_name指定的那一个模型切换语音需要更换模型并重启服务器。理解了这些边界之后读者即可把 NVDA、openHAB 或 Rhasspy 一类工具的 Mary-TTS 服务端地址直接指向http://host:59125用文中三条 curl 命令完成自检。【免费下载链接】TTS - a deep learning toolkit for Text-to-Speech, battle-tested in research and production项目地址: https://gitcode.com/GitHub_Trending/tt/TTS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考