摘要:大模型语音机器人上线前不做并发压测,双十一话务一冲,问题往往不是“接不进来”,而是“接进来了但答得慢、答一半断了、TTS卡住不出声”。它和传统IVR压测最大的区别是链路更长:ASR转写、LLM推理、TTS合成、媒体传输四段串联,任何一段成为瓶颈都会拖垮整通对话。本文从压测目标、指标定义、环境搭建、分层场景设计、工具选型、执行步骤到瓶颈定位,给出一套可落地的并发通话压测方法,附压测架构图、脱敏实测数据、对比表和模拟器脚本框架。文中的分层压测方法不限于双十一,适用于各类可预期话务峰值场景。
关键词:大模型语音机器人、并发通话压力测试、ASR、LLM推理、TTS、压测方案、双十一话务峰值、性能瓶颈分析

大模型语音机器人并发通话压力测试是指在模拟多路用户同时与机器人对话的条件下,验证ASR、LLM、TTS、媒体传输和业务服务各环节在目标并发下的响应能力、稳定性和资源水位的一套测试方法。它和传统IVR压测的区别在于:IVR的瓶颈通常在媒体端口和按键流程,链路短、状态少;大模型语音机器人的链路是“语音进→转写→理解→生成→合成→语音出”,中间多了模型推理,延迟和资源消耗都更不可控。

每年双十一前,我们都会对语音机器人做一轮完整压测。踩过的坑不少,比如压测时只测了通话并发,没测LLM的token吞吐,结果上线后并发一高,机器人答得慢半拍,用户以为断线就挂了。下面把压测这套流程拆开讲,尽量给能直接套用的方法。

一、大模型语音机器人压测,和传统IVR有什么不同

传统IVR压测,重点在媒体层:能同时接多少路、放音和按键响应是否及时。链路相对短,状态机简单,压测工具模拟SIP信令和RTP流基本就能覆盖。

大模型语音机器人不一样。一通对话要经过四段:

text

用户语音 → ASR转写 → LLM理解与生成 → TTS合成 → 媒体播放
              ↑                                      ↓
              └────────── 多轮对话循环 ──────────────┘

每段都有独立的资源消耗和延迟特征:

  • ASR:吃CPU或GPU,受音频时长、并发路数影响,流式转写还要考虑分片延迟。

  • LLM:吃GPU显存和推理吞吐,受输入长度、输出长度、并发请求数影响,首token延迟和整句生成延迟要分开看。

  • TTS:吃CPU或GPU,受文本长度、音色数量、流式合成策略影响,首包延迟很关键。

  • 媒体传输:吃带宽和网络质量,受丢包、抖动影响。

压测时如果只压媒体层,ASR、LLM、TTS没压到,上线后照样出问题。所以大模型语音机器人的压测要分层压、全链路串,不能只测一个点。

两类压测的差异可以对照下表看:

对比维度传统IVR压测大模型语音机器人压测
链路长度短,媒体+按键状态机长,ASR→LLM→TTS→媒体四段串联
主要瓶颈媒体端口、并发许可模型推理资源、token吞吐、首包延迟
核心指标接通率、放音延迟、按键响应分段P95延迟、token吞吐、对话完成率
工具差异SIPp等媒体压测工具为主媒体压测+接口压测+全链路模拟器组合
异常放大断线、单通推理排队、输出截断、TTS合成失败

二、先定压测目标和通过标准

压测不是“跑一下看看”,要先写清楚目标和通过标准。建议从三个维度定:

第一,容量目标。 双十一峰值预计多少路并发对话、峰值CAPS多少、平均对话轮次多少。这些数从历史话务和活动排期估算,和呼叫中心容量估算方法一致。

text

峰值并发对话路数 ≈ 峰值小时对话次数 × 平均对话时长(s) ÷ 3600

举例:峰值小时对话2.4万次,平均对话时长120秒:

text

并发 ≈ 24000 × 120 ÷ 3600 = 800路

第二,体验目标。 用户能感知的延迟主要是三段:ASR首字返回、LLM首token、TTS首包。建议给每段设P95阈值,比如ASR首字P95小于500毫秒,LLM首token P95小于800毫秒,TTS首包P95小于300毫秒。整通对话的响应间隔P95控制在1.5秒以内。具体阈值按业务容忍度定,这里给的是参考值。

