VoiceStudio 的 Supertonic-3 引擎:31 语言 CPU 端 ONNX 语音合成接入与 sidecar 隔离架构实战
【免费下载链接】VoiceStudioVoiceStudio is the open-source, fully-local ElevenLabs alternative — voice cloning, voice design, video dubbing, dictation, transcription & audiobook creation in 646 languages.项目地址: https://gitcode.com/GitHub_Trending/om/VoiceStudio
Supertonic-3 是 VoiceStudio 集成的一款约 9900 万参数、原生 44.1 kHz 采样率的 ONNX 语音合成(TTS)引擎,覆盖 31 种语言并提供 7 个预置音色。它完全面向 CPU 设计——上游 SDK 只有 ONNX Runtime CPU 执行提供方(Execution Provider),没有 CUDA 或 MPS 路径——且运行在独立的 sidecar 子进程中,冷启动与崩溃不会阻塞 VoiceStudio 的其余部分。读完本文,你将掌握该引擎的安装、许可接受、音色/参数用法、sidecar 通信协议、模型版本固定机制及其局限与排障方法。
何时选择 Supertonic-3
官方文档给出的选型依据有两条,二者都指向"无 GPU 但需要多语言朗读"的场景:
- 无可用 GPU 的机器上需要较广的语言覆盖:Supertonic-3 的 CPU-only 设计意味着它不依赖 CUDA 显卡,在纯 CPU 环境下即可工作。
- 需要比默认引擎更高采样率的预置音色旁白:其输出为原生 44.1 kHz,高于默认引擎的采样率档位。
需要注意的是,它不支持克隆与音色设计,因此需要克隆能力的配音(dub)/批量任务不会选择它。这一点同时体现在后端类属性上:supports_voice_design = False、supports_cloning = False(见 backend.py),generate()从不读取参考音频。
安装与启用:三种入口,互不干扰
文档给出的安装路径有三条,实际效果完全等价,可以按使用习惯选择:
方式一:在 VoiceStudio 环境内安装可选依赖
uv sync --extra supertonicpyproject.toml的[project.optional-dependencies]中声明了supertonic = ["supertonic==1.3.1", ...]这一可选项(见 pyproject.toml)。测试 test_optional_dep_pin 会校验该 extra 存在且版本锁定为 1.3.1(或回退版本 1.2.3)。
方式二:在 Model Catalogue → Supertonic-3 中一键安装
界面中的Install按钮会把同一个锁定版本 wheel 安装到引擎自己的 Python 环境中,该环境位于 VoiceStudio 数据目录下。这样做的隔离性收益是:它安装的任何东西都不会触碰 VoiceStudio 本体或其他引擎,同行的Uninstall也只删除那一份目录。此前用uv sync装的版本不受影响、继续可用。
从源码看,两种方式在运行期是兼容的:Supertonic3Backend.venv_python() 会优先选择一键安装器创建的独立 venv(通过OMNIVOICE_SUPERTONIC3_DIR环境变量定位,见 backend.py),找不到时才回退到父进程解释器——也就是uv sync --extra supertonic填充的那个环境。测试 test_prefers_the_venv_its_one_click_install_made 验证了这条优先级逻辑。
方式三:环境变量切换后端
export OMNIVOICE_TTS_BACKEND=supertonic3该变量由 services/tts_backend.py 读取,默认值为"omnivoice"。引擎注册在_LAZY_REGISTRY中(tts_backend.py),首次访问时才懒加载engines.supertonic3.Supertonic3Backend。
依赖关系说明:与需要独立 venv 的 IndexTTS(因
transformers<5版本钉住)不同,Supertonic-3 的传递依赖(onnxruntime、numpy、soundfile、huggingface_hub)在 OmniVoice 父环境中已有兼容版本,子进程隔离在此处是为了与 SubprocessBackend 模式保持"对称",从而把崩溃/泄漏限制在子进程内,而不是为了依赖隔离(见 backend.py 与init.py)。
接受许可:首次使用的前置门槛
首次使用被一道显式接受对话框拦截:推理 SDK 代码是 MIT 许可,但模型权重是 OpenRAIL-M,带有使用限制条款。在Model Catalogue → Supertonic-3中审阅并接受之前,引擎一直保持不可用状态。
底层实现是一把持久化在加密 SQLite 设置存储中的布尔开关。settings_store提供了get_license_accepted(engine_id)/set_license_accepted(engine_id, accepted)辅助函数(见 settings_store.py),键名形如"<engine_id>_license_accepted";constants.py 中定义了LICENSE_ACCEPTED_KEY = "supertonic3_license_accepted"作为规范化引擎 id。前端的SupertonicLicenseDialog在用户审阅 MIT(代码)与 OpenRAIL-M(模型)条款后,通过POST /settings/license置位。
Supertonic3Backend.is_available() 的可用性判断分三步:
- 可选依赖门禁:若无独立 venv,尝试
import supertonic,失败则返回(False, "supertonic package not installed. Install it from Model Catalogue."); - 许可门禁:读
settings_store.get_license_accepted("supertonic3"),未接受则返回(False, "Supertonic-3 license not accepted. Open Model Catalogue → Supertonic-3 and click Accept to enable. ...")。SQLite 读取失败会被捕获并当作未接受处理,不会让异常扩散(纵深防御); - 诚实的硬件上报:返回
(True, "ready (CPU-only via onnxruntime)")。
测试 test_license_gate 验证了"未接受 → False,接受后 → True"的行为,并断言提示信息必须指向 Model Catalogue 中的 Accept 按钮;test_cpu_only_honest 则断言is_available()的返回消息必须包含"cpu"且绝不包含"cuda"/"mps",同时gpu_compat == ("cpu",)。
首次合成:约 400 MB 冷下载与版本固定
首次合成会冷下载约 400 MB 的模型权重,并固定到精确的 HuggingFace revision SHA,确保拿到的字节与 SDK 验证时完全一致。这个 SHA 只出现在一个地方:constants.py 中的PINNED_REVISION_SHA = "724fb5abbf5502583fb520898d45929e62f02c0b"。该 SHA 与supertonic==1.3.1内部MODEL_CONFIGS["supertonic-3"]["revision"]的默认值一致,是 Supertone 官方的 "Initial Supertonic 3 release" 提交。
下载通过huggingface_hub.snapshot_download(repo_id="Supertone/supertonic-3", revision=PINNED_REVISION_SHA)完成(见 sidecar.py),该调用幂等且遵循已转发的HF_HUB_CACHE/HF_HOME/HF_ENDPOINT环境变量。父进程在 spawn 前还会通过SUPERTONIC3_REVISION环境变量把同一 SHA 注入给 sidecar,形成纵深防御(backend.py)。
测试侧有相应的保障:test_pinned_sha_format断言 SHA 是 40 位小写十六进制(test_supertonic3.py);test_sha_resolves(网络门控)通过 HF API 验证该 SHA 真实存在于提交日志;sidecar 的_resolve_pinned_sha()在无环境变量时可独立从 in-tree 常量回退,测试 test_sidecar_resolves_its_pin_without_the_app_backend 验证了这条回退路径。
如需滚动升级固定版本,仓库提供了 scripts/resolve_supertonic3_sha.py:
# 只打印候选 SHA,不修改任何文件 uv run python scripts/resolve_supertonic3_sha.py --dry-run # 写入候选 SHA 到 constants.py(仅在变更时) uv run python scripts/resolve_supertonic3_sha.py # 跳过 ".onnx / tokenizer" 启发式过滤 uv run python scripts/resolve_supertonic3_sha.py --no-filter脚本会从main分支最新的 25 个提交中挑选其文件树包含.onnx或tokenizer.json的最近一次提交,以过滤掉 README 润色、示例音频等不改变推理行为的提交;--dry-run在候选与当前 pin 相同时返回退出码 2(信息性,非失败)。
预置音色
VoiceStudio 对外暴露 7 个预置音色:M1(默认)、M3、M4、M5、F3、F4、F5。SDK 本身接受完整的M1–M5/F1–F5十种,若调用方显式传入全集中的其他 id 也可用;未知 id 会回退到默认音色并打印一条日志。
这份清单定义在 constants.py:VOICE_PRESETS = ["M1", "M3", "M4", "M5", "F3", "F4", "F5"],DEFAULT_VOICE = "M1"。在 Supertonic3Backend.generate() 中,未知音色会先记录unknown voice %r, falling back to %r的 info 日志再回退;sidecar 端tts.get_voice_style(voice_name=voice)对未知音色抛出ValueError,作为第二层防线(sidecar.py)。
行为细节与参数约束
官方文档列出的行为要点,在源码中均有对应实现:
- 输出为 44.1 kHz 单声道:常量
SAMPLE_RATE = 44100(constants.py),sidecar 的 ready 帧会通告sample_rate: 44100(sidecar.py)。 - 长驻 sidecar:运行在自己的环境中(一键安装)或 VoiceStudio 环境中(
uv sync --extra supertonic)。后续调用复用同一个进程与内存中的 ONNX session——模型在首次 synthesize 时惰性加载并缓存为模块级单例_tts(sidecar.py)。 speed钳制在 0.7–2.0:backend.py 中speed = max(0.7, min(2.0, speed)),默认 1.0。- quality steps(质量步数)钳制在 5–12:对应
num_step(SDK 的total_steps),backend.py 中total_steps = max(5, min(12, total_steps)),默认 8。 - 语言为 ISO 639-1 码;
Auto会启用 SDK 的多语言回退。sidecar 的_normalize_lang()把"auto"、""、None统一映射为"na"(语言无关),其他输入取前两位小写(sidecar.py)。后端对外暴露的supported_languages是["multi"](backend.py),在合成时翻译调用方的语言。
generate()最终向 sidecar 转发的参数为:voice、lang、speed、total_steps(backend.py),由基类SubprocessBackend.generate完成 JSON 往返、GPU 槽位获取/释放与 int16 PCM 解码。
sidecar 通信协议
Supertonic-3 使用与 Phase 2SubprocessBackend逐字节一致的长度前缀 JSON over stdio协议(sidecar.py):
[ 4 字节大端 uint32 长度 ][ N 字节 UTF-8 JSON ]典型流程:
- sidecar 启动后立即发送
{"op": "ready", "engine": "supertonic3", "sample_rate": 44100, "version": "<sdk-version>"}——此时模型尚未加载,模型加载被推迟到首次 synthesize 之前,以保证 ready 帧能落在SPAWN_READY_TIMEOUT_S握手超时内(sidecar 在 import 时仅使用标准库,SDK 与 numpy 在首次 synthesize 时才惰性引入)。 - 可选:父进程发送
{"op": "ping"}→ sidecar 回复{"op": "pong"}。 - 父进程发送
{"op": "synthesize", "text": "...", "voice": "M1", "lang": "en", "speed": 1.0, "total_steps": 8};首次调用可能先收到若干{"op": "progress", "stage": "loading_model", "percent": N}帧(0/50/100,覆盖约 400 MB 下载延迟);随后 sidecar 返回{"op": "audio", "audio_pcm_b64": "<base64 int16>", "sample_rate": 44100, "n_samples": N}。 {"op": "shutdown"}→ 退出码 0;未知 op 返回{"op": "error", "stage": "dispatch", "message": "unknown op: <op>"}并继续循环。
单帧大小上限MAX_FRAME_BYTES = 64 * 1024 * 1024与父进程保持一致,超限的畸形帧会以干净的IOError呈现而非内存耗尽(sidecar.py)。每 op 级别的失败是可恢复的:sidecar 发送 error 帧后保持存活,父进程无需付出重生成与模型重载的代价即可重试(sidecar.py)。
值得一提的实现细节是 stdout 隔离:sidecar 在启动时先os.dup(1)复制出一个私有的帧通道 fd,再os.dup2(2, 1)把 fd 1 指向 stderr——这样 wetextprocessing 的 FST 日志、tqdm 进度条、原生打印等库噪声全部进入 stderr(父进程会排水并经过 HF token 脱敏过滤器),帧流不会被污染(sidecar.py)。回归测试 test_sidecar_stdout_isolation_1428.py 覆盖了这条路径。
音频回传前还有一道通道感知的下混处理:float32 数组被 squeeze 后,若维度仍大于 1,则沿尺寸最小的轴做 mean 下混,避免对 channels-last 数组沿时间轴平均而破坏波形(sidecar.py,对应修复 #1328)。
已知限制
- 无克隆、无音色设计:只有预置音色。需要克隆的配音/批量任务不会选中它。
- 仅 CPU:硬件加速是上游 SDK 的属性,而非 VoiceStudio 的限制。SDK 未提供 CUDA / MPS 路径,sidecar 甚至完全不 import torch,也不会查询
torch.cuda——诚实上报是"内置"的,不存在可误报的内容(sidecar.py)。 - OpenRAIL-M 权重不受 VoiceStudio 通用商业使用声明的覆盖:请在接受对话框中审阅模型许可条款(MIT 代码 + OpenRAIL-M 模型,许可链接见 constants.py)。
- onnxruntime 双安装风险被显式防住:
uv.lock中必须恰好存在一条onnxruntime记录且不允许onnxruntime-gpu,否则未来引擎引入 GPU 构建会导致 CPU/GPU 双装并在 import 时告警。测试 test_lockfile_no_onnxruntime_double_install 与 smoke 测试中的uv pip list检查双重保障。
排障
- "supertonic package not installed":运行上文
uv sync --extra supertonic,或从 Model Catalogue 启用。is_available()的未安装提示会提及 "Install it from Model Catalogue"(backend.py)。 - "license not accepted":打开Model Catalogue → Supertonic-3并点击接受。测试 test_optional_dep_missing 同时覆盖了依赖缺失分支的提示语。
- 其他问题:参见 install/troubleshooting.md;sidecar 自身还提供自检模式
python -m engines.supertonic3.sidecar --selftest(在 backend 目录下运行),用于发布准备阶段验证 wheel + 固定 SHA 仍可解析——该路径因涉及 400 MB 下载而受OMNIVOICE_SMOKE=1门控,测试 test_sidecar_selftest 覆盖之。
相关参考
- downloading-models.md:模型下载与缓存机制
- benchmarks.md:各引擎基准数据
- languages.md:语言支持总览
- expressive-speech.md:表现力语音说明
- disk-usage.md:引擎磁盘占用说明
【免费下载链接】VoiceStudioVoiceStudio is the open-source, fully-local ElevenLabs alternative — voice cloning, voice design, video dubbing, dictation, transcription & audiobook creation in 646 languages.项目地址: https://gitcode.com/GitHub_Trending/om/VoiceStudio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考