NeMo Forced Aligner (NFA) 深度指南:用 CTC 模型为语音生成 Token/词/句三级时间戳

发布时间:2026/9/14 19:43:05
NeMo Forced Aligner (NFA) 深度指南:用 CTC 模型为语音生成 Token/词/句三级时间戳 NeMo Forced Aligner (NFA) 深度指南用 CTC 模型为语音生成 Token/词/句三级时间戳【免费下载链接】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导读本文围绕当前仓库 docs/source/tools/nemo_forced_aligner.rst 所介绍的NeMo Forced AlignerNFA工具展开它借助 NeMo 的 CTC 类语音识别模型为音频中的**token、词word与句段segment**自动生成精确的起止时间戳。读完本文你将掌握 NFA 的完整使用流程从准备 manifest、调用 align.py 脚本、理解全部配置参数与默认值到解读 CTM/ASS/JSON 三类输出文件并了解其底层 Viterbi 对齐原理与长音频流式对齐方案可直接用于字幕制作、语音数据标注、TTS 训练数据准备等实战场景。NFA 能做什么核心能力与应用场景NFA 是仓库 tools/nemo_forced_aligner 目录下的独立工具其核心定位是基于 NeMo 的 CTC 语音识别模型为音频生成 token、词、句段三个粒度的逐字对齐时间戳。核心特性均可在原文档中找到依据两种参考文本来源既可以使用用户提供的真实转写文本manifest 中的text字段也可以设置align_using_pred_texttrue让 ASR 模型先转录音频、再以预测文本作为对齐参考开箱即用的多语言模型可以直接使用 NeMo 官方发布的 CTC 类 ASR 检查点支持 14 语言见 ASR 模型检查点列表也可以使用本地自训练模型支持超长音频对 1 小时以上的长音频也能处理取决于硬件与所选 ASR 模型manifest 中不要求duration字段模型约束目前只能使用 CTC 模型或 Hybrid CTC-Transducer 模型以 CTC 模式工作纯 Transducer 模型无法使用——这一点在 align.py 中通过运行时类型检查强制保证。典型应用场景包括为视频生成逐字/逐词卡拉 OK 风格字幕ASS 高亮字幕、为 TTS 训练数据提供字级边界、为语音语料库生成词级时间对齐用于下游分析等。工作原理从 CTC Log-Probs 到三级时间戳要正确使用 NFA理解其内部数据流很有帮助。整个对齐流程在 align.py 的主循环中按 batch 串联核心算法封装在 nemo/collections/asr/parts/utils/aligner_utils.py 中。对齐数据流对 manifest 中的每条语音NFA 依次执行以下步骤生成 Log-Probs用 CTC 模型对音频做前向推理得到形状为(T, V)的逐帧 token 对数概率T为帧数V为词表大小 1 个 blank。对 Hybrid 模型会先通过model.change_decoding_strategy(decoder_typectc)切换到 CTC 解码见 align.py构造参考序列把参考文本经 tokenizer 编码为 token id 序列并在每个 token 之间插入 blank得到y长度为U。文本按分隔符切分为 segment、segment 内按空格切分为 word、word 内为 token形成 aligner_utils.py 中定义的Segment - Word - Token三级嵌套数据结构Viterbi 解码在T × U的时间-位置网格上寻找概率最大的单调对齐路径路径满足每个 token含 blank至少占据一个时间帧、且位置索引单调不减的 CTC 对齐约束见 viterbi_decoding换算时间戳由 add_t_start_end_to_utt_obj 将路径中每个 token 的首次出现帧记为t_start、最后一次出现帧记为t_end再乘以单帧时长output_timestep_duration得到秒级时间戳。单帧时长的确定output_timestep_duration即模型输出的时间分辨率由 get_batch_variables 计算output_timestep_duration model.cfg[preprocessor][window_stride] * model.encoder.subsampling_factor即预处理器窗移 × 编码器下采样倍数。例如 FastConformer 类模型常为 80ms 窗移乘以下采样倍数得到每帧对应约几十毫秒。Viterbi 解码的实现要点viterbi_decoding 的实现有两个值得注意的工程细节批量向量化唯一的 for 循环只遍历时间维度T每个时间步通过torch.gather取当前帧概率、用torch.roll构造停留 / 前进 1 / 前进 2三种转移候选并记录相对回溯指针backpointers_rel0/1/2最后统一回溯避免逐 token 循环letter_repetition_mask当参考文本中出现连续相同 token如tt时标准的前看两步CTC 转移会失效算法用letter_repetition_mask屏蔽连续两个 blank 之间以及连续两个相同字符之间的非法转移从而正确处理重复 token见 aligner_utils.pypadding 处理批量张量按T_max、U_max补齐padding 区域填充极小值-3.4e38torch.float32 最小值保证回溯路径不会进入 padding。文本预处理细节在 data_prep.py 中manifest 文本会做以下规整移除 BOM\ufeff、压缩连续空格、将换行转为空格、将水平省略号…U2026替换为三个点...避免与默认分隔符冲突并规避标点还原错误。此外 restore_token_case 负责在输出时根据词级文本恢复 token 的大小写包括上下标数字的还原见 is_sub_or_superscript_pair。安装与快速上手安装前提NFA 依赖 NeMo 工具包及其 ASR 集合同时需要nemo.collections.asr.parts.utils.aligner_utils模块。若缺失该模块align.py 会在导入阶段直接报错并提示安装命令pip install nemo-toolkit[all]2.5.0其余依赖如soundfile用于读取音频时长可参考 tools/nemo_forced_aligner/requirements.txt。三步 Quickstart安装 NeMo含 ASR 集合安装指引见仓库 docs/source/starthere/ 下的相关文档准备 NeMo 风格 manifest每行一条 JSON包含待处理音频的绝对路径可选包含其文本运行align.py脚本例如python path_to_NeMo/tools/nemo_forced_aligner/align.py \ pretrained_namestt_en_fastconformer_hybrid_large_pc \ manifest_filepathpath to manifest of utterances you want to align \ output_dirpath to where your output files will be saved其中pretrained_name会从 NGC 自动下载对应 CTC 检查点并用于计算 log-probsmanifest_filepath指向待对齐清单output_dir为输出目录。运行结束后即可在output_dir下看到 CTM、ASS 文件以及带输出路径的新 JSON manifest。想快速体验完整流程可直接参考仓库教程 tutorials/tools/NeMo_Forced_Aligner_Tutorial.ipynb。输入 Manifest 格式默认情况下manifest 每行必须包含绝对路径的audio_filepath与转写文本text{audio_filepath: /absolute/path/to/audio.wav, text: the transcription of the utterance}两条规则需要特别注意省略text字段仅当设置align_using_pred_texttrue时可以省略。此时 manifest 中任何已有的text字段都会被忽略ASR 模型会先转录得到pred_text再以它作为对齐参考文本pred_text同时会写入输出 JSON manifest防覆盖保护若align_using_pred_texttrue而原始 manifest 中已存在pred_text字段程序会直接报错退出避免转录结果被覆盖造成混乱校验逻辑见 align.py。此外NFA 不要求duration字段对齐质量与参考文本准确性正相关——参考文本越准对齐越好。所有行的audio_filepath都必须存在且文件可访问否则会在 get_manifest_lines_batch 中抛出FileNotFoundError。命令行参数详解NFA 的配置在 align.py 中由AlignmentConfigdataclass 定义并通过 Hydra 注入命令行以keyvalue形式覆盖。必选参数参数类型说明pretrained_namestr从 NGC 自动下载的 CTC NeMo ASR 模型名用于生成 log-probs。任意语言的 CTC 模型Conformer CTC、FastConformer CTC 等理论上均可用。与model_path二选一model_pathstr本地 CTC NeMo ASR 模型文件路径用于生成 log-probs。与pretrained_name二选一manifest_filepathstr待对齐数据 manifest 路径包含audio_filepath绝对路径与text字段output_dirstr输出目录用于保存 CTM/ASS 文件及汇总路径的新 JSON manifest两个模型参数互斥源码在 align.py 中强制校验——两者都为 None 或都不为 None 都会抛出ValueError。manifest_filepath与output_dir同样必填。可选参数参数默认值说明align_using_pred_textFalse为True时先用 ASR 模型转录音频再以转录文本作为对齐参考pred_text会保存到输出 manifesttranscribe_deviceNone生成 log-probs 的设备None时自动选择cuda可用时否则cpu也可传任何能被torch.device()接受的字符串viterbi_deviceNoneViterbi 解码设备None时同transcribe_device的自动选择逻辑batch_size1生成 log-probs 与 Viterbi 解码所用的 batch 大小use_local_attentionTrue是否尝试为 ASR 模型启用局部注意力仅 Conformer 类模型生效启用时局部注意力上下文设为[64, 64]可显著降低长音频推理显存占用additional_segment_grouping_separator[., ?, !, ...]用于把文本切分为更小句段的字符串列表设为None则整段文本作为一个句段。不能是空字符串或空格空格天然用于词切分否则抛ValueErroraudio_filepath_parts_in_utt_id1取音频路径从尾部数多少个部分来构成 CTM 中的utt_id默认 1 即取文件名 stem。路径中的空格会被替换为-避免破坏 CTM 的空白分隔格式save_output_file_formats[ctm, ass]需要保存的输出格式列表当前可用格式仅这两种流式/长音频相关参数参数默认值说明use_buffered_chunked_streamingFalse是否以分块流式方式获取 logits 做对齐适合超长音频仅支持per_feature归一化的 CTC 模型源码会在 preprocessornormalize ! per_feature时报错见 align.py且当前不支持 batch 推理batch_size 大于 1 也会逐条处理chunk_len_in_secs1.6分块流式的块长秒total_buffer_in_secs4.0分块流式的总缓冲块 左右填充秒chunk_batch_size32分块推理时对同一音频切出的多个块做批处理的 batch 大小simulate_cache_aware_streamingFalse是否使用 cache-aware streaming 获取 logits 用于对齐当启用use_buffered_chunked_streaming时align.py 内部会做几件事把预处理器dither置 0、pad_to置 0计算model_stride_in_secs window_stride * model_downsample_factor、tokens_per_chunk ceil(chunk_len / model_stride_in_secs)、mid_delay ceil((chunk_len (total_buffer - chunk_len) / 2) / model_stride_in_secs)然后封装为FrameBatchASR流式推理器。启用simulate_cache_aware_streaming时则调用模型的transcribe_simulate_cache_aware_streaming见 get_batch_variables。源码确认的校验规则启动时 align.py 会做如下校验提前暴露配置错误batch_size必须 ≥ 1additional_segment_grouping_separator不得为或 若为None/空列表则整段作为一个句段ctm_file_config.minimum_timestamp_duration不得为负数ass_file_config.vertical_alignment必须是top/center/bottom之一三个 ASS 颜色配置都必须是恰好 3 个元素的 RGB 列表manifest 所有行必须含audio_filepathalign_using_pred_textfalse时所有行必须含text模型必须是EncDecCTCModel或EncDecHybridRNNTCTCModel实例否则抛NotImplementedError若transcribe_device或viterbi_device任一为 GPU 而出现 OOM日志会建议改回 CPU。输出 CTM 文件与 CTMFileConfig文件布局与格式对于 manifest 中的每条语音会生成三个粒度的 CTM 文件token 级output_dir/ctm/tokens/utt_id.ctm词级output_dir/ctm/words/utt_id.ctm句段级output_dir/ctm/segments/utt_id.ctm若设置了additional_segment_grouping_separator句段为按其切分的结果否则整段文本为一个句段每行格式如下CTM 标准格式utt_id 1 start time in seconds duration in seconds text, ie token/word/segment其中第二个字段是 CTM 规范要求的声道 ID恒为 1NFA 只处理单声道音频。空白字符在输出时替换为spacetokenblank token 写作b见 constants.py 与 make_ctm_files.py避免引入多余的空白分隔符。CTMFileConfig 参数CTMFileConfig定义于 align.py作为子配置传入主配置包含两个参数参数默认值说明remove_blank_tokensFalse是否在 token 级 CTM 中移除bblank token 的时间戳对应旧版顶层参数remove_blank_tokens_from_ctmminimum_timestamp_duration0所有时间戳的最小时长秒。若某行时长小于该值则从其中点向两侧扩大至该时长或到达音频文件首尾为止。注意非零值可能导致时间戳相互重叠minimum_timestamp_duration的实现细节见 make_ctm_files.py它先用soundfile读取音频真实时长作为扩展上限再以(start end) / 2为中点、按±duration/2向外扩展并 clamp 到[0, audio_file_duration]。若某条语音的参考文本为空或 token 数相对音频过长导致无法对齐segments_and_tokens为空时不会生成任何输出文件见 make_ctm_files.py。输出 ASS 字幕文件与 ASSFileConfigASSAdvanced SubStation Alpha是用于生成字幕视频的格式。NFA 会生成两类 ASS 文件token 级高亮output_dir/ass/tokens/utt_id.ass词级高亮output_dir/ass/words/utt_id.ass同一句段segment内的所有词会在字幕中同时出现播放时随对齐时间逐 token/逐词高亮正在朗读的内容。生成逻辑见 make_ass_files.py其中定义了 384×288 的播放器分辨率、页边距等 ASS 布局常量以及seconds_to_ass_format时间格式转换与rgb_list_to_hex_bgr颜色转换。ASSFileConfig 参数ASSFileConfig定义于 align.py参数如下参数默认值说明fontsize20字幕字号vertical_alignmentcenter文字垂直对齐方式可选center、top、bottomresegment_text_to_fill_spaceFalse为True时会对文本重新分句使每个句段在视频中显示时不超过约max_lines_per_segment行max_lines_per_segment2每个句段显示的行数上限仅当resegment_text_to_fill_spacetrue时生效text_already_spoken_rgb[49, 46, 61]已朗读文本的高亮颜色深灰text_being_spoken_rgb[57, 171, 9]正在朗读文本的高亮颜色深绿text_not_yet_spoken_rgb[194, 193, 199]尚未朗读文本的颜色浅灰若你觉得字幕句段过大或过小可按文档建议设置ass_file_config.resegment_text_to_fill_spacetrue并配合max_lines_per_segment调整。输出 JSON Manifest对齐完成后NFA 会在output_dir下写出一个新 manifest命名为output_dir/original manifest file name stem_with_output_file_paths.json该命名规则在 align.py 中实现。新 manifest 保留原 manifest 的所有字段并按下述规则追加字段写入逻辑见 make_output_manifest.pytoken_level_ctm_filepath当save_output_file_formats含ctmword_level_ctm_filepath同上segment_level_ctm_filepath同上token_level_ass_filepath当save_output_file_formats含assword_level_ass_filepath同上pred_text当align_using_pred_texttrue该 manifest 是后续批量处理如评估、可视化、语料管理的入口文件。长音频与流式对齐NFA 支持 1 小时以上的长音频依赖两个可选机制均在前文参数表中列出Buffered Chunked Streaminguse_buffered_chunked_streamingtrue将长音频切成块、配合左右缓冲以流式方式生成 logits规避整段前向推理的显存压力。使用前提是 CTC 模型预处理器采用per_feature归一化chunk_len_in_secs默认 1.6s与total_buffer_in_secs默认 4.0s控制块长与缓冲Cache-Aware Streamingsimulate_cache_aware_streamingtrue调用模型内置的transcribe_simulate_cache_aware_streaming接口获取 logits同样面向长音频场景。文档同时提醒能对齐多长的音频取决于机器内存流式路径当前不支持 batch 合并推理即使设置batch_size 1也逐条处理。对齐精度评估与可视化原文档建议两种评估方式与真值 CTM 对比如果拥有 ground-truth 的 CTM 文件可以计算预测起止时间与真实起止时间之间的均值绝对误差等指标可视化检查可使用 Gecko 等工具在播放音频的同时展示预测对齐结果需上传音频文件与至少一个 CTM 文件。为获得更好的可视化效果文档给出两条实用建议将ctm_file_config.minimum_timestamp_duration调大避免过短的时间戳导致部分 token/词/句段无法正常显示分析 token 级 CTM 时设置ctm_file_config.remove_blank_tokenstrue让画面更清爽。仓库还提供了 tools/nemo_forced_aligner/align_eou.py用于带 EOU句末端点检测场景的对齐扩展需要更细粒度对齐需求时可进一步参考。常见问题与实用建议模型选型纯 TransducerRNNT模型不可用Hybrid 模型会被自动切换为 CTC 解码模式但仍建议优先使用纯 CTC 模型以获得稳定输出OOM 处理若推理或 Viterbi 阶段显存不足日志会提示把transcribe_device与viterbi_device改为cpu两者可分别指定例如转录用 GPU、Viterbi 用 CPU长音频显存优化优先开启use_local_attentiontrueConformer 类模型或组合使用use_buffered_chunked_streaming/simulate_cache_aware_streaming参考文本质量对齐精度强依赖参考文本与音频内容的一致性文本越准确、标点越规范NFA 默认按.、?、!、...分句输出句段边界越合理空文本处理参考文本为空或 token 数远超音频帧数时该条语音不会生成输出文件并会在日志中提示行为变更提醒自 NeMo 2.5.0 起句段切分后保留分隔符例如默认分隔符下文本Hi, have you updated your NeMo? Yes. Sure!会被切分为[Hi, have you updated your NeMo?, Yes., Sure!]设置自定义additional_segment_grouping_separator时align.py 会打印该行为变更警告测试参考仓库在 tools/nemo_forced_aligner/tests/ 提供了针对add_t_start_end_to_utt_obj、get_utt_obj与restore_token_case的单元测试可作为理解各函数行为与输出格式的补充依据。【免费下载链接】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),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询