第三,稳定性目标。 压测期间错误率、超时率、断线率的上限。比如压测30分钟,对话成功率不低于99%,ASR超时率低于0.5%,LLM超时率低于1%,TTS合成失败率低于0.5%。

目标维度示例指标示例阈值
容量并发对话路数800路
容量峰值CAPS15次/秒
体验ASR首字P95<500ms
体验LLM首token P95<800ms
体验TTS首包P95<300ms
体验对话响应间隔P95<1.5s
稳定对话成功率>99%
稳定LLM超时率<1%

这些阈值不是拍脑袋,要结合历史压测和线上监控数据定。第一次做可以宽松一点,跑几轮后收紧。阈值性质上属于语音交互体验的常见工程实践参考,最终以业务SLA为准。


三、指标怎么定义:别只看并发路数

压测报告里只写“支撑800路并发”没有意义,要看在这800路下各环节的表现。建议按四类指标记录:

第一类,容量指标。

  • 并发对话路数:同时在对话的会话数。

  • CAPS:每秒新建对话数。

  • ASR并发请求数、LLM并发请求数、TTS并发请求数。

  • 各服务实例数和资源水位。

第二类,延迟指标。 每段都要分P50、P95、P99:

  • ASR首字延迟、整句转写延迟。

  • LLM首token延迟、整句生成延迟、输出token速率。

  • TTS首包延迟、整句合成延迟。

  • 端到端响应间隔:用户说完到机器人开始出声的时间。

第三类,质量指标。

  • ASR字错率(用标准测试音频对比)。

  • LLM输出是否截断、是否跑题(人工抽检)。

  • TTS合成失败率、音频是否完整。

  • 对话完成率、异常挂断率。

第四类,资源指标。

  • CPU、内存、GPU利用率、显存占用。

  • 网络带宽、丢包率。

  • 消息队列积压、数据库连接数。

这四类指标要一起看。比如并发800路时LLM首token P95到了2秒,虽然没报错,但体验已经不达标,不能算通过。


四、压测环境怎么搭

压测环境尽量接近生产,至少满足四个条件:

第一,网络拓扑一致。 压测客户端到服务端的网络路径、带宽限制、NAT和防火墙策略尽量和生产一致。如果生产走公网接入,压测也走公网或模拟公网延迟;如果生产内网媒体节点万兆互联,压测环境别用千兆凑合。

第二,服务配置一致。 实例规格、副本数、模型版本、TTS音色配置、ASR模型版本都要和生产对齐。压测环境用小模型、少副本,压出来的数不能直接用。

第三,数据脱敏但真实。 压测用的音频、文本要覆盖真实场景:不同口音、不同语速、不同背景噪声、不同对话轮次。可以用脱敏后的历史对话音频,也可以人工构造。别只用标准普通话测试音频,那样ASR指标会虚高。

第四,监控埋点齐全。 压测前确认各服务的延迟、错误率、资源水位都有埋点,最好有统一看板。压测时一边加压一边看板,比压完再翻日志效率高得多。

如果生产环境不方便直接压,可以搭一套“影子环境”:流量从生产复制一份到影子环境,但影子环境不接真实用户。这种方式对生产影响小,但搭建成本高,适合大型活动前做。


五、压测架构与工具链路

压测的整体链路可以按下面这张图理解,每段标注了对应的压测工具和观测指标:

text

┌──────────────────────────────────────────────────────────────┐
│ 压测控制台:场景编排、并发梯度、停止条件                        │
└───────────────┬──────────────────────────────────────────────┘
                ↓
┌──────────────────────────────────────────────────────────────┐
│ 媒体压测客户端(SIPp / 自研模拟器)                            │
│ 模拟注册、邀请、RTP流、打断、静音                              │
│ 观测:接通率、媒体丢包率、断线率                                │
└───────────────┬──────────────────────────────────────────────┘
                ↓
┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐
│   ASR    │ → │   LLM    │ → │   TTS    │ → │ 媒体播放  │
│ 首字延迟  │   │ 首token  │   │ 首包延迟  │   │ 端到端间隔│
│ 字错率    │   │ token吞吐│   │ 合成失败率│   │ 丢包/抖动 │
└──────────┘   └──────────┘   └──────────┘   └──────────┘
                ↓
