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>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>dudu 文档索引</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;
|
||||
}
|
||||
* { 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; }
|
||||
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; }
|
||||
ul { padding-left: 22px; }
|
||||
li { margin: 8px 0; }
|
||||
a { color: var(--accent-text); text-decoration: none; font-weight: 600; }
|
||||
a:hover { text-decoration: underline; }
|
||||
.desc { color: var(--text-2); font-size: 13.5px; font-weight: 400; }
|
||||
footer { text-align: center; color: var(--text-3); font-size: 13px; margin-top: 44px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hero">
|
||||
<h1>dudu 文档索引</h1>
|
||||
<p>五端付费语音输入法 · 全部设计 / 计划 / 调研 / 排障文档单一入口</p>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<section class="card">
|
||||
<h2>设计方案</h2>
|
||||
<ul>
|
||||
<li><a href="frontend-design.html">前端交互与界面设计</a> <span class="desc">— 五端交互流、界面规格与设计系统对接(v1.1)</span></li>
|
||||
<li><a href="backend-architecture.html">后端与数据架构</a> <span class="desc">— API、WS 流式协议、时长账本计费、Redis/PG 设计(v1.1)</span></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>实现计划</h2>
|
||||
<ul>
|
||||
<li><a href="plan/design.html">MVP 实现计划(阅读版)</a> <span class="desc">— 全端任务拆解与依赖关系</span></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>知识库调研 / 验收报告</h2>
|
||||
<ul>
|
||||
<li><a href="latency-acceptance-12b.html">12B 延迟验收结论(暂定)</a> <span class="desc">— 2026-07-10 · 全链路延迟分解、#23/#24 修复、暂定新目标与 paraformer 待决策</span></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<footer>dudu · 文档索引 · 新增文档须同时登记到本页</footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,181 @@
|
||||
<!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">provider:gummy-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><500ms</td>
|
||||
<td><span class="tag green">P50 942ms · P95 950ms</span>(极稳定)</td>
|
||||
<td><strong>P95 < 1.2s</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code class="inline">release_to_commit</code>(松键→上屏)</td>
|
||||
<td><300ms</td>
|
||||
<td>短句 ~170ms · 8s 会话 350~500ms</td>
|
||||
<td><strong>≤3s 会话 <300ms;长会话 <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(不含注入耗时 <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 期间(最长 3s)usageLoop 仍在 tick</li>
|
||||
<li><strong>修复:</strong>finish 先冻结会话并停 usageLoop 再 flush——stop 后唯一的 usage 是结算帧且必在全部 final 之后,<strong>五端客户端「final 或 usage 即提交」逻辑自动变安全</strong>,无协议改动。修复后 6/6 归零</li>
|
||||
<li>桌面端收尾兜底 350ms → 800ms(final flush 实测 350~540ms,350ms 会截丢尾 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>
|
||||
Reference in New Issue
Block a user