unilm EdgeLM S2T 实战指南:在 Multilingual TEDx 语料上训练多语言语音识别与语音翻译
【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm
本文基于 unilm 仓库中 EdgeLM 分支的 S2T 示例文档 mtedx_example.md,完整讲解如何在其speech_to_text框架上复现 Multilingual TEDx 语料上的两个任务:多语言语音识别(ASR)与语音到文本翻译(ST)。读完本文后,你可以独立完成从语料预处理(TSV manifest、fbank 特征、SentencePiece 词表、config YAML 生成)、单语/联合多语言模型训练,到检查点平均与 WER / SacreBLEU 评测的全流程,并理解多语言目标语言标签(target language tag)在训练损失与强制解码中的底层机制。
1. 语料与任务定义
Multilingual TEDx 是面向语音识别与语音翻译的多语言语料,数据来自 8 种源语言的 TEDx 演讲,并带有到 5 种目标语言子集的人工翻译。整个示例围绕该语料训练两类模型:
- ASR(语音识别):单语模型(每个源语言一个
X-X任务)与联合多语言模型(8 个源语言共享一个模型); - ST(语音翻译):双语模型(如 Es-En)与覆盖 13 个方向的多语言模型。
从源码 prep_mtedx_data.py 可以看到仓库对语言对的完整枚举:
SPLITS = ["train", "valid", "test"] LANGPAIRS = ["es-es", "fr-fr", "pt-pt", "it-it", "ru-ru", "el-el", "ar-ar", "de-de", "es-en", "es-fr", "es-pt", "es-it", "fr-en", "fr-es", "fr-pt", "pt-en", "pt-es", "it-en", "it-es", "ru-en", "el-en"]前 8 个X-X对用于 ASR,后 13 个X-Y对用于 ST,与文档中训练/评测命令里的 subset 列表一一对应。
2. 数据准备
2.1 下载与环境
将 Multilingual TEDx 数据从 OpenSLR(资源编号 100)下载并解压到${MTEDX_ROOT}/${LANG_PAIR}目录(每个语言对一个子目录,内部为data/{split}/{wav,txt}结构,包含 FLAC 音频与分段标注文件)。随后安装 S2T 数据处理的额外依赖:
# additional Python packages for S2T data processing/model training pip install pandas torchaudio soundfile sentencepiece2.2 生成 manifest、特征、词表与配置
对每个任务运行 4 条预处理命令:先分别处理单语数据(ASR 与 ST),再生成联合(joint)多语言的词表与配置:
# Generate TSV manifests, features, vocabulary # and configuration for each language python examples/speech_to_text/prep_mtedx_data.py \ --data-root ${MTEDX_ROOT} --task asr \ --vocab-type unigram --vocab-size 1000 python examples/speech_to_text/prep_mtedx_data.py \ --data-root ${MTEDX_ROOT} --task st \ --vocab-type unigram --vocab-size 1000 # Add vocabulary and configuration for joint data # (based on the manifests and features generated above) python examples/speech_to_text/prep_mtedx_data.py \ --data-root ${MTEDX_ROOT} --task asr --joint \ --vocab-type unigram --vocab-size 8000 python examples/speech_to_text/prep_mtedx_data.py \ --data-root ${MTEDX_ROOT} --task st --joint \ --vocab-type unigram --vocab-size 8000生成的文件(manifest、特征、词表、数据配置)分别落入${MTEDX_ROOT}/${LANG_PAIR}(单语数据)和${MTEDX_ROOT}(联合数据)。
2.3 预处理脚本做了什么(源码级解读)
prep_mtedx_data.py 分为process(单语)与process_joint(联合)两条路径:
- 特征提取(process 函数,L115-L202):读取
data/{split}下的 YAML 分段标注与逐句文本,按offset/duration切分 FLAC 音频,调用 data_utils.py 中的extract_fbank_features提取80 维 log-mel 倒谱滤波器组(fbank)特征。注意特征提取前波形会先按 Kaldi 惯例量化为 16-bit 整型(_waveform * (2 ** 15)),并优先使用 pyKaldi、回退到 torchaudio 计算 fbank。每条utterance保存为.npy后打包进未压缩 ZIP(fbank80.zip)。 - ZIP 字节偏移索引(get_zip_manifest,L108-L132):训练时音频/特征以
zip路径:offset:length的形式访问,避免海量小文件 I/O 开销,这正是 S2T 框架 README(README.md)中提到的“packed ZIP + byte offset”机制。 - TSV manifest:每条样本含 6 列
id / audio / n_frames / tgt_text / speaker / tgt_lang(MANIFEST_COLUMNS,L38-L40)。关键差异在于tgt_text:ASR 任务取源语言转写,ST 任务取目标语言译文(L163-L165)。写入前会经过 filter_manifest_df(L244-L263) 过滤空转写、过短(<5 帧)以及训练集里过长(>3000 帧)的样本。 - 词表:由 gen_vocab(L32-L70) 训练 SentencePiece 模型,并固定特殊 token 位置:
<s>=0、<pad>=1、</s>=2、<unk>=3,再导出 fairseq 词典*.txt。 - config YAML:由
gen_config_yaml写出config_asr.yaml/config_st.yaml。单语与联合配置有两处刻意不同(见 process 尾部 L186-L200 与 process_joint L231-L238):- SpecAugment 策略:单语用
lb(1 条频带掩码≤27 维 + 1 条时域掩码≤100 帧),联合模型用更强的ld(2 条频带 + 2 条时域掩码),具体参数见 S2TDataConfigWriter(L318-L336); - prepend_tgt_lang_tag:仅联合配置置为
True,训练时会把目标语言标签 token 拼接到 target 序列头部(后文详述)。
- SpecAugment 策略:单语用
- 联合数据的符号链接(process_joint L239-L245):把
${MTEDX_ROOT}/${LANG_PAIR}/{split}_{task}.tsv软链为${MTEDX_ROOT}/{split}_{LANG_PAIR}_{task}.tsv,使${MTEDX_ROOT}可直接作为 fairseq 的--data根目录,subset 名即train_es-es_asr这类链接名——这解释了训练命令中--train-subset train_es-es_asr,train_fr-fr_asr,...的命名来源。
3. ASR:训练
3.1 单语模型(以西班牙语为例)
fairseq-train ${MTEDX_ROOT}/es-es \ --config-yaml config_asr.yaml --train-subset train_asr --valid-subset valid_asr \ --save-dir ${ASR_SAVE_DIR} --num-workers 4 --max-tokens 40000 --max-epoch 200 \ --task speech_to_text --criterion label_smoothed_cross_entropy --report-accuracy \ --arch s2t_transformer_xs --optimizer adam --lr 2e-3 --lr-scheduler inverse_sqrt \ --warmup-updates 10000 --clip-norm 10.0 --seed 1 --dropout 0.3 --label-smoothing 0.1 \ --load-pretrained-encoder-from ${PRETRAINED_ENCODER} \ --skip-invalid-size-inputs-valid-test \ --keep-last-epochs 10 --update-freq 8 --patience 10参数要点:
--arch s2t_transformer_xs:定义在 s2t_transformer.py(L458-L464),编码器 6 层、解码器 3 层、encoder_embed_dim=256、FFN 维度 1024、注意力头 4,默认 dropout 0.3,参数量约 10M(见第 5 节结果表);--lr-scheduler inverse_sqrt+--warmup-updates 10000:语音任务常用的逆平方根衰减;--keep-last-epochs 10:保留最近 10 个 epoch 的检查点,供评测阶段做平均;--update-freq 8:单卡模拟 8 卡的梯度累积。文档明确提示,使用多于 1 张 GPU 时应相应调小该值;--load-pretrained-encoder-from ${PRETRAINED_ENCODER}:加载预训练声学编码器加速收敛。
3.2 联合多语言模型(8 个源语言)
fairseq-train ${MTEDX_ROOT} \ --config-yaml config_asr.yaml \ --train-subset train_es-es_asr,train_fr-fr_asr,train_pt-pt_asr,train_it-it_asr,train_ru-ru_asr,train_el-el_asr,train_ar-ar_asr,train_de-de_asr \ --valid-subset valid_es-es_asr,valid_fr-fr_asr,valid_pt-pt_asr,valid_it-it_asr,valid_ru-ru_asr,valid_el-el_asr,valid_ar-ar_asr,valid_de-de_asr \ --save-dir ${MULTILINGUAL_ASR_SAVE_DIR} --num-workers 4 --max-tokens 40000 --max-epoch 200 \ --task speech_to_text --criterion label_smoothed_cross_entropy --report-accuracy \ --arch s2t_transformer_s --optimizer adam --lr 2e-3 --lr-scheduler inverse_sqrt \ --warmup-updates 10000 --clip-norm 10.0 --seed 1 --dropout 0.3 --label-smoothing 0.1 \ --skip-invalid-size-inputs-valid-test \ --keep-last-epochs 10 --update-freq 8 --patience 10 \ --ignore-prefix-size 1MULTILINGUAL_ASR_SAVE_DIR为检查点根路径;模型升级为s2t_transformer_s(_xs的默认超参基础上采用更大的 FFN 维度 256×8 与完整层数,约 31M 参数)。
--ignore-prefix-size 1的必要性:多语言模型在 target 序列头部拼接目标语言 ID token 作为“伪 BOS”,该位置应从损失中剔除。这一约定在框架中是被强校验的——speech_to_text 任务的 build_criterion(L80-L88) 在检测到数据配置prepend_tgt_lang_tag=True但ignore_prefix_size != 1时直接抛出ValueError。具体机制:
- 数据侧:SpeechToTextDataset.getitem(L247-L276) 在编码 target 后,把
<lang:XX>标签 token(来自联合词表训练时的--user_defined_symbols,见 prep_mtedx_data.py L218-L223)torch.cat到 target 最前面; - 损失侧:label_smoothed_cross_entropy 判据(L100-L106) 依据
ignore_prefix_size对lprobs与target同步切片,语言标签不参与交叉熵计算。
4. ASR:推理与评测
CHECKPOINT_FILENAME=avg_last_10_checkpoint.pt python scripts/average_checkpoints.py \ --inputs ${ASR_SAVE_DIR} --num-epoch-checkpoints 10 \ --output "${ASR_SAVE_DIR}/${CHECKPOINT_FILENAME}" fairseq-generate ${MTEDX_ROOT}/es-es \ --config-yaml config_asr.yaml --gen-subset test --task speech_to_text \ --path ${ASR_SAVE_DIR}/${CHECKPOINT_FILENAME} --max-tokens 50000 --beam 5 \ --skip-invalid-size-inputs-valid-test \ --scoring wer --wer-tokenizer 13a --wer-lowercase --wer-remove-punct --remove-bpe # For models trained on joint data CHECKPOINT_FILENAME=avg_last_10_checkpoint.pt python scripts/average_checkpoints.py \ --inputs ${MULTILINGUAL_ASR_SAVE_DIR} --num-epoch-checkpoints 10 \ --output "${MULTILINGUAL_ASR_SAVE_DIR}/${CHECKPOINT_FILENAME}" for LANG in es fr pt it ru el ar de; do fairseq-generate ${MTEDX_ROOT} \ --config-yaml config_asr.yaml --gen-subset test_${LANG}-${LANG}_asr --task speech_to_text \ --prefix-size 1 --path ${MULTILINGUAL_ASR_SAVE_DIR}/${CHECKPOINT_FILENAME} \ --max-tokens 40000 --beam 5 \ --skip-invalid-size-inputs-valid-test \ --scoring wer --wer-tokenizer 13a --wer-lowercase --wer-remove-punct --remove-bpe done- 评测前先用 average_checkpoints.py 对最近 10 个 epoch 的检查点做权重平均,语音小数据场景下可稳定提升 WER;
--scoring wer --wer-tokenizer 13a:13a 对应标准 WER 评测管线(lowercase、去标点、去数字映射),配合--remove-bpe反 BPE;- 多语言模型的
--prefix-size 1:强制解码以第一个 token 起步。对应实现同样有强校验——build_generator(L124-L148) 要求prepend_tgt_lang_tag场景下prefix_size必须为 1,并且把所有<lang:XX>token 加入symbols_to_strip_from_output,保证最终译文/hyp 文件中不残留语言标签。
5. ST:训练
5.1 双语模型(以 Es-En 为例)
fairseq-train ${MTEDX_ROOT}/es-en \ --config-yaml config_st.yaml --train-subset train_st --valid-subset valid_st \ --save-dir ${ST_SAVE_DIR} --num-workers 4 --max-tokens 40000 --max-epoch 200 \ --task speech_to_text --criterion label_smoothed_cross_entropy --report-accuracy \ --arch s2t_transformer_xs --optimizer adam --lr 2e-3 --lr-scheduler inverse_sqrt \ --warmup-updates 10000 --clip-norm 10.0 --seed 1 --dropout 0.3 --label-smoothing 0.1 \ --load-pretrained-encoder-from ${PRETRAINED_ENCODER} \ --skip-invalid-size-inputs-valid-test \ --keep-last-epochs 10 --update-freq 8 --patience 105.2 多语言模型(全部 13 个方向)
fairseq-train ${MTEDX_ROOT} \ --config-yaml config_st.yaml \ --train-subset train_el-en_st,train_es-en_st,train_es-fr_st,train_es-it_st,train_es-pt_st,train_fr-en_st,train_fr-es_st,train_fr-pt_st,train_it-en_st,train_it-es_st,train_pt-en_st,train_pt-es_st,train_ru-en_st \ --valid-subset valid_el-en_st,valid_es-en_st,valid_es-fr_st,valid_es-it_st,valid_es-pt_st,valid_fr-en_st,valid_fr-es_st,valid_fr-pt_st,valid_it-en_st,valid_it-es_st,valid_pt-en_st,valid_pt-es_st,valid_ru-en_st \ --save-dir ${MULTILINGUAL_ST_SAVE_DIR} --num-workers 4 --max-tokens 40000 --max-epoch 200 \ --task speech_to_text --criterion label_smoothed_cross_entropy --report-accuracy \ --arch s2t_transformer_s --optimizer adam --lr 2e-3 --lr-scheduler inverse_sqrt \ --warmup-updates 10000 --clip-norm 10.0 --seed 1 --dropout 0.3 --label-smoothing 0.1 \ --skip-invalid-size-inputs-valid-test \ --keep-last-epochs 10 --update-freq 8 --patience 10 \ --ignore-prefix-size 1 \ --load-pretrained-encoder-from ${PRETRAINED_ENCODER}ST_SAVE_DIR(MULTILINGUAL_ST_SAVE_DIR)为检查点根路径。文档强调一个关键技巧:ST 编码器先用 ASR 预训练再加载(--load-pretrained-encoder-from <(JOINT_)ASR 检查点路径>),可加快训练并提升翻译质量——这与语料本身“ASR + ST 共享语音输入”的结构天然契合。--update-freq 8、--ignore-prefix-size 1的作用与第 3.2 节完全相同。
6. ST:推理与评测
对最近 10 个检查点求平均后在test分片上评测:
CHECKPOINT_FILENAME=avg_last_10_checkpoint.pt python scripts/average_checkpoints.py \ --inputs ${ST_SAVE_DIR} --num-epoch-checkpoints 10 \ --output "${ST_SAVE_DIR}/${CHECKPOINT_FILENAME}" fairseq-generate ${MTEDX_ROOT}/es-en \ --config-yaml config_st.yaml --gen-subset test --task speech_to_text \ --path ${ST_SAVE_DIR}/${CHECKPOINT_FILENAME} \ --max-tokens 50000 --beam 5 --scoring sacrebleu --remove-bpe # For multilingual models python scripts/average_checkpoints.py \ --inputs ${MULTILINGUAL_ST_SAVE_DIR} --num-epoch-checkpoints 10 \ --output "${MULTILINGUAL_ST_SAVE_DIR}/${CHECKPOINT_FILENAME}" for LANGPAIR in es-en es-fr es-pt fr-en fr-es fr-pt pt-en pt-es it-en it-es ru-en el-en; do fairseq-generate ${MTEDX_ROOT} \ --config-yaml config_st.yaml --gen-subset test_${LANGPAIR}_st --task speech_to_text \ --prefix-size 1 --path ${MULTILINGUAL_ST_SAVE_DIR}/${CHECKPOINT_FILENAME} \ --max-tokens 40000 --beam 5 \ --skip-invalid-size-inputs-valid-test \ --scoring sacrebleu --remove-bpe done与 ASR 用 WER 不同,ST 评测指标为SacreBLEU(--scoring sacrebleu)。多语言模型通过--prefix-size 1强制解码从目标语言 ID token(充当 BOS)开始,一个检查点即可服务全部 13 个方向,输出中的语言标签由任务层自动剥离(见第 4 节build_generator说明)。
7. 参考结果
7.1 ASR(WER,越低越好)
| Data | --arch | Params | Es | Fr | Pt | It | Ru | El | Ar | De |
|---|---|---|---|---|---|---|---|---|---|---|
| Monolingual | s2t_transformer_xs | 10M | 46.4 | 45.6 | 54.8 | 48.0 | 74.7 | 109.5 | 104.4 | 111.1 |
7.2 ST(SacreBLEU,越高越好)
| Data | --arch | Params | Es-En | Es-Pt | Es-Fr | Fr-En | Fr-Es | Fr-Pt | Pt-En | Pt-Es | It-En | It-Es | Ru-En | El-En |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Bilingual | s2t_transformer_xs | 10M | 7.0 | 12.2 | 1.7 | 8.9 | 10.6 | 7.9 | 8.1 | 8.7 | 6.4 | 1.0 | 0.7 | 0.6 |
| Multilingual | s2t_transformer_s | 31M | 12.3 | 17.4 | 6.1 | 12.0 | 13.6 | 13.2 | 12.0 | 13.7 | 10.7 | 13.1 | 0.6 | 0.8 |
从表中可以观察到:多语言联合 ST 模型在多数方向上明显优于独立双语模型(如 Es-En 12.3 vs 7.0),而 Ru-En、El-En 因训练数据量有限仍停留在低分区间——这为后续结合 ASR 间接数据或更大语料的实验提供了基线。
8. 关键源码索引
| 模块 | 路径 | 作用 |
|---|---|---|
| 数据预处理入口 | prep_mtedx_data.py | fbank 提取、ZIP 打包、TSV manifest、联合词表与 config YAML 生成 |
| 数据工具 | data_utils.py | SentencePiece 词表(特殊 token 固定 ID)、fbank、SpecAugment 策略、manifest 过滤 |
| 任务定义 | speech_to_text.py | 强校验ignore_prefix_size=1/prefix_size=1,剥离输出中的语言标签 |
| 数据集 | speech_to_text_dataset.py | target 前拼接<lang:XX>标签、OOV 统计、帧打包 |
| 损失判据 | label_smoothed_cross_entropy.py | 按ignore_prefix_size切片语言标签位置 |
| 模型架构 | s2t_transformer.py | s2t_transformer_xs/s2t_transformer_s默认超参 |
| 检查点平均 | average_checkpoints.py | 评测前 10-epoch 权重平均 |
同目录下还有基于同一框架的其他 S2T 示例可对照参考:LibriSpeech ASR、MuST-C ST、CoVoST 2 与 SimulST。
9. 引用
按原示例文档要求,复现 Multilingual TEDx 实验时应引用:
@misc{salesky2021mtedx, title={Multilingual TEDx Corpus for Speech Recognition and Translation}, author={Elizabeth Salesky and Matthew Wiesner and Jacob Bremerman and Roldano Cattoni and Matteo Negri and Marco Turchi and Douglas W. Oard and Matt Post}, year={2021}, } @inproceedings{wang2020fairseqs2t, title = {fairseq S2T: Fast Speech-to-Text Modeling with fairseq}, author = {Changhan Wang and Yun Tang and Xutai Ma and Anne Wu and Dmytro Okhonko and Juan Pino}, booktitle = {Proceedings of the 2020 Conference of the Asian Chapter of the Association for Computational Linguistics (AACL): System Demonstrations}, year = {2020}, } @inproceedings{ott2019fairseq, title = {fairseq: A Fast, Extensible Toolkit for Sequence Modeling}, author = {Myle Ott and Sergey Edunov and Alexei Baevski and Angela Fan and Sam Gross and Nathan Ng and David Grangier and Michael Auli}, booktitle = {Proceedings of NAACL-HLT 2019: Demonstrations}, year = {2019}, }【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考