Files
dudu/doc/latency-acceptance-12b.html
T
wangjia 2979bdd2a3
ci / server (push) Failing after 10s
ci / design-tokens (push) Failing after 10s
docs(12B): 延迟验收暂定结论 + 建立项目文档索引
- doc/latency-acceptance-12b.html:延迟分解、#23/#24 修复记录、暂定新目标
  (first_partial P95<1.2s;release_to_commit ≤3s 会话<300ms / 长会话<600ms)、
  paraformer 切换待 eval 对比决策、复测方法
- doc/index.html:项目文档单一入口(按规范补建,登记现有 4 份文档)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 20:02:16 +08:00

182 lines
9.9 KiB
HTML
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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>dudu 12B 延迟验收结论(暂定)</title>
<style>
:root {
--accent: #4F6EF7;
--accent-text: #3D58DB;
--accent-soft: #EEF1FE;
--bg: #F6F7FA;
--card: #FFFFFF;
--text-1: #1B1E26;
--text-2: #5A6072;
--text-3: #A6ABB8;
--border-1: #E4E6EB;
--positive: #16A34A;
--warning: #E8890C;
--danger: #DC2626;
--code-bg: #1B1E26;
--code-text: #D6DCEA;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
background: var(--bg); color: var(--text-1); line-height: 1.75;
}
.container { max-width: 980px; margin: 0 auto; padding: 0 24px 80px; }
header.hero { background: var(--accent); color: #fff; padding: 48px 24px 40px; text-align: center; }
header.hero h1 { margin: 0 0 6px; font-size: 30px; }
header.hero p { margin: 0; opacity: .85; font-size: 15px; }
.chips { margin-top: 16px; }
.chip { display: inline-block; padding: 3px 14px; margin: 3px; background: rgba(255,255,255,.16); border-radius: 999px; font-size: 13px; }
section.card {
background: var(--card); border: 1px solid var(--border-1); border-radius: 14px;
padding: 28px 32px; margin-top: 24px; box-shadow: 0 1px 3px rgba(17,19,26,.05);
}
h2 { font-size: 21px; margin: 0 0 14px; padding-bottom: 8px; border-bottom: 2px solid var(--accent); display: inline-block; }
h3 { font-size: 16px; margin: 22px 0 8px; color: var(--accent-text); }
table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 13.5px; }
th, td { border: 1px solid var(--border-1); padding: 7px 11px; text-align: left; vertical-align: top; }
th { background: #F0F1F4; font-weight: 600; }
tr:nth-child(even) td { background: #FCFCFD; }
pre.code, pre.diagram {
background: var(--code-bg); color: var(--code-text); padding: 16px 18px; border-radius: 10px;
overflow-x: auto; font-family: "SF Mono", Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.55;
}
code.inline { background: var(--accent-soft); color: var(--accent-text); padding: 1px 6px; border-radius: 4px; font-family: "SF Mono", Menlo, monospace; font-size: 12.5px; }
.callout { border-left: 4px solid var(--accent); background: var(--accent-soft); padding: 11px 16px; border-radius: 0 8px 8px 0; margin: 12px 0; font-size: 13.5px; }
.callout.warn { border-color: var(--warning); background: #FCEFD7; }
.tag { display: inline-block; font-size: 12px; padding: 1px 10px; border-radius: 999px; margin-right: 6px; font-weight: 600; }
.tag.green { background: #DCFCE7; color: var(--positive); }
.tag.orange { background: #FCEFD7; color: var(--warning); }
.tag.red { background: #FEE2E2; color: var(--danger); }
.tag.blue { background: var(--accent-soft); color: var(--accent-text); }
ul, ol { padding-left: 22px; }
li { margin: 3px 0; }
footer { text-align: center; color: var(--text-3); font-size: 13px; margin-top: 44px; }
</style>
</head>
<body>
<header class="hero">
<h1>12B 延迟验收结论(暂定)</h1>
<p>网关全链路实测 · 延迟分解 · 修复与调优 · 暂定新目标</p>
<div class="chips">
<span class="chip">2026-07-10</span>
<span class="chip">工具:server/cmd/latencyprobe</span>
<span class="chip">分支:feat/12b-latency-probe</span>
<span class="chip">providergummy-realtime-v1(真实)</span>
</div>
</header>
<div class="container">
<section class="card">
<h2>一、暂定结论(TL;DR</h2>
<table>
<tr><th>指标</th><th>原目标 P95</th><th>实测(预连接后)</th><th>暂定新目标</th></tr>
<tr>
<td><code class="inline">first_partial</code>(按键→首字)</td>
<td>&lt;500ms</td>
<td><span class="tag green">P50 942ms · P95 950ms</span>(极稳定)</td>
<td><strong>P95 &lt; 1.2s</strong></td>
</tr>
<tr>
<td><code class="inline">release_to_commit</code>(松键→上屏)</td>
<td>&lt;300ms</td>
<td>短句 ~170ms · 8s 会话 350~500ms</td>
<td><strong>≤3s 会话 &lt;300ms;长会话 &lt;600ms</strong></td>
</tr>
</table>
<div class="callout">
<strong>为什么 500ms 结构性不可达:</strong>first_partial = max(握手, DashScope 音频块阈值 ~850ms) + 推理 ~90ms。
地板是 DashScope 的<strong>音频块阈值</strong>,与网关代码无关(直连同样 ~1s)。要破地板只能换模型(见第四节)。
</div>
<div class="callout">
<strong>体感修正:</strong>前导静音实验证明阈值按「音频量」而非「语音量」计——400ms 静音只使 first_partial 推迟 ~100ms。
用户按键后自然停顿 ~300ms 再开口时,<strong>从开口算的首字延迟仅 ~640ms</strong>,体感优于指标数字。
</div>
</section>
<section class="card">
<h2>二、延迟分解(实测)</h2>
<table>
<tr><th>环节</th><th>耗时</th><th>处置</th></tr>
<tr><td>网关预检(限流 / 配额 / 设备槽)</td><td>~10ms</td><td>无需优化</td></tr>
<tr><td>DashScope dial + task-started 握手</td><td>暖 ~130ms · <span class="tag red">抖动 60ms~3.7s</span></td><td><span class="tag green">已消除</span> spare 预连接(#24</td></tr>
<tr><td>DashScope 音频块阈值</td><td><strong>~850ms(地板)</strong></td><td><span class="tag orange">换模型才能降</span>paraformer ~520ms</td></tr>
<tr><td>推理 + 回传</td><td>~90ms</td><td>无手段</td></tr>
<tr><td>final flush(松键后)</td><td>短句 ~170ms · 8s 会话 350~540ms</td><td>随内容量增长,属 provider 物理时间</td></tr>
</table>
<h3>测量口径(对齐桌面端 dictation.rs</h3>
<ul>
<li><code class="inline">first_partial</code>start 帧发出 → 首个 partial(不含麦克风启动,桌面另有 <code class="inline">audio.start_ms</code></li>
<li><code class="inline">release_to_commit</code>stop 帧发出 → 尾部 final(不含注入耗时 &lt;10ms</li>
<li>工具:<code class="inline">go run ./cmd/latencyprobe -wav xx.wav -n 12</code>(单持久连接 + 100ms/帧实时推流,复刻桌面行为)</li>
</ul>
</section>
<section class="card">
<h2>三、本轮落地的修复与优化</h2>
<h3>#23 stop 后周期 usage 帧抢跑尾部 final(已修,服务端根治)</h3>
<ul>
<li><strong>症状:</strong>8s 会话 4/4 复现 usage 先于尾部 final 到达,客户端以 partial 文本提前上屏、丢失 final 修正(iOS 21A 修过客户端侧,桌面端仍暴露)</li>
<li><strong>根因:</strong>finish 等尾部 final 期间(最长 3susageLoop 仍在 tick</li>
<li><strong>修复:</strong>finish 先冻结会话并停 usageLoop 再 flush——stop 后唯一的 usage 是结算帧且必在全部 final 之后,<strong>五端客户端「final 或 usage 即提交」逻辑自动变安全</strong>,无协议改动。修复后 6/6 归零</li>
<li>桌面端收尾兜底 350ms → 800msfinal flush 实测 350~540ms350ms 会截丢尾 final</li>
</ul>
<h3>#24 gummy spare 预连接(已实现)</h3>
<ul>
<li>常备一条已完成 run-task 握手的 DashScope 会话,start 直取、异步补位、40s 定期换新</li>
<li>依据:DashScope 空闲 <strong>60s 存活、120s 报 Idle timeout</strong>(实测),留余量 45s</li>
<li>效果:网关 start 处理 <strong>120~670ms → 3~4ms</strong>dial 抖动(60ms~3.7s)移出关键路径,否则 P95 可达 1.5~4.5s</li>
</ul>
<h3>顺手修复</h3>
<ul>
<li>滑动窗口 Lua「只查不记」与实现不符:val=0 的检查不再写入 0 值成员污染窗口 ZSET</li>
<li>gummycheck 增加 <code class="inline">-model / -pace / -idle</code> 参数,支持模型对比与闲置存活实验</li>
</ul>
</section>
<section class="card">
<h2>四、待决策:要不要换 paraformer</h2>
<table>
<tr><th></th><th>gummy-realtime-v1(现用)</th><th>paraformer-realtime-v2</th></tr>
<tr><td>音频块阈值(首字地板)</td><td>~850ms</td><td><span class="tag green">~520ms</span></td></tr>
<tr><td>partial 刷新节奏</td><td>~1s / 次</td><td><span class="tag green">~500ms / 次(更跟手)</span></td></tr>
<tr><td>识别质量(单样本 TTS 实测)</td><td><span class="tag green">全对</span></td><td><span class="tag red">「各自模块的进度汇报」→「各字文案者进入汇报」</span></td></tr>
<tr><td>partial 时间戳(计量交叉校验用)</td><td>每条带 end_time</td><td>仅 final 带</td></tr>
</table>
<div class="callout warn">
<strong>决策前置条件:</strong>用 eval 框架(<code class="inline">eval/</code>)跑真实数据集对比两模型 WER,再决定是否为 ~300ms 首字收益换质量。
切换成本低:<code class="inline">GummyProvider.Model</code> 一行配置。
</div>
</section>
<section class="card">
<h2>五、复测方法</h2>
<pre class="code"># 起服务端(pg/redis 容器已在跑)
cd server && ./run-dev.sh
# 全链路延迟实测(另开终端)
go run ./cmd/latencyprobe -wav /path/to/16k-mono.wav -n 12
# 直连模型对比 / 闲置存活实验
rbw get dashscope-api-key | go run ./cmd/gummycheck -wav xx.wav -pace 100 -model paraformer-realtime-v2
rbw get dashscope-api-key | go run ./cmd/gummycheck -wav xx.wav -pace 100 -idle 60</pre>
<ul>
<li>注意设备 30 分钟滑动窗口上限 30 次会话,probe 换 <code class="inline">-device</code> 规避</li>
<li>观测日志:<code class="inline">gummy: session ready</code>dial/task-started 耗时)、<code class="inline">gummy: session from spare</code><code class="inline">gateway: start handled</code></li>
</ul>
</section>
<footer>dudu · 12B 延迟验收(暂定结论)· 2026-07-10 · 数据与工具见 feat/12b-latency-probe</footer>
</div>
</body>
</html>