news 2026/9/14 20:14:06

NeMo 流式语音推理实战:asr_streaming_infer.py 通用流式推理指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NeMo 流式语音推理实战:asr_streaming_infer.py 通用流式推理指南

NeMo 流式语音推理实战:asr_streaming_infer.py 通用流式推理指南

【免费下载链接】SpeechA scalable generative AI framework built for researchers and developers working on Large Language Models, Multimodal, and Speech AI (Automatic Speech Recognition and Text-to-Speech)项目地址: https://gitcode.com/GitHub_Trending/nem/Speech

本文以 NeMo 开源仓库中 examples/asr/asr_streaming_inference/ 的asr_streaming_infer.py脚本及其配套配置为核心,系统讲解如何使用 NeMo 在本地完成 buffered(CTC/RNNT/TDT)与 cache-aware(CTC/RNNT)两类流式 ASR 推理,并进一步集成逆文本正则化(ITN)、句末检测(EoU)、流式语音翻译、词级/段级输出与 WER/BLEU/RTFx/LAAL 指标评估。读完本文,你将能基于仓库内的真实配置与源码调用链,从零跑通单文件、目录与 manifest 三种输入形态的流式转写任务。

一、脚本定位:一套脚本覆盖多种流式推理范式

asr_streaming_infer.py是 NeMo 仓库中面向"通用流式推理(Universal Streaming Inference)"的本地推理入口脚本。根据 README.md 的定义,它同时支持:

  • buffered 流式推理:适用于 CTC、RNNT、TDT 解码的 ASR 模型;
  • cache-aware 流式推理:适用于 CTC、RNNT 解码的 ASR 模型,核心特征是跨 chunk 复用注意力缓存(cache),避免重复计算历史帧。

输入形态支持三种:单个音频文件、音频文件目录、manifest 文件。脚本内部通过PipelineBuilder根据pipeline_type字段自动路由到对应的流水线实现(详见下文"源码级工作流"一节)。

除转写外,脚本还集成以下能力(README 明确列出的五项):

能力说明
逆文本正则化(ITN)将 ASR 原始输出(如 "one hundred twenty five dollars")还原为书面格式("$125"),由enable_itn开关控制
句末检测(EoU)基于endpointing配置判断语音停顿边界,输出语句级切分结果
流式语音翻译(ST)在转写基础上调用 vLLM 支撑的 LLM 完成流式翻译,需要预先安装 vLLM,由enable_nmt开关控制
词级输出asr_output_granularity=word时输出带时间戳的词级结果
段级输出asr_output_granularity=segment时输出段级结果(默认)

所有相关配置集中在仓库的 examples/asr/conf/asr_streaming_inference/ 目录,共五个 YAML 文件:

examples/asr/conf/asr_streaming_inference/ ├── buffered_ctc.yaml # buffered + CTC 解码(默认模型 parakeet-ctc-1.1b) ├── buffered_rnnt.yaml # buffered + RNNT 解码(默认模型 parakeet-unified-en-0.6b) ├── buffered_salm.yaml # buffered + SALM 解码(默认模型 canary-qwen-2.5b) ├── cache_aware_ctc.yaml # cache-aware + CTC 解码(默认模型 fastconformer hybrid streaming) └── cache_aware_rnnt.yaml # cache-aware + RNNT 解码(默认模型 nemotron-speech-streaming-en-0.6b)

二、运行环境与输入数据准备

2.1 依赖与前置条件

  • 本脚本基于 Hydra 配置系统驱动(@hydra.main(version_base=None)),启动时通过--config-path--config-name指定配置目录与文件名;
  • 使用流式语音翻译(NMT)功能时,必须安装 vLLM 并保证nmt.device指向可用的 CUDA 设备(配置注释明确cpu不受支持);
  • ITN 依赖nemo_text_processing(其底层依赖 pynini)。源码中对该库做了容错处理:若导入失败仅打印警告并继续运行,不影响纯 ASR 推理(见 asr_streaming_infer.py)。

2.2 输入音频约束

源码 docstring(asr_streaming_infer.py)明确要求:

输入音频必须是16 kHz、单声道(mono)WAV 文件

manifest 场景下,脚本通过prepare_audio_data读取条目并按键(如audio_filepathtext)组织数据,支持后续按时长排序以优化批处理。源码中已通过sort_by_duration=True启用按时长排序(见 asr_streaming_infer.py)。

三、命令行用法与核心参数

脚本的通用调用方式(源码 docstring 与配置注释共同给出)为:

