在线计算器

语音对话延迟预算计算器

从「用户说完」到「听到第一声回复」,拆成可加总的几段,先定位卡在哪儿。

把一次语音对话的「用户说完 → 听到第一声回复」拆成可加总的几段,帮你定位卡在哪一段。 下面的输入分成两类,性质完全不同,请分开看。

A 类|流水线配置引入的等待

默认值取自仓库参数默认值,不是实测延迟

这几个数字是 speech-to-speech 流水线自己引入的、可配置的等待项。改配置就会变, 它们描述的是「等多久」,不是「跑多久」。

轮次路径(三条路的等待项组成不同)
VAD 静音判定,仓库默认 64
仓库默认 800
仓库默认 600|当前路径不计入
仓库默认 2000|是输出门控上限,不参与加总

B 类|算力引入的耗时

没有预设值,必须你自己实测填入

这四段取决于你的模型与硬件。本站没有测过任何一台机器,所以这里一个数字都不给你—— 填你自己跑出来的毫秒数。

从音频送进去到拿到文本
从提示词送出到第一个 token 回来
从文本送进去到第一块音频出来
客户端与服务端之间的来回,本机跑就填 0

分段耗时

分段类别耗时占比
VAD 静音判定
--min_silence_ms
A 配置等待64 ms
7.4%
推测重开窗口
--speculative_reopen_ms
A 配置等待800 ms
92.6%
STT 转写
你自己实测
B 算力未填
0.0%
LLM 首 token
你自己实测
B 算力未填
0.0%
TTS 首包
你自己实测
B 算力未填
0.0%
网络往返
你自己实测
B 算力未填
0.0%
864 ms
A 类合计(配置等待)
0 ms
B 类合计(算力)|尚有未填项
864 ms
合计(A + B)

最大的一段:推测重开窗口800 ms,占 92.6%)。它是配置等待项,想缩短就改这个参数——代价是误判成本上升,参数本身是拿等待换判断准确度的。

B 类还有 4 段没填,当前合计只是个残缺的下界, 别拿它当端到端延迟看。

本站没有任何实测数据:A 类是可配置的等待项(默认值取自仓库参数默认值,不是实测延迟), B 类必须你自己测。这个页面只做加法,不预测你的延迟。

为什么要把延迟拆开算

语音对话卡顿,最常见的处理方式是「换个更快的模型试试」。但这一步经常白做—— 因为你不知道那一秒钟到底花在哪儿了。它可能根本不在推理上,而在流水线主动等你的那几百毫秒里。

一次语音回合的首响应延迟,大致由这样一串组成:你停止说话 → VAD 判定这是一段静音 → Smart Turn 校验「这轮真的说完了吗」并产生对应的等待 → STT 把音频转成文本 → LLM 吐出第一个 token → TTS 合成出第一块音频 → 经网络传到你耳朵里。

这一串里,前半段和后半段的性质完全不同,而这正是这个工具把输入分成两类的原因。

两类数字,别混着看

A 类是流水线配置引入的等待。它们是 speech-to-speech 仓库里的参数, 页面里给出的默认值取自该仓库的参数默认值——是配置项没被改动时的取值,不是实测延迟。 这类数字的特点是:你改配置它就变,而且变化是确定的,不依赖任何硬件。

B 类是算力引入的耗时。STT 转写、LLM 首 token、TTS 首包、网络往返。 这四段取决于你选的模型、跑在什么卡上、服务部署在哪、并发多少。 本站没有跑过任何一台机器,所以这四个输入框里一个预设数字都没有, 必须你自己测了填进去。这不是偷懒,是给不出来——凡是给你「参考区间」的表格, 你都该先问一句它测的是哪块卡、哪个模型、什么并发。

三条路径分别怎么等

Smart Turn 是一个外部模型(pipecat-ai/smart-turn-v3,CPU ONNX), 用当前轮次的内容与韵律来校验 Silero 给出的「说完了」判断。它默认是开的, 要关得显式传 --no_smart_turn。判定结果不同,等待项的组成就不同:

  • 判定完整:立刻开始处理,提交输出前使用推测重开窗口。 等待项 = min_silence_ms + speculative_reopen_ms
  • 判定不完整:先晾一会儿再启动 STT/LLM,让可能恢复的语音有机会 在昂贵计算开始之前把这次修订作废。等待项 = min_silence_ms + smart_turn_incomplete_delay_ms,而输出继续被 smart_turn_max_wait_ms 门控。
  • 关闭 Smart Turn:没有不完整这条路,回到 min_silence_ms + speculative_reopen_ms

所以这几个毫秒数字买的不是延迟,而是误判成本—— Silero 一说「完了」就开工能省时间,但用户只是喘口气的话这活就白干了。 Smart Turn 给「白干」上了一个成本可控的闸。参数细节可以看 VAD 参数全解Smart Turn 的判定机制

怎么用

第一步,选路径。你想分析哪种情况?句尾干净利落的短问句多半走「判定完整」, 说话带思考停顿的长句更容易走「判定不完整」。两条都算一遍,差值就是不完整判定给你带来的额外等待。

