1. 简介
本文档记录 speaker-diarization-community-1(pyannote 声纹分割/说话人日志模型)在昇腾 NPU(Ascend 910B3)环境的适配部署与精度验证结果。
该模型基于 pyannote.audio 4.0.4 的 SpeakerDiarization 流水线,包含三个子模块:
- 分割模型(Segmentation):PyanNet 架构(SincNet + 4层双向 LSTM),约 0.8M 参数,用于检测说话人活动区域
- 嵌入模型(Embedding):WeSpeaker ResNet34-LM,将语音片段映射为 256 维说话人嵌入向量
- 聚类(PLDA + VBx):基于 PLDA 的贝叶斯 HMM 说话人聚类
本项目完成该模型在昇腾 NPU 上的推理适配,验证 NPU 与 CPU 结果的精度误差 < 1%。
相关地址:
2. 验证环境
| 组件 | 版本 |
|---|
| Python | 3.11.x |
| PyTorch | 2.10.0+cpu |
| torch_npu | 2.10.0 |
| torchaudio | 2.10.0 |
| pyannote.audio | 4.0.4 |
| einops | 最新 |
| soundfile | 最新 |
| CANN | 8.5.1 |
| NPU 硬件 | Ascend 910B3 (8 卡) |
3. 模型信息
| 项目 | 值 |
|---|
| 模型架构 | SincNet + 4x BiLSTM + FC + LogSoftmax (Segmentation) |
| WeSpeaker ResNet34-LM (Embedding) |
| VBx PLDA (Clustering) |
| 分割模型参数量 | ~1.47M |
| 嵌入模型参数量 | ~6.8M |
| 采样率 | 16kHz |
| 输出格式 | RTTM 格式说话人日志(含起止时间、说话人标签) |
| 权重格式 | PyTorch .bin |
| 推理框架 | pyannote.audio Pipeline |
| 预训练数据 | VoxCeleb, AMI, DIHARD 等 |
| 许可证 | CC-BY-4.0 |
4. Conda 环境安装
conda create -n speaker-diarization python=3.11 -y
conda activate speaker-diarization
# 安装 PyTorch + torch_npu(华为镜像加速)
pip install torch==2.10.0 torchvision==0.25.0 torchaudio==2.10.0 \
--index-url https://repo.huaweicloud.com/repository/pypi/simple/
pip install torch_npu==2.10.0 \
--index-url https://repo.huaweicloud.com/repository/pypi/simple/
# 安装 pyannote.audio 及依赖
pip install pyannote.audio==4.0.4 einops soundfile
# 如需从 HuggingFace 下载原始权重(可选)
# export HF_ENDPOINT=https://hf-mirror.com
# huggingface-cli download pyannote/speaker-diarization-community-1 --local-dir /path/to/model
5. 推理执行
# NPU 推理
python3 inference.py \
--model_path /path/to/speaker-diarization-community-1 \
--audio_path /path/to/audio.wav
# CPU 推理
python3 inference.py \
--model_path /path/to/speaker-diarization-community-1 \
--audio_path /path/to/audio.wav \
--device cpu
# 指定说话人数量(可选)
python3 inference.py \
--model_path /path/to/speaker-diarization-community-1 \
--audio_path /path/to/audio.wav \
--num_speakers 2
# 评测
python3 benchmark.py --model_path /path/to/speaker-diarization-community-1
6. 参数说明
inference.py
| 参数 | 类型 | 默认值 | 说明 |
|---|
--model_path | str | 必填 | 模型目录路径 |
--audio_path | str | 必填 | WAV 音频文件路径(16kHz 单声道) |
--device | str | npu:0 | 推理设备(npu:0 或 cpu) |
--num_speakers | int | None | 已知说话人数量 |
--min_speakers | int | None | 最少说话人数 |
--max_speakers | int | None | 最多说话人数 |
benchmark.py
| 参数 | 类型 | 默认值 | 说明 |
|---|
--model_path | str | 必填 | 模型目录路径 |
--npu_device | str | npu:0 | NPU 设备 |
--num_warmup | int | 3 | NPU 预热次数 |
--duration | float | 5.0 | 测试音频长度(秒) |
7. 精度评测结果
分割模型(Segmentation)输出精度
| 输出张量 | 向量级相对误差 | 余弦相似度 | 最大绝对误差 | 平均绝对误差 |
|---|
| segmentation scores (1, 293, 7) | 0.247265% | 0.9999988675 | 0.023200 | 0.008008 |
| 指标 | 实测值 | 阈值 | 状态 |
|---|
| 向量级相对误差 | 0.247% | < 1% | PASS |
| 余弦相似度 | 0.999999 | > 0.99 | PASS |
说明
NPU vs CPU 精度误差主要来源于以下两方面:
- LSTM FP16 精度误差:NPU 上 LSTM 层需使用 FP16(半精度)运行,FP16 的尾数精度(约 3.3 位十进制有效数字)低于 FP32 的 7.2 位,引入微小数值差异。
- 算子实现差异:昇腾 NPU 的算子实现与 CUDA/CPU 存在微小的数值差异。
实际测试向量级相对误差为 0.247%,远低于 1% 阈值,满足精度要求。
8. 性能数据
| 操作 | 耗时 |
|---|
| CPU 推理时间(FP32) | 0.464s |
| NPU 推理时间(FP16,3 轮预热后) | 0.017s |
| 加速比 | 27.07x |
9. 适配说明
9.1 NPU 适配要点
昇腾 NPU 上的 torch.nn.LSTM 算子要求输入为 FP16 精度。本适配通过 monkey-patch PyanNet.forward 方法,在调用 LSTM 前自动将输入转换为 FP16,并在 LSTM 输出后转回 FP32,保证后续层在 FP32 精度下运行。
9.2 文件说明
| 文件 | 说明 |
|---|
inference.py | NPU/CPU 推理脚本,支持命令行参数 |
benchmark.py | 精度与性能评测脚本 |
log.txt | 评测运行日志 |
README.md | 本文档 |
10. 注意事项
- 输入音频要求 16kHz 单声道 WAV 格式,脚本自动处理重采样和声道转换。
- NPU 上 LSTM 层自动以 FP16 运行(
pipeline.to(npu) 后脚本自动处理)。
- 如需在 CPU 上推理对比精度,确保不调用
pipeline.to(npu) 即可。
- 对于长音频(>30 分钟),建议分段处理或使用
segmentation_batch_size 参数控制 batch 大小。
- 嵌入模型(ResNet34-LM)和 PLDA 聚类在 CPU 上运行,不影响精度。