尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

从预训练到 ASR 微调:unilm 仓库 HuBERT 自监督语音模型完整实战指南

从预训练到 ASR 微调:unilm 仓库 HuBERT 自监督语音模型完整实战指南 从预训练到 ASR 微调unilm 仓库 HuBERT 自监督语音模型完整实战指南【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm导读本文基于 unilm 仓库中 kosmos-2/fairseq/examples/hubert/README.md 及配套源码系统讲解 HuBERT 自监督语音表征学习模型的完整使用链路加载官方预训练权重、准备伪标签数据特征提取 K-means 聚类、预训练新模型、以 CTC 损失微调做语音识别以及三种解码方式Viterbi / KenLM / Fairseq-LM。读完本文你将掌握在 fairsequnilm 仓库内置版本上复现 HuBERT 全流程的完整命令与关键参数语义并能结合源码理解每一步的底层实现。HuBERT 简介与官方模型清单HuBERTHidden-Unit BERT是一种自监督语音预训练方法核心思想是在无人工标注的条件下通过离线聚类得到的隐式单元hidden units作为伪标签配合掩码预测目标训练 BERT 式语音编码器从而获得可用于下游任务如 ASR的通用语音表征。unilm 仓库在 kosmos-2/fairseq/examples/hubert/ 目录下提供了完整的示例代码与配置文件。官方发布的预训练与微调模型如下表所示模型体积以参数量计预训练数据来自 LibriSpeech 960 小时与 Libri-Light 60k 小时模型参数量预训练数据微调数据用途HuBERT Base~95MLibriSpeech 960 hr无预训练模型直接加载使用HuBERT Large~316MLibri-Light 60k hr无预训练模型直接加载使用HuBERT Extra Large~1BLibri-Light 60k hr无预训练模型直接加载使用HuBERT Large~316MLibri-Light 60k hrLibriSpeech 960 hrASR 微调模型HuBERT Extra Large~1BLibri-Light 60k hrLibriSpeech 960 hrASR 微调模型下载地址请以原文档表格中的官方链接为准。此外仓库还提供了 update_ckpt.py 与 measure_teacher_quality.py 等辅助脚本分别用于旧版 checkpoint 的字段对齐迁移和评估伪标签教师的质量。加载预训练模型通过 fairseq 的 checkpoint 工具即可一行加载模型配合任务task对象可直接提取特征或进行下游推理ckpt_path /path/to/the/checkpoint.pt models, cfg, task fairseq.checkpoint_utils.load_model_ensemble_and_task([ckpt_path]) model models[0]从源码结构看这一调用同时解析模型、配置文件Hydra cfg与任务对象。例如特征提取脚本 dump_hubert_feature.py 正是利用该 API 加载模型后调用model.extract_features(sourcex_chunk, padding_maskNone, maskFalse, output_layerself.layer)获取指定 Transformer 层的中间表征说明同一加载路径可复用于训练数据准备与下游推理。训练新模型数据准备分片特征提取与 K-means 伪标签训练 HuBERT 需要三类文件具体生成步骤见 simple_kmeans/README.md{train,valid}.tsv波形列表文件。首行为音频根目录后续每行是一个音频文件的相对路径{train,valid}.km按帧对齐的伪标签文件每行是音频对应的一串聚类 IDdict.km.txt占位词典文件见下文。label_rate必须与聚类所用特征的帧率一致MFCC 特征默认为 100HzHuBERT 特征默认为 50Hz。整个准备流程分四步全部基于分片shard并行1. 特征提取提取 39 维 MFCCdeltaddelta 特征用于第 1 轮迭代预训练python dump_mfcc_feature.py ${tsv_dir} ${split} ${nshard} ${rank} ${feat_dir}提取已训练 HuBERT 模型第${layer}层 Transformer 特征用于第 2 轮及以后迭代python dump_hubert_feature.py ${tsv_dir} ${split} ${ckpt_path} ${layer} ${nshard} ${rank} ${feat_dir}tsv 会被切分为${nshard}个分片本命令只处理${rank}号分片rank取值[0, nshard-1]特征保存为${feat_dir}/${split}_${rank}_${nshard}.{npy,len}.npy为拼接特征矩阵.len为每段音频的帧数显存不足时可通过--max_chunk调小单次送入模型的音频块大小默认 1600000 采样点见 dump_hubert_feature.py源码中MfccFeatureReader通过torchaudio.compliance.kaldi.mfcc计算 MFCC 并级联 delta/ddeltaHubertFeatureReader则按max_chunk分块调用extract_features再拼接二者读取音频时都要求采样率与任务配置一致默认 16000Hz多声道取均值。2. K-means 聚类用 10% 的数据拟合一个含${n_clusters}个簇的 MiniBatchKMeans 模型python learn_kmeans.py ${feat_dir} ${split} ${nshard} ${km_path} ${n_cluster} --percent 0.1模型保存到${km_path}joblib 格式。可调参数源码 learn_kmeans.py 中以-h查看包括--percent采样比例设为-1表示使用全部数据--init簇初始化方法默认k-means--max_iter迭代轮数上限默认 100--batch_size批大小默认 10000--tol收敛容差默认 0.0--max_no_improvement连续无改进即停止默认 100--n_init随机初始化次数默认 20--reassignment_ratio重分配比例默认 0.0--seed随机种子默认 0。3. K-means 应用打标签用训练好的聚类模型为每个分片生成伪标签python dump_km_label.py ${feat_dir} ${split} ${km_path} ${nshard} ${rank} ${lab_dir}输出到${lab_dir}/${split}_${rank}_${nshard}.km。源码 dump_km_label.py 中ApplyKmeans通过最近簇中心距离在 GPU 上以矩阵运算加速为每帧分配 ID每段音频的 ID 序列写为一行空格分隔的整数。4. 合并分片并创建占位词典for rank in $(seq 0 $((nshard - 1))); do cat $lab_dir/${split}_${rank}_${nshard}.km done $lab_dir/${split}.km占位词典每行一个聚类 ID频数可随便写仅用于 fairseq 词典加载for x in $(seq 0 $((n_clusters - 1))); do echo $x 1 done $lab_dir/dict.km.txt预训练 HuBERT 模型假设{train,valid}.tsv位于/path/to/data{train,valid}.km位于/path/to/labels标签帧率为 100Hz训练一个 12 层 Transformer 的 base 模型$ python fairseq_cli/hydra_train.py \ --config-dir /path/to/fairseq-py/examples/hubert/config/pretrain \ --config-name hubert_base_librispeech \ task.data/path/to/data task.label_dir/path/to/labels task.labels[km] model.label_rate100在 unilm 仓库中fairseq_cli/hydra_train.py实际位于 kosmos-2/fairseq/fairseq_cli/--config-dir指向 config/pretrain/。hubert_base_librispeech.yaml 给出了 base 模型的完整默认配置关键参数如下task._name: hubert_pretrainingtask.sample_rate: 16000task.label_rate: ${model.label_rate}与聚类帧率一致task.max_sample_size/min_sample_size: 250000/32000random_crop: true表示训练时随机裁剪音频段task.normalize: false必须与特征提取器一致否则帧对齐错位criterion._name: hubertpred_masked_weight: 1.0、pred_nomask_weight: 0.0只对掩码帧算损失、loss_weights: [10,]model部分mask_prob: 0.80掩码比例、conv_feature_layers: [(512,10,5)] [(512,3,2)] * 4 [(512,2,2)] * 2CNN 特征提取器结构通道数、卷积核、步长、final_dim: 256、feature_grad_mult: 0.1特征提取器梯度乘以 0.1 以稳定训练、dropout/attention_dropout: 0.1、encoder_layerdrop: 0.05optimization.max_update: 400000、lr: [0.0005]optimizer._name: adamadam_betas: (0.9,0.98)lr_scheduler._name: polynomial_decaywarmup_updates: 32000checkpoint.save_interval_updates: 25000、keep_interval_updates: 1、no_epoch_checkpoints: true按 update 数保存distributed_training.distributed_world_size: 32、nprocs_per_node: 8等为示例分布式配置。该目录还提供了 hubert_large_librivox.yaml 与 hubert_xlarge_librivox.yaml分别对应 Large~316M与 Extra Large~1B规模。用 CTC 损失微调做 ASR假设{train,valid}.tsv位于/path/to/data字符级转录{train,valid}.ltr位于/path/to/trans用预训练 checkpoint/path/to/checkpoint微调$ python fairseq_cli/hydra_train.py \ --config-dir /path/to/fairseq-py/examples/hubert/config/finetune \ --config-name base_10h \ task.data/path/to/data task.label_dir/path/to/trans \ model.w2v_path/path/to/checkpoint配置文件位于 config/finetune/base_10h.yaml。该配置的关键点task.fine_tuning: true、task.labels: [ltr]、task.single_target: true微调阶段只预测一个目标即字符序列criterion._name: ctc、zero_infinity: trueCTC 损失中把无穷大梯度置零model._name: hubert_ctcw2v_path指向预训练权重微调时feature_grad_mult: 0.0冻结卷积特征提取器mask_prob: 0.75、mask_length: 10、mask_channel_prob: 0.5、mask_channel_length: 64表示继续做时间/通道掩码SpecAugment 式增强layerdrop: 0.1freeze_finetune_updates: 10000前 10000 步冻结除输出层外的编码器dataset.validate_after_updates: ${model.freeze_finetune_updates}与其呼应optimization.max_update: 25000、lr: [2e-5]、sentence_avg: truelr_scheduler._name: tri_stagewarmup_steps: 8000、hold_steps: 0、decay_steps: 72000、final_lr_scale: 0.05checkpoint.best_checkpoint_metric: wer按验证集 WER 选最佳 checkpoint。解码推理假设test.tsv与test.ltr为待解码数据位于/path/to/data微调模型位于/path/to/checkpoint。支持三种解码模式模式说明配置文件Viterbi 解码贪心解码不带语言模型infer_viterbi.yamlKenLM 解码配合 arpa 格式的 KenLM n-gram 语言模型infer_kenlm.yamlFairseq-LM 解码配合 Fairseq 神经网络语言模型infer_fsqlm.yamltask.normalize必须与微调时保持一致否则输入分布不一致会显著影响识别结果。Viterbi 解码$ python examples/speech_recognition/new/infer.py \ --config-dir /path/to/fairseq-py/examples/hubert/config/decode \ --config-name infer_viterbi \ task.data/path/to/data \ task.normalize[true|false] \ decoding.exp_dir/path/to/experiment/directory \ common_eval.path/path/to/checkpoint dataset.gen_subsettest \解码结果保存于/path/to/experiment/directory/decode/viterbi/testinfer_viterbi.yaml中hydra.run.dir: ${common_eval.results_path}/viterbicommon_eval.post_process: letter表示对输出做 letter 级别后处理。KenLM / Fairseq-LM 解码假设发音词典与 n-gram 语言模型分别位于/path/to/lexicon与/path/to/arpa$ python examples/speech_recognition/new/infer.py \ --config-dir /path/to/fairseq-py/examples/hubert/config/decode \ --config-name infer_kenlm \ task.data/path/to/data \ task.normalize[true|false] \ decoding.exp_dir/path/to/experiment/directory \ common_eval.path/path/to/checkpoint dataset.gen_subsettest \ decoding.decoder.lexicon/path/to/lexicon \ decoding.decoder.lmpath/path/to/arpaunilm 仓库中infer.py实际位于 kosmos-2/fairseq/examples/speech_recognition/new/infer.py解码默认超参数定义在 examples/speech_recognition/hydra/decoder.py可通过命令行覆盖。infer_kenlm.yaml的默认解码超参数为beam: 500、beamthreshold: 100、lmweight: 2、wordscore: -1、silweight: 0。例如把束宽改为 500 可追加decoding.decoder.beam500。常用参数语义decoding.decoder.beam束搜索宽度decoding.decoder.beamthreshold束剪枝阈值超出该值终止扩展decoding.decoder.lmweight语言模型权重越大越依赖 LMdecoding.decoder.wordscore词得分word bonus鼓励切分出更多词decoding.decoder.silweight静音帧权重。若改用 Fairseq 神经 LM把--config-name换成infer_fsqlm并按 infer_fsqlm.yaml 修改lexicon/lmpath指向相应文件该配置默认beam: 500、beamthreshold: 25、lmweight: 2、wordscore: -1、silweight: 0。两种带 LM 的解码结果分别保存于decode/kenlm/test、decode/fsqlm/test下输出目录名会携带束搜索参数如beam500_th100_lmw2_wrd-1_sil0便于对不同超参数组合做对比实验。decoding.unique_wer_file: true表示各超参数组合共用同一个 WER 结果文件以便汇总。在 unilm 仓库中快速上手的路径索引主文档kosmos-2/fairseq/examples/hubert/README.md数据准备kosmos-2/fairseq/examples/hubert/simple_kmeans/README.md特征提取、聚类、打标签、合并分片、伪词典脚本均在 simple_kmeans/预训练配置config/pretrain/base / large / xlarge 三个规模微调配置config/finetune/base_10h.yaml解码配置config/decode/viterbi / kenlm / fsqlm 三种模式解码超参数定义examples/speech_recognition/hydra/decoder.py使用注意事项小结帧率一致性是数据准备的生命线label_rate、聚类特征的帧率MFCC 100Hz / HuBERT 特征 50Hz与预训练配置必须严格对齐normalize全链路一致特征提取、预训练、微调与解码四个环节的task.normalize必须保持一致分片并行nshard/rank体系让特征提取与打标签可在多机多卡上并行最后再合并.km文件显存不足优先调--max_chunk而不是盲目减小batch_size微调阶段默认冻结卷积特征提取器feature_grad_mult: 0.0并做前 10000 步的编码器冻结这是稳定 CTC 微调的关键设置。【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表