第二步,A 类按需改。如果你改过配置,把你实际启动命令里的值填进去; 没改过就留着默认。注意 min_silence_ms 默认只有 64—— 这个值很小,切得很碎,别把它记成 640。

第三步,B 类老老实实测。最省事的做法是在流水线各环节前后打时间戳, 跑十几轮取个中位数,别用第一次冷启动那一轮(模型加载会把数字撑得很难看)。 网络往返在本机跑就填 0。

第四步,看「最大的一段」。如果最胖的是 A 类,说明你卡在配置的等待上, 改参数就能动——但要清楚代价是误判成本上升。如果最胖的是 B 类,改流水线参数没用, 得从模型、量化、硬件或部署位置上想办法。

为什么门控上限不加进合计

smart_turn_max_wait_ms(默认 2000)经常被误当成「不完整轮次要等 2 秒」。 它不是一段串行耗时,是一个上限:判不完整时那 600 ms 的延迟跑在这个宽限期之内, 输出继续被它门控;期间只要语音恢复,现有轮次就被重开为一个更新的修订版, 累积的音频重新发出,上一版的工作在到达用户之前就被丢弃

把上限加进总和,等于把「最坏情况的天花板」和「这一次实际串行的等待」混成一个数。 所以页面把它单独列出来。三个重开窗口之间还有钳制关系,容易讲错, 单独写在三个重开窗口的层级关系那篇里。

它算不了什么

它不预测你的延迟。它只把你填的数加起来,再告诉你哪一段最胖、各占多少。 真实链路里还有一堆这里没建模的东西:音频采集与缓冲、进程间排队、TTS 播放启动、 抢话与重开导致的返工。而且 A 类是「等待」、B 类是「计算」, 在真实实现里未必严格串行——推测式执行本来就是让计算提前于确认发生的。

它也不会告诉你「你的显卡够不够」「这个延迟算好还是坏」。 本站没有任何实测数据,任何关于「某某模型首 token 大约多少毫秒」的说法都不会出现在这个页面上。 想了解整条链路的拆法,可以接着看 语音延迟预算怎么拆, 或者从speech-to-speech 专题进去按顺序读。

常见问题

为什么 A 类给了默认值,B 类一个数都不给?

因为两类数字的性质完全不同。A 类那几个毫秒(min_silence_ms=64、speculative_reopen_ms=800、smart_turn_incomplete_delay_ms=600、smart_turn_max_wait_ms=2000)是 speech-to-speech 仓库里参数的默认取值,你不改配置它们就是这个数,属于可以查证的事实——但它们描述的是「流水线主动等多久」,不是「跑一次要多久」。B 类那四段是 STT、LLM、TTS 的推理和网络,取决于你用哪个模型、跑在什么硬件上、部署在哪。本站没有跑过任何一台机器,给不出数;给了就是编。所以 B 类的输入框里一个数字都没有,占位符只写「请填你实测的毫秒数」。

三条路径为什么等待项组成不一样?

Smart Turn 的作用是校验 Silero 给出的「说完了」判断,判定结果不同,后续流程就不同。判为完整:立刻开始处理,提交输出前使用 speculative_reopen_ms 的重开窗口,所以等待项是 min_silence_ms + speculative_reopen_ms。判为不完整:先等 smart_turn_incomplete_delay_ms 再启动 STT/LLM,让恢复的语音有机会在昂贵计算开始前作废这次修订,所以等待项换成 min_silence_ms + smart_turn_incomplete_delay_ms。关掉 Smart Turn(--no_smart_turn,注意它默认是开的)就没有不完整这条路,回到 min_silence_ms + speculative_reopen_ms。

smart_turn_max_wait_ms 是 2000,为什么不加进合计?

因为它不是一段串行耗时,是一个上限。判不完整时,那 600 ms 的延迟是跑在这个 2 秒宽限期之内的,输出继续被它门控;期间语音恢复,轮次就被重开为一个更新的修订版,上一版的工作在到达你耳朵之前就被丢掉。把上限加进总和,等于把「最坏情况的天花板」和「这一次实际串行的等待」混成一个数,算出来的东西没有意义。所以页面把它单独列出来,只当上限看。

算出来合计一千多毫秒,是不是就代表我的语音助手延迟这么多?

不是。这个页面做的是加法,加的是你自己填的数,准确度完全取决于你测得准不准。而且真实链路里还有一堆这里没建模的东西:音频采集与缓冲、进程间排队、TTS 播放启动、抢话与重开导致的返工。更重要的是,A 类那几段是「等待」,B 类那几段是「计算」,两者在真实实现里未必严格串行,推测式执行本来就是让计算提前于确认发生的。所以把它当成定位工具用——看哪一段最胖,就往哪儿下手——而不是当成延迟预测器。

想把语音 Agent 真正跑起来?

从装环境到调回合参数,奇连 AI 的 speech-to-speech 专题按顺序排好了。

进专题