┌──────────────────────────────────────────────────────────────┐
│ 监控看板:分段P50/P95/P99、错误率、GPU/CPU/带宽/队列积压        │
└──────────────────────────────────────────────────────────────┘

这张图的作用是:压测时每一段的工具、指标和上下游关系都能对上号,出问题知道先看哪一段。压测控制台负责场景编排和并发梯度,媒体客户端负责模拟真实通话行为,ASR/LLM/TTS三段分别有独立的接口压测和全链路串联,监控看板把四类指标聚合在一起。

工具选型上没有一套工具能覆盖全部,按环节组合使用,具体在第八节展开。


六、压测场景怎么设计:从单环节到全链路

压测场景建议分四层设计,从单环节到全链路逐步加压。

第一层:单环节压测。 分别压ASR、LLM、TTS,摸清每个环节的独立容量上限。

  • ASR:用不同时长音频(3秒、10秒、30秒)压并发转写,看首字延迟和整句延迟随并发的变化。

  • LLM:用不同输入长度和输出长度压并发推理,看首token延迟和输出速率。

  • TTS:用不同文本长度压并发合成,看首包延迟和合成失败率。

单环节压测的目的是找到每个环节的拐点:并发到多少时延迟开始明显上升,到多少时开始报错。

第二层:两两串联压测。 把ASR+LLM、LLM+TTS串联起来压,看上下游之间的排队和背压。比如ASR转写快了,LLM请求堆积,首token延迟就会上升;TTS合成慢了,LLM输出缓冲区会堆积。

第三层:全链路压测。 模拟完整对话:用户说话→ASR→LLM→TTS→播放→下一轮。这是最接近真实场景的压测,也是双十一前必须跑的。

第四层:混合场景压测。 在全链路基础上加入异常场景:用户打断、静音、重复说话、网络抖动、ASR返回空结果、LLM超时重试。这些场景会放大资源消耗,压测时不能忽略。

压测层级压什么关注指标目的
单环节ASR/LLM/TTS各自延迟、错误率、资源水位找单点容量拐点
两两串联ASR+LLM、LLM+TTS排队延迟、背压看上下游耦合
全链路完整多轮对话端到端延迟、成功率验证整体承载
混合场景异常和打断超时率、重试率验证鲁棒性

七、大模型链路特有的三个压测点

大模型语音机器人有三个容易漏掉的压测点,单独拎出来说。

第一,LLM的token吞吐和并发请求数不是一回事。 很多团队压测时只看“同时发多少个请求”,但LLM的实际负载取决于输入token数+输出token数。同样100个并发请求,输入50字和输入500字,GPU负载差很多。压测时要按真实对话的输入输出长度分布来构造请求,记录token吞吐(tokens/s),不能只记QPS。

text

LLM负载 ≈ 并发请求数 × 平均输入token数 × 平均输出token数

实际压测时建议按P50、P95的输入输出长度分别压,看不同长度下的延迟和吞吐。只看平均值会漏掉长尾请求把GPU打满的情况。

第二,ASR流式转写的分片延迟。 流式ASR是把音频分片送进去,边转边出结果。压测时要关注分片大小和分片间隔对首字延迟的影响。分片太大首字延迟高,分片太小请求数多、资源消耗大。双十一高并发时,分片策略要提前调好。

第三,TTS流式合成的首包和整句。 流式TTS先出首包再持续合成,首包延迟决定用户感知的响应速度。压测时要分别记录首包延迟和整句合成延迟,只看整句延迟会漏掉首包慢的问题。

这三个点共同的特点是:不能只用QPS衡量。QPS相同,token长度、分片策略、文本长度不同,实际负载和体验差很多。压测报告里要把这些参数写清楚。


八、压测工具怎么选

压测工具按环节选,没有一套工具能覆盖全部。

环节常见工具适用场景注意点
SIP/RTP媒体SIPp、开源压测工具、自研模拟器模拟通话建立和媒体流要支持RTP流模拟和语音文件播放
ASR自研HTTP/WebSocket客户端、Locust压转写接口要模拟流式分片和真实音频
LLMLocust、wrk、自研客户端压推理接口要按token长度分布构造请求
TTSLocust、自研客户端压合成接口要区分首包和整句
全链路自研对话模拟器模拟完整多轮对话要能控制轮次、打断、静音

