Skip to content

约 10 分钟阅读

19. 语音与多模态推理 ​

前面一直是打字提问。现在小林对麦克风说“年假怎么申请?”,希望直接听到回答。这一篇先沿着这段声音走一遍,看语音识别、语言模型和语音合成怎样接力;再用 sherpa-onnx 看语音框架怎样把模型接进应用;然后判断前面学过的缓存、批处理、量化,哪些能用在语音上、哪些不能;最后讨论怎样测量语音的等待。读完你应该能分清模型、语音框架和计算后端,也能区分首字、首 token 和首个可播放音频这几种“快”。

同一个问题,多了哪些接力 ​

流式ASR、语言模型、TTS和播放链路及打断清理关系

小林的声音先变成文字,资料助手生成回复,再把回复变成声音。可以把它想成“听写员 → 资料答疑员 → 播音员”的接力:中间的人写得再快,也不能消除听写员判断是否说完、播音员准备开口的等待。实际系统可让几段工作重叠,图中还画出了用户打断时的控制路径。

语音推理同样适用缓存、批处理、量化和调度这些思想,但不一定能直接用 vLLM 或 SGLang 执行整条链路。 要先看模型怎样计算,再看引擎是否实现了它的输入、状态、输出与流式协议。“能输入音频”“能流式转写”“能实时生成音频”是三种不同能力。

sherpa-onnx 把语音模型接进应用 ​

小林希望断网时也能在设备上识别问题。只下载一个模型文件还不够:麦克风提供的是声音采样,模型可能需要声学特征;模型输出的是概率或编号,应用需要的是文字。支持流式的模型还要保留跨音频块的状态。

sherpa-onnx 是语音推理与部署框架,把这些步骤组织起来。它有 C++ 核心和多种语言接口,可以部署在手机、桌面、嵌入式设备,也可以在服务器上提供服务。它覆盖语音识别、语音合成、人声检测、关键词检测、说话人相关任务等;具体能力由模型、框架版本和设备后端共同决定。

下面拆开一次识别。ONNX 是模型的表示格式,ONNX Runtime 是执行模型计算的运行时;sherpa-onnx 在计算前后补上语音任务需要的处理。图中展示常见 ONNX Runtime 路线,部分设备使用专门后端。

sherpa-onnx 组织特征与流管理、调用 ONNX Runtime 执行已适配模型、解码成文本,应用接收文本后再检索和调用语言模型

沿箭头看:采样先变成模型所需的输入,神经网络执行计算,再由适配的解码器解释输出。不同架构的特征、状态和解码步骤会有所不同。能用 ONNX Runtime 加载文件,只验证了其中一层;模型的输入输出、词表和前后处理也要与框架适配。

现在把它接回资料助手。下面用固定教学样例推进“听 → 答 → 说”,每一步都会改变当前数据和接手的组件。

小林:年假怎么申请?固定样例 · 教学回放
  1. 1收音
  2. 2准备输入
  3. 3模型计算
  4. 4得到文字
  5. 5查资料并回答
  6. 6合成声音
  7. 7播放

1 / 7 · 应用 · 音频接入

输入
麦克风的声音采样
输出
采样率、声道明确的音频块

应用取得录音权限,检查音频格式,把音频块送给识别器。此时还没有文字,也没有调用语言模型。

模型与结果均为教学示例;不录音、不调用真实模型。实际服务可以重叠运行部分阶段,耗时需单独测量。

识别文字交回应用后,应用检查资料权限、检索年假制度,再把资料和问题交给语言模型服务。sherpa-onnx 可以负责两端的 ASR 和 TTS,vLLM 或 SGLang 可以承接中间已适配的语言模型。播放器与打断控制仍由应用协调。离线要求覆盖整条链路时,语言模型与资料也需要在本地或内网可用。

版本变化要单独回归:sherpa-onnx 2.0.0

sherpa-onnx 从 1.13.x 升到 v2.0.0(2026-10-23 20:49,上海时间)。这一版不再内置 espeak-ng 和 piper-phonemize:TTS 的文本前端只保留内置词典(lexicon)路线,依赖这两个库生成音素的模型要在外部先完成音素化,再把音素或 token 传入;原来指向 espeak 数据的 data_dir 配置会被忽略。识别侧则为流式 NeMo Transducer 补上了 modified_beam_search 热词,并修复了长流 VAD 崩溃、识别结果 JSON 转义等问题。

这些变化分别关系到 TTS 接口兼容、热词可用范围与长时间运行的稳定性,不能相加成一个通用加速倍数。评估升级时,固定模型与录音,先确认所用 TTS 模型是否依赖 espeak 音素化,再分别回归识别结果、热词和长流运行;是否受益取决于实际使用的识别器、合成模型和运行路径。

都在做推理,为什么不能直接替换 ​