python asr_streaming_infer.py \ --config-path=../conf/asr_streaming_inference/ \ --config-name=buffered_ctc.yaml \ audio_file=<音频文件 | 音频目录 | manifest 文件路径> \ output_filename=<输出 json 文件路径> \ lang=en \ enable_itn=False \ enable_nmt=False \ asr_output_granularity=segment

若从仓库根目录运行,可写作:

python examples/asr/asr_streaming_inference/asr_streaming_infer.py \ --config-path=examples/asr/conf/asr_streaming_inference/ \ --config-name=buffered_ctc.yaml \ audio_file=path/to/audio.wav \ output_filename=output.json \ lang=en

3.1 运行时参数(CLI 可覆盖)

以下参数在配置文件中预置默认值,运行时可通过命令行覆盖(五个 YAML 中一致定义):

参数默认值说明
audio_filenull音频文件、目录或 manifest JSON 路径
output_filenamenull输出转写 JSON 文件路径
output_dirnull保存带时间对齐输出的目录
enable_itnfalse是否应用逆文本正则化
enable_nmtfalse是否应用神经机器翻译(流式翻译)
asr_output_granularitysegment输出粒度:wordsegment
cache_dirnull缓存目录(如 ITN 生成的.far文件)
langnullASR 模型的语言代码
return_tail_resultfalse是否返回右侧 padding 缓冲区内遗留的尾部标签
calculate_wertrue是否计算 WER(需 manifest 提供标注)
calculate_bleutrue是否计算 BLEU(翻译场景,需 manifest 提供参考答案)
warmup_steps0计算 RTFx/LAAL 前的预热步数
run_steps1正式运行步数(用于 RTFx/LAAL 测量取平均)

注意:run_steps必须 ≥ 1,否则脚本直接抛出ValueError("run_steps must be at least 1");且 RTFx 测量建议warmup_steps > 0,脚本在warmup_steps=0时会打印相应警告(见 asr_streaming_infer.py)。

3.2 输出 JSON 结构

转写结果写入输出文件,单条记录的固定结构为(源码 docstring 定义):

{"audio_filepath": "path/to/audio/file", "text": "transcription of the audio file", "json_filepath": "path/to/json/file"}

词级/段级对齐结果则写入单独的 JSON 文件(由output_dir控制落盘位置,见 asr_streaming_infer.py)。

四、配置详解:五个 YAML 逐个拆解

所有配置文件共享统一的区块结构:asritnnmtconfidenceendpointingstreamingpipeline settingsruntime argumentsmetrics。差异集中在asrstreamingpipeline_type/asr_decoding_type

4.1 公共区块:ASR 模型与精度

以 buffered_ctc.yaml 为例:

asr: model_name: nvidia/parakeet-ctc-1.1b # 预训练模型名(NGC/HuggingFace)或本地 .nemo 文件路径 device: cuda # 推理设备:'cuda' 或 'cpu' device_id: 0 # GPU 设备 ID compute_dtype: bfloat16 # 'bfloat16'(Ampere+)、'float16'(旧 GPU)或 'float32' use_amp: false # 是否启用自动混合精度

各配置文件的默认模型:

配置默认模型解码类型
buffered_ctc.yamlnvidia/parakeet-ctc-1.1bctc
buffered_rnnt.yamlnvidia/parakeet-unified-en-0.6brnnt
buffered_salm.yamlnvidia/canary-qwen-2.5bsalm
cache_aware_ctc.yamlstt_en_fastconformer_hybrid_large_streaming_multictc
cache_aware_rnnt.yamlnvidia/nemotron-speech-streaming-en-0.6brnnt

在 RNNT 类配置(buffered_rnnt.yaml 与 cache_aware_rnnt.yaml)中,还额外提供decodingper_stream_biasing_defaults两个深化选项:

  • decoding.strategygreedy_batch(默认)或malsd_batch(cache-aware 下仅支持 MALSD 束搜索,配置注释明确说明);
  • decoding.greedy:可启用 CUDA graph 解码器(use_cuda_graph_decoder)、逐流偏置(enable_per_stream_biasing)、帧级置信度保留(preserve_frame_confidence)与max_symbols上限;
  • n-gram LM 融合ngram_lm_model指定构建好的.nemoNGPU-LM 模型路径,ngram_lm_alpha控制语言模型权重(默认 0.0 表示关闭);
  • 短语增强(phrase boosting)boosting_tree.model_path指定 boosting tree 模型;key_phrases_file提供每行一个短语的列表文件;key_phrases_list直接给出行内短语列表;key_phrase_items_list支持带自定义字段(如语言标签)的短语,CLI 形式如[{phrase:"word1",lang:en},{phrase:"frase dos",lang:es}]source_lang用于聚合分词器场景;
  • per_stream_biasing_defaults.boosting_model_cfgbpe_mode可选default/bpe_dropout/var_bpe/case_insensitive(推荐case_insensitivedefault),var_bpe_scoring_temp默认 10.0(对 case_insensitive/var_bpe 模式的保守值,防止过度偏置;小规模偏置表配合束搜索时 0.1~2.0 效果更佳)。

