超级紧凑型支持多语言ONNX(20MB)模型

部署运行你感兴趣的模型镜像

SpeechTTS: 高效的ONNX推理文本转语音系统

在这里插入图片描述
在这里插入图片描述

前言

作者:CrazyNET

概述

SpeechTTS 是一个轻量级、高效的文本转语音 (TTS) 系统,基于 SAMBERT-HiFiGAN 架构,优化用于 ONNX 运行时推理。它将原始中文文本转换为自然发音的语音,使用预训练模型导出为 ONNX 格式。该系统利用 KAN-TTS 框架进行语言处理和声学建模,并结合 HiFiGAN 生成高保真波形。

该项目专注于低延迟推理,适用于实时应用,如虚拟助手、有声读物或配音。它支持情感语音合成(例如,使用 “zhizhe_emo” 声音),并且可以轻松扩展到其他声音或语言。

主要特性

  • 输入:原始中文文本(例如,“你好,我是智能助手。”)
  • 输出:音频波形(16kHz 采样率,单声道)
  • 模型大小:紧凑的 ONNX 模型(~10-20MB,取决于导出)
  • 推理速度:CPU 上实时能力(例如,现代硬件上 ~0.5-1x RTF);GPU 上更快
  • 情感支持:在情感数据集上预训练,用于富有表现力的语音
  • 自定义:通过配置文件轻松切换声音或调整参数

安装

先决条件

  • Python 3.8+
  • ONNX Runtime: pip install onnxruntime (或 onnxruntime-gpu 以支持 CUDA)
  • PyTorch: pip install torch (用于加载 SAMBERT)
  • 其他依赖: pip install pyyaml librosa numpy sounddevice ttsfrd (ttsfrd 用于前端处理)
  • 环境:推荐使用虚拟环境,如 Conda 或 venv。

依赖项

