glm-asr-ctc-bench · 导出好的 ONNX 权重
这个仓库不是模型本身,是三个 ASR 引擎导出好、量化好的 ONNX,供 bench-asr-ctc 一条命令拉下来做对比:
git clone https://github.com/JazerJu/bench-asr-ctc && cd bench-asr-ctc
pip install -r requirements.txt
python scripts/download_models.py fetch # 三个引擎全下完
python bench.py --counts 20 --engines glm fun qwen
FETCH_FP16=1 additionally pulls the fp16 variants (DirectML);FETCH_FP32=1
拉 GLM 的 fp32。下载脚本会把文件放到 models/<engine>/ 下,不需要手动摆放。
目录
三个引擎各一个文件夹,共 3.05 GB。
glm-ctc/ — GLM-ASR-Nano + 我们训练的 CTC 头
| 文件 | 大小 | |
|---|---|---|
GLM-ASR-Encoder.q4.onnx (+.data) |
131.9 + 231.3 MB | 编码器 int4,635 M 参数,50 fps |
GLM-ASR-Encoder.fp16.onnx (+.data) |
3.7 + 1270.4 MB | 编码器 fp16,DirectML 用 |
GLM-ASR-Projector.fp16.onnx |
58.7 MB | 投影器,吃 4 帧堆叠后的 5120 维 |
GLM-ASR-CTC-Final134k.q4.onnx |
21.8 MB | CTC 头 int4,40.0 M 参数 |
GLM-ASR-CTC-Final134k.fp16.onnx |
80.1 MB | CTC 头 fp16 |
GLM-ASR-CTC-Final134k.fp32.onnx |
160.0 MB | CTC 头 fp32,做一致性对拍用 |
tokens-phase2.txt |
0.9 MB | 59,264 条,CTC 与 LLM 共用 |
qwen-ctc/ — Qwen3-ASR-1.7B + 我们训练的 CTC 头(v1)
| 文件 | 大小 | |
|---|---|---|
Qwen3-ASR-Encoder.q4.onnx |
185.9 MB | 编码器 int4,317.5 M 参数,13 fps |
Qwen3-ASR-Encoder.fp16.onnx |
635.6 MB | 编码器 fp16 |
Qwen3-ASR-CTC.q4.onnx |
26.3 MB | CTC 头 int4,48.3 M 参数 |
Qwen3-ASR-CTC.fp16.onnx |
96.8 MB | CTC 头 fp16 |
tokens.txt |
1.2 MB | 72,468 条,存的是原始字节的 base64 |
preprocessor_config.json |
— | WhisperFeatureExtractor 配置 |
fun-asr/ — Fun-ASR-Nano(第三方,镜像)
| 文件 | 大小 |
|---|---|
Fun-ASR-Nano-Encoder-Adaptor.int4.onnx |
127.6 MB |
Fun-ASR-Nano-CTC.int4.onnx |
21.2 MB |
tokens.txt |
1.0 MB |
FunAudioLLM 的模型,int4 转换沿用 CapsWriter-Offline 的打包,镜像在这里只为 一站式复现。
接线时容易踩的三个坑
这些权重不是随便 InferenceSession 一下就能用的,每条弄错都不报错、只是结果是错的:
① Qwen3 的帧率是 13 fps,不是 50。 有效输出帧数是
full*13 + ceil(leave/8)(full, leave = divmod(mel_frames, 100)),不是 T/8。
用 50 fps 的算法会把帧数高估 4 倍,logits 只有 1/4 长,转写被腰斩。
另外特征提取要 padding=False,再自己零填到 3000 帧桶,把真实帧数作为
feature_length 传进去。
② Qwen3 的反词表化必须走字节。 qwen-ctc/tokens.txt 每行是
<原始字节的 base64>\t<紧凑 id>,要拼 bytes 再统一 decode("utf-8")。
紧凑词表里保留了 89 个字节原语,一个汉字可能跨多个 token,
按字符串 "".join() 拼会得到乱码。GLM 那边的 tokens-phase2.txt 则可以直接拼。
③ GLM 的投影器吃的是堆叠后的特征。 编码器输出 1280 维,投影器的输入是
5120 = 1280 × 4,要把 4 个连续帧拼成一个再喂。直接送 1280 维会报
Got: 1280 Expected: 5120。
完整说明见两个导出仓库的 AGENTS.md:
GLM-ASR-CTC-GGUF /
Qwen3-ASR-CTC-GGUF。
识别率参考
FLEURS 官方 test 全量(7,876 句,11 语种,全部 int4 + CUDA EP),CTC 首遍:
| 语种 | 指标 | GLM | Fun | Qwen3 |
|---|---|---|---|---|
| en_us | WER | 18.3% | 18.1% | 18.3% |
| cmn_hans_cn | CER | 10.7% | 9.3% | 10.9% |
| ko_kr | CER | 39.5% | 46.0% | 20.3% |
| ja_jp | CER | 31.0% | 17.0% | 30.9% |
| yue_hant_hk | CER | 42.7% | 43.2% | 30.1% |
| de / fr / es / it / nl / pl | WER | 29.7–69.3% | 63.0–98.8% | 35.6–77.1% |
GLM 6 胜 / Fun 3 胜 / Qwen 2 胜。原始数据和更多切分(Buckeye 口语英文、
中英夹杂、口语技术词召回)见 bench 仓库的 results/。
注意 provider 会影响结果:Fun 的 int4 ONNX 不是 provider 不变的 —— ORT CPU 与 CUDA EP 的转写在约 5% 的样本上不同(最多差 1.9pp CER,CPU 更弱)。 做对比时三个引擎必须用同一个 execution provider,并把它记进结果元数据。
来源与许可
| GLM 编码器 / 投影器 | 从 zai-org/GLM-ASR-Nano-2512 导出,int4 由我们做 |
| GLM CTC 头 | 我们训练的,134k 步,权重原件 JazerJu/glm-asr-ctc |
| Qwen3 编码器 | 官方 Qwen/Qwen3-ASR-1.7B 的 audio tower,冻结,int4 由我们做 |
| Qwen3 CTC 头 | 我们训练的,权重原件 JazerJu/qwen3-asr-ctc |
| Fun-ASR-Nano | FunAudioLLM 的模型,int4 转换来自 CapsWriter-Offline |
我们训练的部分按基础模型的 Apache-2.0 发布。Fun-ASR-Nano 按其上游许可, 这里只是镜像。训练语料各自的许可归各自所有者,本仓库不含任何语料数据。