cache_aware_rnnt.yaml 还额外支持asr.use_cuda_graphs:开启后可为 cache-aware 编码器流式步骤启用 CUDA graphs(要求use_amp=false)。

4.2 公共区块:ITN 配置

五个配置中itn区块完全一致:

itn: input_case: lower_cased # 输入文本大小写:'lower_cased' 或 'cased' whitelist: null # ITN 处理的自定义白名单 overwrite_cache: false # 是否覆盖已有缓存文件 max_number_of_permutations_per_split: 729 # 每个文本分片允许的最大排列数 left_padding_size: 4 # ITN 上下文左侧 padding 大小(#spans) batch_size: 32 # ITN 推理批大小 n_jobs: 16 # ITN 处理并行任务数

4.3 公共区块:流式翻译(NMT)配置

nmt: model_name: "utter-project/EuroLLM-1.7B-Instruct" # vLLM 支持的模型名 source_language: "English" # 源语言 target_language: "Russian" # 目标语言 waitk: -1 # 允许的最大延迟(词数);-1 禁用,仅用当前/前次翻译的最长公共前缀 device: cuda # 翻译设备,仅支持 cuda device_id: 1 # 翻译使用的 GPU ID(可与 ASR 分卡) batch_size: 16 # 翻译批大小;-1 表示与 ASR 批大小一致 llm_params: dtype: "auto" # 计算精度 seed: 42 # 采样随机种子 gpu_memory_utilization: 0.85 # vLLM 允许占用的 GPU 显存比例 max_model_len: 4096 # 模型最大 token 长度 sampling_params: max_tokens: 100 # LLM 最大生成 token 数 temperature: 0.0 # 采样温度,翻译默认 0(贪心) top_p: 0.9 # 核采样累积概率阈值 seed: 42

要点:翻译与 ASR 可分配不同 GPU(asr.device_idnmt.device_id独立设置);waitk参数直接决定流式翻译的"追随延迟"策略——设置为 -1 时采用最长公共前缀策略,每次只输出与上次结果公共前缀一致的内容,保证流式下译文不"回退"。

4.4 公共区块:置信度估计

confidence: exclude_blank: true # 计算置信度时排除 blank token aggregation: mean # 跨时间步聚合方式 method_cfg: name: entropy # 方法:'max_prob' 或 'entropy' entropy_type: tsallis alpha: 0.5 entropy_norm: exp

4.5 公共区块:句末检测(EoU)

endpointing: stop_history_eou: 800 # 评估 EoU 的时间窗口(毫秒) residue_tokens_at_end: 2 # 用于 EoU 判定的尾部残留 token 数

4.6 流式配置:buffered 与 cache-aware 的关键差异

buffered 系列(以 buffered_ctc.yaml 为例):

streaming: sample_rate: 16000 # 音频采样率(Hz) batch_size: 256 # 每批音频帧数 left_padding_size: 1.6 # 左侧 padding 时长(秒) right_padding_size: 1.6 # 右侧 padding 时长(秒) chunk_size: 4.8 # 音频块大小(秒) word_boundary_tolerance: 4 # 词边界容差 request_type: feature_buffer # 请求类型:frame 或 feature_buffer padding_mode: right # padding 模式:left 或 right

buffered_rnnt.yaml 在此基础上多出stateful: true(是否启用有状态处理);buffered_salm.yaml 则是 SALM 解码专属的滑动窗口式配置:

streaming: sample_rate: 16000 batch_size: 256 buffer_size: 8.0 # 缓冲时长(秒) chunk_size: 4.0 # 每个音频块时长(秒) overlap_size: 4.0 # 块间重叠时长(秒) merging_strategy: lcsubstr # 合并策略:lcs 或 lcsubstr request_type: frame max_new_tokens: 64 # 单次最大生成新 token 数

cache-aware 系列(以 cache_aware_rnnt.yaml 为例):

