ESPnet 基于 LibriSpeech 960h 的 HuBERT 自监督预训练食谱实战:k-means 伪标签与掩码预测全流程解析
人工智能语音音频深度学习NLP【免费下载链接】espnetEnd-to-End Speech Processing Toolkit项目地址https://gitcode.com/gh_mirrors/es/espnet点击查看免费下载本指南以 ESPnet 仓库中的 egs2/librispeech/hubert1 食谱为核心完整讲解如何在 960 小时 LibriSpeech 数据上从零训练 HuBERT 自监督模型——包括 MFCC/k-means 伪标签生成、多轮迭代式预训练、掩码预测训练以及如何在低资源LibriLight-Limited 10h数据上微调验证预训练质量。读完本文你将掌握该食谱的目录结构、全部脚本参数、迭代流程、训练配置逐项含义与源码级实现细节能够直接复现文中记录的预训练结果或将其迁移到自有数据。HuBERT 与自监督预训练背景HuBERTHidden Unit BERT是一种自监督语音表示学习方法核心思路是先用聚类算法为无标注语音生成“伪标签”pseudo label再通过 BERT 式的掩码预测mask-prediction训练 Transformer 编码器让模型学会从上下文中预测被掩码的隐式语音单元。由于无需人工标注它可以在海量无标注语音上预训练随后用少量标注数据微调即可取得出色的 ASR 性能。其原始论文、代码与模型出自 Fairseqexamples/hubertTorchaudio 也提供了官方实现与结果。本仓库 egs2/librispeech/hubert1/README.md 记录的正是这一思路在 ESPnet 中的落地使用 LibriSpeech 960 小时数据完成k-means 伪标签生成与掩码预测训练两条主线并给出两轮迭代预训练模型的完整训练环境与微调结果。实现过程中得到了 HuBERT 作者 Wei-Ning Hsu、Abdelrahman Mohamed 以及 Torchaudio HuBERT 实现者 Zhaoheng Ni 的直接支持最终效果与 Torchaudio 官方结果一致。食谱目录结构与运行入口egs2/librispeech/hubert1是一个完整可跑的 ESPnet 2 食谱核心文件分布如下run.sh迭代流程入口定义每轮迭代的聚类特征、层号、聚类数、训练配置等核心参数再调用hubert.shhubert.sh主流水线脚本串联数据准备 → 特征格式化 → k-means → 统计收集 → SSL 训练 → 打包 → 上传的全部 stageconf/tuning/预训练配置文件包括torchaudio_hubertbase/large 的 SSL 配置与下游 ASR 微调配置local/LibriSpeech 数据下载与准备脚本pyscripts/特征抽取MFCC/SSL、k-means 聚类、伪标签生成等 Python 工具scripts/feats/perform_kmeans.shk-means 完整子流程特征抽取 → 聚类 → 打标签 → 质量评估 → 词典生成。运行前需要先通过db.sh配置 LibriSpeech 数据存放路径然后执行./run.sh默认迭代 0 与迭代 1run.sh注释说明 base 模型 1 轮迭代已经足够。脚本使用set -e -u -o pipefail严格模式任一步骤失败即中止方便排查。迭代式预训练流程总览HuBERT 预训练的关键在于“迭代式”地提升伪标签质量每一轮用上一轮模型输出的特征重新聚类生成更好的伪标签再训练更强的模型。run.sh中完整定义了 0、1、2 三轮的配置实际默认跑到第 1 轮各轮设计如下迭代聚类输入特征特征来源层聚类数训练配置iter 0mfcc—100train_ssl_torchaudiohubert_base_960h_pretrain_it0.yamliter 1espnet_hubertTransformer 第 6 层500train_ssl_torchaudiohubert_base_960h_pretrain_it1.yamliter 2espnet_hubertTransformer 第 9 层500train_ssl_torchaudiohubert_large_960h_pretrain_it2.yamlrun.sh中的调用命令关键参数已内联注释train_start_iter0 train_stop_iter1 # 1 iterations is enough for base model n_clusters_iter0100; n_clusters_iter1500; n_clusters_iter2500 feature_iter0mfcc; feature_iter1espnet_hubert; feature_iter2espnet_hubert layer_iter00; layer_iter16; layer_iter29 train_settrain_960; valid_setdev ./hubert.sh \ --ngpu 8 --num_nodes 1 --lang en \ --train_start_iter ${train_start_iter} --train_stop_iter ${train_stop_iter} \ --nj 32 --max_wav_duration 30 \ --train_configs ${train_config_iter0} ${train_config_iter1} ${train_config_iter2} \ --n_clusters ${n_clusters_iter0} ${n_clusters_iter1} ${n_clusters_iter2} \ --features_km ${feature_iter0} ${feature_iter1} ${feature_iter2} \ --layers_km ${layer_iter0} ${layer_iter1} ${layer_iter2} \ --train_set ${train_set} --valid_set ${valid_set} \ --portion_km 0.1 --gpu_dump_feature true \ --alignment_phoneme_dir ./data/librispeech_phoneme_alignment $hubert.sh内部会校验train_configs、n_clusters、features_km、layers_km四个列表长度都必须不小于train_stop_iter且train_start_iter ≤ train_stop_iter否则直接报错退出——这保证了每轮迭代都有对应的配置与聚类参数可用。hubert.sh 完整参数解析hubert.sh是全流程的核心所有参数均以--key value形式传入。下表完整列出其参数默认值取自脚本定义供直接复制使用类别参数默认值说明通用--stage/--stop_stage1 / 10000起始/终止阶段号--skip_data_prep/--skip_train/--skip_evalfalse跳过对应阶段--skip_packing/--skip_upload_hftrue跳过模型打包/上传--ngpu1GPU 数0 表示 CPU--num_nodes/--nj1 / 32节点数、并行 job 数--dumpdir/--expdirdump / exp特征与实验输出目录--pythonpython3执行 espnet 命令的 Python数据--local_data_opts空传给local/data.sh的选项扰动--speed_perturb_factors空速度扰动因子如0.9 1.0 1.1特征--feats_typeraw特征类型本食谱仅支持raw--audio_formatflacwav / flac / wav.ark / flac.ark--fs16k采样率--min_wav_duration/--max_wav_duration0.1 / 20保留的音频时长上下限秒分词--token_typewordchar 或 bpeSSL 训练--num_splits_ssl1文本语料切分数1 时用split_scps降低内存--train_start_iter/--train_stop_iter空预训练起止迭代0 表示 MFCC 轮--train_configs空各迭代训练配置空格分隔、顺序对应--feats_normalize空归一化层类型如global_mvn--n_clusters/--features_km/--layers_km空聚类数 / 聚类特征 / 特征层空格分隔--portion_km1k-means 使用的训练集比例--gpu_dump_featurefalse是否用 GPU 抽取特征推荐 true--kmeans_opts空透传给perform_kmeans.sh的选项--alignment_phoneme_dir空音素对齐目录含 utt_id 音素序列的 tsv上传/推理--hf_repo空HuggingFace 仓库名--inference_ssl_modelvalid.loss.best.pth上一轮/最终使用的 SSL 模型文件--download_model空从 Model Zoo 下载指定模型用于解码任务相关--train_set/--valid_set必填训练/验证集名--langnoinfo语料语言--speech_fold_length/--text_fold_length800 / 400语音/文本 fold 长度batch 切分用流水线 Stage 逐段解析Stage 1–4数据准备与音频格式化Stage 1调用local/data.sh下载并准备 LibriSpeech 的 train/dev/test 数据目录Stage 2若设置speed_perturb_factors调用 scripts/utils/perturb_data_dir_speed.sh 做速度扰动并combine_data.sh合并之后训练集名自动变为train_set_spStage 3对 raw 特征类型把 Kaldi 风格的wav.scp可能含管道命令通过 scripts/audio/format_wav_scp.sh 落盘为真实音频文件同时支持--segments切分和格式/采样率转换Stage 4依据min_wav_duration/max_wav_duration过滤过短/过长音频剔除空文本并fix_data_dir.sh保证各文件条目一致。Stage 5k-means 聚类与伪标签生成每迭代对当前迭代的feats_km特征运行 scripts/feats/perform_kmeans.sh内部包含 5 个子 stageDump feature调用 pyscripts/feats/dump_ssl_feature.py通过--feature_conf选择特征类型——mfcc、fairseq_hubert加载 Fairseq 官方 HuBERT 权重hubert_url/hubert_dir_path指定或espnet_hubert加载 ESPnet 自训练模型目录需包含config.yaml与模型权重SSL 特征抽取默认使用--use_gpu trueLearn K-means调用 pyscripts/utils/learn_kmeans.py基于 scikit-learn输出km_${nclusters}.mdl脚本注释提示该步骤通常需要约 120GB 内存Generate pseudo-labels调用 pyscripts/feats/dump_km_label.py把每帧特征映射到最近簇生成pseudo_labels_km${nclusters}.txt支持RVQ_layers 1时按 RVQ 层生成多组标签Measure qualities当提供alignment_phoneme_dir音素对齐 tsv格式utt_id1 a1,a2,a3,...时用local/measure_teacher_quality.py对比伪标签与真实音素对齐衡量伪标签质量并写入phoneme_pseudo_label_quality.txtupsample默认按特征类型取 1MFCC或 2SSL 帧率与音素对齐率之比Prepare labels dict把伪标签复制为data/${dset}/text.km.${km_tag}并统计词频生成词典tokens.txt含unk、sos/eos等特殊符号。Stage 6HuBERT collect-stats为 SSL 训练收集数据形状统计将wav.scp/text.km.*按nj切分并行执行python3 -m espnet2.bin.hubert_train --collect_stats true再用espnet2.bin.aggregate_stats_dirs聚合。注意--token_list指向data/${lang}_token_list_kmeans_iter${iter}_.../tokens.txt--num_classes即当前迭代的聚类数仅当feats_normalizeglobal_mvn时才汇总均值方差统计。Stage 7HuBERT 掩码预测训练核心训练阶段命令为python3 -m espnet2.bin.launch \ --cmd ${cuda_cmd} --name ${jobname} --log ${ssl_exp}/train.log \ --ngpu ${ngpu} --num_nodes ${num_nodes} --multiprocessing_distributed true -- \ python3 -m espnet2.bin.hubert_train \ --use_preprocessor true --normalize null \ --token_type ${token_type} --token_list ${token_listdir}/tokens.txt \ --num_classes ${n_clusters} \ --train_data_path_and_name_and_type ${train_dir}/wav.scp,speech,sound \ --train_data_path_and_name_and_type ${train_dir}/text.km.${km_tag},text,text \ --valid_data_path_and_name_and_type ${valid_dir}/wav.scp,speech,sound \ --valid_data_path_and_name_and_type ${valid_dir}/text.km.${km_tag},text,text \ --resume true --fold_length 80000 --fold_length 400 \ --output_dir ${ssl_exp} --config ${ssl_config}要点语音以sound类型按帧输入fold_length在 raw 模式下自动乘以 100 换算为采样点当num_splits_ssl 1时先通过espnet2.bin.split_scps切分语料并使用--multiple_iterator true逐子集训练以缓解解析大文本文件的内存压力。每轮训练结束后模型保存在exp/hubert_iter${iter}_${ssl_tag}/文件名如valid.loss.best.pth。Stage 8–9模型打包与上传Stage 8用espnet2.bin.pack ssl把config.yaml、模型权重、训练曲线图片以及 k-means 模型km_*.mdl一起打包成 zip便于发布Stage 9若设置--hf_repo解包到本地 HuggingFace 仓库并生成README.md后git push发布需安装 git-lfs。SSL 预训练配置逐项解析conf/tuning/ 下两个 base 配置it0/it1与一个 large 配置it2是训练效果的关键。三份配置的差异对比如下参数it0 (base)it1 (base)it2 (large)batch_type/batch_binsnumel / 48000000numel / 45000000numel / 4000000accum_grad224max_epoch250250400label_downsamplingcollate211encodertorchaudio_huberttorchaudio_huberttorchaudio_hubertencoder_embed_dim768默认768默认1024encoder_num_layers/encoder_num_heads12 / 1212 / 1224 / 16encoder_ff_interm_features307230724096final_dim256默认256默认768extractor_modegroup_normgroup_normlayer_normoptim/lradam / 5e-4adam / 5e-4adam / 5e-4schedulerwarmuplr, 32000warmuplr, 32000warmuplr, 32000以 train_ssl_torchaudiohubert_base_960h_pretrain_it0.yaml 为例关键字段含义use_amp: true启用自动混合精度该配置在 8×A40 40GB 上训练了 5 天grad_clip: 5.0、init: none不额外初始化保留 torchaudio 默认batch_type: numelbatch_bins: 48000000按元素数动态组批collate_fn_conf.label_downsampling: 2伪标签每 2 帧取 1与 base 模型 50Hz 的标签率对齐it0 用 100 类 MFCC 标签it1 起改为 1对应 500 类 SSL 特征标签encoder_confencoder_layer_drop: 0.05为随机丢弃 Transformer 层的正则dropout 系列控制投影/注意力/FFN 的失活率model: torchaudio直接复用 torchaudio 官方 HuBERT 预训练模型实现。Fairseq 风格配置ASR 微调用conf/tuning/train_asr_hubert_base_960h_pretrain_it0.yaml 展示另一套实现选择——encoder: hubert_pretrain对应FairseqHubertPretrainEncoder包含conv_feature_layers如[(512,10,5)] [(512,3,2)]*4 [(512,2,2)]*2、mask_prob: 0.80、label_rate: 100、feature_grad_mult: 0.1、untie_final_proj: true等 Fairseq 参数model_conf中pred_masked_weight: 1.0、pred_nomask_weight: 0.0与loss_weights: 10.0控制掩码/未掩码帧的损失权重。源码级实现从配置文件到模型训练预训练入口是 espnet2/bin/hubert_train.py它只是薄封装真正逻辑在 espnet2/tasks/hubert.py 的HubertTask继承AbsTask。任务注册了两种编码器hubert_pretrainFairseqHubertPretrainEncoder与torchaudio_hubertTorchAudioHuBERTPretrainEncoder对应配置中的encoder字段。TorchAudioHuBERTPretrainEncoder定义在 espnet2/asr/encoder/hubert_encoder.py其__init__直接调用torchaudio.models.hubert_pretrain_model(...)把extractor_mode、卷积层配置、encoder_embed_dim、encoder_num_layers/heads、掩码参数mask_prob0.8、mask_length10、num_classes、final_dim、feature_grad_mult0.1等逐项透传给 torchaudiofeature_grad_mult控制卷积特征提取层的梯度缩放前向不受影响这是 HuBERT 训练稳定性的关键设计。该 encoder 还支持finetuning模式与freeze_encoder_updates可直接复用为下游 ASR 编码器见hubert_encoder.py中加载预训练权重、冻结特征提取器的逻辑。掩码生成逻辑位于 espnet2/ssl/utils/mask.py实现mask_prob、mask_length、mask_selectionstatic/uniform/normal/poisson、no_mask_overlap、通道掩码等参数模型主体是 espnet2/ssl/espnet_model.py 中的ESPnetPretrainModelforward中把掩码后的特征送入编码器由各损失模块计算掩码帧预测损失。预训练损失定义在 espnet2/ssl/loss/hubert.pyHuBERTPretrainLoss对每个选中的 Transformer 层输出计算交叉熵loss_typecross_entropy支持多layers/loss_weights并计算正确率供验证集监控另一类HuBERTPretrainLogitAdjustmentLoss负责把表示投影到类别空间。测试侧有 test/espnet2/ssl/test_ssl_espnet_model.py 与 test/espnet2/tasks/test_hubert.py 覆盖任务解析与模型前向可作为理解数据流speech text 伪标签同时进入模型的参考。特征抽取的底层实现集中在 pyscripts/feats/ssl_feature_utils.py提供MfccFeatureReader、HubertFeatureReaderFairseq 权重、ESPnetHubertFeatureReaderESPnet 自训练权重通过hubert_model_pathlayer指定抽取层与S3PRLFeatureReaderdump_ssl_feature.py按--feature_conf选择对应 reader 后并行批量抽取。预训练结果与低资源微调验证食谱官方记录了两轮迭代模型的完整环境与微调结果。迭代 0 模型训练环境日期Wed Jan 4 08:48:57 EST 2023Python 3.9.15ESPnet 202209PyTorch 1.13.0cu117Git hash753f40d61813436d4e76660904d02eaed7a6649eSSL 配置train_ssl_torchaudiohubert_base_960h_pretrain_it0.yaml预训练模型发布在 HuggingFaceESPnet 官方账号espnet下模型名含simpleoier_librispeech_hubert_iter0_train_ssl_torchaudiohubert_base_960h_pretrain_it0_raw。迭代 0 在LibriLight-Limited 10h上微调 ASR 的结果数据集SntWrdCorrSubDelInsErrS.Errdecode_asr_model_valid.loss.ave/dev_clean26945363585.813.60.61.215.585.6decode_asr_model_valid.loss.ave/dev_other28645094878.120.41.52.023.991.5decode_asr_model_valid.loss.ave/test_clean26205257685.413.90.71.315.984.5decode_asr_model_valid.loss.ave/test_other29395234378.020.61.52.124.191.6迭代 1 模型训练环境日期Wed Jan 10 01:20:10 EST 2023Python 3.9.15ESPnet 202209PyTorch 1.13.0cu117Git hash753f40d61813436d4e76660904d02eaed7a6649eSSL 配置train_ssl_torchaudiohubert_base_960h_pretrain_it1.yaml预训练模型发布在 HuggingFace模型名含simpleoier_librispeech_hubert_iter1_train_ssl_torchaudiohubert_base_960h_pretrain_it1_raw对应的 10h 微调 ASR 模型也已发布模型名含simpleoier_librilight_limited_asr_train_asr_hubert_base_10h_finetuning_raw_en_char。迭代 1 在LibriLight-Limited 10h上微调 ASR 的结果数据集SntWrdCorrSubDelInsErrS.Errdecode_asr_model_valid.loss.ave/dev_clean26945363590.39.30.50.710.474.8decode_asr_model_valid.loss.ave/dev_other28645094883.815.11.11.217.483.9decode_asr_model_valid.loss.ave/test_clean26205257690.29.40.40.710.575.2decode_asr_model_valid.loss.ave/test_other29395234383.615.21.11.317.685.3对比可见经过一轮迭代MFCC 标签 → HuBERT 第 6 层特征、500 类标签四组数据集的词错误率Err均有明显下降如 dev_clean 从 15.5% 降至 10.4%test_clean 从 15.9% 降至 10.5%验证了迭代式伪标签升级对低资源 ASR 微调的巨大收益。更详细的 k-means 性能、准确率与训练曲线可在上述配置对应的实验目录与发布仓库中查看。后续使用下载模型与复现若想直接使用官方预训练模型而不从零训练可利用hubert.sh的--download_model参数指定 Model Zoo 中的模型名后脚本会调用espnet_model_zoo_download解包模型读取ssl_model_file与ssl_train_config并建立符号链接后续 stage 自动以该模型作为上一轮特征抽取来源。整个过程中生成的实验目录exp/hubert_iter*里都写入了可断点续跑的run.sh例如exp/hubert_iter0_*/run.sh --stage 7方便在资源受限时分段执行。实践注意事项GPU 与显存base 模型 it0 配置在 8×A4040GB上训练约 5 天gpu_dump_feature强烈建议开启脚本会打印警告否则 SSL 特征抽取会非常慢k-means 内存learn_kmeans.py步骤通常需要约 120GB 内存请规划足够的主机内存伪标签质量评估提供alignment_phoneme_dir音素对齐 tsv格式utt_id1 a1,a2,a3,...可自动输出伪标签与真实音素的对比质量报告对齐数据可通过本食谱 local/dump_librispeech_alignment_from_textgrid.py 等工具准备长音频--max_wav_duration默认 20 秒run.sh中设为 30 秒以覆盖更长语音迭代数量base 模型训练 1 轮迭代即可取得与 Torchaudio 官方相近的效果run.sh注释原话追求更强表示可继续迭代 2large 配置400 epoch数据组织每轮 k-means 的伪标签以text.km.${km_tag}形式存放于数据目录词典位于data/en_token_list_kmeans_iter${iter}_${feats_km}_${n_clusters}clusters/删除中间迭代产物时请注意区分。综上egs2/librispeech/hubert1是一个结构完整、可复现的 HuBERT 自监督预训练食谱它以 LibriSpeech 960h 为基准数据通过「MFCC → k-means → 预训练 → SSL 特征 → 再聚类 → 再预训练」的迭代闭环持续提升伪标签质量最终在 10h 低资源微调任务上验证了预训练表征的有效性。无论是复现官方结果、替换自有语料还是将预训练模型接入下游 ASR 微调本食谱都是 ESPnet 生态中自监督语音预训练的权威参考起点。赞分享人工智能语音音频深度学习NLP【免费下载链接】espnetEnd-to-End Speech Processing Toolkit项目地址https://gitcode.com/gh_mirrors/es/espnet点击查看免费下载相关推荐ESPnet2 hubert1 配方全解析基于 K-means 伪标签的 HuBERT 自监督预训练流水线ESPnet2 hubert1 配方全解析基于 K means 伪标签的 HuBERT 自监督预训练流水线 本篇技术指南围绕 ESPnet2 的 hubert人工智能语音音频深度学习NLPHuBERT 自监督语音预训练标签生成实战fairseq simple_kmeans 分片特征提取与 K-means 聚类全流程HuBERT 自监督语音预训练标签生成实战fairseq simple_kmeans 分片特征提取与 K means 聚类全流程 本文基于本仓库 kosmos计算机视觉图像处理机器学习fairseq HuBERT 语音自监督预训练实战指南从伪标签数据准备到预训练、CTC 微调与三种解码模式fairseq HuBERT 语音自监督预训练实战指南从伪标签数据准备到预训练、CTC 微调与三种解码模式 本指南以 examples/hubert/READ人工智能深度学习预训练NLP语音上一篇nanoclaw Claude Agent SDK 深度解析query() 如何以流式输入、Hooks 与 Resume 驱动 Claude Code下一篇Nacos 客户端如何使用本地 failover 文件在服务端不可用时降级读取配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考