工具选型原则:单环节用轻量工具快速压,全链路用自研模拟器贴近真实。 不要指望一个工具压所有环节,也别为了压测专门搭一套大平台,先用脚本跑通再考虑工具化。

在优音通信的语音机器人压测实践中,全链路模拟器是按对话轮次、打断场景、静音超时分别构造脚本的,单环节压测用轻量接口客户端,两者配合使用,既保证覆盖面,又控制压测环境的搭建成本。这种组合方式对小团队也比较友好,先跑通再逐步工具化。


九、压测执行步骤:从冒烟到破坏性演练

压测执行建议按五步走,逐步加压,每一步都记录数据。

第一步,冒烟测试。 1到5路并发跑通全链路,确认各环节都能正常工作,埋点数据能采集到。这一步不追求性能,只验证链路通。

第二步,阶梯加压。 从目标容量的20%开始,按20%、40%、60%、80%、100%逐级加压,每级稳定运行5到10分钟,记录各环节指标。找到延迟开始明显上升的拐点。

第三步,目标容量稳定压测。 在100%目标容量下持续压30到60分钟,看指标是否稳定、有没有内存泄漏、队列积压是否持续增长。

第四步,超目标压测。 加压到目标容量的120%到150%,看系统在超载时的表现:是优雅降级还是雪崩,错误率上升到多少,恢复需要多久。

第五步,破坏性演练。 在稳定压测中随机摘掉一个LLM实例、一个TTS节点、一个消息队列broker,看系统能否自动切换、对话是否受影响、恢复时间多长。这一步最能暴露架构问题。

text

压测执行流程:
冒烟(1-5路) → 阶梯加压(20%-100%) → 目标容量稳定压测(30-60min)
→ 超目标压测(120%-150%) → 破坏性演练 → 输出报告

每一步都要有明确的进入条件和退出条件。比如阶梯加压时,如果某一级错误率超过5%,停止加压,先排查问题。


十、瓶颈怎么定位:看哪几个指标

压测出问题不可怕,找不到瓶颈才麻烦。建议按“先看端到端,再分段看,最后看资源”的顺序定位。

第一步,看端到端。 对话响应间隔P95超标,先确认是哪一段慢。把ASR首字、LLM首token、TTS首包三段延迟拆开看,哪段P95最高,先查哪段。

第二步,分段看。 如果LLM首token慢,看是请求排队还是推理慢。请求排队看LLM服务前面的队列长度和并发请求数;推理慢看GPU利用率和显存占用。如果ASR首字慢,看分片策略和ASR实例CPU水位。

第三步,看资源。 CPU、内存、GPU、带宽、队列积压,哪个先到瓶颈。常见情况是GPU显存先满,导致LLM推理排队;或者TTS节点CPU打满,首包延迟飙升。

第四步,看依赖。 数据库慢查询、Redis热key、消息队列积压,这些依赖问题在高压下会放大。压测时把依赖服务的监控也打开。

一个实用技巧:压测时给每个环节打上trace ID,全链路追踪一遍慢请求,比看聚合指标更快定位。多数APM工具都支持,压测前确认埋点到位。


十一、一次脱敏压测记录:800路目标,拐点出在哪

说一次脱敏的压测记录,保留量级和过程,具体业务细节做过调整。

项目背景:大模型语音机器人,目标双十一峰值800路并发对话,平均对话4轮,输入文本平均40字、输出平均80字。压测环境按生产1:1搭建,ASR、LLM、TTS分别独立部署。

阶梯加压结果:

并发路数LLM首token P95TTS首包 P95ASR首字 P95对话成功率GPU显存水位
200路520ms210ms340ms99.6%48%
400路610ms230ms360ms99.4%63%
600路720ms250ms390ms99.2%78%
720路1.4s280ms420ms98.1%86%
800路2.1s310ms460ms96.3%91%

拐点分析: 600路之前,各段延迟都在阈值内;到720路时LLM首token P95从720毫秒跳到1.4秒,对话成功率掉到98.1%;800路时首token P95到2.1秒,已经明显超出体验阈值。同期ASR和TTS的延迟上升平缓,不是瓶颈。

