状态:草稿(2026-10-06),实测文章。 以下数字是作者亲自测量的值。单轮对话首个声音的耗时是根据各组件实测数据 计算得出的推测,并非从头到尾连续测量。由于大多数测量使用的是合成语音和一个对话提示词,因此可能与实际用户环境有所不同。第 4-3 节是用人声朗读(公开语音语料库)重新测量语音识别的值,其中也包含非母语英语。 编写规则:以实测数据为基础,无法测量的标注为“未实测”。
目录
- 1. 测了什么,为什么测
- 2. 环境与方法
- 3. 语音合成(TTS)结果
- 4. 语音识别(ASR)结果
- 5. 对话 LLM 结果:Gemma 4 12B 4-bit
- 6. 测量中发现的问题
- 7. 单轮对话的延迟是多少
- 8. 面试中可能会被问到的问题
- 未确认的事项
- 参考资料
- 已确认的版本与日期
1. 测了什么,为什么测
第 19 篇中我们调查了开源候选方案,但所有数值都基于文档。为了在外语口语练习中加入“语音交互”功能,必须亲自了解以下三个组件的延迟:
- 语音识别(ASR): 将学习者的话转换为文字。
- 对话 LLM: 对转录的文本生成回复。
- 语音合成(TTS): 将回复朗读成声音。
我们对所有三个组件进行了韩语、日语、中文和英语的测量,并在相同输入下对比了两对开源模型(Qwen3-ASR 与 Nemotron 3.5 ASR,VoxCPM2 与 Magpie TTS)。
2. 环境与方法
| 项目 | 数值 |
|---|---|
| 服务器 | 两台 GPU 服务器。24GB 级消费级 GPU(570 系列驱动)与 8GB 级笔记本 GPU(595 系列驱动) |
| 语音合成 | VoxCPM2(24GB 级 GPU)、Magpie TTS Multilingual 357M(8GB 级 GPU) |
| 语音识别 | Qwen3-ASR-1.7B 及词级别时间对齐器(24GB 级 GPU)、Nemotron 3.5 ASR Streaming 0.6B(8GB 级 GPU) |
| 对话 LLM | Gemma 4 12B 谷歌官方 QAT 4-bit(GGUF 7.0GB),llama.cpp 服务器(--parallel 2,上下文 4096),关闭思考模式(24GB 级 GPU) |
| 方法 | 将服务器运行在临时容器中,对 3 种句子(短、中、长)× 4 种语言各请求 3 次(LLM 请求 5 次),取中位数 |
| 安全机制 | 容器内存限制,如果宿主机可用内存降至标准以下,则中止测量 |
由于这两对模型是在 不同的 GPU 上测量的,因此直接比较速度时需谨慎(内存占用和准确率则可以跨 GPU 进行对比)。语音合成通过服务器返回的合成时间和音频长度计算出 实时系数(合成时间 ÷ 音频长度) ,小于 1 表示生成速度比播放速度快。
3. 语音合成(TTS)结果
3-1. VoxCPM2
在预热状态下(模型已加载且音色已设计好)的 3 次中位数。
| 语言 | 字符数 | 音频(秒) | 合成时间(秒) | 实时系数 |
|---|---|---|---|---|
| 英语 | 39 / 80 / 179 | 2.08 / 4.00 / 9.60 | 1.21 / 2.11 / 4.77 | 0.572 / 0.526 / 0.496 |
| 日语 | 17 / 36 / 67 | 3.04 / 5.28 / 9.12 | 1.69 / 2.78 / 4.56 | 0.556 / 0.519 / 0.500 |
| 中文 | 18 / 23 / 54 | 3.84 / 4.96 / 10.72 | 2.05 / 2.59 / 5.31 | 0.531 / 0.522 / 0.496 |
| 韩语 | 20 / 38 / 67 | 3.84 / 6.88 / 12.64 | 2.06 / 3.50 / 6.25 | 0.536 / 0.509 / 0.494 |
- 无论哪种语言,合成时间约为音频长度的一半。 全部 12 个组合的实时系数在 0.494 到 0.582 之间(中位数为 0.521),同一组合 3 次测量的离散程度在 0.02 以内。
- 句子越短,系数略大。 如果按语言对三个点进行直线拟合,合成时间大致为 音频长度 × 约 0.47 + 约 0.23 秒(基于全部 12 个点的公式为 0.475 × 长度 + 0.23 秒),四种语言的公式几乎完全相同。可以解释为每句话消耗约 0.23 秒的固定开销在短句子中拉高了比例,但该开销的具体来源尚未查明。
- 该方式由服务器合成整句话后一次性返回。 达到第一个声音的时间即为句子的合成时间,若为 2 到 4 秒的短句,则为 1.2 到 2.1 秒。在对话中,该数值是导致首个声音延迟的最大因素。
- 首次创建音色的调用需要额外多花 3 到 3.5 秒。 由于服务器会将音色设计并保存一次,后续进行克隆,因此仅在第一次时发生。
- 占用约 6,600 到 6,900 MiB 的 GPU 内存。 首次启动时的模型加载耗时 385 秒,包含权重下载。
3-2. Magpie TTS Multilingual 357M
使用相同的句子进行了测量(8GB 级笔记本 GPU,3 次中位数)。
| 语言 | 合成时间(秒) | 音频(秒) | 实时系数 | 语音识别回传文本字符错误率 |
|---|---|---|---|---|
| 英语 | 1.23 / 2.10 / 4.59 | 2.69 / 4.55 / 9.33 | 0.458 / 0.462 / 0.495 | 0% / 0% / 0% |
| 日语 | 1.41 / 2.71 / 4.80 | 3.11 / 5.76 / 9.66 | 0.448 / 0.471 / 0.496 | 13% / 12% / 0%(书写差异) |
| 中文 | 1.87 / 2.29 / 5.09 | 3.85 / 4.92 / 10.26 | 0.452 / 0.465 / 0.499 | 0% / 10% / 6% |
| 韩语 | 0.27 / 0.37 / 0.99 | 0.51 / 0.65 / 2.18(异常) | 0.455~0.588 | 100%(无结果) |
- 仅多占用约 750 MiB 的 GPU 内存。 这是加载两个模型后的占用量 5,832 MiB 减去仅加载语音识别模型时的 5,078 MiB 得出的差值。约为 VoxCPM2 的九分之一。
- 正常工作的三个语言的实时系数中位数为 0.466(0.447~0.541)。 该数值与 VoxCPM2 相近或略低,但测量于不同的 GPU。
- 韩语在此配置下无法直接使用(原因与绕过方案见下文)。 20 到 67 个字符的句子生成的音频时长为 0.4 到 4.3 秒(正常情况下应为 4 到 13 秒),将其输入语音识别后得到了空结果。模型卡文档中声称支持韩语,且相同的调用方式在英语、日语和中文中均表现正常。检查点版本并非原因所在。我们在相同环境下测试了模型卡中说明已添加韩语的 v2607 在内的 main、v2607、v2602 三个检查点,结果三句韩语均生成了 0.4 到 2.1 秒(v2602 为 0.7 到 1.3 秒)的音频,回传转录的字符错误率为 1.00,开启文本正则化后结果也一样。使用相同的调用方式,英语在三个版本中均表现正常(字符错误率为 0.00~0.07)。首次开启正则化的调用耗时 4.5 到 4.7 秒。 原因是语言代码选择分词器(Tokenizer)的代码逻辑。 v2607 检查点拥有包含
korean_chartokenizer在内的 15 个分词器(如果用它对韩语句子进行分词会得到 40 个 Token),但 NeMo 3.0.0 的get_tokenizer_for_language会在内部映射表(LANGUAGE_TOKENIZER_MAP)中查找语言代码,若找不到则回退到english_phoneme,而该表中没有韩语,导致ko,ko-KR,korean全部走向了英语音素分词器。韩语句子经过英语音素分词器后只剩下 5 个 Token(大部分为未知字符),导致模型在 0.4 到 0.8 秒内便结束了(英语、日语和中文均映射到了各自的分词器,运行正常)。如果在韩语中korean_chartokenizer强制使用该函数(进行绕过修改),则三句话生成的音频时长分别为 3.5、5.8 和 3.8 秒,通过语音识别回传转录的字符错误率分别为 0.00、0.00 和 0.05。合成耗时分别为 1.6、2.7 和 1.7 秒(实时系数约为 0.46~0.47),与其他语言处于同一水平。也就是说, 模型和检查点本身支持韩语,只是当前版本的 NeMo 代码未将韩语连接起来。更新版本的 NeMo 是否已添加该映射尚未确认(未确认)。本次测试仅包含 3 个句子,且未评估音质。 - 回传错误率是将合成语音输入另一个语音识别模型(Nemotron 3.5 ASR)中并与原文进行对比得出的数值,仅能作为合成质量的大致参考指标。
4. 语音识别(ASR)结果
让模型指定语言去转录上述合成生成的 12 个音频(2~13 秒)。
4-1. Qwen3-ASR-1.7B
| 语言 | 音频(秒) | 推理时间(秒) | 实时系数 | 字符错误率 |
|---|---|---|---|---|
| 英语 | 2.1 / 3.8 / 9.6 | 0.16 / 0.26 / 0.52 | 0.054~0.077 | 0% / 0% / 0% |
| 日语 | 3.0 / 5.3 / 8.6 | 0.15 / 0.31 / 0.51 | 0.049~0.059 | 0% / 15% / 0% |
| 中文 | 3.8 / 4.8 / 10.7 | 0.16 / 0.25 / 0.49 | 0.042~0.052 | 0% / 0% / 0% |
| 韩语 | 4.2 / 7.4 / 12.6 | 0.22 / 0.42 / 0.62 | 0.049~0.057 | 0% / 0% / 0% |
- 转录耗时 0.15~0.6 秒,实时系数为 0.04~0.08。比合成(约 0.5) 快大约 10 倍 ,因此不是瓶颈。
- 即使不指定语言、通过自动检测运行,这 12 个音频也全部识别正确。
- 加载模型后,GPU 内存增加了约 5,756 MiB。首次请求耗时 174 秒(包含权重下载和加载),纯推理耗时 6 秒。
4-2. Nemotron 3.5 ASR Streaming 0.6B
使用相同的 12 个音频(8GB 级笔记本 GPU,将语言指定为区域设置,采用单次转录整个文件的方式)。
| 项目 | 数值 |
|---|---|
| 推理时间 | 每个文件 0.23~0.30 秒(实时系数 0.023~0.112,中位数为 0.050) |
| 平均字符错误率 | 3.9% (Qwen3-ASR 扣除日语书写差异后为 0%) |
| 自动检测 | 12 个全部正确(结果中带有 <ko-KR> 之类的语言标记) |
| GPU 内存 | 模型加载后约 5,078 MiB(该值包含模型以外的运行环境开销) |
| 加载时间 | 权重下载完成后约 31 秒 |
- 转录错误的示例是将
How was误记为How is,三明治误记为三名制,집 근처에误记为집근처에。在这 12 个样本中,Qwen3-ASR 更加准确,而 Nemotron 体积更小且专为流式传输设计。 - 不同分块(Chunk)大小的准确率。 模型处理的单个分块大小可在 80、160、320、560、1,120 ms 中选择。用相同的 12 个音频计算平均错误率:80 ms 为 4.3%,160 ms 为 4.0%,320 ms 为 3.9%,560 ms 为 3.9%,基本保持一致,唯独在 1,120 ms 时突增至 11.3% 。这是因为有一个音频输出了空结果(重新测两次结果相同),但用人声重新测量时,韩语中无论分块大小如何,空结果数量均为 0(第 4-3 节)。这似乎仅在该 12 个合成样本中出现。该数值是将相应设置应用于整个文件的近似值, 未测量实际的流式传输延迟。
4-3. 用人声重新测量的值:母语者朗读与非母语英语
以上 12 个是合成语音,不包含人类的发音和语调。我们使用公开语音语料库重新测量了 Nemotron 3.5 ASR。数据包括:FLEURS(人类朗读的句子)中每种语言 30 个句子,speechocean762(带有发音评分的中文母语者英语朗读语料库)中 100 个句子,采用整文件一次性转写方式,默认分块为 1,120ms,运行在 8GB 级笔记本 GPU 上。
| 数据 | 指标 | 平均值 | 中位数 | 空结果 | 推理时间中位数 |
|---|---|---|---|---|---|
| FLEURS 韩语 | 字错误率 | 5.8% | 3.6% | 0 | 0.296秒 |
| FLEURS 日语 | 字错误率 | 14.7% | 14.7% | 0 | 0.296秒 |
| FLEURS 中文 | 字错误率 | 18.2% | 14.6% | 0 | 0.305秒 |
| FLEURS 英语 | 词错误率 | 10.0% | 5.7% | 0 | 0.291秒 |
| speechocean762 非母语英语 | 词错误率 | 38.8% | 25.0% | 12/100 | 0.248秒 |
如果将非母语英语按发音总评分(0~10)进行划分,错误率差异非常大。
| 总分区间 | 句子数 | 词错误率(平均) | 中位数 |
|---|---|---|---|
| 6 以下 | 15 | 80.4% | 100.0% |
| 6 及以上 8 以下 | 31 | 54.0% | 60.0% |
| 8 及以上 | 54 | 18.4% | 11.8% |
- 韩语 5.8% 的字错误率与模型卡片中的 FLEURS 数值(7.12%,1.12秒分块)处于同一水平。由于样本只有 30 个句子,样本量较小,但与卡片结果一致。上述 12 个合成语音的平均值为 3.9%(四种语言的平均值),低于人类语音的数值(韩语 5.8%、日语 14.7%、中文 18.2%),证明先前的预期过于乐观。
- **在非母语英语中,错误率约为母语朗读(10.0%)的 4 倍(38.8%)**,且发音分数越低,情况恶化越快。在总分低于 6 分的区间,中位数为 100%,即大部分内容都无法转写。这意味着在语言学习应用中,初学者说的话最难识别,同时也最需要相应的反馈。人类评估的分数由语料库提供。
- 分块越小,准确率通常越低,但在韩语中几乎没有区别。
| 分块 | 韩语 CER | 英语 WER | 非母语英语 WER(空结果) |
|---|---|---|---|
| 1,120ms | 5.8% | 10.0% | 38.8% (12) |
| 560ms | 5.9% | 10.5% | 39.7% (7) |
| 320ms | 5.6% | 12.6% | 42.1% (9) |
| 160ms | 6.2% | 13.3% | 44.8% (10) |
| 80ms | 6.1% | 13.5% | 44.7% (8) |
对于英语和非母语英语,当分块从 1,120ms 缩短到 80ms 时,错误率增加了 3~6%p。而韩语保持在 5.6~6.2%,几乎没有差异,模型卡片中的韩语数值(7.12~7.70%)也呈现平稳态势。空结果仅在 1,120ms 时没有出现(非母语英语反而在 1,120ms 时产生了最多的 12 个空结果),上述合成样本中 1,120ms 以上的现象并未重现。
- 局限性。 采用韩语、日语、中文、英语各 30 个句子以及非母语英语 100 个句子的朗读语音。未对对话体、噪声、韩国学习者的英语以及其他母语者的韩语进行测量(未测量)。此结果是将分块设置应用于整个文件的近似值,并非实际的流式传输固定延迟。
5. 对话 LLM 结果:Gemma 4 12B 4-bit
针对学习者水平(CEFR A2),发送了“用一两句话回答并以一个简单的问题结束”的指令,以及用户说的“昨天在咖啡馆看了一本书”这一话语,分别使用四种语言进行了 5 次流式传输测试。 首字延迟指发送请求后到收到第一个字符的时间, 首句延迟指出现第一个标点符号的时间(即可开始语音合成的时间点)。
| 语言 | 首字延迟(秒,中位数 / 范围) | 首句结束(秒) | 回答 Token | 生成速度 (tok/s) |
|---|---|---|---|---|
| 英语 | 0.074 / 0.068~0.080 | 0.203 | 21 | 85.7 |
| 日语 | 0.074 / 0.067~0.119 | 0.100 | 23 | 85.6 |
| 中文 | 0.067 / 0.054~0.127 | 0.129 | 13 | 84.2 |
| 韩语 | 0.076 / 0.074~0.129 | 0.160 | 27 | 85.6 |
- 首字延迟在 0.07 秒左右,生成速度约为 85 tok/s。 这与服务器自身的测量结果一致(输入 67 个 token 处理耗时 95.7ms,即 700 tok/s,每个生成 token 耗时 11.6ms)。
- 第一句话结束的时间为 0.1~0.2 秒。 英语耗时最长的原因是第一句话比较长。
- 指令执行情况:遵守了指令。 所有 20 次测试均用一两句话回答并在末尾附加了问题。韩语示例:
와, 정말 좋았겠네요! 카페에서 책 읽는 건 정말 행복한 일이에요. 어떤 책을 읽었어요?质量(纠错、水平匹配)需要人工评估,本次测量仅客观反映速度。 - 并发请求增加会导致首字延迟变慢。 同时发送 2 个日语提示词时,首字延迟为 0.206 秒;发送 4 个时,中位数为 0.352 秒,最大值为 0.552 秒(由于服务器设置为仅同时处理 2 个请求,其余请求处于排队状态)。
- GPU 内存占用约为 8,450MiB。 模型加载(包含权重下载)耗时 145 秒。
思考模式导致响应内容被完全清空。 在初次测量中,所有 20 次测试的回答都是空的。查看原始响应发现, content 是空字符串,而在 reasoning_content 中积累了诸如 Role: Friendly conversation partner for a Japanese learner... Constraint 1: ... 这样的英语分析内容,这意味着 80 个 token 的预算全耗费在了思考上。这是因为该模型在 llama.cpp 的对话模板中默认会优先进行思考,通过服务器选项(--reasoning-budget 0)和请求选项(chat_template_kwargs: {enable_thinking: false})将其关闭后恢复正常。 在语音对话中必须关闭思考模式。 如果保持开启,首个声音会延迟好几秒,并且如果 token 预算较短,甚至根本无法输出回答。
6. 测量中发现的问题
6-1. 日语:发音正确但书写形式不同导致扣分
日语中间句子的错误率达到了 15%,但发音并没有错。
| 句子 | |
|---|---|
| 原文 | 私はたいてい七時に起きて**、**簡単な朝ご飯を食べて**、**地下鉄で会社に行きます。 |
| 识别 | 私は大抵7時に起きて簡単な朝ご飯を食べて地下鉄で会社に行きます。 |
たいてい 对 大抵, 七 对 7、逗号的有无属于同一内容的不同书写形式。如果发音练习服务通过 字符相似度来将识别结果与目标句子进行对比,那么即使用户完美地读出来了,也会因为这种书写差异而被扣分。中文的数字(七 对 7)预计也会出现同样的问题。解决方法是在比较前对数字和写法进行规范化,或者基于发音(读音)而不是字面进行比较。
6-2. 部署的服务器可能比最新代码旧
在一个环境中,中文合成以 404 Not Found 失败。因为服务器代码中的中文语音预设存在于新代码中,但不存在于已部署的镜像中。当新功能无法正常工作时, 应该首先检查部署镜像的版本,而不是代码。
6-3. 如果各个 GPU 服务器的驱动程序版本不同,镜像将无法启动
为 CUDA 13 构建的 vLLM 镜像在驱动程序 570 系列(最高支持 CUDA 12.8)下 Error 804: forward compatibility was attempted on non supported HW 无法启动。相同的镜像可以在驱动程序 595 系列上运行。CUDA 13.x 要求驱动程序版本在 580 或更高。当同时使用多台服务器时, 必须检查每台服务器的驱动程序版本并与镜像的 CUDA 版本匹配 。本文中的 LLM 测量是使用适用于 CUDA 12 的镜像(llama.cpp)配置的。
6-4. 测量工具中遇到的陷阱
| 症状 | 原因 | 解决 |
|---|---|---|
| 测量脚本未运行,只有服务器处于启动状态 | kubectl run --overrides 的命令行的 --command 进行覆盖 |
服务器保留默认命令,而测量代码用 kubectl exec 运行 |
合成时间为 nan |
响应头名称为小写,但读取时区分大小写 | 将头部键统一规范化为小写 |
容器 OOMKilled |
加载模型瞬间的最大内存超过了限制 | 提高限制。限制仅在容器内生效,对服务器没有影响 |
由于容器 Pending |
节点内存请求总和已经很高,两个请求 6Gi 的容器无法同时启动 | 按顺序执行测量 |
kubectl run -i 在 1 分钟后放弃 |
拉取镜像的时间超过了默认等待时间(1 分钟) | --pod-running-timeout 增加 |
| LLM 响应全部为空 | 思考模式默认开启,把 80 个 token 全用在了思考上 | 在服务器和请求两端关闭思考 |
| 回显错误率大于 1 | 错误地编写了将 22,050Hz 转换为 16,000Hz 的比例(8,000Hz),导致语音变成 2 倍速 | 将比例修正为 320/441。这是测试代码的bug,而不是工具的bug |
库无法接收语言(Unknown prompt key: 'None') |
通过文件路径调用时临时输入列表中没有语言字段的版本问题 | 附加了在临时列表中写入语言的绕过代码(权宜之计) |
这里最大的教训是关于回显错误率的案例。 测量代码的 bug 可能会被误认为是模型的缺陷。 如果出现错误率超过 1 的值,首先应怀疑的不是模型,而是输入(采样率、长度、语言指定)。
7. 单轮延迟是多少
从用户说完话到发出第一个声音,是由这些部分累加而成的。
(말 끝 판단) + ASR + LLM 첫 문장 + TTS 첫 문장 + 전송
将按部件实际测量的结果按句子长度拼接而成的 计算出的估计值(并未从头到尾连续测量)。LLM 的第一句话是上述测量中实际出现的句子,TTS 时间是将该句子的朗读长度代入 3-1 的公式(合成 ≈ 0.475 × 音频长度 + 0.23秒)中计算得出的。
| 语言 | ASR(3~7秒发音) | LLM第一句话结束 | 第一句话示例 | TTS(计算) | 合计 |
|---|---|---|---|---|---|
| 日语 | 0.15~0.3 | 0.10 | いいですね!(约1.1秒时长) |
约0.75 | 约1.0~1.2秒 |
| 中文 | 0.16~0.25 | 0.13 | 听起来很舒服!(约1.5秒) |
约0.94 | 约1.2~1.3秒 |
| 韩语 | 0.22~0.4 | 0.16 | 와, 정말 좋았겠네요!(约2.1秒) |
约1.2 | 约1.6~1.8秒 |
| 英语 | 0.16~0.26 | 0.20 | That sounds like a very relaxing way…!(约3.2秒) |
约1.75 | 约2.1~2.2秒 |
本表中不包含语音终点检测(VAD)和网络传输。假设语音终点判断为0.3~0.5秒,则需加上相应时间。该假设值在多大程度上会导致说话中途被截断的代价,我们在紧下方通过真人朗读的句子进行了测量。公开值的范围为:NVIDIA蓝图建议200~500ms、Pipecat默认0.2秒、LiveKit 0.5秒(流式轮次检测器0.3秒)、OpenAI示例500ms,因此该假设在此范围内。同文档的目标延迟(发话结束到响应开始)为600~1,500ms,采用大型GPU和流式TTS的蓝图服务器端到端延迟为0.86~0.93秒(厂商数据)。本文韩语合计加上语音终点判断后约为1.9~2.3秒,之所以更大,推测是因为本文的TTS并非流式(公开案例中TTS第一声前为0.07~0.37秒)。学习者往往犹豫较多,短促的判断可能会切断说话,但公开资料中未找到专门探讨此现象的研究(未确认)。
语音终点判断时间应该是多少(朗读语音实测)
语音终点判断是指当用户沉默一定时间后即判定说话结束,因此如果该时间短于句子内部自然的停顿,说话就会在半途被截断;而如果太长,响应也会相应延迟。在真人朗读的FLEURS句子(每种语言60句,平均10~14秒)中,使用Silero VAD(6.2.3,阈值0.5,CPU单线程)查找语音段,并将一句话内相邻语音段之间的间隔计为“句内停顿”。脚本和原始数据位于 docs/experiments/2026-10-07-vad-turn-gaps/ 中,且在无GPU的情况下通过CPU单线程运行。
| 语言 | 句内停顿次数 | 停顿中位数 | p90 | 最大值 | 停顿在300ms以上的句子 | 500ms以上 | 700ms以上 | 1,000ms以上 |
|---|---|---|---|---|---|---|---|---|
| 韩语 | 87 | 352ms | 608ms | 1,152ms | 51.7% | 28.3% | 8.3% | 1.7% |
| 英语 | 75 | 288ms | 608ms | 928ms | 40.0% | 13.3% | 6.7% | 0.0% |
| 日语 | 88 | 336ms | 672ms | 1,120ms | 50.0% | 21.7% | 10.0% | 1.7% |
| 中文 | 102 | 288ms | 544ms | 1,536ms | 48.3% | 21.7% | 8.3% | 1.7% |
-
如果将语音终点设定为0.3秒,则朗读句子的40~52%会被判定为在说话中途结束。 上述假设的下限(0.3秒)对该数据而言太短了。若为0.5秒则降至13~28%,若为0.7秒降至7~10%,若为1秒则降至0~1.7%。
-
计算一下的话 如果在上述一轮的总计时间上加上判断说话结束的时间,使用 0.5 秒时韩语约为 2.1~2.3 秒,使用 0.7 秒时约为 2.3~2.5 秒(这是加上上表总计时间的计算结果,并非从头到尾实际测量)。为了减少中断而增加判断时间,该数值会直接加到响应延迟中,这是一种权衡。
-
VAD 本身的开销很小。 在单核 CPU 上处理 1 秒音频的中位数为 3.2ms(最大 55.1ms),单个 32ms 帧为 0.10ms。判断说话结束的延迟几乎全部都是等待时间设置,而不是计算时间。
-
局限性。 这是朗读语音,且句子比单句对话更长(越长停顿的地方越多),因此对话语音中的数值可能会有所不同,且其中不包含结巴或思考时的停顿。仅使用了单个 VAD(Silero 6.2.3)和一个阈值,未测量通过语义来判断说话结束的轮次检测模型。统计的是每个句子是否存在停顿,但并未判断每个停顿是否 realmente 是说话真正结束的地方。
-
瓶颈在于语音合成。 在一轮的总时间中,约有 60~85% 是 TTS,而 ASR(0.2秒)和 LLM(0.1~0.2秒)加起来也在 0.5 秒左右。
-
如果把第一句话切得短一些,首字输出就会变快。 如果日语和汉语的回答以简短的应答开始,总计时间会降至 1 秒左右。英语的第一句话较长,因此最慢。虽然我认为如果在对话指令中要求“以简短的应答开始”可以达到同样的效果,但并未进行测试。
-
接近 ChatGPT 的水平(说话结束后 1 秒左右)。 日语和汉语已经在这个范围内,英语和韩语可以通过进一步拆分第一句话或使用流媒体合成(该服务器未使用)来减少时间。这只是推测,并未进行测试。
8. 面试中可能出现的问题
- 如何分解实时语音对话的延迟? 分为说话结束判断、ASR、LLM 第一句话、TTS 第一音、传输这几个阶段分别测量。在此处,ASR 为 0.2 秒,LLM 第一句话为 0.1~0.2 秒,TTS 为 0.7~1.8 秒,因此 TTS 是瓶颈。
- 实时系数为 0.5 就足够了吗? 这意味着比播放速度更快,在拼接较长回答时是足够的,但到首字输出的时间则另当别论。非流媒体服务器必须将整句话合成完毕后才会输出声音。
- 用语音识别结果对学习者进行评分时需要注意什么? 即使声音正确,显示的字面也可能不同(
たいてい大大抵)。在比较之前需要进行标准化,或者以朗读标准进行比较。 - 当两个模型共享一块 GPU 时,需要关注什么? VRAM 剩余量(TTS 约 6,900MiB,ASR 约 5,800MiB,分别相加)、主机 RAM 以及服务器的驱动版本(是否与镜像的 CUDA 版本匹配)。
- 当测量值违背常识(错误率 > 1)时,该怎么办? 首先怀疑测量代码而不是模型。输入转换(采样率)错误是常见原因。
未能确认的事项
- 对话质量。 虽然测量了速度,但诸如是否符合学习者水平、错误纠正、自然度等质量问题需要由人工评估,此处并未评估。提示词也只测试了一种(昨天在咖啡馆里看书)。
- 韩国学习者的英语、其他母语使用者的韩语语音,以及噪声环境下的识别准确率。 非母语英语仅通过中文使用者朗读的英语语料库进行了测量(第 4-3 节)。
- 将各个组件连接在一起的实际端到端延迟。 第 7 节是计算出的估计值。
- 对在不同 GPU 上测量的值进行直接比较。 我们在不同的 GPU 上测量了这两组模型。
- Magpie TTS 韩语声音的质量(经确认,原因是 NeMo 代码中分词器映射缺失,见第 4 节。绕过该问题后,3 个句子的回传字符错误率为 0~5%)。Nemotron ASR 的 1.12 秒分块空白结果在人类语音中未被复现。
- 并发对话数(TTS、ASR)。 每次只测量一个(LLM 测量了 2~4 个并发)。TTS 服务器持有逐个处理请求的锁,因此同时接受两个对话时似乎需要排队,但并未进行测量。由于该 TTS 服务器是实际服务中的服务器,因此未进行负载测试,仅通过公开数据确认了大致方向。NVIDIA 博客(供应商数据,NIM 服务)指出,当 Magpie TTS 的并发流从 1 个增加到 64 个时,首字延迟在 B200 上从 32 增至 239ms,在 H100 上从 47 增至 275ms,在 A100 上从 79 增至 395ms,在小型系统(DGX Spark)上从 53 增至 962ms(分别约为 7.5 倍、5.9 倍、5.0 倍、18 倍)。这证明了在相同的负载下,硬件越小,并发性对延迟的放大效应越显著这一趋势,该数值不能直接迁移到本文的环境中。
- 流媒体合成的首字延迟以及流媒体语音识别的实际确定延迟。 本次测量未使用流媒体路径。
- 插话(用户在回答过程中打断的情况)以及对话语音中说话结束的判断。 虽然上面测量了朗读语音在句子内部的停顿,但未测量插话和对话语音,仅确认了第 7 节的公开范围。
参考资料
- 第 19 篇(开源调查)、第 21 篇(原理)、第 17 篇(DCGM 指标、驱动版本)
确认的版本和日期
截至 2026-10-06。voxcpm 2.0.3、Qwen3-ASR-1.7B、Qwen3-ForcedAligner-0.6B、Nemotron 3.5 ASR Streaming 0.6B、Magpie TTS Multilingual 357M、NeMo 3.0.0、Gemma 4 12B QAT q4_0、llama.cpp b11429。