<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>延迟优化 on Chico's Tech Blog</title><link>https://realtime-ai.chat/tags/%E5%BB%B6%E8%BF%9F%E4%BC%98%E5%8C%96/</link><description>Recent content in 延迟优化 on Chico's Tech Blog</description><image><title>Chico's Tech Blog</title><url>https://github.com/chicogong.png</url><link>https://github.com/chicogong.png</link></image><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 19 May 2026 10:00:00 +0800</lastBuildDate><atom:link href="https://realtime-ai.chat/tags/%E5%BB%B6%E8%BF%9F%E4%BC%98%E5%8C%96/index.xml" rel="self" type="application/rss+xml"/><item><title>实时语音对话的延迟预算：把「AI 慢半拍」拆到毫秒</title><link>https://realtime-ai.chat/posts/voice-latency-budget/</link><pubDate>Tue, 19 May 2026 10:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/voice-latency-budget/</guid><description>从用户说完到 AI 出声,500~900ms 花在哪里?逐段拆解语音 Agent 的延迟预算,以及流式、打断、级联与端到端的工程取舍。</description><content:encoded><![CDATA[<p>你跟一个语音 AI 说完话,它停顿了一下,才开口回答。</p>
<p>那一下&quot;停顿&quot;,就是它不像人的地方。</p>
<p>人类对话的轮次间隔(turn-taking gap)中位数只有约 <strong>200ms</strong>,熟悉的人之间还经常&quot;抢话&quot;——下一句在上一句结束前就接上了。一旦 AI 的回应超过 <strong>500ms</strong>,你会明显感觉到&quot;它在想&quot;;超过 <strong>800ms</strong>,对话就开始别扭,你会忍不住重复自己,或者以为它没听见。</p>
<p>所以做语音 Agent,延迟不是&quot;优化项&quot;,是<strong>及格线</strong>。这篇把从【用户说完最后一个字】到【AI 喇叭里出第一个音】之间发生的事,拆到毫秒。</p>
<h2 id="这条流水线长什么样">这条流水线长什么样</h2>
<pre class="mermaid">flowchart LR
  A[用户说话] --> B[轮次判定<br/>VAD + 端点]
  B --> C[ASR<br/>语音转文字]
  C --> D[LLM<br/>首 token]
  D --> E[TTS<br/>首包音频]
  E --> F[AI 出声]
  style B fill:#fde7c2,stroke:#e8b23c
  style D fill:#fde7c2,stroke:#e8b23c
</pre><p>橙色的两块——<strong>轮次判定</strong>和 <strong>LLM 首 token</strong>——是预算里最大的两笔开销,也是最值得花力气的地方。</p>
<h2 id="一份现实的延迟预算">一份现实的延迟预算</h2>
<table>
  <thead>
      <tr>
          <th>环节</th>
          <th>它在做什么</th>
          <th>典型耗时</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>轮次判定(VAD + 端点)</td>
          <td>判断&quot;用户真的说完了&quot;</td>
          <td>50–250 ms</td>
      </tr>
      <tr>
          <td>ASR(语音转文字)</td>
          <td>把语音转成文字</td>
          <td>~0–150 ms*</td>
      </tr>
      <tr>
          <td>LLM 首 token(TTFT)</td>
          <td>想出第一个字</td>
          <td>250–500 ms</td>
      </tr>
      <tr>
          <td>TTS 首包</td>
          <td>合成出第一段音频</td>
          <td>75–200 ms</td>
      </tr>
      <tr>
          <td>网络往返</td>
          <td>客户端 ↔ 服务端</td>
          <td>30–80 ms</td>
      </tr>
      <tr>
          <td><strong>合计(可感知)</strong></td>
          <td></td>
          <td><strong>约 500–900 ms</strong></td>
      </tr>
  </tbody>
