跳到正文
RadarAI· PyTorch:Blog(RSS)·· 3 小时前AI 评分34

用 ExecuTorch 在 Arm 边缘设备上优化流式语音识别

AI 导读

PyTorch 博客展示如何用 ExecuTorch 将多语言流式 ASR 模型 Nemotron 3.5 部署到 Google Pixel 11,并分析精度与分块大小对流式质量的影响。

正文 · AI 翻译

PyTorch:Blog· Josiah Davis,Arm 首席 AI 工程师,以及 Kshitij Sisodia,Arm 首席软件工程师·2026-10-27 02:27· 18 分钟前AI 评分39

使用 ExecuTorch 在 Arm® 边缘设备上优化流式语音识别

AI 导读

PyTorch 博客展示如何用 ExecuTorch 将多语言流式 ASR 模型 Nemotron 3.5 部署到 Google Pixel 11,并分析精度与分块大小对流式质量的影响。

正文 · 原文

当你对着设备说话时,你期望文字能随着你的讲话实时出现。这使得流式自动语音识别(ASR)与批量转写成为不同的挑战——在批量转写中,模型在开始前已拥有完整录音。强大的批量准确率并不一定能在流式场景中延续。一项跨模型 ASR 研究说明了这一差距。Qwen3-ASR-1.7B 在受测模型中取得了最佳的批量准确率,但在使用 2.4 秒音频分块评估时,其词错误率(WER)上升了77%。

在该研究的跨模型流式对比(表 5)中,NVIDIA® Nemotron™ Speech Streaming 0.6B 在 560 毫秒音频分块下运行时,取得了最低的平均流式 WER。这一对比指出了一个关键点:准确率必须在部署时所用的分块节奏下进行测量。

本案例研究将较新的多语言Nemotron 3.5从PyTorch迁移到ExecuTorch,并在 Google Pixel 11 上分析其端侧执行情况。我们探究精度和分块大小如何改变流式质量、在单推理线程下音频需要多少处理时间、工作负载的时间花在哪里,以及哪些原生内核在运行。目标是找到一种同时评估准确率和延迟的实用方法。

在这篇博客文章中,你将了解到:

  1. ExecuTorch 如何将 PyTorch 模型连接到优化的 Arm CPU 内核。
  2. 为什么流式 ASR 需要自己的质量评估,以及更长的分块如何以更高延迟为代价提升最终转写准确率。
  3. 如何通过Arm 可伸缩矩阵扩展 2(SME2),使用 FP16 和采用逐通道权重的 INT8 量化(QC8W)来减少 ASR 总处理时间。
  4. 如何结合模型算子计时和原生内核采样来理解性能并识别剩余瓶颈。
  5. 如何同时选择分块大小和精度,以满足你的准确率和延迟目标。

从 PyTorch 模型到 CPU 指令

ExecuTorch 是 PyTorch 的边缘推理框架,包含导出工具和轻量级运行时。导出过程为推理准备模型,并生成一个.pte文件,设备运行时可以加载并执行该文件。

受支持的操作会被委托给XNNPACK,这是一个 CPU 推理库。在 Android™ 上,XNNPACK 可以从Arm® KleidiAI™软件中选择微内核:执行内部矩阵计算的小型优化例程。未委托给 XNNPACK 的算子使用 ExecuTorch 的可移植 CPU 内核运行。

图 1. 从模型导出到 CPU 指令。

SME2 扩展了 Arm 的指令集以加速矩阵计算,包括通用矩阵乘法(GEMM)。在采用 SME2 的 Arm C1 CPU 集群实现 中,矩阵单元由 CPU 集群内的核心共享,KleidiAI 提供了使用该单元的微内核来支持相关操作。在构建中启用 SME2 会使这些路径可用。不过,需要原生性能分析才能显示实际运行了哪些内核。

一次流式调用包含什么

Nemotron 3.5 是一个多语言流式 ASR 模型,围绕 RNN-T 架构构建,包含三个部分:

  1. 编码器使用 FastConformer 注意力层和卷积层来表示音频。
  2. 预测器使用 LSTM 来表示已输出 token 的历史。
  3. 联合器使用一个小型前馈层,将编码器的音频表示与预测器的 token 历史表示相结合,并预测下一个 token。它还可以产生一个空白,将解码推进到下一个音频位置。

前端将音频转换为对数梅尔特征向量,每 10 ms 产生一个向量。编码器将时间位置数量减少 8 倍,因此其输出每 80 ms 音频对应一个位置。这创建了一个更紧凑的序列,表示相同的音频时长。

图 2. 从波形窗口到流式编码器位置。

前瞻是块内可用的未来上下文;块节奏是为一次调用收集新音频的频率。在前瞻为 13 时,一次调用收集 1,120 ms 的音频并产生 14 个编码器位置。预测器和联合器处理所有 14 个有效位置,将其 token 累积到转录文本中。

