Files
live-caption/docs/phase0-verification.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

111 lines
6.3 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.
# Phase 0 验证报告
结论:**方案成立**。系统播放音频可采集、Qwen3-ASR 可在这套系统库上运行、CPU 实时性有充足余量。可以进入实现阶段。
验证日期:2026-10-12 设备:i5-13420H / 15GB / Intel UHD(无独显)/ Deepin 25 / X11
---
## 1. 验证结论一览
| # | 假设 | 结论 | 证据 |
|---|---|---|---|
| 1 | 系统播放的声音可采集 | ✅ | 默认 sink 的 `.monitor` 源录到真实音频(mean −29.6dB / max −6.7dB)|
| 2 | Qwen3-ASR 能在本机跑 | ✅ | 主模型 arch `qwen3vl` ← `libllama` 的 `llama_model_qwen3vl`;mmproj `clip`+`qwen3a` ← `libmtmd` 的 `clip_graph_qwen3a` |
| 3 | 端到端链路可用 | ✅ | 播放 → monitor 采集 → 16k 单声道 → 转写,文本正确 |
| 4 | 中文可用 + 语言自动检测 | ✅ | `language Chinese<asr_text>不排除购房者可以在互联网上下单。` |
| 5 | CPU 实时性够用 | ✅ | 纯推理 RTF ≈ **0.19**;2s 音频约 0.3s |
| 6 | 纯 C++、无 Python | ✅ | 全程 llama.cpp C/C++ 库 |
## 2. 关键实测数据
环境:`-t 8`(i5-13420H 8 核),模型 `Qwen3-ASR-0.6B-Q8_0` + `mmproj-...-Q8_0`。
| 项目 | 结果 |
|---|---|
| 模型加载(一次性) | ≈ 4.6 s |
| 纯推理 RTF | ≈ 0.19(约 3.8× 实时)|
| 62.6s 音频总耗时 | 16.48 s(含加载)|
| 单块 2s 音频 | 墙钟 ≈ 4.9 s − 加载 4.6 s ⇒ 计算 ≈ **0.3 s** |
| 英文准确率 | 与 LibriSpeech 标准答案逐词一致 |
| 中文准确率 | 与 AISHELL-1 标准答案一致(仅多了标点)|
> 流式含义:模型常驻内存时,处理 2 秒窗口约 0.3 s,滑动窗口 + 提交策略下端到端延迟可做到 **~1 s 级**,与 Chrome 实时字幕同量级。
> **口径提示**:本页的 RTF ≈ 0.19 是 **`llama-cli` 纯生成**(`-t 8`)的数字。
> 程序内走 `libmtmd` 音频编码的实现,实测 RTF ≈ **0.56**(单线程,见
> [asr-backends.md](asr-backends.md#实测对比同一批音频1-线程));两个口径都远低于 1.0,
> 但引用数字时要注意区分。另外流式 ONNX 后端的 CPU 占用比它低约 35 倍。
### 2.1 0.6B vs 1.7B 实测对比
均为 Q8_0 主模型 + Q8_0 mmproj,`-t 8`。
| 指标 | 0.6B | 1.7B |
|---|---|---|
| 加载耗时 | 4.6 s | 6.2 s |
| 纯推理 RTF | **0.19**(≈3.8× 实时)| **0.385**(≈2.6× 实时)|
| 62.6s 音频墙钟 | 16.5 s | 30.2 s |
| 单块 2s 计算量 | ≈0.3 s | ≈0.77 s |
| 内存(主+mmproj) | ≈0.97 GB | ≈2.42 GB |
| 中文 | ✅ 正确 | ✅ 正确 |
| 英文 | `flour-fatted sauce` ✅ | `flour-fattened sauce` ❌ |
**结论**:
- 两个尺寸在本机都**能实时**,1.7B 余量更小(2.6× 实时)。
- **1.7B 在这段英文上反而不如 0.6B**(`flour-fatted` → `flour-fattened`)。单样本不能定论,但足以说明默认应选 0.6B,1.7B 作为可选并加性能/内存提示。
- 若某台机器连 0.6B 都吃力,可自行用 `llama-quantize` 从官方 Q8_0/bf16 转 Q4_K_M(注意:**不能直接用社区量化**,架构标记不兼容)。
## 3. 转写输出格式(接入时必须清洗)
原始输出形如:
```
language English<asr_text>He hoped there would be stew for dinner...
language Chinese<asr_text>不排除购房者可以在互联网上下单。
```
解析规则:`language <LANG><asr_text><正文>`。`<LANG>` 直接喂给 UI 左上角的语言标签,正文才算字幕。注意 `<LANG>` 在中文时是 `Chinese`,需做 `中文` 一类的显示映射。
## 4. 兼容性风险(重要)
Qwen3-ASR 的 GGUF **架构标记正在变动**,各家不一致:
| 来源 | `general.architecture` | 发行版 b9951 |
|---|---|---|
| **ggml-org/Qwen3-ASR-0.6B / 1.7B**(官方转换) | `qwen3vl` | ✅ 可加载 |
| cstr/qwen3-asr-0.6b-q4_k | `qwen3asr` | ❌ `unknown model architecture` |
| handy-computer/Qwen3-ASR-0.6B-* | `qwen3_asr` | ❌ `unknown model architecture` |
**结论:模型与推理运行时必须成对锁定版本。**只使用 ggml-org 官方 GGUF,或自行用同版本的 `llama-quantize` 从官方 GGUF 转换。
Q4_K_M(590MB)这类小体积量化目前只有社区版,不兼容;`llama-quantize` 可用(在 `llama.cpp-tools` 里),需要时自行从官方 Q8_0/bf16 转换。当前 Q8_0 的 RTF 0.19 已足够,**Q4 非必需**。
## 5. 环境与工具链实测
- **音频**:PipeWire 1.6.4 + pipewire-pulse;`libpulse` 17.0 开发包齐全。用 libpulse 而非 PipeWire 原生 API → 同时兼容 PipeWire / PulseAudio。
- **llama.cpp**:系统包 `9951+dfsg-1deepin1`(`libllama0` 含 `libllama` / `libmtmd` / `libllama-common`;`libllama-dev` 含 `llama.h` / `mtmd.h` / `mtmd-helper.h`)。
- **无免密 sudo**:不能装包。但 `llama.cpp-tools` 的 deb 可直接 `dpkg-deb -x` 解包使用,无需 root。开发期靠这个。
- **CMake 集成注意**:
- `llama-config.cmake` 在非标准路径 `/usr/lib/x86_64-linux-gnu/llama/cmake-private/`(`find_package(llama)` 默认找不到)。
- 同目录有 `pkgconfig/llama.pc`,**但只列了 `-lggml -lggml-base -lllama`,缺 `-lmtmd`**,需要手动补。
- `ggml` 的 cmake config 和 `ggml.pc` 在标准位置,正常可找到。
- **网络**:只有 `hf-mirror.com` 可达(huggingface.co / github.com 不通)。下载用 **aria2c 多连接**:19 MiB/s vs 单连接 3 MiB/s。
## 6. 踩过的坑
1. **`llama-cli` 会挂住**:不给 `-st` 且不让 stdin EOF 时,生成完会回到交互读取循环。解法:`-st --simple-io </dev/null` + 外层 `timeout`。
2. **Debian 的 `llama-cli` 内部其实跑的是 server**(错误日志里出现 `srv load_model`、`llama_server exited`)。这提示:Phase 1 若不想自己驱动 libllama 的解码循环,用 `llama-server` 子进程 + 本地接口也是合理选项。
3. 下载大文件时**不要开两个 curl 并行**(互相拖累到 ~0.3MB/s)。
## 7. 对后续设计的影响
- 采集层:`libpulse` + 默认 sink 的 monitor,需订阅设备变更事件跟随默认输出。
- 推理层:`AsrBackend` 接口;先用 ggml-org 的 `qwen3vl` 版 GGUF;模型+mmproj 成对管理;输出解析要处理 `language/asr_text` 前缀。
- 延迟策略:模型常驻,2s 滑窗,每 ~0.5–1s 提交一次;目标是端到端 ~1s。
- 打包:模型体积(Q8_0 768MB + mmproj 205MB)需要下载或按需获取策略;不能默认内置进包。
## 8. 复现
见 `../../experiments/phase0/README.md`。