本文档记录 Kokoro-82M(StyleTTS2 架构,82M 参数 TTS 模型)在华为昇腾 NPU(Ascend 910 系列)上的适配与验证结果。
Kokoro-82M 是一个轻量级的文本转语音(TTS)模型,采用 StyleTTS2 + ISTFTNet 架构,原生于 PyTorch 实现。本适配工作基于官方 kokoro pip 包源码,针对昇腾 NPU 做了以下关键修改:
KPipeline 的设备选择逻辑,支持自动识别 torch.npuTorchSTFT 在 NPU 上 fallback 到 CustomSTFT(基于 Conv1d 的 STFT/iSTFT 实现),规避 aclnnAbs / aclnnUnfoldGrad 对复数张量的限制KModel.forward 中使用 torch.tensor(..., device=device, dtype=torch.long) 替代 torch.LongTensor,确保输入张量直接创建在 NPU 上KPipeline.load_single_voice 优先加载本地 voices/ 目录,避免 HuggingFace Hub 不可达时的超时相关获取地址:
| 组件 | 版本 |
|---|---|
CANN | 8.5.1 |
torch | 2.5.1 |
torch-npu | 2.9.0.post1 |
transformers | >=4.30 |
kokoro | >=0.9.2 |
1 逻辑卡(Ascend910B / Atlas 800 A2)/tmp/kokoro-82m-bf16/weightsaarch64pip install kokoro soundfile misaki
pip install torch-npu --extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple注:
misaki为 G2P(Grapheme-to-Phoneme)依赖,英文需要pip install misaki[en],中文需要pip install misaki[zh]。
推荐从 ModelScope 下载(国内网络更稳定):
modelscope download --model hexgrad/Kokoro-82M --local_dir ./Kokoro-82M或从 HuggingFace 镜像下载:
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download hexgrad/Kokoro-82M --local-dir ./Kokoro-82Mfrom kokoro_npu import KPipeline, KModel
import soundfile as sf
# 加载模型到 NPU
pipeline = KPipeline(lang_code='a', model=False)
model = KModel(
config='./Kokoro-82M/config.json',
model='./Kokoro-82M/kokoro-v1_0.pth'
).to('npu').eval()
# 生成音频
for result in pipeline(
'Hello, this is Kokoro running on Ascend NPU.',
voice='af_heart',
model=model
):
audio = result.audio
sf.write('output.wav', audio.numpy(), 24000)NPU 建议:在 NPU 上推理时建议显式设置
disable_complex=True,使 STFT/iSTFT 统一走CustomSTFT后端,确保与 CPU 对齐的精度表现:model = KModel(config='...', model='...', disable_complex=True).to('npu').eval()
# 精度验证(CPU vs NPU)
python accuracy_check.py
# 性能基准测试
python perf_benchmark.py
# 单条推理 + 基准
python inference_npu.py \
--text "Hello world." \
--voice af_heart \
--device npu \
--weights ./Kokoro-82M/kokoro-v1_0.pth \
--config ./Kokoro-82M/config.json使用对齐后的 CustomSTFT 后端,对比 CPU 与 NPU 输出的一致性。
| 指标 | 数值 |
|---|---|
| 对比后端 | CustomSTFT(CPU vs NPU) |
| 测试文本 | Hello world. |
| 语音 | af_heart |
| MSE | 1.18e-05 |
| RMSE | 3.43e-03 |
| MAE | 1.55e-03 |
| Max Error | 4.32e-02 |
| Cosine Similarity | 0.997864 |
| SNR | 23.67 dB |
结论:NPU 输出与 CPU 参考输出高度一致,Cosine Similarity > 0.995,SNR > 20 dB,精度验证通过。
说明:若使用默认的
TorchSTFT(CPUtorch.istft)作为参考基准,与 NPUCustomSTFT的 SNR 约为 5.2 dB,该差异主要来源于CustomSTFT卷积近似带来的固有误差,而非 NPU 算子精度问题。实际人耳听觉上难以区分两者差异。
测试条件:NPU 单卡,预热 5 轮,正式测试 20 轮,取均值。
| 测试用例 | 平均延迟 | P99 延迟 | RTF | 吞吐量 |
|---|---|---|---|---|
| Short text. | 111.6 ms | 119.9 ms | 0.223x | 8.96 utt/s |
| Medium sentence (60 chars) | 174.0 ms | 177.9 ms | 0.072x | 5.75 utt/s |
| Long sentence (120 chars) | 226.5 ms | 232.4 ms | 0.064x | 4.42 utt/s |
汇总:
| 指标 | 数值 |
|---|---|
| 平均延迟 | 170.7 ms |
| 平均 RTF | 0.120x |
| 平均吞吐量 | 6.38 utt/s |
| 实时 capable | YES |
RTF(Real-Time Factor)< 1.0 表示推理速度快于音频播放速度,可支持实时 TTS 场景。
与 CPU(ARM aarch64)对比:
| 设备 | 推理耗时 | 加速比 |
|---|---|---|
| CPU (aarch64, 单核) | ~6000 ms | 1.0x |
| NPU (Ascend910B) | ~112 ms | ~54x |
以下文件为相对于上游 kokoro 包的核心改动:
| 文件 | 变更说明 |
|---|---|
kokoro_npu/pipeline.py | 设备检测支持 NPU;load_single_voice 优先本地缓存 |
kokoro_npu/model.py | forward 中使用 torch.tensor(..., device=device) 替代 torch.LongTensor |
kokoro_npu/istftnet.py | TorchSTFT 在 NPU 上 fallback 到 CustomSTFT.inverse;transform 手动计算 magnitude/phase 规避 aclnnAbs 复数限制 |
完整变更可通过 git diff 或本仓库源码查看。
复数张量限制:当前 CANN 版本下 torch.abs / torch.angle 不支持 torch.complex64 输入,torch.istft 在 NPU 上触发 aclnnUnfoldGrad 内部错误。已在 TorchSTFT 中通过 CustomSTFT fallback 解决。
bf16 支持:Kokoro-82M 原生为 fp32 权重。若需 bf16 推理,可在加载后手动 model.bfloat16().to('npu'),但当前未做专门验证。
语音文件缓存:首次运行需下载 voices/*.pt,建议预先通过 modelscope download 或 huggingface-cli 下载完整仓库到本地,避免运行时网络超时。
长文本分块:KPipeline 对英文自动按 510 音素分块,对非英语按 400 字符分块。长文本会生成多段音频,需在外层拼接。
ESpeak 依赖:非英语语音(如法语、西班牙语)依赖 espeak-ng,需提前安装:apt-get install espeak-ng。