Qwen3-ASR-CTC

一个 48.3M 参数的 CTC 头,接在冻结的 Qwen3-ASR-1.7B 音频编码器后面,做首遍 (first-pass) 转写和强制对齐。编码器不含在本仓库,运行时从 Qwen/Qwen3-ASR-1.7B 加载。

用途是给"CTC 首遍 + LLM 二遍"这类流水线提供快速首遍:贪心解码 RTF 0.0002 (8× 昇腾 910B3,91.3 小时音频 1.1 分钟解完),并且天然能出帧级时间戳。

先说结论:什么时候用它

同一批数据、同一套超参训出来的 GLM-ASR-Nano 版 CTC 头,在五个干净的 held-out 测试集上全面更好

测试集 指标 GLM-ASR-Nano 版 本模型
AISHELL-1 test CER 4.71% 5.31%
AISHELL-1 dev CER 4.09% 4.37%
LibriSpeech test-clean WER 4.88% 6.93%
LibriSpeech test-other WER 9.99% 12.40%
ASCEND test(中英混说) MER 11.84% 14.53%

差距是个与语速无关、近乎恒定的倍数(英文 1.3–1.5×、中文 1.1–1.2×)。 最可能的原因不是编码器,而是优化配方:本模型用 512 样本/更新、只训了 56,916 次更新;GLM 那版是 256 样本/更新、134,140 次更新,而两者 LR 同为 5e-4 (batch 翻倍却没按线性缩放规则放大)。对照实验尚未完成。

所以:这是一个研究产物,不是当前最好的 CTC 首遍模型。 想要最好的转写质量 请用 GLM 那版;想要 Qwen3 编码器的表征、或者要做 13 fps 帧率的对比实验,用这个。

时间戳精度(对 Montreal Forced Aligner 真值实测)

在 LibriSpeech test-clean/other 的 1,500 句 / 29,621 词上,对 gilkeyio/librispeech-alignments 的 MFA 词级对齐:

本模型(13 fps) GLM 版(50 fps)
词起始 中位偏置 +100.0 ms +105.0 ms
词结束 中位偏置 −78.5 ms −100.0 ms
起始 去偏置后 中位|误差| 50.8 ms 40.0 ms
起始 去偏置后 ≤100 ms 77.6% 82.4%
结束 去偏置后 中位|误差| 60.0 ms 50.0 ms

两点要注意:

  1. 有一个系统性偏置,减掉它。 词起始一致偏晚约 100 ms、结束偏早约 80 ms。 这是 CTC 尖峰式发射的固有性质(概率集中在词的中间),不是模型缺陷,是个常数。
  2. 帧率不是精度的主导误差项。 帧移相差 3.85 倍(76.9 vs 20.0 ms), 去偏置后的中位误差只差约 10 ms。单帧量化的理论下限是 ±38 ms, 实测 50.8 ms 只有它的 1.3 倍 —— 主要误差来自模型对词边界的不确定性。

时间轴本身是准的:在音频前面接 1.00 秒数字静音后,98.6% 的字时间戳整体平移 恰好 1.00 秒(中位误差 0.0 ms)。

训练

编码器 Qwen3-ASR-1.7B audio tower,全程冻结
CTC 头 2048→2048→512,5 层 Transformer block(8 头,FFN 128),72,468 类
参数量 48,344,468
数据 26 个 manifest / 7,434,437 条(train 7,285,749 / val 148,688),15 个语种
语料 AISHELL-1、WenetSpeech M、MAGICDATA、Common Voice (yue/zh-HK/zh-TW/ja)、LibriSpeech、GigaSpeech M、KsponSpeech、MLS (de/nl/fr/es/it/pt/pl)、TALCS、CS-Dialogue、ASCEND(后三个中英混说语料 3 倍上采样)
硬件 8× 昇腾 910B3,CANN 9.0.1,torch_npu 2.8.0
配方 batch 64/卡、grad_accum 1、lr 5e-4 余弦、1 个 warmup epoch(blocks 冻结)+ 3 个满 epoch
步数 / 时长 56,916 次更新 / 11 小时 56 分
最终 loss train 0.4958 / val 0.6150

