本文档记录 wsntxxn/cnn8rnn-audioset-sed 在昇腾 NPU(Ascend 910B3)环境的适配部署与精度验证结果。
该模型是一个基于 CRNN(卷积循环神经网络)的声音事件检测(Sound Event Detection)模型,包含 8 层卷积和 1 层 GRU,在 AudioSet 数据集上预训练并在 AudioSet-strong 上微调,时间分辨率 40ms,参数量约 6.4M,可识别 447 类音频事件。
本项目完成该模型在昇腾 NPU 上的推理适配,并验证 NPU 与 CPU 推理结果的精度误差 < 1%。
相关地址:
| 组件 | 版本 |
|---|---|
| Python | 3.11.15 |
| PyTorch | 2.10.0+cpu |
| torch_npu | 2.10.0 |
| transformers | 5.8.1 |
| torchaudio | 2.6.0 |
| CANN | 8.5.1 |
| NPU 驱动 | 25.5.2 |
| NPU 硬件 | Ascend 910B3 (8卡) |
| 操作系统 | Linux (aarch64) |
| 项目 | 值 |
|---|---|
| 模型架构 | Cnn8RnnSoundEventDetection |
| 参数量 | ~6.4M |
| 卷积层数 | 8 层 (ConvBlock ×4) |
| 循环层 | GRU (512→256, bidirectional) |
| 分类数 | 447 (AudioSet) |
| 时间分辨率 | 40ms |
| 采样率 | 32kHz |
| 输入 | 原始波形 (mono, 32kHz) |
| 输出 clipwise_output | (B, 447) — 片段级概率 |
| 输出 framewise_output | (B, 447, T) — 逐帧概率 |
| 前端特征 | Log-Mel 频谱 (n_mels=64, hop=320) |
| 权重格式 | safetensors + pytorch_model.bin |
| 原始框架 | PyTorch (transformers, trust_remote_code) |
| 预训练数据 | AudioSet + AudioSet-strong |
| 许可证 | Apache-2.0 |
创建独立的 conda 环境并安装依赖(使用华为云 PyPI 镜像加速):
# 创建 conda 环境
conda create -n cnn8rnn python=3.11 -y
# 激活环境
conda activate cnn8rnn
# 安装 PyTorch 及相关依赖(华为云镜像)
pip install torch==2.10.0 torchvision==0.25.0 torchaudio==2.6.0 --index-url https://repo.huaweicloud.com/repository/pypi/simple/
# 安装 torch_npu(根据环境选择对应版本)
pip install torch_npu==2.10.0 --index-url https://repo.huaweicloud.com/repository/pypi/simple/
# 安装 transformers 及其他依赖
pip install transformers soundfile scipy --index-url https://repo.huaweicloud.com/repository/pypi/simple/如果 HuggingFace 网络不通,设置镜像:
export HF_ENDPOINT=https://hf-mirror.com/# NPU 推理(默认)
python3 inference.py \
--model_path /path/to/cnn8rnn-audioset-sed \
--wav_path /path/to/audio.wav \
--device npu:0
# CPU 推理
python3 inference.py \
--model_path /path/to/cnn8rnn-audioset-sed \
--wav_path /path/to/audio.wav \
--device cpu
# 使用合成测试信号(无需音频文件)
python3 inference.py \
--model_path /path/to/cnn8rnn-audioset-sed \
--device npu:0输出示例:
Top-10 Predicted Audio Events (clipwise)
1. [354] Speech 0.9213
2. [ 1] Air brake 0.8432
...# 自动生成测试波形,对比 NPU 与 CPU 推理精度
python3 eval.py \
--model_path /path/to/cnn8rnn-audioset-sed \
--npu_device npu:0评测结果日志将输出到 log.txt。
| 参数 | 说明 | 默认值 |
|---|---|---|
--model_path | 模型权重路径 | 必需 |
--wav_path | 输入音频路径(可选,默认生成测试信号) | None |
--device | 运行设备(npu:0 或 cpu) | npu:0 |
--top_k | 显示 Top-K 类别 | 10 |
--no_warmup | 跳过预热阶段 | False |
| 参数 | 说明 | 默认值 |
|---|---|---|
--model_path | 模型权重路径 | 模型路径 |
--npu_device | NPU 设备 ID | npu:0 |
--num_warmup | NPU 预热轮数 | 3 |
--duration | 测试波形时长(秒) | 5.0 |
使用同一段合成测试波形(chirp + noise, 5 秒, 32kHz)分别在 CPU(FP32)和 NPU(FP32)上运行推理,对比 clipwise_output 和 framewise_output 的输出差异。
| 指标 | 含义 | 判定阈值 |
|---|---|---|
| 向量级相对误差 | ` | |
| 余弦相似度 | NPU 与 CPU 输出向量间的方向一致性 | > 0.99 |
| 最大/平均绝对误差 | 逐元素差值统计,反映数值偏差的绝对量级 | — |
| 绝对误差分位数 | 误差分布特征(P50/P90/P95/P99) | — |
| 输出张量 | 向量级相对误差 | 余弦相似度 | 最大绝对误差 | 平均绝对误差 |
|---|---|---|---|---|
| clipwise_output | 0.120760% | 0.9999994040 | 2.95e-04 | 7.21e-06 |
| framewise_output | 0.202952% | 0.9999977946 | 1.40e-03 | 4.87e-06 |
绝对误差分布:
| 输出张量 | P50 | P90 | P95 | P99 |
|---|---|---|---|---|
| clipwise_output | 6.50e-07 | 8.56e-06 | 2.34e-05 | 1.84e-04 |
| framewise_output | 1.10e-07 | 4.19e-06 | 1.06e-05 | 8.67e-05 |
| 指标 | 实测值 | 阈值 | 状态 |
|---|---|---|---|
| 向量级相对误差(clipwise) | 0.120760% | < 1% | ✅ PASS |
| 向量级相对误差(framewise) | 0.202952% | < 1% | ✅ PASS |
| 余弦相似度(clipwise) | 0.9999994 | > 0.99 | ✅ PASS |
| 余弦相似度(framewise) | 0.9999978 | > 0.99 | ✅ PASS |
| 操作 | 耗时 |
|---|---|
| CPU 推理时间(FP32) | 0.8883s |
| NPU 推理时间(FP32/GRU FP16,3轮预热后) | 1.4914s |
| 加速比 (CPU / NPU) | 0.60x |
Cnn8RnnSoundEventDetection 类,加载时必须设置 trust_remote_code=True。DynamicGRUV2Hidden 算子仅支持 FP16 输入。eval.py 和 inference.py 在将模型移至 NPU 后会自动将 GRU 权重转为 FP16,并在 GRU 前/后做 dtype 转换,其余部分保持 FP32。经测试该方案精度损失极小(< 0.21%)。framewise_output(逐帧 447 类概率,时间分辨率 40ms)和 clipwise_output(片段级 447 类概率)。classes.txt 文件包含 447 个 AudioSet 事件名称,已随权重文件提供。