ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

NeMo Speech ASR 微调实战(Stage 4):训练超参配置、多卡启动排障、检查点平均与独立 WER 评估

2026/9/13 12:12:05 拓冰建站 浏览量
NeMo Speech ASR 微调实战(Stage 4):训练超参配置、多卡启动排障、检查点平均与独立 WER 评估 NeMo Speech ASR 微调实战Stage 4训练超参配置、多卡启动排障、检查点平均与独立 WER 评估【免费下载链接】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 Speech 仓库中 ASR 微调工作流的最后一站基于references/training-evaluation.md.claude/skills/nemo-speech-asr-finetune技能的第 4 阶段系统讲解优化器与训练器配置、多 GPU 启动排障、检查点平均checkpoint averaging以及独立评估的正确姿势。读完后你将能够独立完成一次可复现的 ASR 微调从trainer.max_steps 余弦学习率调度到torchrun多卡容器化启动再到用同一套独立评估命令对基线模型、最佳检查点与平均模型做公平的 WER 对比。该文档是 SKILL.md 定义的五阶段微调工作流中的第 4 阶段前序阶段涵盖容器与检查点选择、Lhotse 数据准备、架构检测与分词器调整其总体姿态在 SKILL.md 中明确优先使用 NeMo 容器、训练与验证数据加载器优先 Lhotse、用trainer.max_steps而非trainer.max_epochs控制训练长度、用val_wer作为检查点监控指标、最终质量以独立评估而非训练日志为准。优化器与训练器配置以 max_steps 为中心的训练配置核心原则是用trainer.max_steps控制训练长度而不是trainer.max_epochs并让余弦Cosine Annealing学习率调度器使用与训练器完全相同的max_steps保证调度曲线与训练终止点严格对齐。初始学习率按数据规模与风险分级选择大规模或混合数据的微调从model.optim.lr1e-4起步再按需调整小规模领域适配尤其是目标领域高价值音频低于约 20 小时从3e-5附近起步并密切观察早期验证曲线——SKILL.md 的不可妥协的陷阱部分也特别强调小数据领域适配不要盲目使用1e-4后期精调阶段或已出现不稳定/发散的 run降到1e-5或更低。预热步数warmup设为trainer.max_steps的 1%2%。典型的 Hydra 覆盖片段如下init_from_pretrained_modelhf-or-ngc-name \ trainer.max_steps50000 \ trainer.limit_train_batches1000 \ trainer.val_check_interval1000 \ model.optim.lr1e-4 \ model.optim.sched.nameCosineAnnealing \ model.optim.sched.max_steps50000 \ model.optim.sched.warmup_steps500 \ model.optim.sched.min_lr5e-6理解 Hydra 的与前缀微调入口 speech_to_text_finetune.py 支持init_from_pretrained_model源码中以cfg.get(init_from_pretrained_model, None)读取并与init_from_nemo_model互斥但部分微调 YAML 并未声明该键。文档给出的规则是当 Hydra 提示键不在 struct 中时用init_from_pretrained_model...添加该键对于脚本本身支持、但所选 YAML 中不存在的 trainer/model 键一律使用新增键或覆盖默认值前缀不要因为别的配置里存在类似键就擅自去掉加号——每个 YAML 的 struct 声明是独立的。精度选择与验证监控优先考虑trainer.precisionbf16-true显存占用更低、可承载更大 batch对超过 1000 小时的数据集尤其有意义。若出现发散或稳定性问题回退到更稳定的精度模式。在两种 bfloat16 模式之间首选bf16-true而非bf16-mixed。每一次验证 run 与检查点选择都以val_wer为准推荐的检查点回调配置为exp_manager.checkpoint_callback_params.monitorval_wer \ exp_manager.checkpoint_callback_params.modemin \ exp_manager.checkpoint_callback_params.save_top_k5 \ exp_manager.checkpoint_callback_params.always_save_nemotrue注意save_top_k的取值在这里具有下游含义——它决定了后面检查点平均时会平均多少个.ckpt见下文。多 GPU 启动与排障常规与 torchrun 两种启动方式单机例行任务先走标准 Lightning 启动trainer.devicesnum_gpus。当容器内任务在 NCCL 注册之后立即挂起或某个 rank 在 DDP 接管之前把模型恢复到错误的 GPU 上时改用torchrun --nproc_per_nodenum_gpus直接驱动常规脚本入口。使用 torchrun 时的配套要求保留trainer.devicesnum_gpusLhotse 数据加载器下设置trainer.use_distributed_samplerfalsetorchrun 已负责按进程分片trainer.num_nodes只保留给真正的多机任务单机容器微调应避免每进程仅可见一张 GPU的手工启动模式除非用户明确要求调试该环境。仓库技能给出的容器torchrun模板docker run --rm --gpus all --ipchost \ --ulimit memlock-1 --ulimit stack67108864 \ -e PYTHONPATH/workspace/NeMo \ -v /path/to/NeMo:/workspace/NeMo \ -v /data:/data \ nemo-speech:tag bash -lc cd /workspace/NeMo torchrun --nproc_per_node2 examples/asr/speech_to_text_finetune.py \ init_from_pretrained_modelnvidia/parakeet-tdt-0.6b-v3 \ model.train_ds.manifest_filepath/data/train.json \ model.validation_ds.manifest_filepath/data/val.json \ model.train_ds.use_lhotsetrue \ model.validation_ds.use_lhotsetrue \ trainer.use_distributed_samplerfalse \ trainer.devices2 \ trainer.max_steps10000 通信层与归一化层的保守设置若任务确认卡在通信初始化阶段NCCL P2P 或 CUDA 内存分配器问题再启用保守的分布式环境变量export NCCL_CUMEM_ENABLE0 export NCCL_P2P_DISABLE1另外一条容易忽视的约束trainer.sync_batchnorm保持与原始模型配置一致除非用户明确要求修改——改变归一化同步方式可能直接破坏微调的数值行为。检查点平均Checkpoint Averaging工具行为源码级说明平均工具位于 checkpoint_averaging.py从源码可以确认其工作机制它接收一个.nemo文件或包含唯一.nemo的目录从.nemo的同级目录中收集所有非-last.ckpt的.ckpt文件见 L110-L115对每个 checkpoint 的state_dict做张量累加最后除以数量取平均整型张量如BatchNorm.num_batches_tracked不做平均只做累加见 L143-L149将平均后的权重以strictTrue载入模型并另存为*-averaged.nemo见 L151-L155。由此得到两个实操结论平均的样本数 N 由上一节训练配置中的save_top_k控制且-last.ckpt会被自动排除。python scripts/checkpoint_averaging/checkpoint_averaging.py \ /exp/asr-ft/checkpoints/best.nemo加载失败与 PyTorch 2.6 兼容若模型类加载失败使用脚本的--class_path或--import_fname_list选项后者用于from FILE import *注入缺失类应对AttributeError: Cant get attribute ???错误——脚本头部 docstring 与 L69-L73 均有说明。该脚本在源码中自报弃用状态L43 打印 This script is deprecated...文档因此要求依赖它之前先确认当前 checkout 中仍可用。PyTorch 2.6 上torch.load默认weights_onlyTrue弃用的平均工具可能因此失败。仅对可信检查点设置TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD1后重跑TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD1 python scripts/checkpoint_averaging/checkpoint_averaging.py \ /exp/asr-ft/checkpoints/best.nemo这一环境变量与仓库 install 文档 的说明一致只对可信文件使用完整的 pickle 加载能力避免任意代码执行风险。最新 .nemo 不等于最佳检查点always_save_nemotrue会在后续保存中覆盖.nemo产物因此不能假定目录下最新的.nemo就是验证最优。正确流程是核对.ckpt文件名与验证日志 → 对导出的.nemo、最佳验证检查点导出的产物、平均模型三者分别评估 → 再决定保留哪一个。决策规则对最终导出的.nemo、最佳单个验证检查点产物、平均产物使用同一条独立评估命令与同一打分契约保留独立默认 WER 最优者若平均模型更差记录下来并丢弃平均产物。训练中的val_wer只用于检查点选择不是最终汇报数字——独立 WER 才是公平比较因为它固定了解码选项、文本处理、精度与打分口径。独立评估命令、精度与打分契约精度口径评估不用 AMP推理/评估不要使用 AMP统一使用compute_dtypebfloat16与ampfalse。这一约束在源码中是硬性的transcribe_speech.py 中当compute_dtype不是float32且amptrue时直接抛出ValueErrorL278-L279即两者互斥。对每一个参与比较的模型变体都汇报独立speech_to_text_eval.py的结果而不是只报训练日志。基本评估命令同时给出matmul_precisionhigh与use_cerFalsepython examples/asr/speech_to_text_eval.py \ model_path/exp/asr-ft/checkpoints/best.nemo \ dataset_manifest/data/test.json \ output_filename/exp/asr-ft/test_predictions.json \ batch_size32 \ ampfalse \ compute_dtypebfloat16 \ matmul_precisionhigh \ use_cerFalseRNNT/TDT 模型在支持时启用 CUDA graphs解码器实现见 rnnt_greedy_decoding.py 中use_cuda_graph_decoder的默认开启与不可用时的自动降级逻辑python examples/asr/speech_to_text_eval.py \ model_path/exp/asr-ft/checkpoints/best.nemo \ dataset_manifest/data/test.json \ output_filename/exp/asr-ft/test_predictions.json \ batch_size32 \ ampfalse \ compute_dtypebfloat16 \ matmul_precisionhigh \ rnnt_decoding.strategygreedy_batch \ rnnt_decoding.greedy.use_cuda_graph_decodertrue混合Hybrid模型则分别用 CTC 与 RNNT 解码器各评一次对比解码器选择python examples/asr/speech_to_text_eval.py \ model_path/exp/asr-ft/checkpoints/best.nemo \ dataset_manifest/data/test.json \ decoder_typectc \ output_filename/exp/asr-ft/test_predictions_ctc.json \ ampfalse \ compute_dtypebfloat16 python examples/asr/speech_to_text_eval.py \ model_path/exp/asr-ft/checkpoints/best.nemo \ dataset_manifest/data/test.json \ decoder_typernnt \ output_filename/exp/asr-ft/test_predictions_rnnt.json \ ampfalse \ compute_dtypebfloat16 \ rnnt_decoding.strategygreedy_batch \ rnnt_decoding.greedy.use_cuda_graph_decodertrue其中decoder_typectc/rnnt正是 EvaluationConfig 中为 Joint RNNT/CTC 模型在两种解码器之间切换的字段。两步评估与文本处理契约评估流程对应 evaluation-style-contract.md 的两步法稳定解码 无 AMP bfloat16 转写把预测落到 manifestpred_text字段score-only 打分该预测 manifest默认去掉大小写与标点后再算 WERpython examples/asr/speech_to_text_eval.py \ dataset_manifest/exp/asr-ft/test_predictions.json \ only_score_manifestTrue \ text_processing.do_lowercasetrue \ text_processing.rm_punctuationtrue \ use_cerFalse从 speech_to_text_eval.py 源码可确认该机制only_score_manifestTrue时跳过音频转写直接对 manifest 打分L129-L141text_processing.do_lowercase/rm_punctuation会对text与pred_text两侧对称地做小写化与标点删除L158-L167而rm_punctuation删除的标点集合由text_processing.punctuation_marks控制默认.,?见 EvaluationConfig 默认值。因此转写命令打印的 WER 是原始 WER除非该命令也传了同样的text_processing覆盖score-only 命令输出的才是默认指标若预测中存在标点表之外的符号要么覆盖text_processing.punctuation_marks要么对text与pred_text应用同一文档化的归一化规则生成派生 manifest 再打分仅在用户要求或需要诊断转写风格不匹配时才单独汇报 raw WERscore-only 时去掉do_lowercase/rm_punctuation覆盖。对基线与微调后模型的对比同样使用同一命令 同一打分契约python examples/asr/speech_to_text_eval.py \ model_path/exp/asr-ft/checkpoints/best.nemo \ dataset_manifest/data/val.json \ output_filename/exp/asr-ft/val_best.json \ batch_size32 \ ampfalse \ compute_dtypebfloat16 python examples/asr/speech_to_text_eval.py \ model_path/exp/asr-ft/checkpoints/best-averaged.nemo \ dataset_manifest/data/val.json \ output_filename/exp/asr-ft/val_avg.json \ batch_size32 \ ampfalse \ compute_dtypebfloat16契约还规定每个模型变体应汇报默认 WER/CER、必要时raw WER/CER、确切的预测 manifest 与文本处理设置、参考文本是原始标签还是风格归一化标签。若 raw WER 与默认 WER 差异显著应优先视为转写风格问题而非声学回归——在默认归一化 WER 已改善的情况下不要仅凭 raw WER 断言模型退化。与其他脚本的分工通用微调入口examples/asr/speech_to_text_finetune.py架构专属配方则路由到 CTCexamples/asr/asr_ctc/speech_to_text_ctc_bpe.py、RNNTexamples/asr/asr_transducer/speech_to_text_rnnt_bpe.py、Hybrid RNNT/CTC 或 TDT/CTCexamples/asr/asr_hybrid_transducer_ctc/speech_to_text_hybrid_rnnt_ctc_bpe.py、AED/Canaryexamples/asr/speech_multitask/speech_to_text_aed.py。直接离线转写用examples/asr/transcribe_speech.py流式或分块推理模型使用对应的流式/分块推理脚本。版本敏感结论数据加载器行为、检查点列表等以仓库当前文档为准如docs/source/dataloaders.rst、docs/source/asr/asr_checkpoints.rst与 Lhotse 数据加载器。小结一条可执行的 Stage 4 检查清单以trainer.max_steps 同值余弦调度组织训练按数据规模选 LR大数据 1e-4、小域适配 3e-5、精调/不稳定 1e-5warmup 取 1%2%优先bf16-true用val_wermodemin, save_top_kN, always_save_nemotrue驱动检查点选择多卡容器任务卡死时切换torchrun模板Lhotse 下use_distributed_samplerfalse必要时再上NCCL_CUMEM_ENABLE0/NCCL_P2P_DISABLE1平均工具取同目录非 last 的 N 个 ckpt求均值N 由 save_top_k 决定PyTorch 2.6 可信检查点用TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD1最终决策只认独立评估ampfalse compute_dtypebfloat16基线/最佳检查点/平均产物三者用同一条命令、同一 score-only 打分契约比较保留默认 WER 最优者。【免费下载链接】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),仅供参考