本文档记录 Kokoro-82M-bf16 文本转语音(TTS)模型在华为昇腾 NPU 上的适配与验证结果。
Kokoro-82M 是基于 StyleTTS2 架构的轻量级 TTS 模型(82M 参数),支持多说话人、多语言语音合成。模型使用 PlBERT 文本编码器 + 韵律预测器 + iSTFTNet 解码器的流水线,输出 24kHz 音频。
适配工作主要解决以下问题:
torch.stft 返回复数张量,改用基于 Conv1d 的 CustomSTFT 实现相关地址:
| 组件 | 版本 |
|---|---|
torch | 2.9.0 |
torch-npu | 2.9.0.post1 |
transformers | 4.57.6 |
safetensors | 0.5.3 |
| CANN | 8.5.1 |
| Python | 3.11.14 |
1 逻辑卡(Atlas 800 A2/A3)./kokoro-v1_0.safetensors327 MB(bf16 精度)pip install torch torch-npu transformers safetensors soundfile numpy# 方式一:使用 huggingface-cli(推荐)
HF_ENDPOINT=https://hf-mirror.com huggingface-cli download mlx-community/Kokoro-82M-bf16 --local-dir ./Kokoro-82M-bf16
# 方式二:使用 ModelScope
modelscope download --model mlx-community/Kokoro-82M-bf16 --local_dir ./Kokoro-82M-bf16export ASCEND_RT_VISIBLE_DEVICES=0
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:Truepython inference.py \
--text "Hello world, this is a test of the Kokoro text to speech system." \
--voice af_heart \
--output output.wav \
--device npu| 参数 | 默认值 | 说明 |
|---|---|---|
--text | (必填) | 待合成文本 |
--voice | af_heart | 说话人声音(见 voices/ 目录) |
--model-path | ./kokoro-v1_0.safetensors | 模型权重路径 |
--output | output.wav | 输出音频路径 |
--device | npu | 推理设备(npu/cpu/cuda) |
--speed | 1.0 | 语速倍率 |
--lang | a | 语言代码(a=美式英语, b=英式英语) |
--warmup | 1 | 预热次数 |
--repeat | 1 | 重复推理次数(用于基准测试) |
模型支持 54 种说话人声音(voices/ 目录),命名规则:
af_*:女性声音(American Female)am_*:男性声音(American Male)bf_*:女性声音(British Female)bm_*:男性声音(British Male)常用声音:af_heart, af_bella, af_nicole, am_adam, bf_emma
测试条件:单卡 NPU,重复 10 次取平均值。
| 文本长度 | 音素数 | 延迟(s) | 音频时长(s) | RTF | 吞吐量(tok/s) |
|---|---|---|---|---|---|
| Short | 12 | 0.1137 | 1.55 | 0.0733 | 105.6 |
| Medium | 90 | 0.2307 | 6.47 | 0.0356 | 390.1 |
| Long | 236 | 0.4966 | 16.40 | 0.0303 | 475.2 |
| Very Long | 358 | 0.7224 | 24.12 | 0.0299 | 495.6 |
关键指标:
| 指标 | CPU | NPU | 加速比 |
|---|---|---|---|
| 短文本延迟 | 19.45s | 0.21s | 93x |
| RTF | 3.795 | 0.041 | 93x |
使用 5 条英文文本进行推理验证,所有文本均成功生成音频。
| 文本 | 音素数 | 延迟(s) | 音频时长(s) | RTF |
|---|---|---|---|---|
| Hello world. | 12 | 0.1116 | 1.55 | 0.072 |
| The quick brown fox... | 42 | 0.1558 | 2.95 | 0.053 |
| Artificial intelligence... | 76 | 0.2065 | 5.35 | 0.039 |
| Today is a beautiful day... | 46 | 0.1587 | 3.25 | 0.049 |
| Speech synthesis has come... | 53 | 0.1653 | 3.60 | 0.046 |
所有推理结果音频已保存至 eval_output/ 目录。
NPU 不支持 torch.stft 返回复数张量(DT_COMPLEX64),报错:
RuntimeError: abs: NPU function error: call aclnnAbs failed
Tensor out expected dtype is DT_FLOAT but found DT_COMPLEX64解决方案:在 Generator 中自动检测 NPU 设备,使用基于 Conv1d 的 CustomSTFT 替代 TorchSTFT。CustomSTFT 通过预计算 DFT 矩阵并使用 Conv1d/ConvTranspose1d 实现 STFT/iSTFT,完全避免复数运算。
# kokoro_istftnet.py 中的关键修改
use_custom = disable_complex or (hasattr(torch, 'npu') and torch.npu.is_available())
self.stft = CustomSTFT(...) if use_custom else TorchSTFT(...)原始代码使用 torch.load() 加载 .pth 权重,而本适配版本使用 .safetensors 格式。修改模型加载逻辑以自动检测文件格式:
if model.endswith('.safetensors'):
from safetensors import safe_open
f = safe_open(model, framework='pt')
# 按前缀分组为子模块 state_dict
grouped = defaultdict(dict)
for k in f.keys():
prefix = k.split('.')[0]
grouped[prefix][k[len(prefix)+1:]] = f.get_tensor(k)
state_dict = dict(grouped)
else:
state_dict = torch.load(model, map_location='cpu', weights_only=True)模型整体迁移至 NPU:
model = model.npu().eval()推理时需确保所有张量在同一设备:
ref_s = pack[phoneme_len - 1].npu()
input_ids = torch.LongTensor([[0, *input_ids, 0]]).npu()| 文件 | 说明 |
|---|---|
inference.py | 推理脚本(支持 NPU/CPU/CUDA) |
accuracy_run.py | 精度评测脚本 |
accuracy_run_perf.py | 性能基准测试脚本 |
kokoro_model.py | 模型定义(适配 safetensors 加载) |
kokoro_modules.py | 核心模块(TextEncoder, ProsodyPredictor 等) |
kokoro_istftnet.py | 解码器与 iSTFT(适配 NPU CustomSTFT) |
kokoro_custom_stft.py | 基于 Conv1d 的 STFT/iSTFT 实现 |
kokoro-v1_0.safetensors | 模型权重(327MB, bf16) |
config.json | 模型配置与音素词表 |
voices/ | 说话人声音文件 |
eval_output/ | 评测结果与报告 |
G2P 依赖:完整 G2P 需要安装 misaki[en](pip install misaki[en])。当前脚本内置了简单的字母到音素映射作为 fallback,安装 misaki 后可获得更好的音素转换质量。
长文本处理:模型最大支持 510 个音素的输入序列。对于长文本,建议按句子分段合成后拼接。
声音文件格式:模型同时提供 .pt 和 .safetensors 两种格式的声音文件,两者等价。
首次推理延迟:首次推理包含 NPU 图编译开销,后续推理会显著加速。建议使用 --warmup 1 进行预热。
NPU vs CPU 精度对比(CPU 为基线,NPU 为验证目标):
| 指标 | 数值 |
|---|---|
| 测试用例数 | 待运行 |
| 最大 logits 差异 | 待运行 |
| 预测一致性 | 待运行 |
| 精度要求 | NPU vs CPU 最大 logits 误差 < 1% |
| 精度结论 | 待运行 |
精度评测源代码和日志详见 eval/ 目录。