streaming: sample_rate: 16000 batch_size: 64 word_boundary_tolerance: 4 att_context_size: [70,13] # 注意力上下文大小,可选 [70,13],[70,6],[70,1],[70,0] use_cache: true # 是否启用流式缓存 use_feat_cache: true # 是否缓存 mel 特征;false 则重算缓冲区内全部 mel 特征 chunk_size_in_secs: null # 每个流式步骤加载的音频时长;null 使用默认值(1+lookahead 帧) request_type: frame num_slots: 256 # 上下文管理器槽位数,必须 >= batch_size

cache-aware 与 buffered 的本质差异:cache-aware 通过use_cache/use_feat_cache跨 chunk 复用注意力缓存与 mel 特征缓存,att_context_size控制每步看到的上下文范围,从而在低延迟下避免重复前向计算;chunk_size_in_secs控制每步送入的音频量(如 FastConformer 常见 0.08s 级步长)。

att_context_size取值与模型相关,配置注释特别指出:[70,*] 适用于英文nemotron-speech-streaming-en-0.6b;多语言提示条件模型(如nvidia/nemotron-3.5-asr-streaming-0.6b)则应使用 [56,*] 系列([56,13],[56,6],[56,3],[56,1],[56,0])。

4.7 管道设置与指标配置

matmul_precision: high # 矩阵乘法精度:highest / high / medium log_level: 20 # 日志级别:0/10/20/30/40/50 pipeline_type: buffered # 管道类型:buffered 或 cache_aware asr_decoding_type: ctc # 解码方式:ctc / rnnt / salm

metrics区块按asrnmt分组,控制 WER/BLEU 计算前的文本规范化行为:

metrics: asr: gt_text_attr_name: text # 标注文本的字段名 clean_groundtruth_text: false langid: en # 文本规范化语言,目前仅支持 "en" use_cer: false # 是否使用 CER 代替 WER ignore_capitalization: true # 忽略大小写 ignore_punctuation: true # 忽略标点 strip_punc_space: false nmt: gt_text_attr_name: answer # 翻译参考答案字段名(如 "answer") ignore_capitalization: false ignore_punctuation: false strip_punc_space: false

五、源码级工作流:脚本到底做了什么

阅读 asr_streaming_infer.py 与 pipeline_builder.py,可以还原出完整的执行链路:

  1. 数据准备prepare_audio_data(cfg.audio_file, per_stream_biasing_defaults=..., sort_by_duration=True)读取输入(文件/目录/manifest),解析流级偏置选项并按时长排序;若为 manifest,日志打印其字段键列表;
  2. 构建流水线PipelineBuilder.build_pipeline(cfg)首先校验并设置log_levelmatmul_precision(合法值分别是 0/10/20/30/40/50 与 highest/high/medium,非法值直接抛错),然后通过PipelineType.from_str(cfg.pipeline_type)路由:
    • BUFFEREDBufferedPipelineBuilder
    • CACHE_AWARECacheAwarePipelineBuilder
    • 其他值 → 抛出ValueError
  3. 预热与计时:按warmup_steps + run_steps循环执行pipeline.run(...),使用SimpleTimer在指定 device 上计时,仅统计正式运行步;
  4. RTFx 计算RTFx = 音频总时长 / 平均执行时长data_dur / exec_dur),日志输出形如RTFx: 12.34 (100.00s / 8.10s)
  5. LAAL 计算calculate_asr_laal计算 ASR 的 LAAL(最长允许音频延迟),calculate_translation_laal计算翻译 LAAL,单位毫秒;
  6. 结果落盘dump_output将转写按audio_filepath/text/json_filepath结构写出;
  7. 评估evaluate_pipeline(cfg.output_filename, cfg)依据metrics配置计算 WER(必要时 CER)与 BLEU。

关键调用链汇总:

asr_streaming_infer.py (hydra 入口) └─ nemo.collections.asr.inference.factory.pipeline_builder.PipelineBuilder.build_pipeline ├─ BufferedPipelineBuilder.build (pipeline_type=buffered) └─ CacheAwarePipelineBuilder.build (pipeline_type=cache_aware) └─ pipeline.run → 计算 RTFx / LAAL → dump_output → evaluate_pipeline

这一设计意味着:换用不同的解码类型(CTC/RNNT/TDT/SALM)与流式范式时,无需改动脚本代码,只需切换--config-namepipeline_type/asr_decoding_type

六、可验证的测试与更多示例