absl-py==2.3.1
addict==2.4.0
aiohappyeyeballs==2.4.4
aiohttp==3.10.11
aiosignal==1.3.1
alias-free-torch==0.0.6
aliyun-python-sdk-core==2.16.0
aliyun-python-sdk-kms==2.16.5
annotated-types==0.7.0
antlr4-python3-runtime==4.9.3
async-timeout==5.0.1
attrs==25.3.0
audioread==3.0.1
autopep8==2.3.1
bitarray==3.6.0
bitstring==4.3.1
cachetools==5.5.2
certifi==2025.8.3
cffi==1.17.1
cfgv==3.4.0
charset-normalizer==3.4.2
click==8.1.8
coloredlogs==15.0.1
contourpy==1.1.1
crcmod==1.7
cryptography==45.0.6
cycler==0.12.1
datasets==3.1.0
decorator==5.2.1
dill==0.3.8
Distance==0.1.3
distlib==0.4.0
editdistance==0.8.1
einops==0.8.1
espnet-tts-frontend==0.0.3
et_xmlfile==2.0.0
filelock==3.16.1
flatbuffers==25.2.10
fonttools==4.57.0
frozenlist==1.5.0
fsspec==2024.9.0
funasr==1.2.6
g2p==2.2.2
g2p-en==2.1.0
google-auth==2.40.3
google-auth-oauthlib==1.0.0
greenlet==3.1.1
grpcio==1.70.0
h5py==3.11.0
hdbscan==0.8.40
hf-xet==1.1.7
huggingface-hub==0.34.3
humanfriendly==10.0
hydra-core==1.3.2
HyperPyYAML==1.2.2
identify==2.6.1
idna==3.10
importlib_metadata==8.5.0
importlib_resources==6.4.5
inflect==7.0.0
jaconv==0.4.0
jamo==0.4.1
jedi==0.19.2
jieba==0.42.1
Jinja2==3.1.6
jmespath==0.10.0
joblib==1.4.2
kaldiio==2.18.1
-e git+https://github.com/modelscope/KAN-TTS.git@66202d052189a3dcca5f75c718c47a7a5cc68116#egg=kantts
kiwisolver==1.4.7
kwsbp==0.1.0
lazy_loader==0.4
librosa==0.10.1
llvmlite==0.41.1
local-attention==1.10.0
lxml==6.0.0
Markdown==3.7
markdown-it-py==3.0.0
MarkupSafe==2.1.5
matplotlib==3.7.5
mdurl==0.1.2
MinDAEC==0.1.0
mir_eval==0.8.2
modelscope==1.24.1
mpmath==1.3.0
ms-funcodec==0.2.0
msgpack==1.1.1
multidict==6.1.0
multiprocess==0.70.16
munkres==1.1.4
networkx==3.1
nltk==3.9.1
nodeenv==1.9.1
numba==0.58.1
numpy==1.24.4
nvidia-cublas-cu12==12.1.3.1
nvidia-cuda-cupti-cu12==12.1.105
nvidia-cuda-nvrtc-cu12==12.1.105
nvidia-cuda-runtime-cu12==12.1.105
nvidia-cudnn-cu12==9.1.0.70
nvidia-cufft-cu12==11.0.2.54
nvidia-curand-cu12==10.3.2.106
nvidia-cusolver-cu12==11.4.5.107
nvidia-cusparse-cu12==12.1.0.106
nvidia-nccl-cu12==2.20.5
nvidia-nvjitlink-cu12==12.9.86
nvidia-nvtx-cu12==12.1.105
oauthlib==3.3.1
omegaconf==2.3.0
onnx==1.17.0
onnxruntime==1.19.2
onnxsim==0.4.36
openpyxl==3.1.5
oss2==2.19.1
packaging==25.0
pandas==2.0.3
panphon==0.20.0
parso==0.8.4
pexpect==4.9.0
phaseaug==1.0.1
pickleshare==0.7.5
pillow==10.4.0
platformdirs==4.3.6
pooch==1.8.2
pre-commit==3.5.0
prompt_toolkit==3.0.51
propcache==0.2.0
protobuf==5.29.5
ptflops==0.7.3
ptyprocess==0.7.0
py-sound-connect==0.1.0
pyarrow==17.0.0
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycodestyle==2.12.1
pycparser==2.22
pycryptodome==3.23.0
pydantic==2.8.2
pydantic_core==2.20.1
Pygments==2.19.2
pynndescent==0.5.13
pyparsing==3.1.4
pypinyin==0.44.0
python-dateutil==2.9.0.post0
pytorch-wavelets==1.3.0
pytorch-wpe==0.0.1
pytz==2025.2
PyWavelets==1.4.1
PyYAML==6.0.2
regex==2024.11.6
requests==2.32.4
requests-oauthlib==2.0.0
resampy==0.4.3
rich==14.1.0
rotary-embedding-torch==0.8.9
rsa==4.9.1
ruamel.yaml==0.18.14
ruamel.yaml.clib==0.2.8
safetensors==0.5.3
scikit-learn==1.3.2
scipy==1.10.1
sentencepiece==0.2.0
simplejson==3.20.1
six==1.17.0
sortedcontainers==2.4.0
sounddevice==0.5.2
soundfile==0.13.1
sox==1.5.0
soxr==0.3.7
speechbrain==1.0.3
sympy==1.13.3
tensorboard==2.14.0
tensorboard-data-server==0.7.2
tensorboardX==2.6.2.2
text-unidecode==1.3
thop==0.1.1.post2209072238
threadpoolctl==3.5.0
tokenizers==0.20.3
tomli==2.2.1
torch==2.4.0
torch-complex==0.4.4
torchaudio==2.4.0
torchvision==0.19.0
tqdm==4.67.1
traitlets==5.14.3
transformers==4.46.3
triton==3.0.0
ttsfrd==0.2.1
typeguard==2.13.3
typing_extensions==4.13.2
tzdata==2025.2
umap-learn==0.5.7
unicodecsv==0.14.1
Unidecode==1.4.0
urllib3==2.2.3
virtualenv==20.33.1
wcwidth==0.2.13
Werkzeug==3.0.6
xxhash==3.5.0
yarl==1.15.2
zipp==3.20.2

设置步骤

  1. 获取源码(公众号):

     cd SpeechTTS
    
  2. 安装依赖:

    pip install -r req.info
    

    (如果没有 req.info,请创建并添加上述包。)

  3. 下载模型:

    • 将预训练模型放置在 models/origins/Speech-Sambert-hifigan-TTS-16K/
    • 如果需要,使用 export.py 导出 ONNX 模型(见使用部分)。
  4. 提取资源:

    • models/origins/Speech-Sambert-hifigan-TTS-16K/ 中解压 resource.zip 以获取语言字典。

使用

快速开始

使用提供的 run.py 运行推理:

python run.py

这将处理样本文本 “你好,我是智能助手。” 并使用 sounddevice 播放音频。输出将被重采样到 48kHz 以便播放。