瓶颈定位: 看GPU监控,720路时显存水位到86%,LLM推理开始排队,请求等待时间拉长。显存被占满的主要原因是批处理大小设得偏大,长请求把短请求的显存挤占了。

调优动作: 调整批处理策略,按输入长度分桶调度,短请求优先;同时把LLM实例从4个扩到6个。调完在720路和800路各压30分钟:

并发路数调优后LLM首token P95调优后对话成功率GPU显存水位
720路740ms99.3%72%
800路820ms99.1%79%

800路时首token P95从2.1秒降到820毫秒,对话成功率从96.3%回到99.1%,达到预设阈值。这次压测最大的收获不是“能扛800路”这个结论,而是找到了LLM显存这个真正的拐点,并提前做了批处理策略调整。


十二、压测模拟器脚本框架

全链路模拟器不用写得很复杂,先把“多轮对话+分段计时+打断”跑通。下面是一个简化框架,按实际接口替换。

python

import asyncio
import time
import random

class DialogSimulator:
    def __init__(self, rounds=4, interrupt_prob=0.1):
        self.rounds = rounds
        self.interrupt_prob = interrupt_prob
        self.metrics = []

    async def asr(self, audio):
        start = time.time()
        # 替换为真实ASR流式接口调用
        await asyncio.sleep(random.uniform(0.2, 0.5))
        return time.time() - start

    async def llm(self, text):
        start = time.time()
        # 替换为真实LLM推理接口调用,按输入长度构造请求
        await asyncio.sleep(random.uniform(0.4, 0.9))
        return time.time() - start

    async def tts(self, text):
        start = time.time()
        # 替换为真实TTS流式接口调用,区分首包和整句
        await asyncio.sleep(random.uniform(0.15, 0.3))
        return time.time() - start

    async def one_turn(self):
        asr_ms = await self.asr("audio_chunk")
        llm_ms = await self.llm("user_text")
        tts_ms = await self.tts("reply_text")
        interrupted = random.random() < self.interrupt_prob
        if interrupted:
            # 模拟用户打断,提前进入下一轮
            await asyncio.sleep(0.1)
        self.metrics.append({
            "asr": asr_ms, "llm": llm_ms, "tts": tts_ms,
            "interrupted": interrupted,
        })

    async def run(self):
        for _ in range(self.rounds):
            await self.one_turn()

async def main(concurrency=800):
    tasks = [DialogSimulator().run() for _ in range(concurrency)]
    await asyncio.gather(*tasks)

# 使用示例:按阶梯加压时改 concurrency
# asyncio.run(main(concurrency=200))

这个框架只保留核心逻辑:每轮对话依次调ASR、LLM、TTS,记录各段耗时,按概率模拟打断。实际使用时替换三个接口调用,加上阶梯加压控制和结果聚合,就能跑全链路压测。压测前记得把音频和文本换成脱敏数据。


十三、双十一前的压测节奏

结合双十一的时间节点,建议按四周节奏安排:

第一周:容量估算和环境准备。 按历史话务和活动排期估算峰值并发、CAPS、对话轮次;搭压测环境,准备脱敏测试音频和文本;确认监控埋点。

第二周:单环节和两两串联压测。 分别压ASR、LLM、TTS,找到各自容量拐点;做ASR+LLM、LLM+TTS串联压测,看背压和排队。

第三周:全链路压测和调优。 按目标容量做全链路压测,根据瓶颈调参:LLM批处理大小、TTS并发数、ASR分片策略、连接池大小。调完再压一轮验证。

第四周:超载压测和破坏性演练。 加压到120%到150%,做节点摘除演练,确认降级和容灾策略有效;输出压测报告和值班预案。

这个节奏的前提是提前四周启动。如果只剩两周,至少保证全链路压测和破坏性演练各做一次,单环节压测可以简化。

压测报告建议按固定模板输出,方便版本对比:

报告项内容
压测目标并发路数、CAPS、对话轮次
环境配置实例规格、模型版本、副本数
场景设计单环节/串联/全链路/混合
分段延迟ASR/LLM/TTS的P50/P95/P99
成功率对话成功率、各环节错误率
资源水位GPU/CPU/带宽/队列积压峰值
瓶颈分析拐点位置、根因
调优建议参数调整、扩容建议
遗留风险未覆盖场景、待验证项

