一、暂定结论(TL;DR)
指标 原目标 P95 实测(预连接后) 暂定新目标
first_partial(按键→首字)
<500ms
P50 942ms · P95 950ms (极稳定)
P95 < 1.2s
release_to_commit(松键→上屏)
<300ms
短句 ~170ms · 8s 会话 350~500ms
≤3s 会话 <300ms;长会话 <600ms
为什么 500ms 结构性不可达: first_partial = max(握手, DashScope 音频块阈值 ~850ms) + 推理 ~90ms。
地板是 DashScope 的音频块阈值 ,与网关代码无关(直连同样 ~1s)。要破地板只能换模型(见第四节)。
体感修正: 前导静音实验证明阈值按「音频量」而非「语音量」计——400ms 静音只使 first_partial 推迟 ~100ms。
用户按键后自然停顿 ~300ms 再开口时,从开口算的首字延迟仅 ~640ms ,体感优于指标数字。
二、延迟分解(实测)
环节 耗时 处置
网关预检(限流 / 配额 / 设备槽) ~10ms 无需优化
DashScope dial + task-started 握手 暖 ~130ms · 抖动 60ms~3.7s 已消除 spare 预连接(#24)
DashScope 音频块阈值 ~850ms(地板) 换模型才能降 (paraformer ~520ms)
推理 + 回传 ~90ms 无手段
final flush(松键后) 短句 ~170ms · 8s 会话 350~540ms 随内容量增长,属 provider 物理时间
测量口径(对齐桌面端 dictation.rs)
first_partial:start 帧发出 → 首个 partial(不含麦克风启动,桌面另有 audio.start_ms)
release_to_commit:stop 帧发出 → 尾部 final(不含注入耗时 <10ms)
工具:go run ./cmd/latencyprobe -wav xx.wav -n 12(单持久连接 + 100ms/帧实时推流,复刻桌面行为)
三、本轮落地的修复与优化
#23 stop 后周期 usage 帧抢跑尾部 final(已修,服务端根治)
症状: 8s 会话 4/4 复现 usage 先于尾部 final 到达,客户端以 partial 文本提前上屏、丢失 final 修正(iOS 21A 修过客户端侧,桌面端仍暴露)
根因: finish 等尾部 final 期间(最长 3s)usageLoop 仍在 tick
修复: finish 先冻结会话并停 usageLoop 再 flush——stop 后唯一的 usage 是结算帧且必在全部 final 之后,五端客户端「final 或 usage 即提交」逻辑自动变安全 ,无协议改动。修复后 6/6 归零
桌面端收尾兜底 350ms → 800ms(final flush 实测 350~540ms,350ms 会截丢尾 final)
#24 gummy spare 预连接(已实现)
常备一条已完成 run-task 握手的 DashScope 会话,start 直取、异步补位、40s 定期换新
依据:DashScope 空闲 60s 存活、120s 报 Idle timeout (实测),留余量 45s
效果:网关 start 处理 120~670ms → 3~4ms ;dial 抖动(60ms~3.7s)移出关键路径,否则 P95 可达 1.5~4.5s
顺手修复
滑动窗口 Lua「只查不记」与实现不符:val=0 的检查不再写入 0 值成员污染窗口 ZSET
gummycheck 增加 -model / -pace / -idle 参数,支持模型对比与闲置存活实验
四、待决策:要不要换 paraformer
gummy-realtime-v1(现用) paraformer-realtime-v2
音频块阈值(首字地板) ~850ms ~520ms
partial 刷新节奏 ~1s / 次 ~500ms / 次(更跟手)
识别质量(单样本 TTS 实测) 全对 「各自模块的进度汇报」→「各字文案者进入汇报」
partial 时间戳(计量交叉校验用) 每条带 end_time 仅 final 带
决策前置条件: 用 eval 框架(eval/)跑真实数据集对比两模型 WER,再决定是否为 ~300ms 首字收益换质量。
切换成本低:GummyProvider.Model 一行配置。
五、复测方法
# 起服务端(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
注意设备 30 分钟滑动窗口上限 30 次会话,probe 换 -device 规避
观测日志:gummy: session ready(dial/task-started 耗时)、gummy: session from spare、gateway: start handled
dudu · 12B 延迟验收(暂定结论)· 2026-07-10 · 数据与工具见 feat/12b-latency-probe