仓库提供了与本文档直接对应的功能测试,可用于验证上述用法并观察完整命令:

  • tests/functional_tests/L2_Speech_Transcription_Streaming_Inference.sh:流式转写功能测试,演示了该脚本的实际命令行调用方式与参数覆盖写法;
  • tests/functional_tests/L2_Speech_Transcription_Speech_to_Text_Inference_Boost_GT.sh:验证短语增强(boosting)与转写加速场景的测试;
  • 教程 tutorials/asr/Streaming_ASR_Pipelines.ipynb:以 Notebook 形式讲解流式 ASR 流水线的端到端使用;
  • 若需 cache-aware 编码器 CUDA graphs,源码提示在命令行追加asr.use_cuda_graphs=true即可(见 asr_streaming_infer.py)。

此外,模型训练侧对应的流式架构配置(如 FastConformer cache-aware 训练配置)位于 examples/asr/conf/fastconformer/cache_aware_streaming/,可作为理解att_context_size、chunk 等参数来源的补充参考。

七、常见问题与调参建议

  • 输入格式:务必使用 16 kHz 单声道 WAV;否则需先行重采样/转码,可参考仓库中 examples/asr/transcribe_speech.py 等其他入口脚本的音频读取方式;
  • RTFx 测量:首次运行建议warmup_steps=2左右以预热 CUDA kernel 与缓存,再以run_steps取均值,避免首步计时偏慢导致 RTFx 虚低;
  • 翻译显存不足:降低nmt.llm_params.gpu_memory_utilization(如 0.5)或减小max_model_len/max_tokens;也可将nmt.device_id指向独立 GPU 与 ASR 分卡;
  • cache-aware 下开启 CUDA graphs:注意asr.use_cuda_graphs=true要求use_amp=false(见 cache_aware_rnnt.yaml 注释);
  • WER/BLEU 计算依赖标注:只有输入为 manifest 且包含metrics.asr.gt_text_attr_name(默认text)/metrics.nmt.gt_text_attr_name(默认answer)字段时,指标才会被计算;
  • 流式翻译延迟控制nmt.waitk设置为 -1 时采用最长公共前缀策略,适合对译文稳定性要求高的场景;若追求更紧凑的追随延迟,可按词数设定waitk值。

通过本文介绍的单脚本多范式设计,开发者可以用同一套代码路径快速在 buffered 与 cache-aware 两种流式推理之间切换,并在转写基础上按需叠加 ITN、EoU 检测、流式翻译与细粒度对齐输出,是 NeMo ASR 流式落地的实用起点。

【免费下载链接】SpeechA scalable generative AI framework built for researchers and developers working on Large Language Models, Multimodal, and Speech AI (Automatic Speech Recognition and Text-to-Speech)项目地址: https://gitcode.com/GitHub_Trending/nem/Speech

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 20:13:30

动态环境中四旋翼无人机路径规划与NMPC控制实践

1. 项目概述&#xff1a;动态环境中的四旋翼智能路径规划这个项目解决的是无人机在动态障碍物环境中的自主导航问题。当四旋翼飞行器需要在有人、车辆或其他移动物体存在的空间执行任务时&#xff08;比如仓库巡检、灾害救援等场景&#xff09;&#xff0c;传统静态路径规划算法…

作者头像 李华
网站建设 2026/9/14 20:12:55

品牌战略五维系统架构与实施方法论

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 20:09:44

基于云台扫描与全景拼接的监控系统:从单点到全局的上帝视角实现

1. 从“多路枪机”到“一处俯瞰”&#xff1a;这个项目究竟解决了什么问题先说个场景。你负责一个半开放式的园区、仓库外场或者一块大型施工场地&#xff0c;需要在关键区域做到“无死角覆盖”。传统做法很直接&#xff1a;沿着围界一圈装枪机&#xff0c;每路负责一个方向&am…

作者头像 李华
网站建设 2026/9/14 20:07:26

RK3588与RK3588S工业AI选型本质差异解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 20:05:49

NR2048单芯片语音方案:从三片到一片,开发周期直接砍半

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 20:05:46

Java全栈面试复盘:从动态代理到Vue3权限路由的实战解析

上周帮一位朋友复盘了一场Java全栈工程师岗位的面试&#xff0c;整场聊下来印象特别深。面试官没有机械地追着八股文问&#xff0c;而是围绕一个真实的全栈项目层层追问&#xff0c;从Java后端的接口设计、Redis缓存策略&#xff0c;一路追到Vue3前端的权限路由、tabs标签状态管…

作者头像 李华