补 README.md:独立推理实现 / 从权重形状导出的完整 config / 重写 README
Browse files
README.md
CHANGED
|
@@ -1,21 +1,146 @@
|
|
| 1 |
---
|
| 2 |
license: apache-2.0
|
|
|
|
| 3 |
pipeline_tag: automatic-speech-recognition
|
|
|
|
| 4 |
tags:
|
| 5 |
-
- asr
|
| 6 |
- ctc
|
| 7 |
-
-
|
|
|
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
# GLM-ASR-CTC
|
| 11 |
|
| 12 |
-
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|---|---|
|
| 16 |
-
|
|
| 17 |
-
|
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
|
|
|
| 1 |
---
|
| 2 |
license: apache-2.0
|
| 3 |
+
base_model: zai-org/GLM-ASR-Nano-2512
|
| 4 |
pipeline_tag: automatic-speech-recognition
|
| 5 |
+
library_name: pytorch
|
| 6 |
tags:
|
|
|
|
| 7 |
- ctc
|
| 8 |
+
- speech-recognition
|
| 9 |
+
- forced-alignment
|
| 10 |
+
- multilingual
|
| 11 |
+
language: [zh, en, yue, ja, ko, de, fr, es, it, pt, nl, pl]
|
| 12 |
---
|
| 13 |
|
| 14 |
+
# GLM-ASR-CTC
|
| 15 |
|
| 16 |
+
40.0 M 参数的 CTC 头,接在**冻结的** GLM-ASR-Nano-2512 音频编码器后面,做首遍
|
| 17 |
+
(first-pass) 转写和强制对齐。编码器不在本仓库,运行时从
|
| 18 |
+
[`zai-org/GLM-ASR-Nano-2512`](https://huggingface.co/zai-org/GLM-ASR-Nano-2512) 加载。
|
| 19 |
|
| 20 |
+
用途是给"CTC 首遍 + LLM 二遍"这类流水线提供快速首遍:贪心解码 RTF 0.0002
|
| 21 |
+
(8 卡批量),并且天然能出帧级时间戳。CTC 和 LLM decoder **共用同一套
|
| 22 |
+
tokenizer**,所以首遍文本可以直接喂给 decoder 或热词 RAG,中间不用转换。
|
| 23 |
+
|
| 24 |
+
## 识别率
|
| 25 |
+
|
| 26 |
+
五个 held-out 测试集(训练集从没见过,逐条核对过没有污染),CTC 首遍贪心解码、
|
| 27 |
+
不含 LLM 二遍:
|
| 28 |
+
|
| 29 |
+
| 语料 | 指标 | 本模型 | 对照:Qwen3-ASR-CTC |
|
| 30 |
+
|---|---|---|---|
|
| 31 |
+
| AISHELL-1 test | CER | **4.71%** | 5.31% |
|
| 32 |
+
| AISHELL-1 dev | CER | **4.09%** | 4.37% |
|
| 33 |
+
| LibriSpeech test-clean | WER | **4.88%** | 6.93% |
|
| 34 |
+
| LibriSpeech test-other | WER | **9.99%** | 12.40% |
|
| 35 |
+
| ASCEND test(中英混说) | MER | **11.84%** | 14.53% |
|
| 36 |
+
|
| 37 |
+
对照那一列是同一批数据、同一套超参训出来的
|
| 38 |
+
[Qwen3-ASR 版](https://huggingface.co/JazerJu/qwen3-asr-ctc)。GLM 在五个集上
|
| 39 |
+
全面领先,按句配对自举 2000 次、八次对比全部 100.0%,没有一个置信区间沾到 0。
|
| 40 |
+
差距很可能来自编码器容量:GLM 的 audio tower 是 635.0 M 参数 / 有效宽度 1280,
|
| 41 |
+
Qwen3 是 317.5 M / 1024 —— Qwen3-ASR-1.7B 把容量放在 LLM 上,
|
| 42 |
+
对一个永远看不到 LLM 的 CTC 头恰好是反的。
|
| 43 |
+
|
| 44 |
+
FLEURS 全量官方 test split(7,876 条,11 语种,int4,CUDA EP)对 Fun-ASR-Nano
|
| 45 |
+
是 8 胜 3 负,详见 [bench-asr-ctc](https://github.com/JazerJu/bench-asr-ctc)。
|
| 46 |
+
|
| 47 |
+
## 时间戳精度(对 Montreal Forced Aligner 真值实测)
|
| 48 |
+
|
| 49 |
+
LibriSpeech test-clean/other 的 1,500 句 / 29,621 词,真值来自
|
| 50 |
+
[`gilkeyio/librispeech-alignments`](https://huggingface.co/datasets/gilkeyio/librispeech-alignments):
|
| 51 |
+
|
| 52 |
+
| | 本模型(50 fps) | Qwen3 版(13 fps) |
|
| 53 |
+
|---|---|---|
|
| 54 |
+
| 词起始 中位偏置 | +105.0 ms | +100.0 ms |
|
| 55 |
+
| 词结束 中位偏置 | −100.0 ms | −78.5 ms |
|
| 56 |
+
| 起始 去偏置后 中位\|误差\| | **40.0 ms** | 50.8 ms |
|
| 57 |
+
| 起始 去偏置后 ≤100 ms | **82.4%** | 77.6% |
|
| 58 |
+
| 结束 去偏置后 中位\|误差\| | **50.0 ms** | 60.0 ms |
|
| 59 |
+
| 结束 去偏置后 ≤100 ms | **81.9%** | 73.5% |
|
| 60 |
+
|
| 61 |
+
那个 +105 ms 的起始延迟是**常数**,是 CTC 尖峰式发射的固有性质(概率集中在词的
|
| 62 |
+
中间),不是模型缺陷,减掉即可。
|
| 63 |
+
|
| 64 |
+
顺带一个实测结论:**帧率不是时间戳精度的主导误差项**。本模型帧移 20 ms、
|
| 65 |
+
Qwen3 是 76.9 ms,差 3.85 倍,但去偏置后的中位误差只差约 10 ms —— 主要误差
|
| 66 |
+
来自模型对词边界本身的不确定性,不是量化。
|
| 67 |
+
|
| 68 |
+
## 训练
|
| 69 |
+
|
| 70 |
+
| | |
|
| 71 |
|---|---|
|
| 72 |
+
| 编码器 | GLM-ASR-Nano-2512 audio tower,**全程冻结**(635.0 M 参数,输出 1280 维,50 fps) |
|
| 73 |
+
| CTC 头 | 1280→2048→512,5 层 Transformer block(8 头,FFN 128),59,264 类 |
|
| 74 |
+
| 参数量 | 39,997,952 |
|
| 75 |
+
| 数据 | 26 个 manifest / 7,442,192 条,15 个语种,约 1.2 万小时 |
|
| 76 |
+
| 语料 | 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 倍上采样) |
|
| 77 |
+
| 硬件 | 8× A100-SXM4-40GB |
|
| 78 |
+
| 配方 | batch 8/卡、grad_accum 4(256 样本/更新)、lr 5e-4 余弦、1 个 warmup epoch(blocks 冻结)+ 3 个满 epoch |
|
| 79 |
+
| 步数 / 时长 | 134,140 次更新 / 约 16 小时 |
|
| 80 |
+
| 最终 loss | train 0.4604 / val 0.5211 |
|
| 81 |
+
|
| 82 |
+
## 用法
|
| 83 |
+
|
| 84 |
+
```bash
|
| 85 |
+
pip install torch "transformers>=5.0" safetensors soundfile
|
| 86 |
+
```
|
| 87 |
+
|
| 88 |
+
```python
|
| 89 |
+
from modeling_ctc import GlmCtcAsr
|
| 90 |
+
|
| 91 |
+
asr = GlmCtcAsr(".", device="cuda") # 自动拉 zai-org/GLM-ASR-Nano-2512
|
| 92 |
+
print(asr.transcribe([waveform_16k_float32]))
|
| 93 |
+
```
|
| 94 |
+
|
| 95 |
+
离线环境把本地编码器目录给 `GLM_ASR_ENCODER`。完整示例(含 CTC 强制对齐出
|
| 96 |
+
字级时间戳)见 `example.py`:
|
| 97 |
+
|
| 98 |
+
```bash
|
| 99 |
+
python example.py audio.wav
|
| 100 |
+
# 转写: 甚至出现交易几乎停滞的情况
|
| 101 |
+
# 字级时间戳(帧移 20.0 ms):
|
| 102 |
+
# '甚至' 0.44 - 0.46 s
|
| 103 |
+
# '出现' 0.96 - 0.98 s
|
| 104 |
+
# ...
|
| 105 |
+
```
|
| 106 |
+
|
| 107 |
+
> ⚠️ **transformers 必须 ≥ 5.0。** GLM-ASR 的 `model_type` 是 `glmasr`,
|
| 108 |
+
> 4.x 不认识它,会报 "does not recognize this architecture"。钉在 4.x 的环境
|
| 109 |
+
> 只能走 ONNX 路径,见下面的导出仓库。
|
| 110 |
+
|
| 111 |
+
## 和 Qwen3 那版的接线差异
|
| 112 |
+
|
| 113 |
+
两个 CTC 头结构同构、超参不同,但**编码器的调用约定完全不一样**,混用会静默出错:
|
| 114 |
+
|
| 115 |
+
| | 本仓库(GLM) | [Qwen3 版](https://huggingface.co/JazerJu/qwen3-asr-ctc) |
|
| 116 |
+
|---|---|---|
|
| 117 |
+
| 编码器加载 | `AutoModel.from_pretrained().audio_tower` | `qwen_asr.Qwen3ASRModel`(`AutoModel` 加载不了) |
|
| 118 |
+
| 编码器输入 | `[B, 128, T]` 三维 | `[128, ΣT]` 时间维拼接 + `feature_lens` |
|
| 119 |
+
| 输出帧率 | **50 fps**(20 ms/帧) | **13 fps**(76.9 ms/帧),且不是 `T/8` |
|
| 120 |
+
| 编码器输出维 | 1280 | 2048 |
|
| 121 |
+
| 反词表化 | `tokens-phase2.txt` 直接拼字符串 | **必须走字节**(紧凑词表含 89 个字节原语) |
|
| 122 |
+
| attention mask | 无需干预 | **必须打补丁**,否则批推理余弦只有 0.81 |
|
| 123 |
+
|
| 124 |
+
本仓库这一侧都是常规做法,`modeling_ctc.py` 里没有需要特别当心的补丁。
|
| 125 |
+
|
| 126 |
+
## 文件
|
| 127 |
+
|
| 128 |
+
| | |
|
| 129 |
+
|---|---|
|
| 130 |
+
| `ctc_head.safetensors` | 40.0 M 参数,fp32,160 MB |
|
| 131 |
+
| `config.json` | 超参,值从权重实际形状导出,含 `ffn_hidden` / `num_heads` |
|
| 132 |
+
| `tokens-phase2.txt` | CTC 与 LLM 共用的 tokenizer pieces(59,264 条) |
|
| 133 |
+
| `modeling_ctc.py` | 独立推理实现,不依赖任何本项目仓库 |
|
| 134 |
+
| `example.py` | 转写 + 强制对齐示例 |
|
| 135 |
+
|
| 136 |
+
## 相关仓库
|
| 137 |
+
|
| 138 |
+
- 训练与评测代码:<https://github.com/JazerJu/glm-asr-ctc-train>
|
| 139 |
+
- ONNX / GGUF 导出与推理:<https://github.com/JazerJu/GLM-ASR-CTC-GGUF>
|
| 140 |
+
- 导出好的 int4 ONNX(可直接跑):<https://huggingface.co/JazerJu/glm-asr-ctc-bench>
|
| 141 |
+
- 三方对比评测:<https://github.com/JazerJu/bench-asr-ctc>
|
| 142 |
+
|
| 143 |
+
## 许可
|
| 144 |
|
| 145 |
+
CTC 头权重按基础模型 GLM-ASR-Nano-2512 的 Apache-2.0 发布。训练语料各自的许可
|
| 146 |
+
归各自所有者,本仓库不含任何语料数据。
|