前瞻 0、3 和 6 分别给出 80、320 和 560 ms 的块。更长的块会增加首次文本和后续更新的等待时间;预处理和推理会在音频收集后增加时间。

同时选择块大小和精度

我们在主机上使用 ExecuTorch 运行时及其 XNNPACK CPU 后端测量了转录准确率。我们创建了一个本地流式适配器,使用 Hugging Face Open ASR Leaderboard 评估框架进行数据集准备、转录文本归一化和 WER 评分。

我们在四种块大小下评估了 FP32、FP16 和 INT8。INT8 规格为 QC8W,对符合条件的线性操作使用动态 INT8 激活和逐通道 INT8 权重,输出为 FP32。

图 3. 四个语料库上的流式 WER 与块大小关系。

上图中的每个点覆盖来自 LibriSpeech Other(LS Other)、AMI Cleaned、Earnings22 和 VoxPopuli Cleaned AA 数据集的 14,019 条话语。WER 将所有四个语料库的总词错误数除以总参考词数。

更长的分块可提升最终转录准确率。从 80 ms 到 1,120 ms,FP16 的 WER 从 15.2% 降至 11.5%,QC8W 从 15.5% 降至 11.7%。FP16 基本与 FP32 持平,在每个分块大小下差异均小于 0.03 个百分点,因此我们在后续性能分析中排除 FP32。QC8W 保持了很强的准确率,相对 FP32 的 WER 仅增加 0.21–0.31 个百分点。

这些主机端 WER 结果可为精度和前瞻(lookahead)选择提供依据。但它无法衡量文本在设备上出现所需的时间。

在边缘设备上测试实时预算

我们在 Google Pixel 11 智能手机设备上处理了一段 24.9 秒的录音,使用 1,120 ms 分块和 一个绑定到中核 CPU 的推理线程。我们选择中核 CPU 作为该系统上持续流式工作负载的代表性目标。我们测试了 ExecuTorch 1.3.1 的两个构建版本,分别开启和关闭 SME2 支持。每个构建版本都保留了 XNNPACK 和 KleidiAI,并使用相同的模型产物。

每种配置均进行两次预热和一次测量追踪运行。总时间涵盖从音频预处理到最终去分词化处理加载录音的全过程。

图 4. 禁用和启用 SME2 时的整段录音处理时间。

SME2 大幅缩短处理时间:FP16 从 9.79 秒降至 4.61 秒(快 2.12 倍),QC8W 从 5.20 秒降至 3.24 秒(快 1.61 倍)。

无论是否启用 SME2,两者处理录音的时间都远小于音频时长。用处理时间除以音频时长,我们计算出实时因子:FP16 为 0.19,QC8W 为 0.13(启用 SME2 时)。仅使用单个推理线程就提供了充足的处理余量。音频仍需先到达才能被解码,因此这一余量并不能消除分块收集延迟。但它为分块之间的其他 CPU 工作留出了容量,并有助于在持续转录期间管理热负载。

使用 ETDump 定位瓶颈

ETDump 记录 ExecuTorch 算子事件和耗时。为了解 2.12 倍 FP16 和 1.61 倍 QC8W 的加速来自何处,我们将编码器、预测器和联合器中的机器学习(ML)算子分为以下几类:

  • GEMM(蓝色):矩阵乘法,主要是编码器的稠密层。
  • 数据移动(橙色):复制、拼接、重复和嵌入查找。
  • 逐元素(红色):激活、比较和其他逐值运算。
  • 卷积与归一化(绿色和紫色):卷积滤波器和归一化算子;两者在此处占比相对较小。
  • 其他(紫罗兰色):其余耗时较少的小型操作,例如张量创建。
  • 开销(灰色):分组算子事件之外的完整运行时间;这可能包括运行器和框架开销。

图 5. 整段运行加速背后的算子成本和开销。

ETDump 的时间是编码器、预测器和联合器网络的总和。加上剩余开销即可得到图 4 中显示的完整处理时间。

GEMM 贡献了大部分加速。

启用 SME2 后,GEMM 时间从 FP16 的 8.2 秒降至 3.1 秒,QC8W 从 4.1 秒降至 2.0 秒。GEMM 仍是运行中占比最大的部分,但其在总处理时间中的份额从 FP16 的 84% 降至 67%,QC8W 从 78% 降至 62%。两个构建的数据移动耗时大致相同,因此随着 GEMM 加速,其相对份额上升:FP16 从 8% 升至 17%,QC8W 从 9% 升至 17%。这部分剩余工作限制了整体加速幅度,也为进一步优化提供了目标。

运行了哪些内核?

ETDump 能定位开销大的算子族,但不会指出执行这些算子的原生微内核名称。

Arm Streamline 允许我们对原生调用路径进行采样并测量硬件计数器。在 Pixel 11 上,我们测得 FP16 的 SME 利用率为 38.4%,QC8W 为 53.7%。这表明每次采集期间矩阵硬件被分配的比例,并非峰值算术吞吐量的百分比。我们还对 GEMM 函数进行了采样,以识别每个构建所选择的微内核。

