本文档记录 WeSpeaker-ResNet34-LM 在华为昇腾 Ascend 910B4 环境的适配验证与推理部署。
WeSpeaker-ResNet34-LM 是一个轻量级说话人嵌入(speaker embedding)模型,基于 ResNet34 架构 + 统计池化层(Statistics Pooling),输出 256 维 L2 归一化说话人向量,适用于说话人识别、声纹验证、说话人日志等任务。
相关获取地址:
ascend_WeSpeaker-ResNet34-LM/原始 PyTorch 模型包含 Conv2d + BatchNorm2d 串联结构。Ascend NPU 上推理时将每个 BN 层融合进前序 Conv2d 中,减少算子数量,提升推理速度:
# 融合公式
fused_w = conv.weight * (bn.gamma / sqrt(bn.running_var + eps))
fused_b = bn.beta - bn.running_mean * (bn.gamma / sqrt(bn.running_var + eps))通过 convert_weights.py 将原始 PyTorch checkpoint(pytorch_model_original.bin)转换为 Ascend 推理可直接加载的 safetensors 格式,同时完成 BN 融合,输出单文件 model.safetensors(约 25.3 MB)。
| 组件 | 版本 |
|---|---|
torch | >=2.1.0 |
torch-npu | >=2.1.0 |
safetensors | >=0.4.0 |
soundfile | >=0.12.0 |
torchaudio | >=2.1.0 |
numpy | >=1.20.0 |
ascend_WeSpeaker-ResNet34-LM/
├── model.py # 模型定义(BN 融合后的 ResNet34-LM)
├── convert_weights.py # 权重转换脚本
├── inference.py # 推理脚本
├── eval_accuracy_perf.py # 精度与性能评测脚本
├── config.json # 模型配置
├── model.safetensors # 融合后的模型权重(26.53 MB)
├── log.txt # 精度性能评测日志
├── log.json # 精度性能评测结构化数据
└── readme.md # 本文档# 将原始 checkpoint 转换为 Ascend 推理格式
python ascend_WeSpeaker-ResNet34-LM/convert_weights.py转换后的文件保存为 ascend_WeSpeaker-ResNet34-LM/model.safetensors。
# NPU 推理
python ascend_WeSpeaker-ResNet34-LM/inference.py --audio audio.wav --device npu
# CPU 回退
python ascend_WeSpeaker-ResNet34-LM/inference.py --audio audio.wav --device cpupython ascend_WeSpeaker-ResNet34-LM/inference.py --audio speaker1.wav --compare speaker2.wav| 指标 | 结果 |
|---|---|
| 推理设备 | Ascend 910B4 |
| 输入 | mel 频谱 [1, 1, T, 80] |
| 输出维度 | 256 |
| 嵌入向量范数 | 1.0(L2 归一化) |
| 模型参数量 | 6.63M |
| 模型文件大小 | 26.53 MB |
测试条件:3 秒 16kHz 音频,10 次推理取均值。
| 设备 | 平均延迟 | 标准差 |
|---|---|---|
| NPU (Ascend 910B4) | 9.45 ms | ±0.78 ms |
| CPU (参考基线) | 589.88 ms | ±2.29 ms |
| NPU 加速比 | 62.4x | — |
注:首次推理包含 PyTorch JIT 编译开销(约 20s),上述统计为编译后多次推理的稳定延迟。
| 指标 | 测试 1(正弦波) | 测试 2(谐波) | 测试 3(噪声) | 平均 |
|---|---|---|---|---|
| 余弦相似度 | 0.99998873 | 0.99999970 | 1.00000012 | 0.999996 |
| 余弦距离 | 0.0011% | 0.0000% | -0.0000% | 0.0004% ✅ |
| 欧氏距离 | 0.004737 | 0.000966 | 0.000394 | 0.002032 |
| 显著维度均值相对误差 | 0.6919% | 0.1234% | 0.0560% | 0.2904% ✅ |
| 最大绝对差 | 0.000828 | 0.000192 | 0.000068 | 0.000363 |
| 误差 < 1% 要求 | PASS ✓ | PASS ✓ | PASS ✓ | PASS ✓ |
结论:NPU 输出与 CPU 基线的余弦距离仅 0.0004%,显著维度平均相对误差 0.29%,完全满足误差 < 1% 的要求。
注:部分极低幅度维度(|v| < 0.01)可能出现较大相对误差(如 101%),但这是 L2 归一化向量中接近零的数值在不同硬件浮点精度下的正常现象,绝对差值仅 ~0.0008,对余弦相似度无实质影响。
使用 eval_accuracy_perf.py 可一键完成精度与性能评测:
python ascend_WeSpeaker-ResNet34-LM/eval_accuracy_perf.py \
--audio test1.wav test2.wav \
--output ascend_WeSpeaker-ResNet34-LM/log.txt详细评测日志见 log.txt。
inference.py 支持以下命令行参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--audio | str | 必填 | 输入音频文件路径 |
--compare | str | None | 对比音频文件路径 |
--device | str | npu | 推理设备(npu/cpu) |
--model | str | auto | 模型 safetensors 路径 |
import sys
sys.path.insert(0, 'ascend_WeSpeaker-ResNet34-LM')
from inference import load_model_weights, extract_embedding
import soundfile as sf
# 加载模型
model = load_model_weights('ascend_WeSpeaker-ResNet34-LM/model.safetensors', device='npu')
# 提取嵌入
audio, sr = sf.read('test_audio.wav')
emb = extract_embedding(model, audio, sr=sr, device='npu')
print(f'Embedding dim={len(emb)}, norm={sum(emb**2)**0.5:.6f}')