OddTTS更新:集成MOSS-TTS-Nano 0.1B ONNX,纯CPU实时语音克隆与20种语言支持

引言

几天前,经 Kid 大佬指点,有两个可以纯 CPU 跑的轻量级TTS模型:MOSS-TTS-Nano 0.1B ONNX(100M)模型 和 ZipVoice Sherpa ONNX(123M)模型。具体可以看上周这篇文章里 Kid 大佬的留言

今天周末了,我去网上看了一下这两个模型,看上去的样子感觉的确不错,鉴于 100M < 123M,我就先把 MOSS-TTS-Nano先给整合了一下到 OddTTS。

MOSS-TTS-Nano 是 OpenMOSS 团队推出的开源多语言微型语音生成模型。仅 0.1B 参数,无需 GPU 即可在普通 CPU 上实时运行,支持语音克隆、流式推理和 ONNX 加速。------ OpenMOSS 官方介绍

相比于上周集成的 Audio8(0.1B RTF 约 3.26x),MOSS-TTS-Nano 在 CPU 上的推理效率明显更高:在禁用文本规范化的极速模式下,RTF 可达到约 0.5 ,这意味着它已经能够胜任类似 小落同学 这样的低延迟实时对话场景。同时,它支持近 20 种语言48 kHz 立体声 输出,音质和语言覆盖度都非常出色。

本次更新已提交至 GitHub,版本号升级至 v1.3.27,默认引擎也切换为 ODDTTS_MOSS_NANO。下面我将从模型概览、技术挑战、性能对比和代码实现等角度,详细解析这次集成。

快速开始使用 OddTTS

OddTTS 是一个功能强大的多引擎语音合成服务,提供统一的 API 接口和友好的 Web 界面,一套接口搞定多种主流 TTS 引擎,包括 EdgeTTSKokoro-82M-v1.1-zhAudio8ChatTTSBert-VITS2GptSovits v2MOSS-TTS-Nano 等,同时也支持 OpenAI TTS API 的调用。

  • 仓库: https://github.com/oddmeta/oddtts
  • 版本: v1.3.27
  • 安装: pip install oddtts
  • 运行: oddtts
  • 演示: http://localhost:9001

Python 测试

python 复制代码
import openai
client = openai.OpenAI(base_url="http://localhost:9001/v1", api_key="dummy")
response = client.audio.speech.create(input="你好,欢迎使用 OddTTS 小奥语音合成服务。")

curl 测试

bash 复制代码
curl http://127.0.0.1:9001/v1/audio/speech -H "Content-Type: application/json" -d "{\"input\": \"你好,欢迎使用 OddTTS 小奥语音合成服务。\"}" --output speech.mp3

直接听合成的效果

以下音频由 OddTTS 调用 MOSS-TTS-Nano 0.1B ONNX 引擎合成(48 kHz 立体声):

  • oddtts-20260904-mosstts-nano-100m-onnx.wav

    这个声音总觉得有点。。。不知道怎么描述。。。

  • oddtts-20260904-mosstts-nano-中英混合-超长停顿问题.mp3

    在前面的中文和后面的英文中间出现一个长停顿,不确定原因是什么。

一、MOSS-TTS-Nano 模型概览

1.1 基本信息