</table>
<p>* ASR 与用户说话<strong>并行</strong>进行,大部分转写在用户说完之前就做完了,所以它对预算的<strong>增量</strong>很小——前提是你用的是流式 ASR。</p>
<h2 id="逐段拆开">逐段拆开</h2>
<h3 id="轮次判定延迟里的隐形大头">轮次判定:延迟里的隐形大头</h3>
<p>最容易被忽略、又最肥的一块。</p>
<p>很多系统用一个固定的&quot;静音超时&quot;来判断用户说完了——比如静音持续 700ms 就认为该 AI 说话了。问题是:<strong>这 700ms 是凭空加在每一句话上的延迟</strong>,而且用户说话中间正常的停顿(想词、换气)还会触发误判。</p>
<p>2026 年更好的做法是<strong>语义端点检测</strong>(semantic turn detection):用一个很小的模型实时判断&quot;这句话在语义上说完了没&quot;。&ldquo;我想订一张去——&ldquo;显然没说完,哪怕这里静音了 800ms;&ldquo;我想订一张去北京的机票&quot;说完了,300ms 就可以接。把固定静音超时换成语义判定,这一段常常能从 250ms 砍到 100ms 以内。</p>
<h3 id="asr让它和说话并行就几乎不要钱">ASR:让它和说话并行,就几乎不要钱</h3>
<p>ASR 唯一的纪律是:<strong>必须流式</strong>。流式 ASR 一边听一边转写,用户说完时文字基本也就好了,只剩最后一个分块的尾巴。如果你用的是非流式(&ldquo;等录音结束再整段识别&rdquo;),那等于把整段语音时长又加回了预算——一句 3 秒的话就白白多 3 秒。这是新手最常见的坑。</p>
<h3 id="llm-首-token最大的一块也最难压">LLM 首 token:最大的一块,也最难压</h3>
<p>LLM 拿走了预算里最大的份额,因为它最难在不牺牲回答质量的前提下压缩。</p>
<p>关键认知:你要的是 <strong>TTFT(首 token 延迟)低</strong>,不是&quot;整段生成快&rdquo;。用户只需要尽快听到<strong>第一个字</strong>,后面的边生成边说。能压 TTFT 的手段:</p>
<ul>
<li><strong>缩短 system prompt</strong>——每一个 token 都要参与首次前向计算</li>
<li><strong>prompt caching</strong>——把固定的前缀缓存住,省掉重复的 prefill</li>
<li><strong>小模型兜首句</strong>——用一个快模型先回&quot;嗯&quot;&ldquo;好的,我看一下&rdquo;,大模型在背后接管</li>
<li><strong>投机解码 / 更近的推理节点</strong>——把网络和排队的尾巴削掉</li>
</ul>
<h3 id="tts-首包同样只看第一段">TTS 首包:同样只看&quot;第一段&rdquo;</h3>
<p>和 LLM 一个道理——要流式 TTS,**首包(time-to-first-audio)**出来就播,别等整句合成完。再把 LLM 的输出按标点/句子切块,边出边喂给 TTS。现代流式 TTS 的首包能做到 75–200ms。</p>
<h2 id="流式的魔法感知延迟--真实延迟">流式的魔法:感知延迟 ≠ 真实延迟</h2>
<p>这是整套设计的核心。</p>
<p>一次完整回答的<strong>真实</strong>总耗时可能有 1.5 秒甚至更长。但用户感受到的延迟,只是<strong>到第一个音</strong>的那段时间——因为 LLM 还在生成后半句时,前半句已经在用户耳朵里播了。</p>
<pre class="mermaid">flowchart LR
  L1[LLM: 生成第1句] --> L2[LLM: 生成第2句] --> L3[LLM: 生成第3句]
  L1 -.切块.-> T1[TTS+播放 第1句]
  L2 -.切块.-> T2[TTS+播放 第2句]
  L3 -.切块.-> T3[TTS+播放 第3句]