自定义推理

修改 run.py 以输入自定义文本:

audio = ort_model.ExecInfer(["您的自定义中文文本。"])
  • 播放音频:使用 sounddevice 进行实时播放。
  • 保存音频:添加保存逻辑,例如 import soundfile as sf; sf.write('output.wav', audio, 16000)

导出 ONNX 模型

使用 export.py 将 PyTorch HiFiGAN 转换为 ONNX:

python export.py
  • 输入:Mel 谱图(形状:[1, 80, T])
  • 输出:波形(形状:[1, 1, T * hop_length])

配置参数

配置从 YAML 文件加载(例如,SAMBERT 使用 am/config.yaml,HiFiGAN 使用 voc/config.yaml)。

关键 SAMBERT 参数 (am/config.yaml)
  • embedding_dim: 512(语言嵌入维度)
  • encoder_num_layers: 8(Transformer 编码器层)
  • decoder_num_layers: 12(Transformer 解码器层)
  • num_mels: 80(Mel 滤波器组)
  • outputs_per_step: 3(长度调节器因子)
  • speaker_units: 32(说话者嵌入维度)
  • emotion_units: 32(情感嵌入维度)
  • 语言单元:在 dict/ 中定义(例如,sy_dict.txt 用于音节)
关键 HiFiGAN 参数 (voc/config.yaml)
  • upsample_rates: [10,5,2,2](上采样因子)
  • resblock_kernel_sizes: [3,7,11](残差块内核)
  • sampling_rate: 16000(输出音频采样率)
  • n_fft: 2048(FFT 窗口大小)
  • hop_size: 200(STFT 跳跃长度)
推理参数
  • 设备:CPU/GPU(自动检测;在 model.py 中设置 device='cuda' 以使用 GPU)
  • 批处理大小:1(单个语句;可扩展为批处理)
  • 说话者:“M7”(用于 zhizhe_emo;在 model.py 中可配置)
  • 资源路径:从配置自动检测;确保 resource/ 已提取。

模型细节

架构

SpeechTTS 使用两阶段管道:

  1. SAMBERT (声学模型):从语言特征生成 Mel 谱图。

    • 输入:文本 → 语言编码(音节、声调、情感、说话者)
    • 输出:Mel 谱图(80 维,可变长度)
    • 特性:基于 Transformer,具有方差预测器(持续时间、音高、能量)
  2. HiFiGAN (声码器):将 Mel 谱图转换为波形。

    • 输入:Mel 谱图
    • 输出:原始音频波形(16kHz)
    • 特性:多感受野融合 (MRF) 用于高保真合成

模型导出为 ONNX 以支持跨平台推理,支持可变长度输入的动态形状。

预训练模型

  • 声音:zhizhe_emo(情感男性声音)
  • 采样率:16kHz
  • 训练数据:带有情感注释的专有数据集
  • ONNX 模型:simplify_model_zhizhe_emo.onnx(简化以提高效率)

语言处理

使用 ttsfrd 前端处理原始文本:

  • 将中文文本转换为 MIT 符号(例如,“{ni3 t o n e 3 tone3 tone3s_begin w o r d b e g i n word_begin wordbeginemotion_neutral$M7}”)
  • 编码为 SAMBERT 输入向量(音节、声调等)。

算法分析

SAMBERT: 自注意力多频带编码器 TTS

SAMBERT 是一个端到端的声学模型,从文本预测 Mel 谱图。

  1. 语言编码

    • 文本 → 前端 (ttsfrd):带有韵律、情感、说话者标签的音素序列。
    • 嵌入:音节 (sy)、声调、标志嵌入为向量。
  2. 编码器

    • 多头自注意力 Transformer(8 层)处理语言序列。
    • 输出上下文表示。
  3. 方差适配器

    • 使用 FSMN-RNN 预测持续时间、音高、能量。
    • 长度调节器:将编码器输出扩展以匹配 Mel 长度。
  4. 解码器

    • 混合注意力解码器(12 层)生成 Mel 特征。
    • PostNet:使用 FSMN 层细化 Mel。
  5. 损失:Mel 重构的 MAE,韵律(持续时间/音高/能量)。

效率:每个层 O(N) 由于注意力;ONNX 优化为每秒语音 ~100-200ms(CPU)。

HiFiGAN: 高保真生成对抗网络声码器

