拓冰建站拓冰建站
首页 / 资讯中心 / 正文

NeMo ASR Adapters 实战指南:用适配器模块为预训练语音识别模型做领域适配

NeMo ASR Adapters 实战指南用适配器模块为预训练语音识别模型做领域适配【免费下载链接】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_adapters示例目录系统讲解如何在不破坏预训练模型原始能力的前提下通过轻量级 Adapter适配器模块完成 ASR 模型的领域适配。读完本文你将掌握使用train_asr_adapter.py为预训练模型挂载并训练一个或多个适配器、使用eval_asr_adapter.py按名称选择特定适配器进行评估以及使用scoring_and_analysis.py按照论文《Damage Control During Domain Adaptation for Transducer Based Automatic Speech Recognition》的评分准则挑选最优超参数组合的完整实战方案。一、背景为什么 ASR 领域适配需要 AdapterAdapter 是一类插入到预训练模型内部的小型可训练模块。与全量微调Fine-tuning不同训练 Adapter 时冻结模型全部原始参数仅更新新加入的 Adapter 参数从而以极低的参数量代价实现领域适配。其典型收益包括轻量只需训练极小一部分参数如隐藏维度 1632 的瓶颈层训练速度快、显存占用低可叠加同一个模型可以挂载多个命名各异的 Adapter分别对应不同领域/口音/语言推理时按名切换无需复制多份完整模型抗遗忘由于基础权重完全冻结原始领域的能力基本不受影响缓解灾难性遗忘。该示例目录存放了为 NeMo 中受支持的 ASR 模型启用 Adapter 支持的三个脚本配套配置位于 examples/asr/conf/asr_adapters 目录。关于 Adapter 的概念、训练与使用方式的更深入讨论可参阅仓库中的适配器教程tutorials/asr/asr_adapters。二、目录结构与前置准备examples/asr/asr_adapters/ ├── README.md # 本文对应的说明文档 ├── train_asr_adapter.py # 训练一个或多个适配器 ├── eval_asr_adapter.py # 评估已适配模型 └── scoring_and_analysis.py # 结果评分与超参数分析 examples/asr/conf/asr_adapters/ ├── asr_adaptation.yaml # 适配器训练/评估的基础配置 └── asr_adaptation_hp.yaml # 超参数搜索专用配置运行上述脚本需要安装好 NeMo 及其 ASR 相关依赖一个预训练 ASR 模型可以是模型名pretrained_model如stt_en_fastconformer_hybrid_large_pc这类受支持的模型名也可以是本地.nemo文件nemo_model训练/验证用的 NeMo 格式 manifest 数据文件.json每行包含audio_filepath、text、duration等字段一个 GPU 环境配置中默认trainer.devices-1使用全部可用 GPU。三、训练一个或多个适配器train_asr_adapter.pytrain_asr_adapter.py脚本接收三个方面的信息预训练模型的路径、用于定义并添加 Adapter 模块的配置、以及训练/验证数据集的相关设置。它会把任意数量的 Adapter 模块挂载到网络上。3.1 基础训练命令以下是脚本 docstring 中给出的标准训练命令python train_asr_adapter.py \ --config-path../conf/asr_adapters \ --config-nameasr_adaptation.yaml \ model.pretrained_modelnull \ model.nemo_modelnull \ model.adapter.adapter_nameUnique adapter name \ model.adapter.adapter_typelinear, tiny_attn, or others from config sub-sections of adapter \ model.adapter.adapter_module_namenull, or str module. Type: encoder, decoder, joint, or multiple with between them \ model.adapter.linear.in_featuresdimension of the layer outputs of the model \ model.adapter.linear.dim32 \ model.adapter.linear.dropout0.0 \ model.train_ds.manifest_filepathPath to manifest \ model.train_ds.batch_size16 \ model.validation_ds.manifest_filepathPath to manifest \ model.validation_ds.batch_size16 \ model.optim.lr0.001 \ model.optim.weight_decay0.0 \ model.optim.sched.warmup_steps100 \ trainer.max_steps300 \ trainer.devices1 \ trainer.precision32 \ exp_manager.exp_dirSome directory for experiment manager注意两点model.pretrained_model与model.nemo_model必须二选一。脚本源码在 train_asr_adapter.py 中显式校验两者均为null或同时非null都会抛出ValueError。每条命令中的配置覆盖项Hydra Overrides会覆盖模型内部同名配置——这是该配置文件与常规 ASR 训练配置最大的不同。3.2 核心配置参数说明配置文件 asr_adaptation.yaml 的注释明确了几个必须由用户填写的关键参数参数含义与取值model.pretrained_model/model.nemo_model二选一。前者填预训练模型名后者填本地.nemo文件路径model.adapter.adapter_name适配器全局唯一名称。同一模型的每个适配器必须拥有独一无二的名字model.adapter.adapter_type适配器类型对应下方linear、tiny_attn等子配置块model.adapter.adapter_module_name适配器挂载的模块名encoder、decoder、joint多个模块用连接如encoderdecoder不填则为nullmodel.adapter.linear.in_features模型各层输出维度即适配器输入维度依赖具体模型。Conformer 模型可在model.encoder.d_model找到ConvASR 模型如 MarbleNet通常在model.encoder.jasper.0.filtersmodel.train_ds.manifest_filepath/model.validation_ds.manifest_filepath训练/验证 manifest 文件路径配置文件中adapter_name: ???这类 Hydra 必填占位符意味着不提供该覆盖项脚本无法启动这避免了忘记命名适配器导致的无意义训练。3.3 训练执行流程README 用 Mermaid 图描述了训练时的完整执行流对照源码 train_asr_adapter.py 可将每个环节落实到具体代码配置解析hydra_runner(config_path../conf/asr_adapters, config_nameasr_adaptation.yaml)装饰器加载 YAML 并合并命令行 OverridesL151。恢复预训练模型ASRModel.from_pretrained(...)或ASRModel.restore_from(...)先取回配置return_configTrue经update_model_config_to_support_adapter()改写后再以override_config_path实例化L163-L171。改写 encoder 配置以支持 Adapterupdate_model_config_to_support_adapter()通过adapter_mixins.get_registered_adapter(model_cfg.encoder._target_)查找该 encoder 类是否注册了 Adapter 支持若有则把model_cfg.encoder._target_替换为adapter_metadata.adapter_class_pathL100-L108。数据与优化器设置update_model_cfg()会把新配置中模型不存在的键剔除仅白名单num_workers、pin_memory强制注入再OmegaConf.merge合并随后依次调用setup_training_data、setup_multiple_validation_data、setup_optimizationL174-L182。添加新适配器从cfg.model.adapter中弹出adapter_name、adapter_type、adapter_module_name按类型解析子配置后调用model.add_adapter(adapter_name, cfgadapter_type_cfg)并用assert model.is_adapter_available()校验挂载成功L192-L219。启用/冻结策略先set_enabled_adapters(enabledFalse)禁用全部适配器再按名称只启用最新添加的适配器随后model.freeze()冻结全部权重model.train()恢复训练模式保证 dropout 等生效最后unfreeze_enabled_adapters()仅解冻被启用的适配器参数L222-L230。训练与存档trainer.fit(model)启动训练若设置了adapter_state_dict_name训练结束后通过model.save_adapters(state_path)将适配器权重单独保存默认文件名adapters.pt若设置delete_ckpt_after_traintrue还会调用clean_exp_ckpt()清理 PTL 检查点以节省存储L236-L253。细节提示unfreeze_enabled_adapters()在 adapter_mixins.py 中还会默认冻结所有 BatchNorm 层的 moving average 更新track_running_statsFalse这一设计确保禁用全部适配器时恰好还原基础模型的输出是保证 Adapter 可无损移除的关键。3.4 多适配器训练的注意事项README 特别强调要在单个模型上训练多个适配器必须把配置中的model.nemo_model指向之前已经适配过的模型即上一轮训练产出的.nemo并且为每个新适配器使用新的唯一model.adapter.adapter_name。由于该配置文件本身并不会被写入适配后的模型中它只是训练脚本的配置而非模型的配置因此你可以多次调用本脚本每次以上一轮的输出为输入逐个往模型里追加适配器。3.5 适配器训练推荐配置与常规 ASR 训练或全量微调不同Adapter 训练有一组显著不同的推荐设置见 asr_adaptation.yaml 头部注释model.adapter.dim瓶颈维度取小值即可1632 通常足够model.optim.lr使用非常小的学习率搭配极短的训练计划仅几百步通常低 LR 下在数据集上跑几个 epoch 就足以完成适配model.optim.weight_decay强权重衰减虽然能防止原始训练能力明显退化但也会限制模型学习新领域的能力基线一般取 0.0model.optim.sched.warmup_steps应调整为适配这种较短训练计划的小步数配置里同时提供了warmup_ratio: 0.1即预热步数为总步数的 10%trainer.max_steps推荐用max_steps把训练限制在1020 个 epoch 内。Adapter 收敛极快过长时间训练会对新领域过拟合进而导致旧领域灾难性遗忘也可等价地用trainer.max_epochs控制trainer.check_val_every_n_epoch由于训练短且快建议每数个 epoch 校验一次而非每个 epoch 都校验以加速训练。四、评估已适配模型eval_asr_adapter.pyeval_asr_adapter.py用于方便地评估已适配模型给定适配后模型的路径/名称再从模型携带的多个 Adapter 中按名称任选一个进行评估。4.1 评估命令python eval_asr_adapter.py \ --config-path../conf/asr_adapters \ --config-nameasr_adaptation.yaml \ model.pretrained_modelnull \ model.nemo_modelnull \ model.adapter.adapter_namename of the adapter to evaluate \ model.test_ds.manifest_filepathPath to validation/test manifest \ model.test_ds.batch_size16 \ model.train_ds.manifest_filepathnull \ model.validation_ds.manifest_filepathnull \ model.adapter.in_featuresnull \ trainer.devices1 \ trainer.precision324.2 评估执行流程README 中给出的评估 Mermaid 流程如下对照 eval_asr_adapter.py 源码可以看到与训练脚本对称的调用链先恢复预训练/适配后的模型同样先改配置再实例化L82-L90然后setup_multiple_test_data()只设置测试数据接着先禁用全部适配器再按提供的adapter_name启用指定适配器最后冻结权重后执行trainer.test(model)L96-L112。4.3 评估基础模型README 明确指出若想评估基础模型所有适配器均禁用只需把model.adapter.adapter_namenull传给该脚本即可——此时所有适配器被禁用模型退化为纯基础模型参与评测。这在对比适配前后 WER 变化时非常有用也是后文评分分析中原始领域退化指标的来源。五、超参数搜索asr_adaptation_hp.yaml针对需要网格搜索的场景目录提供了专用配置 asr_adaptation_hp.yaml配合 Hydra 的 sweeper 自动并行执行多组实验。README 给出的命令为python train_asr_adapter.py \ --config-path../conf/asr_adapters \ --config-nameasr_adaptation_hp.yaml \ -m \ model.pretrained_modelnull \ model.nemo_modelnull \ model.adapter.adapter_nameUnique adapter name \ model.adapter.adapter_typelinear, tiny_attn, or others from config sub-sections of adapter \ model.adapter.adapter_module_namenull, or str module. Type: encoder, decoder, joint, or multiple with between them \ model.adapter.linear.in_featuresdimension of the layer outputs of the model \ model.train_ds.manifest_filepathPath to manifest \ model.train_ds.batch_size16 \ model.validation_ds.manifest_filepathPath to manifest \ model.validation_ds.batch_size16 \ exp_manager.exp_dirsome directory \ exp_manager.create_wandb_loggertrue \ exp_manager.wandb_logger_kwargs.projectProject Name \ delete_ckpt_after_trainTrue该配置的几个关键设计搜索空间hydra.sweeper.params定义了要搜索的参数及其候选值例如model.optim.lr: 0.001,0.0001、model.adapter.linear.dim: 32,64,96,128、model.adapter.linear.adapter_strategy.stochastic_depth: 0.0,0.5,0.6,0.7,0.8,0.9文件注释中还给出了tiny_attn类型搜索n_head、proj_dim、stochastic_depth的示例实验命名exp_manager.name会把所有超参数拼进名字如${name}-lr-${model.optim.lr}-adim-${model.adapter.linear.dim}-sd-${model.adapter.linear.adapter_strategy.stochastic_depth}注释强调必须把所有超参都加入命名以保证 HP 搜索崩溃后能成功恢复容错恢复resume_if_exists: true、resume_ignore_no_checkpoint: true以及delete_ckpt_after_trainTrue及时清理检查点都是为了应对超参搜索中途失败的情况并行调度hydra.launcher.num_gpus-1使用全部 GPU、jobs_per_gpu控制在单卡上并发运行的 job 数显存充足时可大于 1。六、结果评分与超参数分析scoring_and_analysis.py训练完多组超参实验后需要一套客观准则来挑选最优配置。scoring_and_analysis.py实现了论文《Damage Control During Domain Adaptation for Transducer Based Automatic Speech Recognition》中提出的受限constrained与非受限unconstrained适配实验的评分指标。6.1 基本用法脚本输入是一个 CSV 文件内含所有超参数及其对应的 WER。默认针对 Crowdsourced high-quality UK and Ireland English Dialect speech data setSLR83 数据集的分析场景做了预配置用于其他实验时需按脚本开头注释说明修改全局变量。# 分析适配器实验结果 python scoring_and_analysis.py \ --csv path to cleaned result csv file \ --dataset_type_column column name in csv with the dataset types # 分析微调实验结果加 -ft python scoring_and_analysis.py \ --csv path to csv \ --dataset_type_column column name in csv with the dataset types \ -ft6.2 高级用法# 显示全部超参数的完整排名而非仅最优并展示 Top-3 python scoring_and_analysis.py \ --csv path to csv \ --dataset_type_column dataset_group_column_name \ --show_analysis \ --topk 3 # 只分析部分实验用 -cargs 固定受限实验的超参-uargs 固定非受限实验的超参 python scoring_and_analysis.py \ --csv path to csv \ --dataset_type_column dataset_group_column_name \ -cargs Adapter Position encoder \ -cargs Adapter Dropout 0.5 \ -uargs Train Steps 5000命令行参数汇总来自 scoring_and_analysis.py 的 argparse 定义参数简写说明--csv-c必填清洗后的结果 CSV 路径--dataset_type_column-dtype必填CSV 中数据集类型所在列例如 SLR83 用GroupGSC 用Dataset Size--constrained_args-cargs固定受限实验的 (超参名, 值) 对可多次指定--unconstrained_args-uargs固定非受限实验的 (超参名, 值) 对可多次指定--topk-k展示前 k 组最优超参默认 1--finetuning-ft若 CSV 中是微调实验结果则加上此开关--show_analysis-s显示所有数据集类型的关键值完整排名表6.3 评分指标的计算逻辑需要根据实验内容修改的全局变量集中在 scoring_and_analysis.py 开头UNCONSTRAINED_EXP_KEY/CONSTRAINED_EXP_KEY两组实验各自的排序依据——非受限实验按测试 WER 最小化min受限实验按 Score 最大化maxADAPTER_HYPERPARAMTER_COLUMNS/FINETUNING_HYPERPARAMETER_COLUMNS输出中展示的超参数列适配器为维度、dropout、随机深度、训练步数微调为训练步数、学习率TEST_WER_COLUMN新领域测试集 WER 列名ORIGINAL_TEST_WER_COLUMN原始领域LibriSpeech Test OtherWER 列名EXP_CATEGORY_KEY按实验类型区分的分类列适配器为Adapter Position微调为Frozen ModuleMAX_DEGRADATION_PERCENTAGE允许的原始领域最大绝对 WER 退化百分比默认 3BASELINE_ORIGINAL_WER原始领域基线 WER默认 5.118BASELINE_ADAPTED_WER各目标领域按dataset_type_column取值区分如irish_english_male、scottish_english_female等 11 个口音/性别组合的基线 WER 字典。评分由三个量构成见parse_results()L115-L146Original Scale原始领域退化惩罚分。退化越大分数越低由calculate_original_scale()计算(MAX_DEGRADATION_PERCENTAGE - min(MAX_DEGRADATION_PERCENTAGE, |WER_original - baseline|)) / MAX_DEGRADATION_PERCENTAGEAdapt WERR新领域词错误率降低率WER Reduction Rate由calculate_adapt_werr()计算max(baseline_adapted - WER_adapted, 0) / baseline_adapted即相对基线的提升比例Score二者乘积Original Scale * Adapt WERR同时约束新领域提升与旧领域不退化两个目标。脚本会把计算出的三列回写进 CSVdf.to_csv(filepath, indexFalse)随后按EXP_CATEGORY_KEY分类、按超参组合分组取均值再按排序依据输出 Top-K 配置及对应的新旧领域 WER并打印按数据集类型的明细表与平均值。七、何时不应使用 Adapter与微调的取舍README 明确列出了 Adapter 的局限这是选择方案时必须权衡的词表约束新数据集的词表必须能被预训练模型已有的词表/分词器覆盖。若存在词表外的 tokenAdapter 只能学到 UNK对于字符级模型甚至会直接失败语言约束作为上一条的推论新数据集的语言必须与原始模型一致。更复杂的跨语言 Adapter 目前仍在研究中。当以上限制导致 Adapter 无法直接使用时全量微调Fine-tuning是更合适的替代方案。仓库内 examples/asr/speech_to_text_finetune.py 即提供了对应的微调入口。关于微调的更多配置说明可参阅 NeMo 文档中 ASR 配置的 Fine-tuning 小节。八、底层机制Adapter 的核心 API整个训练/评估脚本建立在 nemo/core/classes/mixins/adapter_mixins.py 提供的适配器 mixin 之上理解这些 API 有助于自定义适配器行为add_adapter(name, cfg)L227向模块挂载新适配器。要求名字全局唯一重名抛ValueError且不能使用保留名global_cfg适配器实例通过safe_instantiate从配置的_target_创建并以nn.ModuleDict形式保存在adapter_layer中is_adapter_available()L283判断是否已有任何适配器实例不管启用与否set_enabled_adapters(nameNone, enabledTrue)L295无name时启用/禁用全部适配器有name时只修改指定适配器的enabled标志。典型用法是先全部禁用、再按名启用一个如训练/评估脚本中的模式get_enabled_adapters()L338返回当前所有已启用适配器的名称列表unfreeze_enabled_adapters(freeze_batchnormTrue)L443解冻所有已启用适配器的参数同时默认冻结 BatchNorm 层的运行统计更新保证禁用适配器时能精确还原基础模型输出save_adapters(filepath, nameNone)L857把适配器权重单独保存为独立文件便于分发轻量适配器update_adapter_cfg(cfg)L1055把全局适配器配置传播给所有已存在的适配器模块。适配器模块类本身位于 nemo/collections/common/parts/adapter_modules.pyLinearAdapter与 nemo/collections/asr/parts/submodules/adapters/multi_head_attention_adapter_module.pyRelPositionMultiHeadAttentionAdapter配置中通过_target_引用。九、进一步学习tutorials/asr/asr_adapters/ASR_with_Adapters.ipynbAdapter 入门介绍其在 ASR 模型中的应用、领域适配的优缺点并在 toy 数据集上实际训练一个适配器tutorials/asr/asr_adapters/Multi_Task_Adapters.ipynb多任务模型的适配器定制讲解如何在语音识别与语音翻译双任务上使用 Adapter 微调以及自定义数据集与 prompt formatter 的构造配置全文可参考 asr_adaptation.yaml训练/评估与 asr_adaptation_hp.yaml超参搜索。结语本示例目录以三个脚本 两个配置的形式覆盖了 ASR Adapter 的完整生命周期用train_asr_adapter.py在冻结的预训练模型上叠加任意数量的命名适配器用eval_asr_adapter.py按名评估单个适配器或传adapter_namenull评估基础模型再用scoring_and_analysis.py以新领域 WER 下降 旧领域退化受控的联合准则从超参搜索中挑选最优配置。结合底层adapter_mixins提供的add_adapter、set_enabled_adapters、unfreeze_enabled_adapters等 API你可以轻松将这套领域适配流程迁移到自己的模型、数据集与适配器设计上。【免费下载链接】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),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门