函数名揭示了采样到的路径。_sme2_mopa 后缀表示矩阵外积累加例程。NEON 和 I8MM 是控制路径所使用的向量指令族。

精度 SME2 采样到的 GEMM 路径与函数
FP16 True KleidiAI FP16 SME2
kai_kernel_matmul_clamp_f16_f16p2vlx2_f16p2vlx2_2vlx2vl_sme2_mopa

XNNPACK FP16 NEON
xnn_f16_gemm_minmax_ukernel_6x16__asm_aarch64_neonfp16arith_cortex_a75
FP16 False XNNPACK FP16 NEON
xnn_f16_gemm_minmax_ukernel_6x16__asm_aarch64_neonfp16arith_cortex_a75
QC8W True KleidiAI INT8 SME2,FP32 输出
kai_kernel_matmul_clamp_f32_qai8dxp1vlx4_qsi8cxp4vlx4_1vlx4vl_sme2_mopa

KleidiAI FP32 SME2
kai_kernel_matmul_clamp_f32_f32p2vlx1_f32p2vlx1biasf32_sme2_mopa
QC8W False KleidiAI INT8 NEON I8MM,FP32 输出
kai_run_matmul_clamp_f32_qai8dxp4x8_qsi8cxp4x8_16x4_neon_i8mm

这些采集结果证实,针对 SME2 的 KleidiAI GEMM 内核在 Pixel 11 上同时为 FP16 和 QC8W 运行,此外还有其他内核路径。在 FP16 构建中,部分 GEMM 操作仍使用 NEON。在 QC8W 构建中,部分 GEMM 操作仍以 FP32 运行。

这凸显了生态系统中的工具缺口。ETDump 暴露模型算子耗时,而 Streamline 采样原生函数,但两者都无法直接关联这些视图。将单个模型层映射到观察到的内核函数仍属未来工作。

选择工作点

部署需要在精度和分块大小之间平衡响应延迟与准确率。应用可能从准确率目标或延迟预算出发;以下示例说明了这两种方法。

下面的图 6 将主机 WER 结果与 Pixel 11 组件基准测试配对,针对 启用 SME2 的 FP16 和 QC8W。灰色刻度标记音频采集结束的时间;虚线部分加上实测的计算延迟。

x 轴是条件性首 token 时间估计:音频采集时间加上编码器–预测器–连接器序列时间的中位数。组件基准测试使用合成输入、全新流状态,并在三轮中对每种配置测量 75 个样本。它假设第一个输出会发出文本。

图 6. 启用 SME2 时 WER 与估计首 token 延迟的关系。

对于示例性的 13% WER 上限,FP16 和 QC8W 在 320、560 和 1,120 ms 分块大小下都符合要求。320 ms 分块更有利于更早响应,FP16 的 WER 为 12.67%,QC8W 为 12.97%。更长的分块可提高准确率,在 1,120 ms 时分别达到 11.50% 和 11.72%,但需要更多音频到达后才开始显示转录文本。

对于 800 ms 延迟预算,两种精度在 320 ms 和 560 ms 下都落在预算内,并且也低于示例性的 13% WER 上限。320 ms 配置更有利于更早响应,而 560 ms 提供更好的准确率。在 560 ms 下,FP16 结合了 12.01% WER 和估计的 691 ms 延迟,而 QC8W 结合了 12.26% 和 660 ms。在这里,两个 80 ms 配置都未达到 WER 目标。相反,两个 1,120 ms 配置都未达到延迟预算。

结论:这对开发者意味着什么

  • 在预期的分块大小下评估流式 ASR。 整段录音的准确率不能预测流式质量。在这里,更长的分块提高了最终转录准确率,同时增加了响应延迟。
  • ExecuTorch 将 PyTorch 模型连接到优化的 Arm CPU 内核。 其导出和运行时路径让 XNNPACK 为符合条件的操作选择 KleidiAI 微内核。
  • SME2 创造了更多处理余量。 加速矩阵运算减少了 ASR 花费的时间,为设备上的其他应用任务或并发工作负载留出更多空间。
  • ETDump 揭示算子加速和剩余瓶颈。 对算子计时进行分组可以显示收益来自哪里,以及数据移动如何成为处理时间中更大的部分。
  • Streamline 识别实际运行的本地微内核。 本地样本确认选择了 SME2 内核,而硬件计数器显示矩阵硬件分配情况。
  • 同时选择分块大小和精度。 比较精度和分块大小的组合有助于开发者为其应用在响应延迟和转录准确率之间取得平衡。

文章 Optimizing Streaming Speech Recognition on Arm® Edge Devices with ExecuTorch 首次发表于 PyTorch。

来源:PyTorch:Blog · pytorch.org

来源:RadarAI · aihot.news