HiFiGAN 从 Mel 谱图合成波形。

  1. 生成器

    • 上采样层将 Mel 扩展到波形分辨率。
    • 多感受野融合 (MRF) 块捕获多样模式。
  2. 判别器

    • 多周期和多尺度判别器确保真实性。
  3. 训练:对抗损失 + 特征匹配以实现高质量。

效率:并行生成;推理 ~0.2x RTF(CPU),GPU 上更快。

整体管道效率

  • 实时因子 (RTF):~0.5-1.0(语音持续时间 / 处理时间)在 i7 CPU 上;RTX GPU 上 <0.1。
  • 内存使用:~200-500MB(ONNX 模型 + 运行时)。
  • 延迟:短语句 200-500ms。
  • 基准(i7-12700H 示例,16GB RAM):
    • 10s 语句:SAMBERT ~150ms,HiFiGAN ~100ms,总计 ~250ms (RTF 0.025)。
  • 优化:ONNX 简化减少操作 20-30%。

算法实现详解

整体架构

SpeechTTS 采用两阶段流水线架构:

  1. SAMBERT(声学模型):将语言特征转换为梅尔频谱图
  2. HiFiGAN(声码器):将梅尔频谱图转换为音频波形

核心算法流程

1. 文本预处理与语言特征提取
# 来自 model_classes/model.py 的核心实现
def ExecInfer(self, text):
    if isinstance(text, list):
        text = text[0]
    
    # 导入文本处理函数
    from kantts.utils.ling_unit import text_to_mit_symbols
    
    # 文本预处理:将原始文本转换为MIT符号序列
    texts = [text]  # text_to_mit_symbols 期望文本列表
    symbols_list = text_to_mit_symbols(texts, self.resource_dir, self.speaker)
    
    # 处理符号序列:提取索引和符号
    processed_symbols = []
    for item in symbols_list:
        parts = item.strip().split('\t')
        if len(parts) >= 2:
            symbol_part = parts[1].strip()
            if symbol_part:
                processed_symbols.append(symbol_part)
    
    # 合并所有符号
    symbols = " ".join(processed_symbols)

算法说明

  • text_to_mit_symbols 函数将中文文本转换为包含音素、音调、情感和说话人信息的MIT符号序列
  • 输出格式:"{ni3$tone3$s_begin$word_begin$emotion_neutral$M7}"
  • 支持情感语音合成(通过 emotion_neutral 等标签)
2. 语言单元编码
# 语言特征编码
ling_data = self.ling_unit.encode_symbol_sequence(symbols)

# 分解为不同的语言特征
sy = torch.from_numpy(ling_data[0]).unsqueeze(0).long().to(self.device)           # 音节
tone = torch.from_numpy(ling_data[1]).unsqueeze(0).long().to(self.device)        # 音调
syllable_flag = torch.from_numpy(ling_data[2]).unsqueeze(0).long().to(self.device)  # 音节标志
word_segment = torch.from_numpy(ling_data[3]).unsqueeze(0).long().to(self.device)   # 词分段
inputs_emotion = torch.from_numpy(ling_data[4]).unsqueeze(0).long().to(self.device)  # 情感
inputs_speaker = torch.from_numpy(ling_data[5]).unsqueeze(0).long().to(self.device)  # 说话人

# 组合语言特征输入
inputs_ling = torch.stack([sy, tone, syllable_flag, word_segment], dim=2)

算法说明

  • KanTtsLinguisticUnit 负责将符号序列编码为数值特征向量
  • 包含6种语言特征:音节、音调、音节标志、词分段、情感、说话人
  • 每种特征都被编码为整数索引,便于模型处理
3. SAMBERT声学模型推理
# SAMBERT模型推理
with torch.no_grad():
    res = self.sambert(inputs_ling, inputs_emotion, inputs_speaker, input_lengths)
    mel = res['postnet_outputs'].cpu().numpy()
    mel = np.transpose(mel, (0, 2, 1))

SAMBERT架构详解

  1. 编码器(Encoder)

    • 8层Transformer多头自注意力机制
    • 处理输入的语言特征序列
    • 输出上下文相关的表示
  2. 方差适配器(Variance Adaptor)

    • 使用FSMN-RNN预测时长、音高、能量
    • 长度调节器:将编码器输出扩展到与梅尔频谱长度匹配
  3. 解码器(Decoder)

    • 12层混合注意力解码器
    • 生成梅尔频谱特征
    • PostNet使用FSMN层进行精细化处理