十四、常见坑与FAQ

Q1:压测只压通话并发行不行?
不够。大模型语音机器人的瓶颈常在ASR、LLM、TTS,只压媒体层测不出模型链路的容量。要分层压、全链路串。

Q2:LLM压测只看QPS行不行?
不行。同样QPS,输入输出token长度不同,GPU负载差很多。要按真实对话的token长度分布构造请求,记录token吞吐。

Q3:压测环境能用小模型代替吗?
不建议。小模型和大模型的延迟、显存占用、吞吐特征不同,压出来的数不能直接用。至少用和生产同规格的模型做一轮验证。

Q4:压测音频用标准普通话行不行?
不够。要覆盖不同口音、语速、背景噪声,否则ASR指标会虚高。用脱敏后的真实对话音频更接近线上。

Q5:压测时错误率多少算通过?
看业务容忍度。参考值是对话成功率不低于99%,LLM超时率低于1%,ASR超时率低于0.5%。具体按业务和SLA定。

Q6:破坏性演练有必要做吗?
有必要。双十一期间单节点故障概率不低,提前演练能发现路由收敛慢、切换不彻底的问题。至少做一次媒体节点和一次LLM实例摘除。

Q7:压测报告要写什么?
至少写:压测目标、环境配置、场景设计、各环节P50/P95/P99延迟、错误率、资源水位、瓶颈分析、调优建议、遗留风险。别只写一个并发数,文末有模板可以参考。

Q8:压测数据要不要脱敏?
要。压测用的音频和文本如果来自真实对话,必须脱敏,去除号码、姓名、地址等敏感信息,并在授权环境下使用。

Q9:压测对生产有影响怎么办?
优先用影子环境或独立压测环境。如果必须在生产压,选低峰时段,限制压测流量比例,设置熔断阈值,一旦核心指标异常立即停止。

Q10:双十一当天还要压测吗?
当天不压。压测在活动前完成,当天只做监控和预案执行。活动前一周可以做一次小流量回归,确认配置变更没有引入问题。

Q11:压测时怎么模拟用户打断?
打断是语音机器人特有的场景。模拟器在TTS播放阶段按概率提前发送下一段音频,触发机器人停止当前输出。压测时打断比例建议设5%到15%,看机器人处理打断的响应延迟和资源消耗。

Q12:LLM超时重试会不会放大压力?
会。超时重试相当于把一次请求变成两次,高并发下容易形成雪崩。压测时要专门跑一组“注入超时+重试”的场景,观察队列积压和GPU水位,确认重试策略有退避和上限。


十五、结论摘要

  1. 大模型语音机器人压测要分层做。 ASR、LLM、TTS、媒体四段分别压,再做全链路串联,不能只压通话并发。

  2. 先定目标和阈值。 容量、体验、稳定性三个维度都要有量化标准,P95延迟和错误率是核心。

  3. LLM不能只看QPS。 按token长度分布构造请求,记录token吞吐和首token延迟。

  4. 流式ASR和TTS要分开看首包。 首字延迟、首包延迟决定用户感知,只看整句延迟会漏问题。

  5. 压测环境尽量接近生产。 网络、配置、模型版本、测试数据都要对齐,否则数据不可用。

  6. 执行按五步走。 冒烟、阶梯加压、目标容量稳定压测、超载压测、破坏性演练。

  7. 瓶颈按端到端→分段→资源→依赖的顺序定位。 全链路trace ID比聚合指标更快。

  8. 双十一前四周启动压测。 单环节、全链路、超载和破坏性演练都要覆盖,报告写清遗留风险。

大模型语音机器人的并发压测,核心不是“压出一个并发数”,而是把ASR、LLM、TTS、媒体四段的容量和延迟摸清楚,找到拐点,提前调优和降级。文中并发数字和延迟阈值是示例参考,实际按业务模型、模型规模和压测结果调整;压测需在授权环境和脱敏数据下进行。这套分层压测和瓶颈定位方法不限于双十一,各类可预期话务峰值场景都可以参考。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