Files
live-caption/docs/asr-backends.md
T
blumia d234b9658d docs: refresh docs to match the current state, add GUI/CLI/troubleshooting
The README still listed the settings UI as "todo" and its quick start told
users to download models into the working directory; phase 3 still described
the caption window's close button as "quit" and used the wrong binary name.
Bring the docs up to date and fill the gaps: a GUI guide (first run, settings
tabs, tray, download, verify), a full CLI option reference marking the
test-only flags, a troubleshooting page, the model registry's size/sha256
fields plus a licence/size table, the RTF measurement caveat (llama-cli 0.19
vs the in-process 0.56), and a note that the streaming-ONNX backend has its
own code path. phase0/phase1 experiment docs are marked as historical.

文档与现状对齐:README 的 Phase 4 从「待做」改为完成、快速开始不再让人把模型下到当前
目录;phase3 的 ✕ 说明改为「隐藏到托盘」、用法改用 live-caption;新增 GUI/CLI/排错三份
文档;asr-backends 补上注册表的 size/sha256 字段与模型许可/体积表;phase0 补上 RTF 口径
说明(llama-cli 的 0.19 与程序内的 0.56);phase2 补上「流式 ONNX 走另一条分支」的说明。
2026-10-12 17:29:45 +08:00

155 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 推理后端与模型管理
## 结构:2 个实现覆盖所有模型
实测确认了一件很重要的事:**不同模型不需要各写一套代码**。所有流式 ONNX 模型走的是同一套 API,差别只是「指向哪个模型文件 + 几行选项」。
```
IAsr(src/core/iasr.h)
├─ Qwen3Asr llama.cpp / ggml GGUF 模型(Qwen3-ASR) AsrKind::PrefixRollback
└─ SherpaAsr sherpa-onnx / onnxruntime
├─ X-ASR-zh-en 中英流式
├─ zipformer-zh-2025 中文流式(k2-fsa 官方)
└─ Nemotron-3.5 40 语言流式(含日语) AsrKind::NativeStreaming
```
两条路径的区别(`StreamingAsr` 里按 `IAsr::kind()` 分流):
| | PrefixRollback | NativeStreaming |
|---|---|---|
| 模型类型 | 离线模型(LLM 解码器) | 有状态流式识别器 |
| 上层要做的 | 切块 + 前缀回滚 + KV 复用 | 只喂音频,取当前整句文本 |
| 每步成本 | 随句子长度增长 | 恒定 |
| 已稳定/不稳定 | 用 token 回滚算 | 用「与上次的公共前缀」算 |
## 模型注册表与存储
**新增模型 = 加一条数据,不改代码。**
- 注册表:`data/models.json`(编译进二进制,同时也给脚本用)
- 存储位置:`~/.local/share/live-caption/models/<id>/`
(即 `QStandardPaths::GenericDataLocation + /live-caption/models`)
- 下载:GUI 的「模型 → 下载」,或 `scripts/fetch-models.sh [id...]` / `--all`;已存在的文件会跳过
```bash
./scripts/fetch-models.sh # 列出模型与安装状态
./scripts/fetch-models.sh zipformer-zh-2025
```
一条模型长这样:
```json
{
"id": "zipformer-zh-2025",
"name": "中文流式(k2-fsa 官方 2025-06-30)",
"backend": "sherpa-online", // llama-cpp | sherpa-online
"languages": ["zh"],
"license": "Apache-2.0",
"note": "167MB,最快最准的中文流式模型",
"files": {
"encoder": { "name": "encoder.int8.onnx", "url": "https://...", "size": 161000000, "sha256": "5ac5..." },
"tokens": { "name": "tokens.txt", "url": "https://...", "size": 3000, "sha256": "6193..." }
}
}
```
`size` / `sha256` 就是完整性校验的依据:**打开/选择模型时只比大小**(快),
「校验完整性」或 `--verify-model` 才**重算 sha256**(慢,但能发现内容损坏)。
## 模型清单
| id | 语言 | 后端 | 许可 | 体积 | sha256(首个文件,前 16 位) |
|---|---|---|---|---|---|
| `qwen3-asr-0.6b-q8` | 52 语言 | llama-cpp | Apache-2.0 | 1019MB | `bca259818b50ca7c…` |
| `zipformer-zh-2025` | zh | sherpa-online | Apache-2.0 | 167MB | `5ac51e27981bb4da…` |
| `xasr-zh-en-480` | zh, en | sherpa-online | Apache-2.0 | 615MB | `0c3454033d249081…` |
| `nemotron35-560ms` | 16 语言(含 ja) | sherpa-online | OpenMDW-1.1 | 682MB | `012e9321373af990…` |
分发包模型时记得带上许可(尤其 Nemotron 是 OpenMDW-1.1,不是 Apache-2.0)。
## 用法
```bash
# 默认后端:llama.cpp + Qwen3-ASR GGUF
./build/live-caption-cli --model M.gguf --mmproj MM.gguf
# 流式 ONNX 后端:按注册表 id 从模型目录取
./build/live-caption-cli --asr-backend sherpa --asr-model zipformer-zh-2025
./build/live-caption-cli --asr-backend sherpa --asr-model nemotron35-560ms --language ja
# 覆盖模型目录 / 语言提示
./build/live-caption-cli --asr-backend sherpa --asr-model ... --model-dir /path/to/models
```
## 实测对比(同一批音频,1 线程)
| 模型 | 中文 | 英文 | 日语 | RTF | 核·秒/秒音频 | 首个字幕 | 体积 | 许可 |
|---|---|---|---|---|---|---|---|---|
| Qwen3-ASR 0.6B(llama) | ✅ | ✅ | ✅ | 0.56 | 4.27 | ~2.5s | 973MB | Apache-2.0 |
| zipformer-zh-2025 | ✅ | — | — | 0.098 | **0.10** | **0.48s** | 167MB | Apache-2.0 |
| X-ASR-zh-en 480ms | ✅ | ✅ | — | 0.122 | 0.12 | 1.44s | 587MB | Apache-2.0 |
| Nemotron 3.5 560ms | ⚠️ 漏字 | ⚠️ 若干错词 | ⚠️ 有错字 | 0.35 | 0.35 | 1.12s | 651MB | OpenMDW-1.1 |
> 静态模型(zipformer-zh-2025)的多线程是**负优化**:onnxruntime 对小模型开多线程,
> 同步/自旋开销会让它更慢(8 线程比 1 线程慢 2.6 倍、CPU 高 28 倍)。所以适配器里固定
> `threads = 1`。
## 设置对话框
三个页签(模型 / 显示 / 高级),底部三个按钮 **应用 / 取消 / 确定** ——
「应用」= 应用但不关闭,方便实时预览(改不透明度、字号时会立刻看到效果)。
只有**模型 / 识别语言 / 采集设备**变化才会重启识别后端;透明度、字号、行数、位置这类外观改动是即时生效的,不会打断正在进行的转写。
各设置项的完整说明见 [gui.md](gui.md)。
## 采集设备选择
默认跟随系统默认输出;也可以在设置里指定某个输出设备(`--list-devices` 可列出):
```bash
./build/live-caption-cli --list-devices
./build/live-caption-cli --cli-live --device alsa_output...HiFi__HDMI1__sink
```
## 完整性校验
注册表里每个文件都记了 `size` 与 `sha256`:
- 快速检查(打开/选择模型时):文件存在且**大小**对得上;
- 完整校验(设置里「校验完整性」或 `--verify-model <id>`):逐个**重算 sha256**,损坏的文件名会列出来。
```bash
./build/live-caption-cli --verify-model zipformer-zh-2025
```
## 两个坑
1. **sherpa-onnx 的预编译库是旧 C++ ABI**(`_GLIBCXX_USE_CXX11_ABI=0`),和 Qt 的新 ABI 冲突,
C++ API 链接不上。**必须用它的 C API**(`sherpa-onnx/c-api/c-api.h`,`extern "C"`,无名字改写)。
2. **末尾要补一小段静音**(`streamFinish()` 里补 0.3s),否则最后一个字会被截掉。
但**不需要 `InputFinished`**:实时字幕的音频流永不结束,一句话的边界是「静音」而不是「输入结束」,
`InputFinished` 的语义只对文件成立。实测只补静音(不调 `InputFinished`)结果就是完整的。
真实场景里那段尾部静音本来就会被喂进去(VAD 判定静音要 0.8s,这 0.8s 已经送给模型了),
所以补静音只是个兜底。
## 自动语言识别
| 模型 | 自带 LID |
|---|---|
| Qwen3-ASR | ✅ 输出 `language X`(实测中英都准)|
| Nemotron 3.5 | ✅ `language=auto`,但实测会串(日语开头吐韩文)|
| X-ASR / zipformer | ❌ 固定语言对,不出语言标签 |
LID 不必由 ASR 模型提供:Chrome 就带了个独立的 2.5MB `ONDEVICE_langid.tflite`(我们在它的语言包目录里看到了),
Windows 同样。sherpa-onnx 也有专门的语种识别模型。所以**「按语言装包 + 用户选语言或小 LID 模型」**是可行路线。
## 推荐组合(按语言装包)
| 语言 | 实时预览 | 定稿 |
|---|---|---|
| 中文 | `zipformer-zh-2025`(最快最准) | Qwen3-ASR |
| 英文 | `xasr-zh-en-480` | Qwen3-ASR |
| 日语 | `nemotron35-560ms --language ja`(质量一般) | Qwen3-ASR(开源日语第一) |
| 其他 | — | Qwen3-ASR(52 语言兜底) |