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。
This commit is contained in:
1 parent
85b206f1cd
commit
6d64987d64
2 files changed
+45
-26
No files matched your search
+29
-14
@@ -13,15 +13,16 @@
|
||||
| 1–2s 就出字 | ✅ | ❌ 需 8s chunk |
|
||||
| 准确率 | ✅(2s 提交 + 8s 编码切片) | ✅(仅 chunk≈8s 时) |
|
||||
|
||||
同一段 62.6s 连续语音(不设段落上限):
|
||||
同一段 62.6s 连续语音:
|
||||
|
||||
| 模式 | 墙钟 | RTF | 首步 | 末步 | 最慢步 |
|
||||
|---|---|---|---|---|---|
|
||||
| `incremental` | 66.3s | 1.06 | 0.62s | 3.14s | 4.06s |
|
||||
| `append` chunk=2 | 32.6s | 0.52 | 0.70s | 0.67s | 1.32s |
|
||||
| `append` chunk=8 | **16.0s** | **0.26** | — | — | 2.52s |
|
||||
| 配置 | 墙钟 | RTF | 平均步 | 最慢步 |
|
||||
|---|---|---|---|---|
|
||||
| `incremental` chunk=2 segment=20 | 35.5s | 0.57 | 1.09s | 1.86s |
|
||||
| `incremental` chunk=2 不限段长 | 67.7s | 1.08 | 2.10s | 4.30s |
|
||||
| `append` chunk=5 | 18.1s | 0.29 | 1.33s | 1.56s |
|
||||
| `append` chunk=8 | **15.2s** | **0.24** | 1.80s | 1.91s |
|
||||
|
||||
`append` 的每步耗时几乎不随总长变化;`incremental` 则线性增长(尾步是最慢的)。
|
||||
`append` 的每步耗时几乎不随总长变化;`incremental` 则线性增长。
|
||||
|
||||
### 为什么 `append` 必须用大 chunk
|
||||
|
||||
@@ -37,13 +38,11 @@
|
||||
|
||||
### 追加式为什么便宜
|
||||
|
||||
`append` 把每块音频当作一个新的对话轮追加到 KV 末尾:
|
||||
`append` 把音频切成定长段,**每段独立转写后按顺序拼接**(对应 sglang 给 Qwen3-ASR 定的 segment 流式模式):
|
||||
|
||||
```
|
||||
[user: audio_1][assistant: text_1][user: audio_2][assistant: text_2]...
|
||||
```
|
||||
|
||||
纯追加 —— **前缀完全不重算、旧音频不重编码、KV 永不回退**,所以单步成本与音频总长无关。
|
||||
- 不做任何前缀重算;
|
||||
- 旧音频不重编码;
|
||||
- KV 每段重置(成本与音频总长无关)。
|
||||
|
||||
而 `incremental` 每步都要把「音频尾部 + 到目前为止的全部文本前缀」按新的音频上下文重算一遍(因果注意力决定了:把新音频插到文本之前,文本之后的 KV 全部作废)。实测拆解显示这一步的代价是 O(N²):
|
||||
|
||||
@@ -53,7 +52,23 @@
|
||||
| 46.0s | 1.23s | 1.20s | 0.38s | 2.81s |
|
||||
| 62.6s | 1.46s | **1.53s** | 0.16s | 3.15s |
|
||||
|
||||
「文本前缀 prefill」从 0.03s 涨到 1.53s,占末尾步耗时的一半。`append` 模式把它降到了 **0.06s**。
|
||||
「文本前缀 prefill」从 0.03s 涨到 1.53s,占末尾步耗时的一半。
|
||||
|
||||
**踩坑记录**:最初把各段实现成「接在上一轮之后的对话轮」(携带上文),结果模型会**抄上一轮的文本** —— 音频内容明显变了,它还是把上一轮的句子原样再吐一遍(实测:第 1 段是「英文尾 2.4s + 中文 5.6s」,却输出了整句英文)。改成每段独立转写后消失。所以这里的「追加」指的是**结果按顺序拼接**,不是「上下文一直累积」。
|
||||
|
||||
### 追加式的残留问题:段边界重复
|
||||
|
||||
各段互不重叠,所以边界处会把上一段的尾巴再写一遍,例如中文实测:
|
||||
|
||||
```
|
||||
+ 不排除购房者可以在互联网上下单。不排除购房者可以在。
|
||||
+ 在互联网上下单,不排除购房者可以在互联网上下单。 ← "在互联网上下单," 是上一段的尾巴
|
||||
```
|
||||
|
||||
要消除它需要重叠窗口 + 去重,那就是 `incremental` 的做法(也因此贵)。所以:
|
||||
|
||||
- **要字幕质量 → `incremental`(默认)**;
|
||||
- **要省 CPU / 转写长音频 → `append`,chunk 取 5–8s**。
|
||||
|
||||
## 结论
|
||||
|
||||
|
||||
Reference in new issue
Block a user