2026/9/13 2:32:51

EdgeLM (fairseq) 中的 Wav2Vec 2.0 语音自监督预训练:从数据清单、预训练到 CTC 微调的完整实践

EdgeLM (fairseq) 中的 Wav2Vec 2.0 语音自监督预训练:从数据清单、预训练到 CTC 微调的完整实践 EdgeLM (fairseq) 中的 Wav2Vec 2.0 语音自监督预训练从数据清单、预训练到 CTC 微调的完整实践【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm本文以edgelm目录下的 wav2vec 示例文档 为核心讲解如何在该仓库内置的 fairseq 框架中完成 Wav2Vec 2.0 的完整流程准备音频数据清单、执行自监督预训练base/large 模型、GPU 与 TPU、用 CTC 标准微调预训练模型、以及结合语言模型进行解码评测。读完本文你将掌握wav2vec_manifest.py清单构建脚本的工作原理、examples/wav2vec/config下预训练与微调配置文件中各参数的含义以及如何通过distributed_world_size与update_freq组合模拟大规模 GPU 集群。一、Wav2Vec 系列三个模型与它们的定位该文档覆盖 fairseq 中三个自监督语音模型对应三篇论文Wav2Vec 2.0Baevski et al., 2020在无标注音频上学习语音表征是当前示例的主线Wav2Vec 1Schneider et al., 2019较早的非自编码器式预训练vq-wav2vecBaevski et al., 2019通过向量量化Gumbel 或 K-means学习离散语音码本可作为 BERT 式词元化训练的数据源。此外文档还引用了基于 XLSR 的多语言工作在多语言预训练XLSR-5356k 小时、53 种语言基础上将预训练与自训练self-training结合的鲁棒性研究以及面向未见语言的零样本跨语言音素识别在 CommonVoice 与 Babel 数据上微调的 26 语/21 语/40 语模型。XLSR 模型使用的多语言语料包括MLS: Multilingual LibriSpeech8 种语言50.7k 小时荷兰语、英语、法语、德语、意大利语、波兰语、葡萄牙语、西班牙语CommonVoice36 种语言3.6k 小时Babel17 种语言1.7k 小时。零样本微调模型分为两组音素化器PhonemizerEspeak26 语言与 Phonetisaurus21/40 语言。虽然音素都是 IPA 符号但两种音素化器的转写仍存在细微差异因此应当选用与你数据所用音素化器对应的模型与发音词典dictionary。二、准备预训练数据清单wav2vec_manifest.py预训练需要一个包含音频文件的目录文档建议将每个文件切分为 10 到 30 秒的独立片段。第一步是安装soundfile依赖并生成清单pip install soundfile $ python examples/wav2vec/wav2vec_manifest.py /path/to/waves --dest /manifest/path --ext $ext --valid-percent $valid脚本 wav2vec_manifest.py 的实际参数由源码确认比文档描述更完整参数默认值说明root位置参数必填包含音频文件的根目录--dest.输出目录脚本会自动创建--extflac要索引的音频扩展名flac、wav 等须为 soundfile 可读格式--valid-percent0.01划入验证集的数据比例0 到 1 之间--seed42随机种子保证划分可复现--path-must-containNone若设置仅包含路径含该子串的文件从源码结构看wav2vec_manifest.py清单生成逻辑是以glob.iglob递归搜索root下所有*.$ext文件对每个文件用soundfile.info(fname).frames读取帧数然后按rand.random() valid_percent将文件相对路径与帧数写入train.tsv或valid.tsv。TSV 首行写入目录的绝对路径后续每行为相对路径TAB帧数。因此若想使用预定义的验证集如 Librispeech 的 dev-other应把--valid-percent设为 0再单独预处理一份清单覆盖valid.tsv--path-must-contain参数在文档中未提及但可用于只索引某个子集的音频例如只处理某说话人、某子集。三、预训练 Wav2Vec 2.0base 与 large 模型输入音频要求为单通道、16 kHz 采样。预训练通过fairseq-hydra-train执行配置文件位于 config/pretraining 目录。3.1 base 模型$ fairseq-hydra-train \ task.data/path/to/data \ --config-dir /path/to/fairseq-py/examples/wav2vec/config/pretraining \ --config-name wav2vec2_base_librispeech这是 wav2vec 2.0 论文中在 Librispeech 上训练 base 模型所用的配置。对照 wav2vec2_base_librispeech.yaml关键参数为taskaudio_pretrainingmax_sample_size: 250000、min_sample_size: 32000约 15.6 秒与 2 秒控制批内音频裁剪长度normalize: falsecriterionwav2vecinfonce: trueGumbel 对比损失的 InfoNCE 形式loss_weights: [0.1, 10]优化Adamadam_betas: (0.9, 0.98)、adam_eps: 1e-06、weight_decay: 0.01学习率[0.0005]max_update: 400000polynomial_decay学习率调度、warmup_updates: 32000modelwav2vec2quantize_targets: trueGumbel 量化目标final_dim: 256、encoder_embed_dim: 768正则项encoder_layerdrop: 0.05、dropout_input: 0.1、dropout_features: 0.1、feature_grad_mult: 0.1特征提取器梯度缩放抑制其更新速度分布式distributed_world_size: 64、ddp_backend: legacy_ddp。文档提示若只有 k 块 GPU可在--config-dir之前追加distributed_training.distributed_world_sizek与optimization.update_freq[x]x 64/k来模拟 64 GPU 的等效批大小。3.2 large 模型$ fairseq-hydra-train \ task.data/path/to/data \ --config-dir /path/to/fairseq-py/examples/wav2vec/config/pretraining \ --config-name wav2vec2_large_librivox这是论文中在 Libri-light 上训练 large 模型的配置。wav2vec2_large_librivox.yaml 与 base 的主要差异配置项base (Librispeech)large (Libri-light)task.max_sample_size250000320000task.normalizefalsetruecriterion.loss_weights[0.1, 10][0.1, 0]optimization.lr/max_update0.0005 / 4000000.005 / 1000000dataset.max_tokens14000001200000另加batch_size: 4model.final_dim/encoder_embed_dim256 / 768768 / 1024model.encoder_layers/ ffn / heads默认 12 层24 层 / 4096 / 16 头正则项layerdrop、dropout 等0.05 / 0.1 / 0.1全部 0.0feature_grad_mult0.11.0distributed_world_size64128从源码 Wav2Vec2Config 可以看到这些参数的默认值encoder_layers: 12、encoder_embed_dim: 768、encoder_ffn_embed_dim: 3072、encoder_attention_heads: 12、latent_vars: 320码本每组码字数量 V、latent_groups: 2码本组数 G、conv_feature_layers默认为[(512, 10, 5)] [(512, 3, 2)] * 4 [(512,2,2)] [(512,2,2)]。large 配置中显式覆盖了latent_temp: [2.0, 0.1, 0.999995]Gumbel-Sigmoid 的初始温度、最终温度与衰减率并启用extractor_mode: layer_norm与layer_norm_first: true——这与task.normalize: true是配套设计源码注释指出 layer_norm 模式应配合 normalizeTrue 使用。模拟 128 GPU 的方式同上x 128/k。3.3 预训练任务的数据配置audio_pretraining任务由 AudioPretrainingTask 注册注册名audio_pretraining。从 AudioPretrainingConfig 的定义可以看到sample_rate默认 16000音频会自动上/下采样到该速率、binarized_dataset支持超大语料的二值化数据对应 binarize_manifest.sh、num_batch_buckets用于分桶批处理、enable_padding选择对短样本 padding 而非裁剪且 TPU 训练需要inferred_w2v_config预计算 mask 索引。3.4 在 Google Cloud TPU 上预训练Wav2Vec 2.0 在该仓库中支持 TPU仅预训练。v3-8 上通过 hydra$ OMP_NUM_THREADS1 fairseq-hydra-train \ task.data/manifest/path \ --config-dir /PATH/TO/FAIRSEQ/examples/wav2vec/config/pretraining \ --config-name wav2vec2_large_librivox_tpu.yaml对应配置文件为 wav2vec2_large_librivox_tpu.yaml 与 wav2vec2_large_librivox_tpu-pod.yamlpod 切片 v3-NN 8 时需相应修改distributed_world_size。也可以直接用命令行参数文档注明该方式当时存在已知问题$ OMP_NUM_THREADS1 python train.py /manifest/path --save-dir /model/path --num-workers 6 --fp16 --max-update 400000 --save-interval 1 --no-epoch-checkpoints \ --arch wav2vec2 --task audio_pretraining --min-lr 1e-06 --stop-min-lr 1e-09 --optimizer adam --lr 0.005 --lr-scheduler cosine \ --conv-feature-layers [(512, 10, 5), (512, 8, 4), (512, 4, 2), (512, 4, 2), (512, 4, 2), (512, 1, 1), (512, 1, 1)] \ --conv-aggregator-layers [(512, 2, 1), (512, 3, 1), (512, 4, 1), (512, 5, 1), (512, 6, 1), (512, 7, 1), (512, 8, 1), (512, 9, 1), (512, 10, 1), (512, 11, 1), (512, 12, 1), (512, 13, 1)] \ --skip-connections-agg --residual-scale 0.5 --log-compression --warmup-updates 500 --warmup-init-lr 1e-07 --criterion wav2vec --num-negatives 10 \ --max-sample-size 150000 --max-tokens 1500000 --skip-invalid-size-inputs-valid-test \ --tpu --distributed-world-size 8 --num-batch-buckets 3 --enable-padding \ --encoder-layerdrop 0 --mask-channel-prob 0.1pod 切片方式则用python -m torch_xla.distributed.xla_dist --tpu ${TPUNAME} ...启动模型参数相同--distributed-world-size按实际 pod 大小设置。四、用 CTC 微调预训练模型微调需要并行对齐的音频-转写对以及 fairseq 格式的词汇表文件字母级词汇表 dict.ltr.txt 随项目发布。文档提供了一个从wav2vec_manifest.py产出的 TSV 文件为 Librispeech 生成标签的脚本 libri_labels.pysplittrain $ python libri_labels.py /path/to/tsv --output-dir /output/dir --output-name $split在 100h Librispeech 上以字母为目标微调$ fairseq-hydra-train \ distributed_training.distributed_port$PORT \ task.data/path/to/data \ model.w2v_path/path/to/model.pt \ --config-dir /path/to/fairseq-py/examples/wav2vec/config/finetuning \ --config-name base_100h微调配置目录 config/finetuning 下共有 10 个配置文件覆盖 10m/1h/10h/100h/960h 五个数据量级并区分 basebase_*与 Libri-Light 60k 小时预训练vox_*两组可通过--config-name选择。以 base_100h.yaml 为例其结构与预训练配置有本质不同taskaudio_finetuninglabels: ltr读取字母标签扩展名验证子集dev_othermodelwav2vec_ctc关键项w2v_path: ???命令行注入预训练权重路径、apply_mask: true与通道掩码mask_channel_prob: 0.5、mask_channel_length: 64微调阶段保留掩码增强、feature_grad_mult: 0.0冻结特征提取器、freeze_finetune_updates: 0criterionctczero_infinity: true把 -inf logit 置 0避免数值问题优化max_update: 80000、lr: [0.00003]、sentence_avg: true、update_freq: [4]tri_stage学习率调度phase_ratio: [0.1, 0.4, 0.5]、final_lr_scale: 0.05checkpoint 以wer为最优指标。对比 base_10m.yaml 可以看到数据量对微调策略的影响10 分钟微调只训max_update: 13000步学习率提高到0.00005通道掩码概率降为0.25且freeze_finetune_updates: 10000——即先冻结编码器 10000 步只训练 CTC 头再解冻这是小数据微调防止灾难性遗忘的关键手段。model.w2v_path与task.data在配置中均为???MISSING必须从命令行传入这正是上面命令中model.w2v_path/path/to/model.pt的由来。GPU 规模模拟微调配置默认distributed_world_size: 2若要模拟 24 GPU同样在--config-dir前加distributed_training.distributed_world_sizek与optimization.update_freq[x]x 24/k。关于语言模型解码训练中加入语言模型需要安装 flashlight 的 Python 绑定原 wav2letter并在命令行加criterion.wer_args[/path/to/kenlm, /path/to/lexicon, 2, -1]。五、评测 CTC 模型带语言模型的评测同样依赖 flashlight 绑定。论文使用的 Transformer 语言模型来自 wav2letter 模型库2019 SOTA 配方下载后记得将语言模型词汇表全部转为大写字母词典使用与预训练模型配套的 dict.ltr.txt。评测命令注意此处调用的是仓库内train.py同级的推理脚本入口为examples/speech_recognition/infer.py$subsetdev_other python examples/speech_recognition/infer.py /checkpoint/abaevski/data/speech/libri/10h/wav2vec/raw --task audio_finetuning \ --nbest 1 --path /path/to/model --gen-subset $subset --results-path /path/to/save/results/for/sclite --w2l-decoder kenlm \ --lm-model /path/to/kenlm.bin --lm-weight 2 --word-score -1 --sil-weight 0 --criterion ctc --labels ltr --max-tokens 4000000 \ --post-process letter解码器三种选择--w2l-decoder kenlmKenLM 语言模型 发音词典、--w2l-decoder viterbi不做语言模型 rescoring 的原始分数省略词典即可、--w2l-decoder fairseqlmfairseq Transformer 语言模型。--post-process letter表示字母级后处理。六、用 Transformers 使用 Wav2Vec 2.0Wav2Vec 2.0 自 Transformers 4.4 起也被支持预训练模型可下载文档与 Hub 页面见其官方仓库。文档给出的最小推理与微调示例# !pip install transformers # !pip install datasets import soundfile as sf import torch from datasets import load_dataset from transformers import Wav2Vec2ForCTC, Wav2Vec2Processor # load pretrained model processor Wav2Vec2Processor.from_pretrained(facebook/wav2vec2-base-960h) model Wav2Vec2ForCTC.from_pretrained(facebook/wav2vec2-base-960h) librispeech_samples_ds load_dataset(patrickvonplaten/librispeech_asr_dummy, clean, splitvalidation) # load audio audio_input, sample_rate sf.read(librispeech_samples_ds[0][file]) # pad input values and return pt tensor input_values processor(audio_input, sampling_ratesample_rate, return_tensorspt).input_values # INFERENCE # retrieve logits take argmax logits model(input_values).logits predicted_ids torch.argmax(logits, dim-1) # transcribe transcription processor.decode(predicted_ids[0]) # FINE-TUNE target_transcription A MAN SAID TO THE UNIVERSE I EXIST # encode labels with processor.as_target_processor(): labels processor(target_transcription, return_tensorspt).input_ids # compute loss by passing labels loss model(input_values, labelslabels).loss loss.backward()该路径与 fairseq 原生流程互补Transformers 适合快速推理与 HuggingFace 生态集成fairseq 原生流程第三节起则支持从零预训练、大规模分布式训练与 KenLM rescoring 评测。七、Wav2Vec 1 与 vq-wav2vec离散表征路线7.1 Wav2Vec 1预训练模型 Wav2Vec large 在 Librispeech 上训练。用法示例通过 fairseq checkpoint 工具加载import torch import fairseq cp_path /path/to/wav2vec.pt model, cfg, task fairseq.checkpoint_utils.load_model_ensemble_and_task([cp_path]) model model[0] model.eval() wav_input_16khz torch.randn(1,10000) z model.feature_extractor(wav_input_16khz) c model.feature_aggregator(z)训练命令非 hydra直接train.py--arch wav2vec对应 Wav2VecModel$ python train.py /manifest/path --save-dir /model/path --num-workers 6 --fp16 --max-update 400000 --save-interval 1 --no-epoch-checkpoints \ --arch wav2vec --task audio_pretraining --min-lr 1e-06 --stop-min-lr 1e-09 --optimizer adam --lr 0.005 --lr-scheduler cosine \ --conv-feature-layers [(512, 10, 5), (512, 8, 4), (512, 4, 2), (512, 4, 2), (512, 4, 2), (512, 1, 1), (512, 1, 1)] \ --conv-aggregator-layers [(512, 2, 1), (512, 3, 1), (512, 4, 1), (512, 5, 1), (512, 6, 1), (512, 7, 1), (512, 8, 1), (512, 9, 1), (512, 10, 1), (512, 11, 1), (512, 12, 1), (512, 13, 1)] \ --skip-connections-agg --residual-scale 0.5 --log-compression --warmup-updates 500 --warmup-init-lr 1e-07 --criterion wav2vec --num-negatives 10 \ --max-sample-size 150000 --max-tokens 1500000 --skip-invalid-size-inputs-valid-test训练完成后可以从下游任务数据中提取嵌入表示$ PYTHONPATH/path/to/fairseq python examples/wav2vec/wav2vec_featurize.py --input /path/to/task/waves --output /path/to/output \ --model /model/path/checkpoint_best.pt --split train valid test对应脚本为 wav2vec_featurize.py。7.2 vq-wav2vecGumbel 与 K-means 码本vq-wav2vec 学习离散语音码。预训练模型包括 Gumbel 与 K-means 两种量化方式以及基于 K-means 码训练的 Roberta。用法示例import torch import fairseq cp torch.load(/path/to/vq-wav2vec.pt) model, cfg, task fairseq.checkpoint_utils.load_model_ensemble_and_task([cp]) model model[0] model.eval() wav_input_16khz torch.randn(1,10000) z model.feature_extractor(wav_input_16khz) _, idxs model.vector_quantizer.forward_idx(z) print(idxs.shape) # output: torch.Size([1, 60, 2]), 60 timesteps with 2 indexes corresponding to 2 groups in the model输出形状[1, 60, 2]的含义输入 1 秒 16kHz 音频经卷积下采样后得到 60 个时间步每个时间步输出 2 个码字索引对应码本的 2 个组。Gumbel 变体的训练命令与 Wav2Vec 1 的差异在 vq 相关参数$ python train.py /manifest/path --save-dir /model/path --num-workers 6 --fp16 --max-update 400000 \ --save-interval 1 --no-epoch-checkpoints --arch wav2vec --task audio_pretraining --min-lr 1e-06 --stop-min-lr 1e-09 \ --optimizer adam --lr 1e-05 --lr-scheduler cosine \ --conv-feature-layers [(512, 10, 5), (512, 8, 4), (512, 4, 2), (512, 4, 2), (512, 4, 2), (512, 1, 1), (512, 1, 1), (512, 1, 1)] \ --conv-aggregator-layers [(512, 2, 1), (512, 3, 1), (512, 4, 1), (512, 5, 1), (512, 6, 1), (512, 7, 1), (512, 8, 1), (512, 9, 1), (512, 10, 1), (512, 11, 1), (512, 12, 1), (512, 13, 1)] \ --activation gelu --offset auto --skip-connections-agg --residual-scale 0.5 \ --log-keys [prob_perplexity,code_perplexity,temp] --vq-type gumbel --vq-groups 2 --vq-depth 2 \ --combine-groups --vq-vars 320 --vq-temp (2,0.5,0.999995) --prediction-steps 12 --warmup-updates 1000 \ --warmup-init-lr 1e-07 --criterion wav2vec --num-negatives 10 --max-sample-size 150000 \ --max-tokens 300000 --cross-sample-negatives 0 --update-freq 1 --seed 2 --skip-invalid-size-inputs-valid-test关键 vq 参数解读--vq-type gumbel或kmeansK-means 训练需追加--loss-weights [1]、--vq-groups 2码本组数 G、--vq-depth 2量化器层数、--combine-groups组间拼接共享、--vq-vars 320每组码字数 V、--vq-temp (2,0.5,0.999995)初始温度 2、最终温度 0.5、衰减率 0.999995、--log-keys中code_perplexity监控码本使用效率。预训练模型在 16 GPU 上训练。得到离散码后可将音频词元化用于 BERT 训练$ PYTHONPATH/path/to/fairseq python examples/wav2vec/vq-wav2vec_featurize.py --data-dir /manifest/path --output-dir /path/to/output \ --checkpoint /model/path/checkpoint_best.pt --split train valid test --extension tsv对应脚本为 vq-wav2vec_featurize.py。八、预训练模型清单与适用场景文档列出了完整的模型矩阵。核心结论可归纳为三类Librispeech 预训练base/large × 无微调/10m/100h/960h研究预训练 少量标注数据可扩展性曲线的首选Libri-Light LV-60 60k 小时预训练含 self-training 版本论文主结果的模型self-training 版本*_pl.pt在同等标注量下通常更优多域混合LV-60 CommonVoice Switchboard Fisherw2v_large_lv_fsh_swbd_cv*面向域偏移鲁棒性的模型提供直接预训练权重与在 Librispeech 960h、Switchboard 300h 上微调后的版本。多语言方面XLSR-53large56k 小时53 语言是唯一列出的多语言预训练模型其上微调的零样本音素识别模型按音素化器分为 Espeak 26 语LV-60 与 XLSR-53 两个版本与 Phonetisaurus 21 语/40 语两个版本并配套对应发音词典文件。选型要点如果你的转写是用 Espeak 音素化的就用 espeak 版本模型与 espeak 词典用 Phonetisaurus 音素化的则选 phonetisaurus 版本因为两者的 IPA 转写存在细微差别。九、实践检查清单综合文档与源码落地流程可归纳为音频切分为 10–30 秒片段统一为 16 kHz 单通道pip install soundfile后运行wav2vec_manifest.py生成train.tsv/valid.tsv注意--ext与实际格式一致用预定义验证集时--valid-percent 0并自行覆盖valid.tsv预训练选wav2vec2_base_librispeech或wav2vec2_large_librivox按 GPU 数量调整distributed_world_size与update_freq乘积保持等效批大小微调前用libri_labels.py或同类脚本从 TSV 生成 fairseq 格式字母标签选与数据量匹配的base_*/vox_*微调配置通过model.w2v_path注入预训练权重评测用examples/speech_recognition/infer.py按需在kenlm/viterbi/fairseqlm三种解码方式间切换若目标是离散表征下游做 BERT 式建模走 vq-wav2vec 路线并用vq-wav2vec_featurize.py词元化。所有配置文件均可在 edgelm/examples/wav2vec/config 下直接查看pretraining 4 个、finetuning 10 个模型实现位于 wav2vec2.py、wav2vec.py 与微调模型 wav2vec2_asr.py任务实现位于 audio_pretraining.py 与 audio_finetuning.py可作为进一步定制参数时的源码依据。【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考