vocab_compact.json 是从 Qwen3 原生的 151,705 词表压出来的紧凑词表:在全部 662 万条语料上只有 72,377 个 token 被用到(47.7%),另外 52.3% 一次都没出现过 —— 那些行的 ctc_lo 权重从头到尾拿不到正梯度,只在 softmax 分母里被反复压低。 压到 72,468 类后省掉 40.6M 参数,实测零 unk、零往返漂移。

用法

pip install torch transformers qwen-asr safetensors soundfile
from modeling_ctc import Qwen3CtcAsr

asr = Qwen3CtcAsr(".", device="cuda")        # 会自动拉 Qwen/Qwen3-ASR-1.7B
print(asr.transcribe([waveform_16k_float32]))

离线环境把本地编码器目录给 QWEN3_ASR_ENCODER。完整示例(含 CTC 强制对齐出 字级时间戳)见 example.py

python example.py audio.wav
# 转写: 甚至出现交易几乎停滞的情况
# 字级时间戳(帧移 76.9 ms):
#   '甚至'   0.77 -  0.85 s
#   '出现'   1.23 -  1.31 s
#   ...

三个会让你静默拿到错误结果的坑

modeling_ctc.py 里都处理了,自己重写时务必照做:

  1. 编码器输入是时间维拼接的 2D 张量 [128, ΣT_mel]feature_lens, 不是 [B, 128, T]。传 3D 会报 split_with_sizes 的错。

  2. 帧率是 13 fps(76.9 ms/帧),不是 Whisper/GLM 的 50 fps。 编码器用 3 层 stride-2 conv2d 做 8 倍降采样,但官方长度公式是"每 100 个 mel 帧出 13 帧" (qwen3_output_lengths(),已对 9 次真实前向逐条核对)。沿用 50 fps 的算法 会把可用帧数高估 4 倍 —— CTC 以为容量充足,实际 log_probs 只有 1/4 长, loss 看着能降但对齐全是错的。

  3. 必须打 attention mask 补丁。 qwen-asr 0.0.6 里 _prepare_attention_mask 定义了却从来没被调用,cu_seq_lens_q/k 只有 flash_attention_2 后端认。 不打补丁时同一条音频单条推理 vs 批推理的余弦相似度只有 0.81–0.88,打完 0.9998+。CUDA 上同样中招,不是昇腾特有的问题。patch_qwen3_attention_mask() 是幂等的,Qwen3CtcAsr 会自动调用。

已知局限

  • 训练语料里 TALCS / MAGICDATA / CS-Dialogue 的官方 test split 混进了训练集, 所以本模型在这三个 test 上的数字不能当泛化指标。上面表格里的五个测试集都是 实测确认干净的。
  • 中文时间戳没有真值可校。本模型在 AISHELL 上比 GLM 版系统性晚约 303 ms, 但英文上两者只差 30.5 ms 且都对得上 MFA —— 中文那个偏差是真实存在的, 只是缺少中文的词级真值,无法判断哪一边更准。
  • 日语只训了 Common Voice ja,覆盖偏窄。

训练与评测代码

https://gitea.cemp.top/jju/glm-asr-ctc-trn-dev

scripts/evaluate.py(CER/WER/MER)、scripts/ctc_align.py(强制对齐 + 三种 验证模式)、scripts/build_test_manifests.py(建 held-out 测试集并实测污染)。

许可

CTC 头权重按基础模型 Qwen3-ASR-1.7B 的 Apache-2.0 发布。训练语料各自的许可 归各自所有者,本仓库不含任何语料数据。

Downloads last month
8
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for JazerJu/qwen3-asr-ctc

Finetuned
(99)
this model