本文档记录 facebook/wav2vec2-base-960h 语音识别模型在昇腾 NPU(Ascend 910B3)上的迁移适配、精度评测与性能验证结果。
Wav2Vec2 是 Facebook 提出的自监督语音表示学习模型,通过对原始音频波形进行 CNN 特征提取 + Transformer 上下文建模,再通过 CTC(Connectionist Temporal Classification)头进行语音识别。该模型在 LibriSpeech 960 小时英文语料上微调,支持 16kHz 采样率单声道音频输入,输出英文字母级 CTC 序列。
Wav2Vec2 的特征提取(CNN)和 Transformer 层在 NPU 上均有对应算子支持,适配集中在设备迁移和预处理管道。
相关获取地址:
facebook/wav2vec2-base-960h| 组件 | 版本 |
|---|---|
torch | 2.8.0 |
torch_npu | 2.8.0.post4 |
transformers | 5.8.1 |
CANN | 8.5.1 |
8 × Ascend 910B3conda create -n wav2vec2-base-960h python=3.11 -y
conda activate wav2vec2-base-960h
pip install torch==2.8.0 torch_npu==2.8.0.post4 \
-i https://pypi.tuna.tsinghua.edu.cn/simple
pip install transformers torchaudio numpy soundfile \
-i https://pypi.tuna.tsinghua.edu.cn/simplemodelscope download --model facebook/wav2vec2-base-960h \
--local_dir ./wav2vec2-base-960h# 单条语音识别
python inference.py --audio speech.wav --device npu
# 编程接口
python inference.py --audio_dir ./audio/ --device npufrom inference import Wav2Vec2ASR
asr = Wav2Vec2ASR(model_path="./wav2vec2-base-960h", device="npu")
# 从文件读取
import soundfile as sf
audio, sr = sf.read("speech.wav")
# 转写
text = asr.transcribe([audio], sampling_rate=sr)
print(text[0])python inference.py --audio speech.wav --device npu预期输出:音频的英文转写文本(CTC 解码),无运行时错误。
验证 NPU 设备:
import torch, torch_npu
print(f"NPU count: {torch.npu.device_count()}")
print(f"Device: {torch.npu.get_device_name(0)}")测试条件:8 段 1 秒随机合成音频(16000 采样点,固定随机种子),batch_size=4,NPU 预热 1 轮。
| 指标 | 数值 |
|---|---|
| CPU 吞吐量 | 7.0 audio/s |
| NPU 吞吐量 | 202.6 audio/s |
| CPU/NPU 加速比 | 28.8 × |
音频模型在 CPU 上推理较慢(需处理长序列音频帧),NPU 加速效果显著,适合实时语音识别场景。Wav2Vec2 的 CNN 特征编码器和 Transformer 层在 NPU 上均能获得良好加速。
分别在 CPU 和 NPU 上对 8 段合成音频进行推理(固定随机种子保证输入一致),比较:
| 指标 | 数值 |
|---|---|
| 平均余弦相似度 | 0.999985 |
| 平均 MAE | 0.023024 |
| 平均最大误差 | 0.146569 |
| 精度误差率 | 0.0015% |
| Token 匹配率 | 100.0% |
结论:精度误差率 0.0015%,远低于 1% 要求。逐帧 CTC token 匹配率 100%,转写结果与 CPU 完全一致,评测通过。
注:音频模型的 logits MAE(0.023)高于图像/文本模型,这是因为 Wav2Vec2 的 CNN 特征提取包含多层卷积,卷积累加效应导致单元素误差偏大,但余弦相似度和 Token 匹配率证明语义方向完全一致,不影响最终转写结果。
Wav2Vec2 由三部分组成:
AutoModelForCTC.from_pretrained() 加载,model.to("npu:0") 迁移AutoProcessor)在 CPU 完成:重采样到 16kHz → 归一化 → 转为 tensorprocessor.batch_decode())masked_spec_embed 参数在新版 checkpoint 中缺失(TF 导出遗留),会自动初始化,不影响推理精度import torch, torch_npu
from transformers import AutoProcessor, AutoModelForCTC
model = AutoModelForCTC.from_pretrained("wav2vec2-base-960h").to("npu:0")
processor = AutoProcessor.from_pretrained("wav2vec2-base-960h")
inputs = processor(audio, sampling_rate=16000, return_tensors="pt", padding=True)
inputs = {k: v.to("npu:0") for k, v in inputs.items()}
with torch.no_grad():
logits = model(**inputs).logits
pred_ids = torch.argmax(logits, dim=-1)
text = processor.batch_decode(pred_ids)torchaudio.functional.resample() 或 scipy.signal.resample()padding=True 自动填充到 batch 内最长长度,超长样本可能造成大量填充浪费,建议先按长度分组