特性 MOSS-TTS-Nano 0.1B ONNX
团队 OpenMOSS(复旦大学 NLP 实验室 + MOSI.AI
参数量 ~0.1B(约 1 亿参数)
模型文件大小 不到 300 MB
架构 Audio Tokenizer + LLM 纯自回归
音频分词器 MOSS-Audio-Tokenizer-Nano(2000万参数)
量化方式 ONNX FP16 / INT8(Runtime 自动适配)
采样率 48000 Hz 立体声
支持语言 近 20 种
硬件要求 4 核 CPU 即可流畅运行,无需 GPU
开源协议 Apache 2.0

1.2 核心技术架构

MOSS-TTS-Nano 采用创新的 Audio Tokenizer + LLM 纯自回归流水线:

  1. 文本预处理:输入文本经文本正则化与分词处理(可选 WeTextProcessing 进行中文数字读法规范化)。
  2. 音频编码:参考音频(提示语音)经音频分词器编码为离散 Token 流。
  3. 自回归生成:轻量级语言模型以文本 Token 和音频 Token 为条件,自回归生成音频 Token。
  4. 音频解码 :音频分词器解码器将 Token 流实时还原为 48 kHz、双声道 波形。

其中,MOSS-Audio-Tokenizer-Nano 音频分词器仅 2000 万参数,支持将 48 kHz 立体声音频压缩为 12.5 Hz 的 token 流,采用 RVQ(残差向量量化)和 16 个码本,是高保真音频压缩的关键。

1.3 支持的近 20 种语言

MOSS-TTS-Nano 支持以下语言(部分列举):

语言 代码 语言 代码 语言 代码
中文 zh 英语 en 德语 de
西班牙语 es 法语 fr 日语 ja
意大利语 it 韩语 ko 俄语 ru
阿拉伯语 ar 波兰语 pl 葡萄牙语 pt
捷克语 cs 丹麦语 da 瑞典语 sv
希腊语 el 土耳其语 tr 匈牙利语 hu
波斯语 fa ...

1.4 ONNX 版本的优势

OddTTS 选择的是 ONNX 版本 而非 PyTorch 版本,原因如下:

维度 PyTorch 版 ONNX 版
推理框架 PyTorch ONNX Runtime
深度学习环境 需要 PyTorch 全家桶 无需 PyTorch 依赖
CPU 部署 可以运行 更适合、效率更高
推理效率 基准 约为 PyTorch 版的 2 倍
部署体积 大(含 PyTorch) 更轻量
集成难度 较高 较低,更易嵌入软件

二、技术挑战与解决方案

2.1 外部仓库依赖与 Vendoring

问题 :MOSS-TTS-Nano 的推理依赖其官方仓库中的 onnx_tts_runtime 模块,但该模块并未发布到 PyPI,直接 pip install 无法获得。

解决方案 :在 setup.py 中自定义 build_py 命令,在构建 wheel 时自动将 moss-tts-nano 仓库 vendoring 到 oddtts/vendor/moss-tts-nano/ 目录下:

python 复制代码
class build_py(_build_py):
    def run(self):
        super().run()
        self._vendor_moss_nano()

    def _vendor_moss_nano(self):
        # 优先使用本地已有的源码,否则 git clone
        # 复制时排除 models/、__pycache__/ 等大目录
        ignore = shutil.ignore_patterns(
            "models", "__pycache__", "*.egg-info",
            "generated_audio", ".cache", ".git",
            "*.onnx", "*.data", "*.wav",
        )
        shutil.copytree(src, dst, ignore=ignore, dirs_exist_ok=True)

这样,用户通过 pip install oddtts 安装后,onnx_tts_runtime 模块即可通过 oddtts/vendor/moss-tts-nano/ 自动导入,无需手动克隆仓库。

2.2 模型下载双源策略

模型下载顺序:ModelScope → HuggingFace

考虑到 OddTTS 主要面向国内用户,MOSS-TTS-Nano 的两个 ONNX 模型均优先从 ModelScope 下载,失败则自动回退 HuggingFace:

模型 ModelScope HuggingFace
TTS 模型 openmoss/MOSS-TTS-Nano-100M-ONNX OpenMOSS-Team/MOSS-TTS-Nano-100M-ONNX
Codec 模型 openmoss/MOSS-Audio-Tokenizer-Nano-ONNX OpenMOSS-Team/MOSS-Audio-Tokenizer-Nano-ONNX

2.3 Windows 下 WeTextProcessing 的编译依赖

问题 :MOSS-TTS-Nano 支持通过 WeTextProcessing 进行中文文本规范化(如将阿拉伯数字转为中文读法),但 WeTextProcessing 依赖 pynini,而 Windows 上没有预编译的 pynini wheel,直接 pip install 会因缺少 MSVC 编译器而失败。

解决方案

  1. 在 OddTTS 的 tts_moss_nano.py 中,将 WeTextProcessing 设为可选依赖:即使未安装,合成依然能正常运行,只是缺少中文数字读法规范化。
  2. 在测试脚本 tests/test_moss-tts_0_1b_onnx.py 中,针对 Windows 自动尝试通过 conda-forge 安装预编译的 pynini
bash 复制代码
conda install -c conda-forge pynini=2.1.6.post1 -y
pip install WeTextProcessing

2.4 Runtime 初始化与模块路径处理

问题 :从源码运行时,onnx_tts_runtime 模块可能位于 tests/moss-tts-nano/moss-tts-nano/ 目录;而通过 pip 安装后,它位于 oddtts/vendor/moss-tts-nano/ 目录。需要兼容这两种场景。

解决方案 :在 MossNanoAPI._init_runtime() 中,优先从 pip 安装后的 vendoring 目录导入,并动态插入 sys.path;若未找到,则给出明确的错误提示和操作指引。

三、性能对比测试

3.1 测试环境

  • 测试文本: 55 字中文文本(含中英混读)
  • 测试条件: 纯 CPU,WAV 格式
  • 硬件环境: 普通 PC(无 GPU)
  • 引擎版本: OddTTS v1.3.27

3.2 性能数据

引擎 采样率 文本长度 合成耗时 音频时长 RTF(实时率)
Kokoro v1.1 24000 Hz 55字 2.68秒 8.18秒 0.33
MOSS-TTS-Nano ONNX 48000 Hz 55字 10.59秒 9.20秒 1.15
MOSS-TTS-Nano ONNX 极速模式 48000 Hz 55字 ~4.6秒 9.20秒 ~0.50
Audio8 0.1B ONNX INT8 44100 Hz 55字 27.85秒 8.54秒 3.26

极速模式 参数:sample_mode=greedydo_sample=False,关闭 WeTextProcessing,启用多线程(最多 8 线程)。

测试数据

MOSS-TTS-Nano ONNX 基础合成速度(48kHz)

bash 复制代码
ONNX 基础合成             10.59s   9.20s   1.15x
ONNX 语音克隆             12.07s  10.40s   1.16x
  ONNX 中文               10.57s   9.20s   1.15x
  ONNX 英文               11.23s  10.40s   1.08x
  ONNX 日文               15.21s  18.32s   0.83x
  ONNX 韩文               10.54s   9.04s   1.17x

3.3 性能分析

MOSS-TTS-Nano ONNX(标准模式)

  • 合成速度约为 Audio8 0.1B 的 3 倍快(RTF 1.15 vs 3.26)。
  • 比 Kokoro v1.1 慢约 3.5 倍(RTF 1.15 vs 0.33),但采样率更高(48kHz vs 24kHz),且支持语音克隆和多语言。

MOSS-TTS-Nano ONNX(极速模式)

  • RTF 约 0.5,已经非常接近实时,可用于低延迟场景如语音助手、实时对话。
  • 牺牲了一部分采样多样性(greedy 解码),但在实际听感上差异不大。

Audio8 0.1B ONNX INT8

  • 虽然同样支持多语言和语音克隆,但 RTF 高达 3.26,难以用于实时场景,更适合离线批处理。

四、代码实现细节

4.1 引擎注册与调度

oddtts_params.py 中新增枚举值:

python 复制代码
class ODDTTS_TYPE(Enum):
    ODDTTS_MOSS_NANO = 10

    @property
    def description(self):
        return {
            self.ODDTTS_MOSS_NANO: 'MOSS-TTS-Nano 0.1B ONNX - OpenMOSS 轻量级多语言TTS(纯CPU,近20种语言,48kHz)'
        }

base_tts_driver.py 中注册策略:

python 复制代码
from .tts_moss_nano import MossNanoAPI

def get_strategy(self, tts_type: ODDTTS_TYPE) -> BaseTTS:
    tts = BaseTTS()
    elif tts_type == ODDTTS_TYPE.ODDTTS_MOSS_NANO:
        tts.client = MossNanoAPI()
        return tts

4.2 合成参数配置

MossNanoAPI 使用 OnnxTtsRuntime.synthesize() 进行合成,关键参数如下:

python 复制代码
self.runtime.synthesize(
    text=text,
    voice=voice,          # 当前仅内置 "Junhao"
    output_audio_path=tmp_path,
    sample_mode="fixed",  # 或 "greedy" 用于极速模式
    do_sample=True,       # False 可进一步加速
    streaming=True,
    enable_wetext=has_tn,           # 是否启用中文文本规范化
    enable_normalize_tts_text=has_tn,
)

注意TTSParams 中的 ratevolumepitch 参数对 MOSS-TTS-Nano 引擎无效,仅 voiceresponse_format 有效。

4.3 流式生成实现

虽然 generate_tts_stream() 方法返回的是异步生成器,但受限于底层 OnnxTtsRuntime 的同步 API,当前实现是先完整合成音频,再作为单个 chunk 返回

python 复制代码
async def generate_tts_stream(self, text: str, tts_params: TTSParams):
    audio_numpy = self._synthesize(text, tts_params)  # 先完整合成
    audio_data = convert_audio_format(...)
    yield audio_data  # 再返回结果

这是因为 ONNX Runtime 目前返回的是完整音频数组。后续如果官方支持真正的流式 token 输出,OddTTS 可以进一步实现低延迟的逐段返回。

五、实际应用指南

5.1 安装与配置

bash 复制代码
# 安装 OddTTS(会自动包含 MOSS-TTS-Nano 的 vendoring 依赖)
pip install oddtts

# 启动服务(首次启动会自动下载 ONNX 模型)
oddtts

如果希望启用中文文本规范化(数字读法优化),额外执行:

bash 复制代码
conda install -c conda-forge pynini=2.1.6.post1 -y
pip install WeTextProcessing

5.2 切换引擎

在 Web 界面或配置文件中切换默认引擎:

python 复制代码
# oddtts_config.py
"tts_type": ODDTTS_TYPE.ODDTTS_MOSS_NANO,

5.3 API 调用示例

python 复制代码
import requests

# 生成语音文件
response = requests.post("http://localhost:9001/v1/audio/speech", json={
    "input": "欢迎使用 MOSS-TTS-Nano 语音合成系统",
    "voice": "Junhao",
    "response_format": "wav",
    "model": "oddtts-moss-nano"
})

# 保存音频文件
with open("output.wav", "wb") as f:
    f.write(response.content)

5.4 独立测试脚本

OddTTS 项目也提供了独立的测试脚本,无需启动服务端即可验证 MOSS-TTS-Nano:

bash 复制代码
conda activate oddtts
python tests/test_moss-tts_0_1b_onnx.py

该脚本会自动:

  1. 克隆 MOSS-TTS-Nano 官方仓库(如未安装)
  2. 安装 ONNX 最小依赖(跳过 PyTorch)
  3. 下载 ONNX 模型(优先 ModelScope)
  4. 执行基础合成、语音克隆、多语言、CLI 生成等测试项

六、总结与展望

6.1 本次更新的意义

  1. 实时场景突破:MOSS-TTS-Nano 在极速模式下 RTF 约 0.5,标志着 OddTTS 首次拥有能在普通 CPU 上接近实时运行的语音克隆引擎,填补了 Audio8 在实时性上的不足。
  2. 多语言与音质兼得:支持近 20 种语言,输出 48 kHz 立体声,在语言覆盖度和音质上都达到了较高水准。
  3. 部署简化 :通过 setup.py 的自定义 vendoring 机制,用户无需手动克隆仓库或配置复杂环境,pip install oddtts 即可获得完整功能。
  4. 生态扩展:为 OddTTS 增加了又一款重量级引擎,与 Kokoro(极速中文)、Audio8(高质多语言离线)、MOSS-TTS-Nano(实时语音克隆)形成互补。

6.2 性能权衡

  • Kokoro v1.1:RTF 最低(0.33),中文场景首选,但不支持语音克隆。
  • MOSS-TTS-Nano ONNX 极速模式:RTF ~0.5,支持语音克隆 + 20 种语言,实时场景首选。
  • MOSS-TTS-Nano ONNX 标准模式:RTF ~1.15,音质更自然,适合对延迟不敏感的在线服务。
  • Audio8 0.1B/0.6B:音质和语言支持同样优秀,但 RTF 较高(3.26~4.93),适合离线批处理。

6.3 后续优化方向

  1. 真流式输出:等待 MOSS-TTS-Nano 官方支持逐 token 流式解码,进一步降低首音延迟。
  2. 更多预设音色 :当前仅内置 Junhao 一个音色,后续可通过参考音频扩展更多预设音色列表。
  3. 参数暴露 :将 sample_modedo_sampletemperature 等生成参数通过 API 暴露,供用户按需调节。
  4. GPU 加速 :虽然定位纯 CPU,但后续可探索 onnxruntime-gpu 后端,进一步压榨性能。

6.4 社区贡献

欢迎开发者参与 OddTTS 的开发和优化:

结语

MOSS-TTS-Nano 的集成是 OddTTS 在「轻量级、纯 CPU、实时语音克隆」方向上的一次重要尝试。0.1B 参数却能输出 48 kHz 立体声、支持近 20 种语言、实现 RTF 0.5 的实时推理,这让我们看到了小模型在端侧和实时场景中的巨大潜力。期待更多开发者加入,共同推动语音合成技术的普及与落地。


相关资源

相关推荐
iwgh3 天前
OddTTS更新:纯CPU支持11种语言的语音合成!
语音合成·tts·kokoro·oddtts·audio8
hey you~5 天前
大模型语音机器人会话链路深度解析:从ASR识别到智能应答的完整技术拆解
语音合成·多轮对话·实时语音交互·大模型语音机器人·会话链路
angushine5 天前
qwen3-tts使用实例
python·tts
谢白羽12 天前
vLLM-Omni 部署 IndexTTS 2.5
llm·agent·tts·vllm·大模型部署
贾伟康13 天前
【中国方言题库|10】HarmonyOS ArkTS 语音播放实战:管理读音播放与页面生命周期
生命周期·harmonyos·arkts·语音合成·texttospeech
uncle_ll15 天前
数字人JoyVASA 实战记录
图像处理·数字人·语音合成
贾伟康16 天前
【中国方言题库|04】HarmonyOS ArkTS 粤语分库实战:处理繁简文本、读音与练习入口
harmonyos·arkts·unicode·tts·arkui
贾伟康20 天前
【知律|08】HarmonyOS ArkTS 语音阅读实战:管理法条朗读状态和中断恢复
生命周期·harmonyos·arkts·语音合成·arkui
熊猫钓鱼>_>24 天前
AI 3D 虚拟盲盒工坊:用腾讯云混元3D + TTS Skills 打造会说话的三维收藏品
人工智能·大模型·llm·agent·tts·混元3d·多skill协同