</pre><p>所以工程上的铁律:<strong>这条链路上任何一环都不能&quot;攒齐再传&rdquo;</strong>。VAD、ASR、LLM、TTS,全部流式串起来,一环阻塞,整条链路的&quot;感知延迟&quot;就塌回成&quot;真实延迟&quot;。</p>
<h2 id="打断barge-in不只是停-tts">打断(barge-in):不只是&quot;停 TTS&quot;</h2>
<p>人会打断。语音 Agent 必须能被打断,而且打断要干净。</p>
<p>用户插话时,要做的<strong>不止</strong>是停掉正在播的音频,而是四件事一起:</p>
<ol>
<li>停止 TTS 音频播放</li>
<li>取消<strong>还在合成</strong>的 TTS 任务</li>
<li>取消<strong>还在生成</strong>的 LLM 请求</li>
<li>重置整条流式管道的状态</li>
</ol>
<p>漏掉任何一步,AI 要么跟你抢着说,要么在你打断之后还要&quot;把上一个念头说完&quot;。</p>
<p>另一个反方向的坑是<strong>误打断</strong>:背景噪音、旁边人说话、你自己的&quot;嗯哼&quot;,都可能被当成插话。解法是带说话人意识的 VAD(personalized VAD),只对&quot;主说话人&quot;的语音触发打断。</p>
<h2 id="级联-vs-端到端2026-年怎么选">级联 vs 端到端:2026 年怎么选</h2>
<ul>
<li><strong>级联</strong>(ASR → LLM → TTS):三个模块各自独立。可控、可调试、每一环都能单独监控和替换。2026 年它仍然是生产环境的默认选择,尤其是电话客服这种强管控、强合规的场景。</li>
<li><strong>端到端语音模型</strong>(speech-to-speech):语音直接进、语音直接出,中间不落文字。延迟更低,情感和韵律保留得更好(信息没有在&quot;转成文字再转回来&quot;的过程中丢失)。代价是难调试、难审计、难合规。</li>
</ul>
<p>我的判断:别把它当成二选一。强管控场景用级联;Web 端的陪伴、互动类产品可以上端到端;成规模的团队最后大概率是<strong>两套都跑,按场景路由</strong>。</p>
<h2 id="最后工程优先级别搞反">最后:工程优先级别搞反</h2>
<p>如果你在做语音 Agent,优化的顺序应该是:</p>
<ol>
<li><strong>先把流式管道打通</strong>——确保没有任何一环在&quot;攒齐再传&quot;。这一步的收益最大,而且不花钱。</li>
<li><strong>再砍轮次判定</strong>——把固定静音超时换成语义端点检测。</li>
<li><strong>最后才去抠 LLM</strong>——换小模型、上 prompt caching、投机解码。</li>
</ol>
<p>很多团队一上来就盯着&quot;换个更快的大模型&quot;,但如果你的管道根本不是流式的,换什么模型都救不回那种&quot;慢半拍&quot;的感觉。先把链路理顺,再谈毫秒。</p>
]]></content:encoded></item><item><title>流式 TTS:把首包延迟压到 150ms</title><link>https://realtime-ai.chat/posts/streaming-tts-latency/</link><pubDate>Wed, 13 May 2026 10:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/streaming-tts-latency/</guid><description>整句合成耗时 1.5 秒,用户却只感知 150ms——这篇拆开流式 TTS 的首包延迟:怎么压、怎么取舍、踩过哪些韵律和卡顿的坑。</description><content:encoded><![CDATA[<p>合成一句 12 个字的话,模型跑完要 1.2 秒。但如果做对了,用户感受到的延迟是 150ms。</p>
<p>这不是魔法,是流式 TTS 的基本盘。差别在于:你是等整句音频生成完再播,还是第一个音频块一出来就往用户耳朵里塞。前者用户等 1.2 秒,后者等 150ms——同一个模型,同样的算力,体验差一个数量级。</p>
<p>我在《<a href="../voice-latency-budget/">实时语音对话的延迟预算</a>》里把整条语音 Agent 链路拆过一遍,TTS 那一段只给了一句话:&ldquo;要流式,首包出来就播。&ldquo;这篇把那一句话展开,只讲 TTS。</p>
<h2 id="为什么是首包不是整句">为什么是&quot;首包&rdquo;,不是&quot;整句&rdquo;</h2>
<p>先说清楚一个被混淆得很厉害的指标。</p>
<p>很多 TTS 厂商的官网首页挂着&quot;实时率 0.3&quot;或者&quot;合成速度比真人快 3 倍&quot;——这说的是<strong>整句合成耗时</strong>:一句 5 秒的话,1.5 秒合成完。这个数字对离线场景(把一本书转成有声书)有意义,对实时对话<strong>几乎没意义</strong>。</p>
<p>实时对话里真正决定体验的是 <strong>TTFA(time-to-first-audio,首包音频延迟)</strong>:从你把文字喂给 TTS,到第一段能播放的音频抵达用户、开始出声,中间隔了多久。</p>
<p>道理和流式 LLM 一样。LLM 看的是首 token 延迟(TTFT),不是整段生成完的时间;TTS 看的是首包,不是整句。因为一旦第一个音节开始播,后面的音频是边合成边播的——只要合成速度比播放速度快(实时率小于 1),用户就永远听不到&quot;卡壳&quot;。整句要 1.5 秒还是 3 秒,用户根本感知不到,他在听前半句的时候,后半句已经悄悄合成好排在缓冲区里了。</p>
<p>所以这篇标题里的&quot;150ms&quot;,指的是 TTFA。这是 2026 年一个<strong>够格但不极致</strong>的数字:对话不会让人觉得&quot;AI 在想&quot;,但还没到 Cartesia Sonic-3 那种 40ms 模型延迟的极限。</p>
<p>有个数字陷阱要先点破。厂商宣传的&quot;75ms&quot;或&quot;100ms&quot;通常是<strong>纯模型推理时间</strong>——在一块独占 GPU 上,喂一段短文本,模型吐出第一块音频要多久。它不含网络往返、不含 API 网关排队、不含音频编码、不含你播放器的缓冲。一个 benchmark 跑 100ms 的模型,部署在共享云上、赶上流量高峰,端到端能轻松飙到 800ms。所以看 TTFA 数字,永远要问一句:这是模型延迟,还是用户真实感知到出声的延迟?这篇说的 150ms,是后者。</p>
<h2 id="首包延迟花在哪">首包延迟花在哪</h2>
<p>把 TTFA 拆开,大致是这么几块:</p>
<table>
  <thead>
      <tr>
          <th>环节</th>
          <th>它在做什么</th>
          <th>典型耗时</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>网络上行 + 排队</td>
          <td>文字请求到达 TTS 服务、进队列</td>
          <td>20–80 ms</td>
      </tr>
      <tr>
          <td>模型 prefill</td>
          <td>处理输入文本、首块音频前的计算</td>
          <td>40–120 ms</td>
      </tr>
      <tr>
          <td>首块音频生成</td>
          <td>吐出第一个音频 chunk</td>
          <td>30–90 ms</td>
      </tr>
      <tr>
          <td>音频编码</td>
          <td>PCM / Opus / MP3 封装</td>
          <td>5–30 ms</td>
      </tr>
      <tr>
          <td>网络下行</td>
          <td>首块音频回到客户端</td>
          <td>20–80 ms</td>
      </tr>
      <tr>
          <td>播放器缓冲</td>
          <td>凑够最小缓冲再起播</td>
          <td>50–200 ms</td>
      </tr>
      <tr>
          <td><strong>合计(可感知 TTFA)</strong></td>
          <td></td>
          <td><strong>约 150–500 ms</strong></td>
      </tr>
  </tbody>
