Commit Graph
8 Commits
Author SHA1 Message Date
blumia b37b9eb779 fix(asr): do not call InputFinished for a never-ending stream
A live caption stream never ends: the boundary of an utterance is silence,
not end-of-input, so InputFinished (which means "no more audio ever") does
not apply. Drop it and rely on the trailing audio alone; keep a short
silence padding as a safety net for end-of-file cases. Verified that the
file path still emits the final character without InputFinished.

实时字幕的音频流永不结束,一句话的边界是"静音"而不是"输入结束",所以
不该调用语义为"再也不会有音频"的 InputFinished。改为只补一小段静音兜底,
实测文件模式的结果依然完整。文档也一并更正。
2026-10-12 16:10:59 +08:00
blumia bd921b1ac5 feat(asr): add pluggable ONNX streaming backend and model registry
Add a second backend (sherpa-onnx) alongside llama.cpp, so native
streaming models can be selected by ID from a JSON registry. All such
models share one adapter: only the model files and a few options differ.
Models now live under the app data directory and are fetched by
scripts/fetch-models.sh. Adding a model is a data change, not code.

Measured on the same audio: the streaming backend is ~35x cheaper in CPU
than Qwen3-ASR (0.10-0.12 vs 4.27 core-seconds per audio second), shows
the first caption at 0.48-1.44s, and matches its accuracy for zh/en.

新增 sherpa-onnx 流式后端,与 llama.cpp 并存;模型按注册表 id 从应用
数据目录加载。同族模型共用一个适配器,新增模型只改 data/models.json。
实测流式后端 CPU 约为 Qwen3-ASR 的 1/35,首个字幕 0.48~1.44s,中英
准确率持平。注意预编译库是旧 C++ ABI,必须走其 C API。
2026-10-12 16:06:51 +08:00
blumia 6d64987d64 fix(stream): transcribe each append-mode chunk independently
The append mode used to feed chunks as successive conversation turns with
the context carried over. The model then copied the previous turn's text
verbatim instead of transcribing the new audio, so a continuous video
kept showing the same sentence forever. Transcribe each chunk
independently instead, matching sglang's segment streaming mode for
Qwen3-ASR; the fixed mode also stays flat at RTF 0.24 versus 0.57-1.08
for the incremental mode.

修复追加式的一个真 bug:原先把各段接成「携带上文的对话轮」,模型会抄上
一轮的文本 —— 连续视频里字幕永远重复同一句。改为每段独立转写(对应
sglang 给 Qwen3-ASR 的 segment 流式模式),内容随之正确变化;成本仍保持
平坦,RTF 0.24,而增量模式是 0.57~1.08。
2026-10-12 14:32:07 +08:00
blumia 85b206f1cd feat(stream): add append-only streaming mode with flat cost
Add an append-only streaming path that feeds each audio chunk as a new
conversation turn, so nothing is ever recomputed: the KV grows by
append, no prefix is re-decoded and no audio is re-encoded. Per-step
cost becomes flat instead of growing with the segment (RTF 1.06 -> 0.26
on 62.6s of continuous speech), but accuracy requires ~8s chunks because
the audio encoder needs its 8s attention window, so text only appears
every 8s. The incremental mode stays the default.

新增追加式流式:每块音频作为一个新的对话轮追加,前缀不重算、旧音频不重
编码,单步成本不再随段落增长(连续 62.6s 语音 RTF 从 1.06 降到 0.26)。
但准确率要求 chunk≈8s,否则会被截断,所以出字粒度是 8s;增量式仍为默认。
2026-10-12 14:22:29 +08:00
blumia 736ec14d5b refactor: split core/ui/apps targets and add unit tests
Move all business logic into liblivecaption_core (no Qt dependency) and
the widgets into liblivecaption_ui, leaving two executables: the caption
window and the CLI, which no longer links Qt Widgets. Abstract the ASR
backend behind IAsr so the streaming policy and the live pipeline can be
tested with a scripted fake backend instead of a real model.

把全部业务逻辑下沉到不依赖 Qt 的 liblivecaption_core,界面独立成
liblivecaption_ui,拆出悬浮窗与命令行两个可执行程序(CLI 不再链接 Qt
Widgets);并用 IAsr 抽象推理后端,使流式策略与实时管线可脱离真模型
用假实现做单元测试。测试还抓到一个真 bug:段恰好结束在 chunk 边界时
只提交了稳定部分,最后几个词被丢掉,已修。
2026-10-12 13:43:50 +08:00
blumia 4ed4e23282 feat(ui): add floating caption window with live transcription
Add a frameless always-on-top caption window wired to the live capture
pipeline. Silence-based segmentation gates the audio so the model never
sees silence, and the panel background is painted in paintEvent with a
configurable opacity instead of a style sheet.

新增悬浮字幕窗(无边框、置顶、可折叠/展开),接入实时采集与流式转写。
分段由静音检测驱动,静音期间不送音频,避免模型对静音产生幻觉。底板
改为在 paintEvent 中绘制,不透明度可调。
2026-10-12 13:32:16 +08:00
blumia 21d68e2294 feat(stream): add incremental streaming decode with 8s slice reuse
Add native streaming ASR: 8s-aligned audio slices are cached in the KV
cache, only new audio is encoded, and the previous text is fed back as
an assistant prefix with token rollback. Text matches offline results.
Streaming keeps each step within the 2s budget for segments up to 20s.

新增原生流式解码:8s 对齐的音频切片存入 KV 复用,只编码新音频,并把
上一轮文本作为 assistant 前缀回喂(带 token 回滚)。转写结果与离线
一致;20s 以内的段落每步计算都在 2s 预算内。
2026-10-12 13:01:26 +08:00
blumia 18dbc9c8d3 feat: add real-time caption CLI prototype with Qwen3-ASR
Add a C++/Qt6/CMake CLI prototype that captures the default sink
monitor through libpulse and transcribes it in-process with Qwen3-ASR
via libllama/libmtmd. Add phase 0/1 verification docs.

新增实时字幕命令行原型:libpulse 采集默认输出 monitor,进程内用
libllama/libmtmd 跑 Qwen3-ASR 推理。附阶段 0/1 验证文档。
2026-10-12 11:40:59 +08:00