Files
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

80 lines
3.9 KiB
Markdown
Raw Permalink 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 1:命令行原型
目标:把 `docs/phase0-verification.md` 验证过的链路写成一个真正的 C++/Qt/CMake 项目骨架,并在命令行跑通「采集系统输出 → 实时转写 → 打印」。
UI 悬浮窗留到 Phase 2。
> **历史文档**:这里记的是 Phase 1 当时的样子。代码后来重排成了 `src/core` + `src/ui` +
> `src/models` + `apps/{gui,cli}`,入口是 `./build/live-caption`(图形界面)和
> `./build/live-caption-cli`(命令行);模型改成按注册表 `data/models.json` 取,不再是手工
> 传 `--model`/`--mmproj`。现行用法见 [README](../../README.md) 与
> [docs/cli.md](../../docs/cli.md)。
## 目录
```
src/
├─ main.cpp # CLI 入口、VAD、滑窗策略、稳定前缀提交
├─ qwen3asr.{h,cpp}# 进程内 Qwen3-ASR 封装(libllama + libmtmd)
├─ audio.{h,cpp} # WAV 读取 + 默认输出 monitor 采集 + libsamplerate 重采样
└─ transcript.{h,cpp} # 解析 `language X<asr_text>正文`,语言显示名映射
```
## 构建
```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
```
依赖:Qt6 Core、libpulse、libsamplerate、系统 llama.cpp(`libllama0`/`libllama-dev`,见 Phase 0 报告里的链接注意事项)。
## 运行
```bash
M=/tmp/opencode/models/Qwen3-ASR-0.6B-Q8_0.gguf
MM=/tmp/opencode/models/mmproj-Qwen3-ASR-0.6B-Q8_0.gguf
# 转写单个文件(不需要采集)
./build/live-caption-cli --model $M --mmproj $MM --file test_16k.wav
# 实时字幕(采集默认输出设备的 monitor)
./build/live-caption-cli --model $M --mmproj $MM --threads 8
# 需要看 llama.cpp 日志时加 --verbose
```
实时输出约定:`~` 是预览行(其中稳定前缀为正常色、不稳定尾部为暗色),`=` 是提交行。
## 实测结果
文件模式(16k 单声道):
| 音频 | 结果 |
|---|---|
| LibriSpeech 英文 10.4s | `He hoped there would be stew for dinner—turnips and carrots and bruised potatoes and fat mutton pieces—to be ladled out in thick peppered flour-fatted sauce.` ✅ |
| AISHELL 中文 3.35s | `不排除购房者可以在互联网上下单。` ✅ |
实时模式(播放上述音频到默认输出,经 monitor 采集转写):
- 英文/中文均实时正确,语言标签正确显示「英语」「中文」。
- 每次推理耗时(0.6B Q8_0,8 线程):
| 窗口时长 | 计算耗时 | RTF |
|---|---|---|
| 0.8 s | ≈0.30 s | 0.42 |
| 2.5 s | ≈0.55 s | 0.22 |
| 5.9 s | ≈1.06 s | 0.18 |
| 20 s | ≈3.59 s | 0.18 |
短窗口 RTF 差是因为有固定开销(prompt 处理 + 音频编码 + 分词),窗口越长越划算。
## 过程中发现并修复的两个 bug
1. **丢样本**:工作线程每轮只处理 `floor(可用样本/320)` 帧并丢弃余数,每次唤醒丢约 160 个样本(~20% 音频),造成假静音和句子被截断。修复:跨批次保留残帧。
2. **VAD 噪声底跟错**:原先用均值跟踪噪声底,遇到本身就很轻的音频(AISHELL 峰值 RMS 仅 0.028、中位 0.006)会一路抬升阈值,把 77% 的话音判成静音。修复:改为「快降慢升」的最小值跟踪,阈值 = `max(floor*3, 0.0015)`。
## 已知问题(留给后续)
- **强制切窗会诱发模型编结尾**:窗口在词中间被切断(到达 max window 或静音点)时,模型会给尾部补一个看似合理的结尾(例如 `...mutton pieces too.`)。已在显示层用「稳定前缀提交」缓解(只把跨多次转写一致的前缀当已定文本),但**根治要靠模型原生的流式解码**:按官方论文的做法,用动态注意力窗口 + 只固定到倒数第 4 个 chunk,尾部 token 不提交。
- 目前每段独立转写、每次清空 KV cache,因此段与段之间没有上下文。原生流式(复用 KV cache、滑动删除已提交部分)能同时降低延迟和提升连贯性,是 Phase 2 的核心工作(见 [../../docs/phase2-streaming.md](../../docs/phase2-streaming.md))。