</table>
<p>看这张表,有两件事值得拎出来说。</p>
<p>第一,<strong>播放器缓冲常常是最肥的一块,也最容易被忽略</strong>。工程师盯着模型延迟抠了半天,把模型从 120ms 压到 80ms,结果播放器为了抗抖动设了 200ms 缓冲——白忙活。这块后面单独讲。</p>
<p>第二,<strong>网络往返是固定成本,且省不掉,只能靠部署位置压</strong>。一次上下行加起来 40–160ms,如果你的 TTS 服务在弗吉尼亚,用户在上海,光物理距离就吃掉 200ms 以上。这部分不优化,模型再快也是纸面数字。</p>
<h2 id="怎么把它压下去">怎么把它压下去</h2>
<p>按收益从大到小排,六个手段。</p>
<h3 id="1-流式合成这是地基不是优化项">1. 流式合成:这是地基,不是优化项</h3>
<p>如果你的 TTS 是&quot;等整句文本到齐 → 整段合成 → 整段返回&quot;,那前面所有讨论都不成立。流式 TTS 的协议(通常是 WebSocket)允许<strong>文字一边到一边合成</strong>:LLM 还在生成后半句,前半句的音频已经在合成了。</p>
<p>2026 年主流的实时 TTS 都走这条路。ElevenLabs Flash 官方标的端到端 135ms TTFB;Cartesia Sonic-3 靠 SSM(状态空间模型)架构做到 40ms 首包、90ms 模型延迟;Deepgram 的 Voice Agent TTS 标 sub-200ms。这些数字的前提全是流式——没有流式,谈不上首包。</p>
<h3 id="2-按句标点分块而不是按字数">2. 按句/标点分块,而不是按字数</h3>
<p>LLM 吐出来的是 token 流,你不能每来一个 token 就喂给 TTS——那样韵律会碎成渣。你需要在中间攒一个<strong>最小可合成单元</strong>再发。</p>
<p>分块策略大致三种:</p>
<ul>
<li><strong>固定字符数</strong>(比如 150–300 字符):延迟可预测,但会从句子中间切开,韵律遭殃。</li>
<li><strong>句子/标点边界</strong>:在句号、问号、逗号处切。韵律自然,但延迟不固定——遇上一个长句,首块迟迟攒不齐。</li>
<li><strong>动态自适应</strong>:首块用最激进的策略(凑够一个短语就发),后续块按标点切。</li>
</ul>
<p>我的建议很明确:<strong>首块和后续块用不同策略</strong>。首块只追求&quot;快&quot;——攒到第一个逗号、或者凑够一个能独立成韵的短语(7–10 个字)就立刻发出去,让用户尽快听到声。从第二块开始切回句子边界,保住整体韵律。用户对首块的韵律宽容度其实很高,他在乎的是&quot;AI 开口了没&quot;;但要是整段都按短语切,听感就会一顿一顿的。</p>
<h3 id="3-模型预热别让第一个用户当小白鼠">3. 模型预热:别让第一个用户当小白鼠</h3>
<p>冷启动是隐形杀手。一个刚拉起的 TTS 实例,第一次请求往往要额外几百毫秒——CUDA context 初始化、模型权重换入显存、KV cache 分配。</p>
<p>解法是<strong>预热</strong>:实例就绪后、接真实流量前,先用一段哑文本跑几次完整合成,把所有 lazy 初始化的路径走通。配合发布策略——新实例预热完成才进负载均衡的轮转。否则每次扩容、每次滚动发布,都会有一批倒霉用户撞上冷启动的尾巴。</p>
<h3 id="4-合成与播放重叠">4. 合成与播放重叠</h3>
<p>这是流式 TTS 的核心收益,也是最容易在实现上漏掉的地方。原则一句话:<strong>链路上任何一环都不能&quot;攒齐再传&quot;</strong>。</p>
<pre class="mermaid">flowchart LR
  L[LLM 输出 token 流] -->|按标点切块| C1[文本块1]
  L -->|按标点切块| C2[文本块2]
  L -->|按标点切块| C3[文本块3]
  C1 --> T1[TTS 合成 块1]
  C2 --> T2[TTS 合成 块2]
  C3 --> T3[TTS 合成 块3]
  T1 --> P[播放队列<br/>边收边播]
  T2 --> P
  T3 --> P
  P --> S[用户听到连续语音]
