Skip to content

fix(textstream): 快照前缀被改写时保留权威全文,不再中止整条转写 - #1257

Open
solodddd wants to merge 2 commits into
Open-Less:betafrom
solodddd:fix/textstream-snapshot-prefix
Open

solodddd wants to merge 2 commits into
Open-Less:betafrom
solodddd:fix/textstream-snapshot-prefix

Conversation

@solodddd

Copy link
Copy Markdown

Closes #1256

问题

TextStream 的窗口重解码可能改写已经上报为 stable 的文字(实测:一段音译在窗口内切换书写系统,Co → 科蒂纳)。Snapshot.update() 把这种情况当成致命错误 raise,worker 的 main() 把它包成 {"type":"error"} 后 exit 1 → 整条录音记为 transcribeFailed,文本为空。录音文件是完好的,但“重新转录”走同一引擎、同一位置再次失败,等于这段录音永久不可恢复。

本机 74 条 TextStream 记录里命中 1 条;随后一条 96.5 s 的录音又命中一次。命中即整段丢失。

为什么在 app 侧修

  • protocol.rs:Stream 只校验 sequence 单调递增;Final 只额外要求 draft 为空。没有前缀单调性校验。
  • textstream.rs:消费 finalized + draft 时是整段替换(offset: 0),不是追加。
  • 上游库的 stable_text 是按字符/空白单位切分出来的启发式(而解码上下文是按 token id 回滚的,两者边界并不同),不能当硬契约用。

也就是说协议本身允许 preview 被改写;把它当致命错误,是自己把可恢复的状况升级成了录音报废。

改动

worker.py — Snapshots.update():前缀不成立时回退到双方仍一致的公共前缀,不再抛异常。

         if terminal:
             finalized = full
         if not full.startswith(finalized):
-            raise ValueError("decoder snapshot does not contain its finalized prefix")
+            agreed = 0
+            for previous, current in zip(finalized, full):
+                if previous != current:
+                    break
+                agreed += 1
+            finalized = finalized[:agreed]
         self.finalized, self.draft = finalized, full[len(finalized) :]

test_worker.py — 原来那条 assertRaises(ValueError) 改成断言恢复行为,并补一条部分重合的用例(我们去了Co → 我们去了科蒂纳。 应得到 ("我们去了", "科蒂纳。"))。

验证

  • python3 -m unittest test_worker -v → 13 passed(macOS 27.0.1 / Python 3.14)
  • 真机回放两段真实录音(46.57 s / 96.5 s),走原封不动的 .runtime/worker.py + 同一个模型:
    • 改前:{"type":"error","message":"decoder snapshot does not contain its finalized prefix"},exit 1,无文本
    • 改后:{"type":"final","sequence":25,"draft":""},exit 0,全文正常输出

边界

  • 不改协议、不改 Rust;terminal 快照仍以库的终态为准(if terminal: finalized = full 未动)。
  • 不改变“stable 是否应该永不改写”这个库层语义问题——那是 moona3k/mlx-qwen3-asr#31 讨论的内容,这里只做消费方容错。
  • 本次没有做参考转写对比,不能据此声明识别质量提升;只证明不再中止。
  • 触发该状态的音频条件未完全定位(本次是音译切换书写系统);不同语言/机器的触发分布未测。

@H-Chris233 H-Chris233 added area:asr ASR area bug Something isn't working needs-review Needs review P1 High priority platform:macos macOS-specific labels Oct 23, 2026
@H-Chris233 H-Chris233 self-assigned this Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:asr ASR area bug Something isn't working needs-review Needs review P1 High priority platform:macos macOS-specific

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[macos][TextStream] 解码快照前缀不一致时整条转写中止(录音仍在,可恢复)

2 participants