“模型”好比听写的方法,“计算后端”是执行数字运算的设备接口,“语音框架”把收音、计算和文字结果组织成可调用的任务;多人服务还会增加排队与调度。实际项目可以覆盖多个层次,先确定职责再比较工具。

对象在这个例子里负责什么比较时看什么
ASR / TTS 模型决定声音与文字之间怎样转换语言、准确率、音质、架构与资源需求
sherpa-onnx组织已适配语音模型的输入、执行、解码、流状态与语言接口模型与设备组合、流式结果、内存、实时率
ONNX Runtime执行受支持的计算图与算子算子、精度、执行后端、硬件兼容性
vLLM / SGLang组织已适配生成模型的缓存、批处理与服务调度首 token、生成间隔、并发容量、显存与成本

FunASR 也有推理与部署能力;它与 sherpa-onnx 在部分语音场景存在交集,也可以在模型导出与部署环节配合。选择时应核对具体模型的适配和产品需求,而不是固定成“一个只训练、一个只推理”。

热词怎样影响识别 ​

假设公司联系人叫“周望君”,模型却把相似发音写成“周望军”。热词增强会在搜索候选文字时,给指定词对应的路径增加分数;模型参数可以保持不变。训练或微调则会更新参数,两者处理问题的位置不同。

截至 2026-10-26,sherpa-onnx 的热词文档限定这套能力使用 Transducer 模型与 modified_beam_search 解码,流式和非流式均有支持。下面只演示配置条件,不计算真实声学概率。

联系人:周望君配置条件 · 教学实验
模型条件满足解码条件满足权重始终不变
具备热词增强条件

搜索时可给“周望君”对应的路径加分,模型权重保持不变。候选是否最终胜出仍取决于声音、原始分数和热词分数。

这里只判断文档规定的配置前提,不模拟识别准确率,也不预测错误配置会被具体接口如何处理。实际还要核对词表、热词文件和加载结果。

具备热词条件时,也要测“该出现时是否识别正确”和“不该出现时是否被误插入”。加分过高可能把普通词强行拉向热词。把热词写入文件后,还需要确认目标接口确实加载了文件;模型不匹配或仍使用贪心解码时,这条热词增强路线就用不上。

从哪里开始实际接入 ​

先选一个官方已适配的模型包,在电脑上用文件识别例子跑通同一段录音,确认文字结果。接着换到目标设备,保持模型、词表和音频相同,比较结果与耗时。最后再接麦克风、验证流式或切段行为,以及业务需要的热词、时间戳等输出。

这里“支持 Android”“支持某个模型”“支持 NPU”是三项条件。落地时需要确认目标模型 × 框架版本 × 设备后端 × 所需功能的组合可用;导出格式相同也可能因算子、状态或接口适配而失败。

具体 API 与配置沿已有专题继续:sherpa-onnx 概览、识别运行模式、模型与部署选型。下面回到计算结构,看看为何不同语音模型能借用的优化各有边界。

进一步区分:不同 ASR / TTS 架构能迁移哪些优化?
语音路线核心计算可迁移的优化需要专门处理的部分
CTC ASR声学编码器输出帧级分布,再折叠或搜索算子、量化、声学 batch、长度分桶特征帧、流式状态、CTC 解码与热词
Transducer ASRencoder、prediction network、joint 协作编码器优化、搜索批处理、状态池blank、对齐、beam、跨块状态
Encoder-decoder ASR音频编码,再自回归生成文本decoder KV、批处理、attention 优化encoder 状态、cross-attention、长音频分段
LLM 型 ASR音频编码与投影,语言模型生成文本受支持路径上的 KV、连续 batch、量化音频编码、模态位置、输入处理与端点
时长/声学模型加声码器 TTS文本到声学特征,再转波形batch、编译、算子与精度优化时长、音素、声学帧、声码器分块
自回归音频 token TTS逐步生成语义或 codec token可能使用 KV、调度、投机多码本、采样、codec 解码与音频拼接
扩散 / flow TTS多步去噪或积分生成声学表示编译、融合、batch、减少求解步骤质量与步数关系、条件编码和声码器
端到端语音模型音频输入输出,可能交错文本与音频引擎已适配部分的调度与缓存全双工、音频时钟、打断、回声和多流状态

Whisper 类架构含自回归 decoder,但不等于普通纯文本 decoder-only 模型。Flow 或扩散模型的“步数”,也不是 LLM 的输出 token 数。每个路线都应使用与自身结构匹配的优化和质量指标。

语音为什么还有等待 ​

一段离线音频可以一次送入模型;实时麦克风只能不断收到未来的声音。系统可能要攒够一个声学块,保留右侧上下文,等待人声检测(VAD,判断有没有人在说话)确认这句话已经结束,再修正和提交文本。

对话里“用户已经说完”与“系统确认说完”存在时间差。把断句等待从 500 ms 降到 200 ms,可能比语言模型快几个 token 更影响体验;但过短会在自然停顿处截断句子,损害识别与交互。