</pre><p>块 1 在播的时候,块 2 在合成,块 3 的文本还在 LLM 里生成。三件事并行。只要合成速度跟得上播放速度,用户听到的就是一条不断的声音。一旦某一环改成&quot;等齐&quot;,感知延迟立刻塌回真实延迟。</p>
<h3 id="5-就近部署">5. 就近部署</h3>
<p>网络往返省不掉,但能缩短。把 TTS 推理节点放在离用户近的区域,40–160ms 的往返能压到几十毫秒。对全球业务,这意味着多区域部署 + 按用户地理位置路由。这条不涉及任何模型技巧,纯靠基建,但收益实打实。</p>
<h3 id="6-选对音频格式">6. 选对音频格式</h3>
<p>回传格式直接影响首包能多快&quot;可播&quot;。这里有个反直觉的点:很多 TTS 流式返回的<strong>头几个字节根本不是音频</strong>,而是容器元数据——WAV 头、Ogg 识别页、MP3 的 ID3 标签。播放器要等这些 + 第一个真实音频帧才能起播。</p>
<p>实时场景优先用<strong>裸 PCM</strong>(比如 pcm_22050):没有容器头,第一个字节就是可播音频,省掉解析开销。代价是带宽——PCM 不压缩,流量大。带宽敏感就退一步用 Opus,它的帧结构对低延迟友好,别用 MP3。</p>
<h2 id="首包延迟音质成本三角取舍">首包延迟、音质、成本:三角取舍</h2>
<p>没有免费的午餐。把首包压到极限,一定在别处付了代价。</p>
<table>
  <thead>
      <tr>
          <th>你想要</th>
          <th>代价</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>首块切得极碎(快)</td>
          <td>韵律断裂,听感一顿一顿</td>
      </tr>
      <tr>
          <td>顶级音质模型</td>
          <td>推理慢,首包难压</td>
      </tr>
      <tr>
          <td>独占 GPU、低 P99</td>
          <td>成本高,利用率低</td>
      </tr>
      <tr>
          <td>多区域就近部署</td>
          <td>运维复杂、机器成本翻倍</td>
      </tr>
      <tr>
          <td>裸 PCM 低延迟</td>
          <td>带宽成本上升</td>
      </tr>
  </tbody>
