z
zkx_/Irodori-TTS-500M-v2-Ascend
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

Irodori-TTS-500M-v2 on Ascend NPU

1. 简介

本文档记录 Irodori-TTS-500M-v2 在华为昇腾 NPU 环境的部署与验证结果。

Irodori-TTS-500M-v2 是一个基于 Rectified Flow Diffusion Transformer (RF-DiT) 架构的日语文本转语音(TTS)模型,支持零样本语音克隆和基于 emoji 的风格控制。原始仓库为 Aratako/Irodori-TTS。

本次昇腾适配主要完成以下工作:

  • 在 irodori_tts/inference_runtime.py 中增加 npu 设备识别、同步与缓存清理支持
  • 在 irodori_tts/codec.py 中将默认设备从 cuda 改为 npu
  • 在 irodori_tts/model.py 中修复 scaled_dot_product_attention 的 attn_mask shape,以兼容 Ascend NPU aclnnFlashAttentionScore 算子要求
  • 提供 inference.py 一键推理脚本,支持本地权重加载与 tokenizer 路径覆盖

相关获取地址:

  • 权重下载地址(ModelScope):https://modelscope.cn/models/Aratako/Irodori-TTS-500M-v2
  • 权重下载地址(HuggingFace):https://huggingface.co/Aratako/Irodori-TTS-500M-v2
  • 原始代码仓库:https://github.com/Aratako/Irodori-TTS

2. 验证环境

组件版本
torch2.9.0+cpu
torch-npu2.9.0.post1+gitee7ba04
transformers4.57.6
dacvae1.0.0
CANN8.5.1
  • NPU:910B4 x 1
  • 模型路径:./weights/model.safetensors
  • 推理脚本:inference.py

3. 依赖安装

使用华为 PyPI 镜像加速安装:

pip install -i https://repo.huaweicloud.com/repository/pypi/simple \
    transformers sentencepiece safetensors torchaudio soundfile \
    huggingface-hub torchcodec

# dacvae 需要从 GitHub 安装
pip install "dacvae @ git+https://github.com/facebookresearch/dacvae.git"

# audiotools 用于参考音频响度归一化(可选)
pip install git+https://github.com/descriptinc/audiotools.git

4. 权重下载

4.1 模型权重

export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download Aratako/Irodori-TTS-500M-v2 model.safetensors --local-dir ./weights

或从 ModelScope 下载:

modelscope download --model Aratako/Irodori-TTS-500M-v2 --local_dir ./weights

4.2 Codec 权重

export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download Aratako/Semantic-DACVAE-Japanese-32dim weights.pth --local-dir ./weights/codec

4.3 Tokenizer

export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download llm-jp/llm-jp-3-150m tokenizer.json tokenizer_config.json --local-dir ./weights/tokenizer

下载完成后目录结构:

./weights/
├── model.safetensors
├── codec/
│   └── weights.pth
└── tokenizer/
    ├── tokenizer.json
    └── tokenizer_config.json

5. 推理测试

5.1 标准 TTS(无参考音频)

python inference.py \
  --text "お電話ありがとうございます。ただいま電話が大変混み合っております。" \
  --output-wav output_standard.wav \
  --model-device npu \
  --codec-device npu \
  --num-steps 20 \
  --seed 42 \
  --no-ref

5.2 语音克隆(带参考音频)

python inference.py \
  --text "お電話ありがとうございます。ただいま電話が大変混み合っております。" \
  --output-wav output_clone.wav \
  --model-device npu \
  --codec-device npu \
  --num-steps 20 \
  --seed 42 \
  --ref-wav /path/to/reference.wav

5.3 关键参数说明

参数说明
--model-device模型推理设备,npu / cuda / cpu
--codec-deviceCodec 编解码设备,npu / cuda / cpu
--model-precision模型精度,fp32 / bf16(NPU 支持 bf16)
--codec-precisionCodec 精度,fp32 / bf16
--num-steps扩散步数,默认 40,可减少以加速推理
--no-ref不使用参考音频,用于标准 TTS
--ref-wav参考音频路径,用于语音克隆

6. 精度与性能评测

6.1 评测脚本

提供一键评测脚本 eval_ascend.py,自动执行精度对比(NPU vs CPU)与性能基准测试:

# 完整评测(精度 + 性能)
python eval_ascend.py \
  --text "お電話ありがとうございます。" \
  --num-steps 20 \
  --seed 42 \
  --num-runs 3

# 仅性能测试
python eval_ascend.py --skip-accuracy

# 仅精度测试
python eval_ascend.py --skip-performance

评测脚本功能:

  • 自动下载权重:若本地 ./weights/ 目录不存在权重文件,自动从 ModelScope 下载
  • 精度对比:使用相同 seed 在 NPU 和 CPU 上分别推理,比较输出音频的相对误差、SNR、MSE
  • 性能基准:在 NPU 上运行多次推理,统计平均耗时、RTF(实时因子)、各阶段耗时
  • 结果判定:自动判定是否满足相对误差 < 1% 的要求