ASR 主体通常可以在用户说话时运行;用户停止后,关键路径更接近“端点等待 + ASR 收尾 + 首段回复文本 + TTS 首块 + 播放开销”,而不是把整段 ASR 运行时间再加一遍。

首音频时延预算从用户实际停止说话起算
断句等待
300 ms
累计排队
50 ms
ASR 收尾
150 ms
首段可合成文本
250 ms
TTS 首个可播放块
180 ms

首个可播放音频约 930 ms

串行关键路径估算,未计网络、播放缓冲、回声消除与设备开销;ASR 主体假设已在说话时运行,只计收尾。分块模式仍须攒够可合成文本,后续音频也须及时续上。这里不估计整段对话完成时间。

先降低 LLM 时间,再降低断句等待,观察总预算的变化。切换到等待完整文本和音频,会把两段额外等待带回首音频路径。真实系统可能重叠更多阶段,也可能因网络、语音质量或播放缓冲增加成本,因此要用 trace 校准每项。

从文本片段到连续声音 ​

ASR 可以逐步返回临时文本,但最终结果可能修订;协议需要区分 partial 与 final。TTS 接口即使通过流传输,也可能先算完全部音频再切块返回;这种传输流式并不意味着模型首音频计算已经缩短。

真正的增量 TTS 还要考虑输入文本块是否足以确定发音和韵律。文本太短可能造成停顿、重音或语调不自然;等待整句又增加首音频。LLM 的 token 边界也不一定是适合合成的词句边界。

首块很快只是开始。后续块若不能赶上播放时钟,就会断音。需要同时观察音频 chunk 的到达间隔、可播放时长和缓冲水位。

语音的性能指标 ​

指标解释需要防止的误读
RTF处理墙钟时间 / 音频时长30 秒音频耗时 3 秒,RTF=0.1;实时等待还需测端点、收尾与输出
首字/首个 partial从约定起点到首次文本起点是音频首帧、用户停说还是请求发出,结论不同
Final 时延用户实际结束到稳定最终结果含端点与收尾,不能只测模型 forward
首音频时延到首个可播放音频HTTP 首字节可能是头信息或不足以播放的数据
音频续流块间隔、缓冲和欠载平均生成速度快仍可能偶发长停顿
质量WER/CER、说话人、音质、自然度等不同任务需要不同评估,不能只测吞吐

例如 10 路音频的批量离线 RTF 很低,可能来自充分聚批。在线只有一小块音频到达时,等待凑 batch 会损伤延迟;要把 batch 大小和最大等待时间一起调。

取消、打断和会话状态 ​

用户说“停一下”时,需要终止或失效化旧 LLM 请求、TTS 合成、待播放音频,并清理会话引用。已经发出的音频不能靠取消 GPU 任务撤回,播放器也要有清空队列的协议。

底层原生推理未必能立即中断,超时后仍可能继续使用缓冲。应用应区分“用户不再等待”与“底层资源已释放”,避免重复提交同一任务或过早复用内存。具体实践见推理输入合同与资源生命周期。

什么时候选择哪条部署路线 ​

如果模型是引擎明确适配的音频输入或输出生成模型,可以评估 vLLM、SGLang 及其相关多模态扩展,但要单测流式、采样、codec 和并发状态。仅支持文本部分,不能推断整条语音链路都受加速。

传统 ASR/TTS 或端侧 SDK,可以先看 sherpa-onnx、模型官方运行时或 FunASR 等任务框架,再确认它们实际支持的 ONNX Runtime、TensorRT、OpenVINO、Core ML、ExecuTorch 等设备执行路线;这些后端分别属于不同生态,并非每个框架都能任意切换。服务器上的声学模型也可以与 LLM 引擎并列运行,通过业务层连接。

图像与视频同理:视觉 encoder、预处理、多模态 token 展开和解码各有成本。图像数量、分辨率、视频帧数和音频长度可能让“相同文本 token 数”的请求完全不是同一种负载。

判断练习:ASR 的 final 慢 800 ms,换 vLLM 能直接解决吗?

先拆出 VAD 端点等待、声学收尾、decoder、搜索和队列。如果 600 ms 来自确认用户说完,替换 decoder 引擎未必有效。如果模型受支持且 decoder 是主要瓶颈,才有明确的评估方向。还要保持识别质量和切句完整度。

语音交互把听、答、说与播放串在一起。sherpa-onnx 组织语音任务,ONNX Runtime 等后端执行受支持的模型计算,应用连接资料、语言模型和播放控制。端点判断、首个可播放块、后续续流和打断共同决定体验;沿实际结构逐段测量,才能判断该优化解码、调度,还是音频链路。

不管是文字还是语音,优化做完以后都要回答同一个问题:怎样证明它真的有效?下一篇讲性能测试与分析。

别急,先让缓存热一下。