</table>
<p>我的取舍偏好,按场景分:</p>
<p><strong>实时对话(客服、语音助手)</strong>:首包延迟优先,音质够用就行。用户在打电话,他不会拿着话筒细品音色,他要的是不卡、不等。这种场景我会接受首块韵律略糙,换 150ms 的 TTFA。</p>
<p><strong>有声内容(播客、有声书、视频配音)</strong>:音质优先,首包延迟根本不是问题——这是离线批处理,慢就慢。该上最好的模型、最细的韵律控制。</p>
<p><strong>成本敏感的规模化场景</strong>:别盲目追 P50。真正影响体验的是 <strong>P99</strong>——你不能让 1% 的用户等 2 秒。Cartesia 用 SSM 架构主打的卖点就是 P99 比 transformer 稳,因为 SSM 是线性扩展、不像 transformer 那样随序列长度二次膨胀。规模一大,P99 的稳定性比 P50 的漂亮数字值钱得多。</p>
<p>一句话:<strong>先明确你在哪个场景,再谈压到多少毫秒</strong>。脱离场景比拼 TTFA 数字,是营销,不是工程。</p>
<h2 id="实践中真正会咬人的坑">实践中真正会咬人的坑</h2>
<p>前面讲的是怎么做对。这一节讲怎么做错——这些坑我和身边的人基本都踩过。</p>
<p><strong>坑一:分块切太碎,韵律断裂。</strong> 为了压首包,有人把分块阈值设得很激进,每凑 3–5 个字就发一块。结果 TTS 拿到的全是没头没尾的碎片,它无法预测句子级的语调走向——该升调的地方平了,该停顿的地方连上了,整句听起来像机器人念词卡。根因是流式 TTS 在<strong>局部上下文</strong>下做韵律预测,缺了句子的全局结构。务实的做法:首块可以碎(用户宽容),但从第二块起一定切回标点/句子边界,把韵律的锅甩给完整的句子。</p>
<p><strong>坑二:首块太短,反而更慢。</strong> 听起来矛盾——首块越短不是越快发出去吗?但太短的首块(比如 2 个字)会触发两个问题:一是 TTS 对超短文本的相对开销更高(prefill 的固定成本摊不开);二是它播完只要零点几秒,而第二块还没合成好,中间出现<strong>空隙</strong>,用户听到&quot;你好……(停顿)……我是客服&quot;。首块不是越短越好,要够短到快、又够长到能撑住后续块的合成时间。经验值是凑够一个完整短语,7–10 个字。</p>
<p><strong>坑三:缓冲欠载(buffer underrun)导致卡顿。</strong> 播放器从网络收音频块,凑够一点就开播。如果某一块因为网络抖动或合成慢迟到了,播放队列被掏空——这就是缓冲欠载,用户听到爆音或者卡顿。</p>
<p>缓冲设置是个跷跷板:缓冲小,起播快(TTFA 低),但抗抖动差;缓冲大,起播慢,但播得稳。没有放之四海的数值。数据中心内部、网络稳定,50–100ms 缓冲够了;移动端、网络飘忽,得放到 150–250ms 来吸收抖动。</p>
<p>更关键的是<strong>把欠载率当独立指标监控</strong>,别只看 TTFA。一个务实的阈值:如果缓冲欠载超过请求总数的 2%,就该调大缓冲——哪怕这意味着 TTFA 涨几十毫秒。卡顿对体验的伤害,远大于首包慢那一点点。慢半拍用户能忍,中间卡一下用户立刻出戏。</p>
<p><strong>坑四:只测了模型,没测端到端。</strong> 回到开头那个数字陷阱。你在本地用独占 GPU 测出 80ms 首包,上线后用户反馈&quot;AI 反应慢&quot;。因为真实链路上还叠着网络、网关排队、编码、播放器缓冲。<strong>测 TTFA 一定要从用户视角测</strong>——从发出请求到扬声器真正出声,端到端打点,而且要测 P99,不是 P50。</p>
<h2 id="落地优先级">落地优先级</h2>
<p>如果你正在做 TTS 这一段,顺序是这样:</p>
<ol>
<li><strong>先确认是流式的</strong>,而且整条链路没有任何一环&quot;攒齐再传&quot;。这步收益最大、几乎不花钱。</li>
<li><strong>调分块策略</strong>——首块激进、后续块按标点。这步直接决定 TTFA 和韵律的平衡。</li>
<li><strong>加预热</strong>,别让扩容和发布把冷启动甩给用户。</li>
<li><strong>测端到端 P99</strong>,把播放器缓冲和欠载率纳入监控。</li>
<li><strong>最后才谈就近部署、换更快的模型</strong>——这些是基建和钱的问题,放在管道理顺之后。</li>
</ol>
<p>很多团队一上来就到处比价&quot;哪家 TTS 首包最低&quot;。但如果你的播放器缓冲设了 250ms、链路里还藏着一个&quot;攒齐再传&quot;的环节,换哪家模型都救不回那种慢半拍。先把自己这边的链路理顺,再去谈毫秒。</p>
<hr>
<p>参考来源:<a href="https://elevenlabs.io/docs/eleven-api/concepts/latency">ElevenLabs Latency 文档</a> · <a href="https://cartesia.ai/sonic">Cartesia Sonic-3</a> · <a href="https://gradium.ai/content/best-low-latency-tts-apis-2026">Gradium: Best Low-Latency TTS APIs 2026</a> · <a href="https://deepgram.com/learn/streaming-tts-latency-accuracy-tradeoff-2026">Deepgram: Streaming TTS Latency Tradeoff</a> · <a href="https://picovoice.ai/blog/text-to-speech-latency/">Picovoice: TTS Latency</a></p>
]]></content:encoded></item></channel></rss>