6.2 精度评测结果

精度对比条件:num_steps=3, seed=42, text="お電話ありがとうございます",NPU(fp32) vs CPU(fp32) 相同 seed 确定性推理。 使用 3 步推理(CPU 1步 ~84s,3步 ~70s 可接受),固定初始噪声生成器为 CPU Generator 以消除 PRNG 差异。

指标数值
相对误差 (L2)0.0405%
SNR67.85 dB
MSE6.76e-09
最大逐点差异0.0003
判断结果✅ 通过(相对误差 < 1.0%)

结论:NPU 与 CPU 的输出音频在相同 seed 下几乎完全一致,相对误差仅 0.04%,远低于 1% 阈值,说明昇腾 NPU 的算子计算精度满足 TTS 推理要求。

关键修复:初始噪声必须使用 CPU 生成器(torch.Generator(device="cpu")),因为 NPU 生成器的 PRNG 序列与 CPU 不同,会导致 ~132% 的假误差。

6.3 性能评测结果

性能测试条件:num_steps=20, seconds=5.0, device=npu, precision=fp32。

指标数值
总耗时16.05 s
扩散模型推理840.6 ms (42ms/step)
Codec 解码544.6 ms
生成音频长度3.80 s
实时率4.22 x

各阶段耗时分解:

阶段耗时
tokenize_text0.8 ms
prepare_reference0.2 ms
sample_rf840.6 ms
unpatchify_latent0.1 ms
decode_latent544.6 ms

分析:扩散模型推理(sample_rf)在 20 步下仅 840ms,平均每步约 42ms;Codec 解码(decode_latent)约 545ms。总耗时 16s 包含模型加载 / JIT 编译。

7. 验证结果

已验证通过的推理命令见 5.1 节。标准 TTS 在 NPU 上推理成功,输出音频文件 output_standard.wav。

8. 昇腾适配修改说明

本次适配涉及以下源码修改:

8.1 irodori_tts/inference_runtime.py

  • 增加 _is_npu_available() 检测
  • resolve_runtime_device():增加 npu 分支校验
  • list_available_runtime_devices():NPU 可用时优先返回 npu
  • list_available_runtime_precisions():NPU 支持 bf16
  • _sync_device():增加 torch.npu.synchronize()
  • resolve_runtime_dtype():放宽 bf16 限制到 cuda 或 npu
  • unload():增加 torch.npu.empty_cache()

7.2 irodori_tts/codec.py

  • DACVAECodec.load() 默认设备从 cuda 改为 npu

7.3 irodori_tts/model.py

  • SelfAttention.forward():将 attn_mask 从 [B, 1, 1, S] 显式扩展为 [B, 1, S, S]
  • JointAttention.forward():将 attn_mask 从 [B, 1, 1, total_kv] 显式扩展为 [B, 1, S, total_kv]

修改原因:Ascend NPU 的 aclnnFlashAttentionScore 算子要求 attn_mask shape 必须为 [B, N, Sq, Skv]、[B, 1, Sq, Skv]、[1, 1, Sq, Skv] 或 [Sq, Skv]。原始代码中的 [B, 1, 1, S] 虽可在 CUDA 上通过广播生效,但在 NPU 上会直接触发 EZ9999 Tiling 失败。

8.4 irodori_tts/rf.py

  • _make_rng():将 torch.Generator(device=device) 改为始终使用 torch.Generator(device="cpu")

修改原因:NPU 的随机数生成器(PRNG)序列与 CPU 不同,即使使用相同 seed 也会产生不同的初始噪声。扩散模型的初始噪声由 torch.Generator 生成,NPU vs CPU 噪声不同会导致输出音频完全不一致(实测相对误差 ~132%)。将生成器固定为 CPU 可确保跨设备相同 seed 产生相同噪声。

8.5 eval_ascend.py(新增)

  • 新增推理调度、精度对比与性能基准测试的一键脚本。
  • run_single_inference():封装模型加载、推理、计时等逻辑,支持 NPU/CPU 设备选择。
  • run_accuracy_test():NPU 确定性检验 + NPU vs CPU 精度对比(3-step),自动判定是否 < 1%。
  • run_performance_benchmark():多轮性能测试,输出各阶段耗时与 RTF。

9. 注意事项

  1. 模型仅支持日文输入,其他语言可能产生不可预期的结果。
  2. 参考音频格式:确保参考音频为有效的 WAV 格式(非 Git LFS 指针文件)。
  3. Emoji 风格控制:在输入文本中插入特定 emoji 可控制说话风格和音效,详见原始仓库 EMOJI_ANNOTATIONS.md。
  4. bf16 精度:NPU 已支持 bf16,可在 --model-precision bf16 下尝试,但需验证音质是否满足要求。
  5. torchcodec 依赖:若保存音频时提示缺少 torchcodec,请执行 pip install torchcodec。