SpeechLM:语音与未配对文本双分支联合预训练的技术解析与 ASR/ST 实战指南
【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm
本文围绕 SpeechLM(Enhanced Speech Pre-Training with Unpaired Textual Data)的官方使用文档展开,讲解如何利用其清洗后的 checkpoint 直接提取各层语音表征,并完整覆盖 ASR(LibriSpeech)、语音翻译(CoVoST-2)微调与从零预训练的全套命令与配置;同时结合仓库源码,深入剖析“语音分支 + 单元编码器文本分支”双分支架构、预训练损失构成与 Base/Large 配置差异,帮助读者既能照抄命令跑通流程,也能理解每个参数在底层代码中的实际作用。
1. SpeechLM 的核心思路
SpeechLM 针对自监督语音预训练长期依赖“大规模带转录音频”的瓶颈,提出了一个关键机制:在预训练阶段同时利用未配对(unpaired)文本数据。其做法是将文本先转换(tokenize)成与语音同构的“离散单元序列”(音素序列 phn 或隐藏单元序列 km),再喂给一个与语音编码器共享目标的单元编码器(unit encoder),使模型在只有语音、只有文本、以及两者混合的 batch 上都能进行掩码预测训练。仓库中这一机制由以下文件共同实现:
- speechlm/speechlm/models/speechlm.py:完整训练版模型(
joint_sc2t_pretrainingtask 使用); - speechlm/speechlm/tasks/joint_sc2t_pretrain.py:联合“语音 + 文本”数据的任务定义;
- speechlm/speechlm/criterions/speechlm_criterion.py:多目标损失函数;
- speechlm/SpeechLM.py:面向推理的独立精简版,合并了全部特征提取所需代码,不依赖 fairseq。
文档中的模型命名规则为:SpeechLM-P(phoneme 音素单元)与SpeechLM-H(hidden-unit 隐藏单元),Base(960h LibriSpeech 预训练)与Large(60k h LibriLight 预训练)。所有模型均额外混合了 40M 规模的文本数据进行预训练。
2. 预训练与微调模型清单
原始文档给出的完整模型列表如下(下载链接分别托管于 Google Drive 与 OneDrive,具体地址以 speechlm/speechlm_READme.md 中的链接为准):
| 模型 | 预训练数据 | 微调数据 |
|---|---|---|
| SpeechLM-P Base | 960h LibriSpeech + 40M 文本 | 无(原始预训练模型) |
| SpeechLM-P Base | 960h LibriSpeech + 40M 文本 | 100h LibriSpeech(ASR) |
| SpeechLM-H Base | 960h LibriSpeech + 40M 文本 | 无(原始预训练模型) |
| SpeechLM-H Base | 960h LibriSpeech + 40M 文本 | 100h LibriSpeech(ASR) |
| SpeechLM-P Base | 960h LibriSpeech + 40M 文本 | CoVoST-2 En→De |
| SpeechLM-P Base | 960h LibriSpeech + 40M 文本 | CoVoST-2 En→Ca |
| SpeechLM-P Base | 960h LibriSpeech + 40M 文本 | CoVoST-2 En→Ar |
| SpeechLM-P Base | 960h LibriSpeech + 40M 文本 | CoVoST-2 En→Tr |
| SpeechLM-P Large | 60k h LibriLight + 40M 文本 | 无(原始预训练模型) |
| SpeechLM-P Large | 60k h LibriLight + 40M 文本 | 960h LibriSpeech(ASR) |
| SpeechLM-P Large | 60k h LibriLight + 40M 文本 | CoVoST-2 En→De / En→Ca / En→Ar / En→Tr |
此外,文档还单独提供了清洗版(cleaned)checkpoint(移除非推理必需模块后重新打包),共三个:SpeechLM-P Base、SpeechLM-H Base、SpeechLM-P Large。这些 checkpoint 是下一节特征提取的入口,因为 speechlm/SpeechLM.py 就是按它们的状态字典结构来组织的。
3. 使用清洗版 Checkpoint 提取语音特征
文档给出的官方用法(可直接复制运行):
import torch import torch.nn.functional as F from SpeechLM import SpeechLMConfig, SpeechLM checkpoint = torch.load('path/to/the/cleaned/checkpoint.pt') cfg = SpeechLMConfig(checkpoint['cfg']['model']) model = SpeechLM(cfg) model.load_state_dict(checkpoint['model']) model.eval() wav_input_16khz = torch.randn(1,10000) normalize = checkpoint['cfg']['task']['normalize'] # False for base model, True for large model if normalize: wav_input_16khz = F.layer_norm(wav_input_16khz[0], wav_input_16khz[0].shape).unsqueeze(0) # extract the representation of last layer rep = model.extract_features(wav_input_16khz)[0] # extract the representation of each layer output_layer = model.cfg.encoder_layers + model.cfg.text_transformer.encoder.layers rep, layer_results = model.extract_features(wav_input_16khz, output_layer=output_layer, ret_layer_results=True)[0] layer_reps = [x.transpose(0, 1) for x in layer_results]使用要点:
- 输入是 16 kHz 原始波形,形状
(B, T),无需提特征;模型内部由卷积特征提取器完成下采样。 - normalize 开关必须与预训练时一致:从预训练配置看,Base 模型 speechlm/speechlm/config/pretrain/speechlm_base_librispeech.yaml 中
task.normalize: false,Large 模型 speechlm/speechlm/config/pretrain/speechlm_large_librilight.yaml 中为normalize: true(extractor_mode也从default换成了layer_norm)。因此 Large 模型推理前必须做逐样本 layer_norm,Base 模型不能做。 - 逐层表征提取:
output_layer = encoder_layers + text_transformer.encoder.layers表示取“最后一层”。这里暴露了架构信息——SpeechLM 的完整前向包含语音编码器 + 单元编码器两段串联,所以层编号是两段相加。extract_features(..., ret_layer_results=True)返回所有中间层,layer_results中每个张量形状为(T, B, D),示例代码将其转置回(B, T, D)方便使用。
3.1 源码解读:SpeechLM.py的推理路径
SpeechLMConfig 定义了全部结构超参的默认值,被 checkpoint 中的cfg['model']覆盖。几个值得注意的参数:
label_rate:默认 50(20 ms 帧率),但 Base 预训练脚本实际以model.label_rate=100(10 ms)覆盖,见 base_speechlmp.sh;conv_feature_layers: "[(512,10,5)] + [(512,3,2)] * 4 + [(512,2,2)] * 2":wav2vec 2.0 风格的 8 层卷积,总下采样率为 5×2^6=320,即 16 kHz 波形约每 20 ms 一个特征帧;final_dim: 256:预测投影维度;add_unit_encoder / mix_with_unit / use_pred_unit / l2_embedding:控制文本分支行为。
SpeechLM.forward按输入分派两条路径(speechlm/SpeechLM.py#L419-L446):
forward_speech:卷积特征提取 → 掩码 → 语音 Transformer 编码器 → (若add_unit_encoder=True)把语音编码器输出经convert_embeddings与单元嵌入混合后,送入unit_encoder(第二段 Transformer 编码器),并对两段输出分别计算掩码预测 logits;forward_text:纯文本路径,将单元 token 嵌入后走同样的掩码预测,用于训练时的纯文本 batch。
特征提取走extract_features(speechlm/SpeechLM.py#L590-L633):以features_only=True, mask=False前向,语音输出为x;当output_layer超过cfg.encoder_layers时,会自动把语音编码器输出接入unit_encoder继续前向,这正是能取到“第 6~18 层(语音 6 层 + 文本 12 层)”这类层索引的原因。另外forward_targets中的feat2tar_ratio = label_rate × 320 / 16000(speechlm/SpeechLM.py#L153-L155)用于把特征帧与标签序列对齐,推理时不需要标签,故可忽略。
4. 环境准备(Setup)
文档给出的环境搭建步骤:
git submodule update --init SpeechLM/fairseq cd SpeechLM/ pip install --editable fairseq/ pip install sacrebleu==1.5.1对应当前仓库的实际情况需要说明两点:
- 本仓库中 SpeechLM 位于
speechlm/目录下,fairseq 是 git submodule,仓库快照中 speechlm/fairseq 为空目录——必须先执行上述git submodule update --init拉取依赖才能训练/微调; - 文档中的命令路径
SpeechLM/...对应到本仓库即speechlm/speechlm/...,例如文档写speechlm/scripts/tune_speechlm_asr/finetune_base_ctc.sh,实际文件是 speechlm/speechlm/scripts/tune_speechlm_asr/finetune_base_ctc.sh。后文所有命令均按仓库实际路径给出。
sacrebleu==1.5.1是 ST 任务评估 BLEU 所需。训练/微调本身通过 fairseq 的 Hydra 入口fairseq_cli/hydra_train.py启动,配置目录指向speechlm/speechlm/config/。
5. LibriSpeech 上的 ASR 微调
5.1 数据准备
按 wav2vec 2.0 的 manifest 规范准备train.tsv(音频清单)与train.ltr(字母标签),并确认词表与预训练模型一致。词表文件即 speechlm/dataset/LibriSpeech/asr/dict.ltr.txt,示例数据见 speechlm/dataset/LibriSpeech/asr 下的train_sample100.tsv/train_sample100.ltr(各取 100 条样例)。把准备好的数据放入$data_dir。
5.2 微调 CTC 模型
Base 模型:
# Usage: speechlm/scripts/tune_speechlm_asr/finetune_base_ctc.sh <model_path> <data_dir> <cpt_tag> [mount=$PWD] [world_size=8] [update_freq=1] model_path=path/to/your/pre-trained/model data_dir=dataset/LibriSpeech/asr bash speechlm/speechlm/scripts/tune_speechlm_asr/finetune_base_ctc.sh $model_path $data_dir 'tag400k'Large 模型:
# Usage: speechlm/scripts/tune_speechlm_asr/finetune_large_ctc.sh <model_path> <data_dir> <cpt_tag> [mount=$PWD] [world_size=8] [update_freq=4] model_path=path/to/your/pre-trained/model data_dir=dataset/LibriSpeech/asr bash speechlm/speechlm/scripts/tune_speechlm_asr/finetune_large_ctc.sh $model_path $data_dir 'tag400k'
从配置文件可以读出两套微调的默认设置,Base 与 Large 差异明显:
| 配置项 | Base(100h) | Large(960h) |
|---|---|---|
| 配置文件 | speechlm_base_100h.yaml | speechlm_large_960h.yaml |
| 训练/验证子集 | train_100/dev_other | train_960/dev_other |
| 最大更新步数 | 30000 | 200000 |
| 学习率 | 1e-5(sentence_avg) | 1e-5(sentence_avg) |
归一化task.normalize | false | true |
| 模型 / 损失 | speechlm_ctc+ctc(zero_infinity: true) | 同左 |
| 学习率调度 | tri_stage,phase_ratio [0.1, 0.4, 0.5],final_lr_scale 0.05 | 同左 |
| 掩码(微调期) | apply_mask: true,mask_prob 0.65,mask_channel_prob 0.5(长度 64),feature_grad_mult: 0.0(冻结特征提取器) | 同左 |
其中model.w2v_path指向预训练权重(由脚本传入),best_checkpoint_metric: wer表示按 WER 保留最佳 checkpoint。feature_grad_mult: 0.0意味着微调时卷积特征提取器不更新,这与 SpeechLM.py 中forward_features的分支一致:系数为 0 时在torch.no_grad()下提特征。
5.3 解码
直接 CTC 解码(Viterbi):
# Usage: speechlm/scripts/tune_speechlm_asr/inference_ctc.sh <model_path> <data_dir> [gen-set=dev_clean,dev_other,test_clean,test_other] model_path=path/to/your/fine-tuned/model data_dir=dataset/LibriSpeech/asr bash speechlm/speechlm/scripts/tune_speechlm_asr/inference_ctc.sh $model_path $data_dir # for large models # bash speechlm/speechlm/scripts/tune_speechlm_asr/inference_ctc_large.sh $model_path $data_dir4-gram 语言模型解码:基于 Flashlight 与 kenlm 实现。需把 LibriSpeech LM 语料的 4-gram arpa 模型与 word-to-letter 词典(librispeech_lexicon.lst,文档中给出托管链接)放入
$data_dir,然后:# Usage: speechlm/scripts/tune_speechlm_asr/inference_ctc_kenlm.sh <model_path> <data_dir> [gen-set=dev_clean,dev_other,test_clean,test_other] bash speechlm/speechlm/scripts/tune_speechlm_asr/inference_ctc_kenlm.sh $model_path $data_dirLarge 模型 + fairseq 词级 LM 解码:把
lm_librispeech_word_transformer.pt及其词表dict.txt放入$data_dir/fairseq_word_lm(dict.txt需大写化处理以兼容 word-to-letter 词典),word-to-letter 词典放入$data_dir:# Usage: speechlm/scripts/tune_speechlm_asr/inference_ctc_large_fsqlm.sh <model_path> <data_dir> [gen-set=dev_clean,dev_other,test_clean,test_other] bash speechlm/speechlm/scripts/tune_speechlm_asr/inference_ctc_large_fsqlm.sh $model_path $data_dir dev_other解码侧的三种解码器配置分别对应 speechlm/speechlm/config/decode/ 下的
infer_viterbi.yaml、infer_kenlm.yaml、infer_fsqlm.yaml。
6. CoVoST-2 上的语音翻译(ST)微调
6.1 数据准备
下载 Common Voice 4 版英语音频到
$cv_root/en;运行清单生成脚本(完成 mp3→波形转换、生成语音-翻译 tsv、生成数据配置文件):
lang=de # ca,ar,tr cv_root=dataset/CommonVoice/v4 bash speechlm/speechlm/data_process/prepare_covost2_enxx.sh $lang $cv_root生成逻辑见 speechlm/speechlm/data_process/prepare_covost2_enxx.sh 与 covost2/prepare_covost_data.py、covost2/mp3_to_wav.py。文档提供的示例数据在 speechlm/dataset/CommonVoice/v4/en/en-de,其中:
- config_base_ende.yaml 指定 sentencepiece 模型
spm_char_st_en_de.model、字符级词表spm_char_st_en_de.txt、16 kHz 采样、use_audio_input: true; dev-sample100_st_en_de_local.tsv是 100 条的 dev 样例清单。
- config_base_ende.yaml 指定 sentencepiece 模型
6.2 微调 Encoder-Decoder 模型
Base 模型(产出存于
$mount/exp/finetune_covost):model_path=path/to/your/pre-trained/model lang=de # ca,ar,tr data_dir=dataset/CommonVoice/v4/en/en-${lang} # Usage (Base model): speechlm/scripts/tune_speechlm_st/ft_base_covost_enxx.sh <model_path> <data_dir> <lang> <cpt-tag> [mount=$PWD] [world_size=8] [update_freq=2] bash speechlm/speechlm/scripts/tune_speechlm_st/ft_base_covost_enxx.sh $model_path $data_dir $lang 'tag400k'Large 模型(默认
update_freq=4):# Usage (Large model): speechlm/scripts/tune_speechlm_st/ft_large_covost_enxx.sh <model_path> <data_dir> <lang> <cpt-tag> [mount=$PWD] [world_size=8] [update_freq=4] bash speechlm/speechlm/scripts/tune_speechlm_st/ft_large_covost_enxx.sh $model_path $data_dir $lang 'tag400k'
从源码结构看,ST 模型是 speechlm/speechlm/models/speechlm_st.py 中的编码器-解码器结构:其配置类SpeechLMS2TConfig继承自 Hubert 系 ASR 配置,新增decoder_embed_dim: 768、decoder_layers: 6、decoder_attention_heads: 12等参数,并默认开启解码器相对位置编码(use_rel_pos_enc: true),即复用预训练的语音编码器再接一个自回归解码器做翻译。
6.3 解码
# Usage: speechlm/scripts/tune_speechlm_st/inference_base.sh <model_path> <data_dir> <lang> [gen-set=dev] [beam_size=5] model_path=path/to/your/fine-tuned/model lang=de # ca,ar,tr data_dir=dataset/CommonVoice/v4/en/en-${lang} bash speechlm/speechlm/scripts/tune_speechlm_st/inference_base.sh $model_path $data_dir $lang devLarge 模型同理:
# Usage: speechlm/scripts/tune_speechlm_st/inference_large.sh <model_path> <data_dir> <lang> [gen-set=dev] [beam_size=5] bash speechlm/speechlm/scripts/tune_speechlm_st/inference_large.sh $model_path $data_dir $lang dev默认 beam_size=5,评估 BLEU 依赖第 4 节安装的 sacrebleu。
7. 从零预训练
7.1 三类模型的预训练脚本
所有预训练均要求先按下一节“Tokenizers”准备语音单元标签与文本单元数据。产出 checkpoint 存于$mount/pretrain。
SpeechLM-P Base(脚本 base_speechlmp.sh):
data_dir=dataset/LibriSpeech/phone_unit # should contain train_960.{tsv,phn} text_data_dir=dataset/LibriLM/phone_unit/bin-idx # should contain train_text.phn-ltr.{phn,ltr}.{bin,idx} # Usage: speechlm/scripts/pretrain_speechlm/base_speechlmp.sh <data_dir> <text_data_dir> [mount=$PWD] [world_size=32] [update_freq=1] bash speechlm/speechlm/scripts/pretrain_speechlm/base_speechlmp.sh $data_dir $text_data_dirSpeechLM-H Base:
data_dir=dataset/LibriSpeech/hidden_unit # should contain train_960.{tsv,phn} text_data_dir=dataset/LibriLM/km-ltr/bin-idx # should contain train_text.km-ltr.{km,ltr}.{bin,idx} # Usage: speechlm/scripts/pretrain_speechlm/base_speechlmh.sh <data_dir> <text_data_dir> [mount=$PWD] [world_size=32] [update_freq=1] bash speechlm/speechlm/scripts/pretrain_speechlm/base_speechlmp.sh $data_dir $text_data_dir注意:原文档此处 Usage 注释写的是
base_speechlmh.sh,但命令体复制的是base_speechlmp.sh,从仓库中确实存在独立的 base_speechlmh.sh 脚本来推断,命令行应为base_speechlmh.sh,原文此处疑似笔误。SpeechLM-P Large(脚本 large_speechlmp.sh):
data_dir=dataset/LibriSpeech/phone_unit # should contain train_960.{tsv,phn} text_data_dir=dataset/LibriLM/phone_unit/bin-idx # should contain train_text.phn-ltr.{phn,ltr}.{bin,idx} # Usage: speechlm/scripts/pretrain_speechlm/large_speechlmp.sh <data_dir> <text_data_dir> [mount=$PWD] [world_size=32] [update_freq=1] bash speechlm/speechlm/scripts/pretrain_speechlm/large_speechlmp.sh $data_dir $text_data_dir
以 Base 脚本为例,其内部调用为(base_speechlmp.sh#L19-L40):
python $CODE_ROOT/fairseq/fairseq_cli/hydra_train.py \ --config-dir $CODE_ROOT/speechlm/config/pretrain \ --config-name speechlm_base_librispeech \ common.user_dir=$CODE_ROOT/speechlm \ task.labels='["phn"]' \ model.label_rate=100 \ task.data=$DATA_DIR task.label_dir=$DATA_DIR \ task.text_cfg.text_data=$TEXT_DATA_DIR \ dataset.train_subset="train_960+train_text.phn-ltr" \ dataset.valid_subset="dev_clean+dev_clean.phn-ltr" \ dataset.max_tokens=1400000 \ distributed_training.distributed_world_size=${world_size} \ optimization.update_freq=[${update_freq}] \ ...几个值得注意的实现细节:
dataset.train_subset="train_960+train_text.phn-ltr":+号把语音子集与文本子集拼成一个联合 batch 流,这正是“语音与未配对文本联合训练”在数据层的落点,对应 task 实现 joint_sc2t_pretrain.py 与数据包装器 speechlm/speechlm/data/multimodal_corpus_dataset.py、concat_dataset.py;task.labels='["phn"]'与model.label_rate=100:P 模型以音素为标签、10 ms 帧率;- 脚本还会校验当前目录必须位于
SpeechLM代码根下,模型输出目录为${mount}/exp/pretrain/base_speechlmp_${world_size}gpu_${update_freq}accum。
7.2 Base 与 Large 训练配置对照
两份预训练配置的差异(base vs large):
| 配置项 | Base(LibriSpeech) | Large(LibriLight) |
|---|---|---|
task.normalize/extractor_mode | false / default | true / layer_norm |
| 语音编码器 | 6 层 × 768 维 × 8 头,FFN 3072 | 12 层 × 1024 维 × 16 头,FFN 4096 |
| 文本单元编码器 | 6 层 × 768 维 × 8 头 | 12 层 × 1024 维 × 16 头 |
mask_prob | 0.80 | 0.80 |
feature_grad_mult | 0.1(特征提取器降速训练) | 1.0 |
| dropout 系列 | 0.1 | 0.0(改用layer_norm_first: true) |
max_tokens | 1400000 | 900000 |
| 初始学习率 / clip_norm | 5e-4 / 10.0 | 1e-3 / 1.0 |
scaling_for_att | 默认 1.0 | 32(防大模型注意力溢出) |
| 其他共用 | max_update: 400000,Adam β=(0.9,0.98) ε=1e-06,weight_decay 0.01,polynomial_decay 调度、warmup 32000,max_sample_size: 250000/min_sample_size: 32000(16 kHz 随机裁剪) | 同左 |
文本侧text_cfg配置(两版一致):data_config: config.yaml、tokens_per_sample: 1024、shorten_method: random_crop、text_maxtokens_ratio: 1.0,即每条文本最长 1024 单元 token,超长随机裁剪。
7.3 预训练损失构成
损失由 speechlm_criterion.py 汇总,配置文件中的默认权重为:
pred_masked_weight: 1.0/pred_nomask_weight: 0.0:只对被掩码帧计交叉熵(HuBERT 式掩码预测);loss_weights: [10,]:第二段目标(单元编码器输出 → 文本侧单元)的权重,即总损失为语音分支掩码损失 + 10 × 单元分支掩码损失;text_ctc_weight: 0.1:文本单元序列上的 CTC 辅助损失,源码中model.add_text_ctc: true时unit_encoder_ctc_head产生encoder_out_ctc(SpeechLM.py 的 forward_text 对应逻辑);text_mum_weight: 0.0:masked unit modeling 权重,两版配置均未启用(compute_mum: false)。
mix_with_unit: true则对应 convert_embeddings:以mask_prob/2的比率把语音表征随机替换为单元嵌入,迫使语音编码器输出“单元可替换”,这是让语音与文本两个模态在表征空间对齐的关键机制。
8. Tokenizer 体系:把“未配对文本”变成语音同构单元
8.1 语音侧音素 Tokenizer(Phoneme-unit)
对无标注语音产生帧对齐音素,实现方式是一个混合 HMM ASR 模型:Base 设定下用 100h LibriSpeech 标注数据在 Kaldi recipe 下训练 HMM,再解码未配对语音,从 lattice 中取出对齐音素。文档直接提供了 960h 处理好的音素结果(train_960.tsv/.phn、dev_clean.tsv/.phn,托管链接见 README),标签帧率为 100(10 ms)。仓库内对应样例:speechlm/dataset/LibriSpeech/phone_unit/train_sample100.phn 与 dict.phn.txt。音素生成的辅助工具链位于 speechlm/speechlm/data_process/phoneme_tokenizer/(ltr2kaldi_phn_sil025.py、repeat_withou_insert_sil_less_4375.py等),负责字母→音素转换、静音切分等预处理。
8.2 文本侧音素 Tokenizer
把未配对文本转为 (phonemes, letters) 配对数据,流水线为words -> phonemes -> upsampled phones。运行一键脚本(会下载 LibriSpeech LM 语料并产出train_text.phn-ltr.phn.{idx,bin}与train_text.phn-ltr.ltr.{idx,bin}):
# data will be in dataset/LibriLM/phone_unit/ bash speechlm/speechlm/data_process/prepare_phn2ltr_librilm.sh运行前需把文档提供的音素/字母词表放入dataset/LibriLM/phone_unit/bin-idx/;仓库中该目录实际文件为 dict.phn.txt 与 dict.ltr.txt(README 原文写作dcit.phn.txt,系拼写笔误),另有该子集的 config.yaml。
8.3 语音侧隐藏单元 Tokenizer(Hidden-unit)
SpeechLM-H 变体使用离散隐藏单元替代音素。准备三部分(参考 wav2vec 2.0 manifest 规范):音频清单train.tsv、对齐的隐藏单元train.km、单元词表dict.km.txt。样例见 speechlm/dataset/LibriSpeech/hidden_unit/(train_sample100.tsv/train_sample100.km/ dict.km.txt),文本侧词表在 speechlm/dataset/LibriLM/hidden_unit/bin-idx/。
8.4 文本侧隐藏单元 Tokenizer(FastSpeech 式)
用一个FastSpeech 风格的序列到序列模型(原版生成连续频谱,这里改为生成离散单元)把未配对文本直接转换成语音式隐藏单元。训练语料仅 100h LibriSpeech:
把 ASR 转录转成音素序列;
用语音侧隐藏单元 Tokenizer 从语音中提取隐藏单元;
在配对数据上训练模型(speechlm/speechlm/models/fasttext2unit.py):
data_dir=dataset/LibriSpeech/fast_phone2unit bash speechlm/speechlm/scripts/tokenizer_fastT2U/train_s_5e-4.sh $data_dir对大规模文本语料生成隐藏单元:
gen_set=dataset/LibriSpeech/fast_phone2unit/genset_examples bash speechlm/speechlm/scripts/tokenizer_fastT2U/generate.sh $model_path $gen_set推理入口为 speechlm/speechlm/generate_unit.py / unit_generator.py。训练与生成的样例数据(
train_exmples.tsv、genset_examples.tsv、config.yaml、config_generate.yaml)位于 speechlm/dataset/LibriSpeech/fast_phone2unit,tokenizer 模型 checkpoint 的下载链接见 README 原文。
9. 引用信息与代码组织小结
如果本研究对你的工作有帮助,请引用论文SpeechLM: Enhanced Speech Pre-Training with Unpaired Textual Data(Zhang, Chen, Zhou, et al., 2022):
@article{zhang2022speechlm, title = {SpeechLM: Enhanced Speech Pre-Training with Unpaired Textual Data}, author = {Zhang, Ziqiang and Chen, Sanyuan and Zhou, Long and Wu, Yu and Ren, Shuo and Liu, Shujie and Yao, Zhuoyuan and Gong, Xun and Dai, Lirong and Li, Jinyu and Wei, Furu}, eprint={2209.15329}, archivePrefix={arXiv}, primaryClass={cs.CL}, year={2022} }最后给出与本文各章节对应的仓库文件地图,便于按图索骥:
| 主题 | 关键路径 |
|---|---|
| 推理/特征提取独立实现 | speechlm/SpeechLM.py、speechlm/modules.py |
| 预训练模型/损失/任务 | speechlm/speechlm/models/speechlm.py、speechlm/speechlm/criterions/speechlm_criterion.py、speechlm/speechlm/tasks/joint_sc2t_pretrain.py |
| ASR/ST 微调模型 | speechlm/speechlm/models/speechlm_ctcasr.py、speechlm/speechlm/models/speechlm_st.py |
| 训练/微调/解码配置 | speechlm/speechlm/config/(pretrain、finetune、decode 三个子目录) |
| 全部可执行脚本 | speechlm/speechlm/scripts/(pretrain_speechlm、tune_speechlm_asr、tune_speechlm_st、tokenizer_fastT2U) |
| 数据样例 | speechlm/dataset/(LibriSpeech、LibriLM、CommonVoice) |
适用前提提醒:本指南中的命令默认在speechlm/speechlm/代码根目录下执行,且 fairseq submodule 已初始化;Base 与 Large 模型的normalize/归一化约定不同,特征提取与微调时必须与各自预训练配置保持一致,否则表征与预训练分布不符。
【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考