Zipformer-Streaming.AXERA
Zipformer 流式中英双语 ASR 的 Axera AX650N 量化推理包。
- Python 推理(
python/streaming_asr.py,axengine + kaldi-native-fbank) - C++ 可执行文件(
bin/zipformer_asr_ax650,aarch64) - 一键运行脚本(
run_ax650.sh) - 真实 streaming 状态校准 + Pulsar2 U16 量化
- 板端 token 精度 / RTF 评测
源码(ONNX 导出、校准、Pulsar2 量化、C++ 源码)见 GitHub: ZY-2012/zipformer_streaming.axera
上游模型:
pfluo/k2fsa-zipformer-chinese-english-mixed
(recipe:icefall pruned_transducer_stateless7_streaming)
权重为 pfluo 原始流式 checkpoint;
sherpa-onnx-...-2023-02-20是另一份较旧的 checkpoint,与本包权重不同。
模型
| 文件 | 大小 | 量化 |
|---|---|---|
models/encoder.axmodel |
80 MB | U16 激活 + S8 权重,attention key/value 投影 FP32 |
models/decoder.axmodel |
14 MB | FP32 |
models/joiner.axmodel |
3.3 MB | U16 + S8 |
流式:chunk=32 帧(320 ms),encoder 输入 T=39 帧(7 帧左上下文), 35 个状态逐 chunk 回填;batch=1,全静态 shape。
模型接口
| 图 | 输入 | 输出 |
|---|---|---|
| encoder | x [1,39,80] fp32 + 35 个状态 |
encoder_out [1,8,512] fp32 + 35 个新状态 |
| decoder | y [1,2] int32 |
decoder_out [1,512] fp32 |
| joiner | encoder_out [1,512], decoder_out [1,512] |
logit [1,6254] fp32 |
状态:cached_len/avg/key/val/val2/conv1/conv2 各 5 个 stage
(layers 2,4,3,2,4,left context 64,32,16,8,32)。blank=0,context=2。
详见 models/model_meta.json。
精度(AX650N,vs FP32 ONNX)
| 测试集 | token error | 说明 |
|---|---|---|
| 20 条域内 wav | **0.735%**(2/272) | 2 条各 1 token |
| 8 条公开测试 wav | **2.27%**(6/264) | 3.wav 尾部 4 token,46/8k 各 1 |
逐张量 cosine:
| 项 | cosine |
|---|---|
| encoder_out(新状态) | 0.9992 |
| encoder_out(state carry) | 0.946 |
| decoder_out | 0.99998 |
| joiner logit | 0.999999 |
无人工标注测试集,上表为与 FP32 ONNX 假设的 token 序列对比; 详见 reports/accuracy.md。
速度(AX650N,C++)
| 指标 | 数值 |
|---|---|
| RTF(含 fbank) | 0.103 – 0.121(6 条平均 0.114) |
| 模型加载 | ~0.7 s |
| 端到端(10 s 音频) | ~1.0 s |
Python(WAV + fbank + axengine)在 10.35 s 音频上约 0.87 s(RTF ≈ 0.084)。 详见 reports/performance.md。
目录结构
zipformer_streaming.axera/
├── models/
│ ├── encoder.axmodel decoder.axmodel joiner.axmodel
│ ├── tokens.txt
│ ├── model_meta.json
│ └── config.json
├── python/
│ ├── streaming_asr.py # 板端 Python 运行时
│ └── requirements.txt
├── bin/
│ └── zipformer_asr_ax650 # 预编译 C++ 可执行文件(aarch64)
├── samples/ # 16 kHz 示例 WAV
├── reports/ # 精度 / 性能
├── run_ax650.sh # 一键运行
├── configuration.json
└── README.md
快速开始(AX650N 板端)
# 默认:C++ + samples 目录
bash run_ax650.sh
# Python
bash run_ax650.sh python
# C++ 指定单条 / 目录
bash run_ax650.sh cpp --audio samples/0.wav
bash run_ax650.sh cpp --audio-dir samples
手动调用:
export LD_LIBRARY_PATH=/soc/lib:${LD_LIBRARY_PATH:-}
./bin/zipformer_asr_ax650 \
--models-dir models --tokens models/tokens.txt \
--audio samples/0.wav
python3 python/streaming_asr.py \
--model-dir models --tokens models/tokens.txt \
--wav samples/0.wav --stats
参数:
- C++:
--models-dir、--tokens、--audio/--audio-dir - Python:
--model-dir、--tokens、--wav/--features、--out、--stats
C++ demo 只接受 16 kHz mono 16-bit PCM WAV;其他采样率/格式请先重采样。
示例输出(AX650N 实测)
bash run_ax650.sh
| wav | 识别结果 |
|---|---|
samples/0.wav |
昨天是 MONDAY TODAY IS礼拜二 THE DAY AFTER TOMORROW是星期三 |
samples/1.wav |
这是第一种第二种叫呃与 ALWAYS ALWAYS ALWAYS是什么意思啊 |
samples/2.wav |
这个是频繁的啊不认识记下来 FREQUENTLY频繁的 |
samples/3.wav |
第一句是个什么时态加了 ES是一般现在时态写上去 |
samples/46.wav |
你好石头把厨房扫脱下 |
samples/demo.wav |
甚至出现交易几乎停滞的情况 |
Python:
bash run_ax650.sh python samples/0.wav
# 0.wav: 昨天是 MONDAY TODAY IS礼拜二 THE DAY AFTER TOMORROW是星期三
# load=1.207s infer=0.642s audio=10.35s rtf=0.062
3.wav 是公开测试中的难例,与 FP32 参考相比尾部有 4 个 token 差异; 其余样本与 FP32 参考均为 0–1 token 差异。
Python 依赖
pip install -r python/requirements.txt
axengine 安装见 AXERA-TECH/pyaxengine;
WAV 模式需要 kaldi-native-fbank,也可以用 --features 读取预计算
.npy [T,80] fbank。
限制
- 仅 greedy 解码(context_size=2),chunk=32(320 ms)。
- demo 为文件级推理,内部按 chunk 回填状态;不含 VAD/麦克风实时采集。
- AX630C 尚未验证;C++ 源码可在 GitHub 用 AX620E 目标重新编译。
- 8 kHz 测试音频需先重采样到 16 kHz(C++ 直接拒绝 8 kHz WAV)。
模型转换
见 GitHub 的 model_convert: pfluo 原始权重 → 静态 ONNX(chunk 32 / T 39)→ pfluo jit 对分 cosine 1.0 → 真实 streaming 状态校准 → Pulsar2 U16 量化。
参考
- 上游模型:pfluo/k2fsa-zipformer-chinese-english-mixed
- icefall:k2-fsa/icefall
- Pulsar2:AXERA-TECH/Pulsar2
- 板端运行时:AXERA-TECH/pyaxengine
- BSP:AXERA-TECH/ax650n_bsp_sdk
- fbank:kaldi-native-fbank
License
推理代码 Apache-2.0;模型权重遵循上游 pfluo / icefall 的许可。