4. HiFiGAN声码器推理
# ONNX推理
input_feed = {self.input_name[0]: mel}
audio = self.onnx_session.run(self.output_name, input_feed=input_feed)[0].squeeze()

HiFiGAN架构详解

  1. 生成器(Generator)

    • 上采样层:将梅尔频谱上采样到波形分辨率
    • 多感受野融合(MRF)块:捕获不同尺度的模式
    • 上采样率:[10, 5, 2, 2],总倍数为200
  2. 判别器(Discriminator)

    • 多周期判别器:确保周期性特征的真实性
    • 多尺度判别器:确保不同尺度下的音频质量

关键算法参数

SAMBERT参数(来自 am/config.yaml
Model:
  KanTtsSAMBERT:
    params:
      embedding_dim: 512          # 嵌入维度
      encoder_num_layers: 8       # 编码器层数
      decoder_num_layers: 12      # 解码器层数
      num_mels: 80                # 梅尔滤波器数量
      outputs_per_step: 3         # 长度调节器因子
      speaker_units: 32           # 说话人嵌入维度
      emotion_units: 32           # 情感嵌入维度
HiFiGAN参数(来自 voc/config.yaml
upsample_rates: [10, 5, 2, 2]    # 上采样率
resblock_kernel_sizes: [3, 7, 11]  # 残差块核大小
sampling_rate: 16000             # 采样率
n_fft: 2048                      # FFT窗口大小
hop_size: 200                    # STFT跳长

性能优化算法

1. ONNX优化
# 来自 model_classes/model.py 的ONNX会话优化
def __InitSession(self):
    self.sess_options = onnxruntime.SessionOptions()
    self.sess_options.intra_op_num_threads = 4
    self.sess_options.execution_mode = onnxruntime.ExecutionMode.ORT_SEQUENTIAL
    self.sess_options.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_ALL

优化策略

  • 图优化级别:ORT_ENABLE_ALL(启用所有优化)
  • 线程数:4个内部操作线程
  • 执行模式:顺序执行模式
2. 实时性优化
  • 实时因子(RTF):约0.5-1.0(在i7 CPU上)
  • 内存使用:约200-500MB
  • 延迟:短语句200-500ms

算法复杂度分析

SAMBERT复杂度
  • 时间复杂度:O(N×L),其中N为层数,L为序列长度
  • 空间复杂度:O(d×L),其中d为嵌入维度
  • 推理时间:约100-200ms/秒语音
HiFiGAN复杂度
  • 时间复杂度:O(T×C),其中T为时间步长,C为通道数
  • 空间复杂度:O(C×K),其中K为核大小
  • 推理时间:约50-100ms/秒语音

完整推理流程示例

# 来自 run.py 的完整使用示例
from model_classes.model import ONNXModel
import sounddevice as sd
import numpy as np
from model_utils.any_utils import resample_audio

# 初始化模型
ort_model = ONNXModel(
    onnx_path="./models/exports/speech_sambert_hifigan_tts_16k_onnx/simplify_model_zhizhe_emo.onnx",
    sambert_cfg="./models/origins/Speech-Sambert-hifigan-TTS-16K/voices/zhizhe_emo/am/config.yaml",
    sambert_ckpt="./models/origins/Speech-Sambert-hifigan-TTS-16K/voices/zhizhe_emo/am/ckpt/checkpoint_0.pth",
)

# 执行推理
audio = ort_model.ExecInfer(["你好,我是智能助手。我的名字叫KanTTS"])

# 音频播放
out_stream = sd.OutputStream(samplerate=48000, blocksize=1024, device=8, channels=1, dtype=np.float32)
out_stream.start()
audio = resample_audio(audio, 16000, 48000)  # 重采样到48kHz
out_stream.write(audio)
out_stream.stop()
out_stream.close()

这个实现展示了从文本到音频的完整流水线,包括文本预处理、语言特征提取、声学模型推理、声码器合成和音频播放等关键步骤。

联系方式
模型及其源码获取
  • 公众号回复“kantts-onnx”

您可能感兴趣的与本文相关的镜像

HunyuanVideo-Foley

HunyuanVideo-Foley

语音合成

HunyuanVideo-Foley是由腾讯混元2025年8月28日宣布开源端到端视频音效生成模型,用户只需输入视频和文字,就能为视频匹配电影级音效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值