核心内容摘要
9.1樱花PPT网页大片:让你的数字作品绽放绝美春色!
IndexTTS是B站语音团队开源的一系列语音克隆模型。
早期版本在多场景应用中均表现惊艳笔者也有过部署实测低延迟小智AI服务端搭建-本地TTS篇IndexTTSvLLM加速推理字错率和克隆相似性均出于当时领先水平。
经过 vLLM 推理加速RTF 可以低至
15因此也是笔者首选的语音克隆模型服务。
不过还有硬伤情感表达不够AI 味依旧浓郁不支持语速控制更像在读稿。
刚好最近项目中需要解决以上痛点寻找了一圈解决方案兜兜转转还是来到了IndexTTS。
因为当前市面上无论开源 还是 闭源的语音克隆方案上述两点都没有很好解决。
早在去年 9 月B站就开源了IndexTTS-
0号称情感丰富和时长可控。
刚好借此机会实测一番分享给各位。
IndexTTS-2简介官方仓库https://github.com/index-tts/index-tts
1 模型架构相比 v1 版本模型架构发生了不小变化简言之IndexTTS2由三个核心模块组成Text-to-SemanticT2S、Semantic-to-MelS2M以及BigVGANv2声码器。
T2S 模块输入源文本、风格提示、音色提示、目标语音token数输出语义 token 序列。
模型GPT2自回归模型S2M 模块输入语义 token、音色提示输出梅尔频谱图。
模型基于流匹配的非回归生成框架BigVGANv2 声码器输入梅尔频谱图输出高质量的语音波形。
2 亮点介绍论文https://arxiv.org/abs/
2
21619有哪些亮点支持语速控制提出一种“时间编码”机制首次解决了传统 AR 模型难以精确控制语音时长的问题。
允许用户显式指定生成的token数量从而实现语速控制。
支持情感表达提出音色与情感解耦机制也就是支持用户同时指定音色参考与情感参考实现更加灵活、细腻的情感表达。
此外模型还具备基于文本描述的情感控制能力。
如何实现首先定义7种标准情感并建立对应的情感embedding。
用户输入自然语言微调 Qwen3-
6b 输出情感概率分布加权得到最终的情感embedding。
3 核心代码解读对应模型架构部分# 核心模块 GPT 模型 (UnifiedVoice)负责从文本和音色参考生成语义码codes。
Semantic 模型基于 w2v-BERT
0提取参考音频的语义嵌入。
- get_emb函数输入w2v-bert特征和掩码取第17层隐藏状态作为语义特征 Semantic codec将语义嵌入量化为离散码本索引。
S2Mel 模型包含 length_regulator、cfmFlow Matching 扩散模型等用于从语义码生成梅尔频谱。
CampPlus提取参考音频的风格向量全局音色特征。
BigVGAN声码器将梅尔频谱转为波形。
QwenEmotion情感分析模型可从文本生成情感向量。
TextNormalizer TextTokenizer文本规范化与分词BPE。
# 缓存机制 缓存参考音频的语义条件、风格向量、梅尔频谱等避免重复计算。
# 模型加载 self.qwen_emo QwenEmotion(os.path.join(self.model_dir, self.cfg.qwen_emo_path))会加载qwen模型 self.gpt UnifiedVoice(**self.cfg.gpt, use_accelself.use_accel)加载GPT模型use_deepspeed用户加速gpt self.s2mel MyModel(self.cfg.s2mel, use_gpt_latentTrue) 会使用enable_torch_compile将模型转换为更高效的执行图减少推理时间和显存占用 self.bigvgan bigvgan.BigVGAN.from_pretrained 会用 use_cuda_kernel 启用自定义 CUDA 加速。
self.normalizer TextNormalizer(enable_glossaryTrue)文本标准化实例启用术语表有具体使用示例 self.tokenizer TextTokenizer(self.bpe_path, self.normalizer) 文本分词器使用BPE分词算法和标准化器 self.emo_matrix 加载feat
pt共8种表情向量每种有多条 self.spk_matrix 加载feat
pt内置的音频向量和上面对应 self.mel_fn梅尔频谱计算函数根据配置初始化 # 语音处理工具 - remove_long_silence压缩过长的静音 token得到的还是codecs - interval_silence / insert_interval_silence在句子之间插入指定长度的静音段前者生成静音后者插入静音。
- _load_and_cut_audio加载音频截断到15s # 推理函数 infer如果是流式输出返回迭代器非流式输出返回分句的音频列表 infer_generator - 先判断情感控制 qwen大模型会输出:{happy:
0, angry:
0, sad:
99, afraid:
0, disgusted:
0, melancholic:
0, surprised:
0, calm:
01}若无外部情感参考音频则使用音色参考音频作为情感参考。
- 从emo_matrix中提取向量和emo_vector相乘得到emovec_mat - 输入情感参考音频得到语义嵌入emo_cond_emb如果没有就和参考音频一样 - 再处理参考音频如果参考音频变了则重新加载 - 16kHz 音频 → w2v-BERT 特征 → 语义嵌入spk_cond_emb → codec量化得到 S_ref → 经过s2mel得到prompt_condition。
- 22kHz 音频 → 梅尔频谱 ref_mel。
- 16kHz 音频 → FBank 特征 → CampPlus → 风格向量 style - 开始文本分词和分句max_text_tokens_per_segment决定分几句 - 循环生成每段语音 - GPT 生成语义码codes合并音色与情感cond再合并emovec_mat得到emovec再调用 gpt.inference_speech 生成codes用 self.gpt 对码和文本做一次前向得到 latent用于后续扩散模型条件。
- Flow Matching 扩散模型生成梅尔频谱s2mel模型得到vc_target其中的target_lengths用
72控制梅尔频谱的长度从而控制语速 - BigVGAN 声码器合成波形将梅尔频谱转为波形 clamp 到 int16 范围。
- 收集波形和静音生成一句wav默认生成一段200ms静音生成sampling_rate必须是
2
4 效果展示相比 v1IndexTTS2在音色相似度上有了质的飞跃在情感控制上相比 CosyVoice2 也强不少
推理加速测试以下均在 RTX 4080 显卡上进行实测。
在不进行任何推理加速的情况下模型加载后的显存占用IndexTTS2的T2S模块依旧采用的是GPT2自回归模型架构不过层数更多因此极大增加了推理延时实测RTF值如下多次测试 RTF:
8614 RTF:
6096 RTF:
6241 RTF:
2211 RTF:
8663显然无法满足实时应用需求。
这里最耗时的有两个部分最重的是 GPT2 推理其次是 s2mel后者可通过torch.compile将模型转换为优化的执行图减少运行时开销实测提速 2x。
下面重点解决 GPT2 推理。
1 vLLM 加速推理IndexTTS2的T2S模块是 GPT2因此可通过 vLLM 引擎进行加载从而实现推理加速实测加速效果如下在gpu_memory_utilization设置为
25 的情况下显存占用
2 Deepspeed加速推理官方仓库采用 uv 管理环境安装deepspeeduv sync --extra deepspeed同时需要安装flash_attnflash_attn安装坑比较多推荐找到对应版本的安装包进行本地安装https://github.com/Dao-AILab/flash-attention/releases/wget https://github.com/Dao-AILab/flash-attention/releases/download/v
2.
3/flash_attn-
2.
3cu12torch
8cxx11abiFALSE-cp310-cp310-linux_x86_
whl uv pip install flash_attn-
2.
3cu12torch
8cxx11abiFALSE-cp310-cp310-linux_x86_
whl加速效果如下GPT2 推理部分加速效果相比vLLM更有性价比。
显存占用如下
推理服务部署
1 方案选型尽管vLLM支持并发但单发都无法做到实时根本不可用啊。
而DeepSpeed加速可以将 RTF 干到
5以下却不支持并发。
因为DeepSpeed的KV缓存机制为单个推理流程服务在多线程并发访问时会产生内存冲突。
所以只能选择在 FastAPI 这一层实施GPU 推理串行化HTTP 请求异步化也就是服务层面支持并发调用但推理还是队列化处理的确保不把服务打崩。
举例而言假设同时来了 10 个请求[请求1] 成功 - 耗时:
63s [请求2] 成功 - 耗时:
99s [请求6] 成功 - 耗时:
20s [请求3] 成功 - 耗时:
1
32s [请求0] 成功 - 耗时:
1
61s [请求4] 成功 - 耗时:
1
14s [请求7] 成功 - 耗时:
1
65s [请求8] 成功 - 耗时:
2
03s [请求5] 成功 - 耗时:
2
44s [请求9] 成功 - 耗时:
2
87s先抢到资源的先推理服务不忙的时候可满足实时推理需求。
2 请求示例请求示例如下class TTSRequest(BaseModel): voice_id: Optional[str] None # 参考语音的id tts_text: Optional[str] None # 待合成的文本 emo_vec: Optional[list] [0] * 8 # 情绪向量 max_tokens: Optional[int] 80 # 单句文本最大长度 speed: Optional[float]
0voice_id会提取注册为音色进行缓存避免每次请求都要重新提取特征tts_text待合成的文本支持无限长服务内部会进行分句max_tokens分句做到最大长度emo_vec情绪向量输入范围[
]代表[喜, 怒, 哀, 惧, 厌恶, 低落, 惊喜, 平静]写在最后本文分享了实时语音克隆IndexTTS2的技术方案对两种推理加速方案进行了实测。
如果对你有帮助欢迎点赞收藏备用。
另外IndexTTS