xTune 实战指南:基于一致性正则的跨语言微调(Consistency Regularization for Cross-Lingual Fine-Tuning)
2026/9/14 12:33:48 网站建设 项目流程

xTune 实战指南:基于一致性正则的跨语言微调(Consistency Regularization for Cross-Lingual Fine-Tuning)

【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm

xTune 是 unilm 仓库中实现 ACL 2021 论文《Consistency Regularization for Cross-Lingual Fine-Tuning》的官方代码,其核心思想是用两阶段训练加一致性正则(consistency regularization),让 XLM-RoBERTa 在只用英语数据(或少量翻译数据)微调后,仍能泛化到数十种目标语言。读完本文,你将能够完整搭建 xTune 的训练环境、下载并预处理 XTREME 基准数据,使用scripts/train.sh一键跑通分类、序列标注、问答两类任务的跨语言微调,并理解源码中 R1(样本一致性)与 R2(模型一致性)两项正则损失的实现细节。

一、环境与安装

xTune 依赖一个定制版的 transformers(仓库内 xtune/src/transformers 是基于 HuggingFace transformers 2.5.1 的分支,内嵌了XLMRobertaForSequenceClassificationStable等支持一致性损失的模型类),因此官方推荐使用官方 Docker 镜像运行:

# 官方 Docker 镜像 dancingsoul/pytorch:xTune

若手动安装,需在xtune/目录下执行(见 xtune/setup.py,其中固定了sentencepiece==0.1.91seqeval==0.0.12networkx==1.11等依赖版本):

cd xtune pip install --user .

注意:训练脚本默认开启--fp16 --fp16_opt_level O2,依赖 NVIDIA Apex(见 xtune/src/run_cls.py 中对 apex 的 import),并建议在 V100-32GB 级别的 GPU 上运行;若出现 OOM,可减少per_gpu_train_batch_size同时增大gradient_accumulation_steps,或多卡训练。

二、数据与模型准备

2.1 XTREME 数据集

官方微调支持 7 个 XTREME 任务:xnlipawsx(分类)、panx(NER)、udpos(POS 标注)、mlqatydiqaxquad(问答)。准备步骤(依据 xtune/README.md):

  1. 在项目根目录创建下载目录:
mkdir -p download
  1. panx 数据集需手动下载:从 XTREME 官方渠道下载panx_dataset(下载文件名为AmazonPhotos.zip),放入download/目录。xtune/scripts/download_data.sh 中的download_panx函数检测到AmazonPhotos.zip后会解压其中的 40 个语言包(ar.tar.gzhu.tar.gz),把每个语言的train/dev/test重命名为lg-train等,再调用utils_preprocess.py统一转成 TSV 格式;否则该函数只打印提示并跳过。
  2. 其余数据集(XNLI、PAWS-X、UD-POS、SQuAD、XQuAD、MLQA、TyDiQA-GoldP、 Tatoeba/BUCC 平行语料)通过一条命令下载并预处理:
bash scripts/download_data.sh

从 download_data.sh 的实现可以看到,每个数据集下载后都会执行python utils_preprocess.py --data_dir ... --output_dir ... --task <task>统一格式化为脚本可读取的 TSV;udpos还会额外用 conllu_to_conll.py 把 conllu 转成 conll(保留 fused form,即词级标注,这是 panx/udpos 这类 token 级任务必需的)。

官方 README 特别提醒两点:

  • 为了便于评估,仓库保留了测试集标签;而 XTREME 官方仓库在预处理时会删除测试标签并打乱测试句顺序(用于跨语言检索),因此若使用 XTREME 官方仓库的数据,需要在其utils_process.py中把csv.writer(fout, delimiter='\t')替换为csv.writer(fout, delimiter='\t', quoting=csv.QUOTE_NONE, quotechar='')
  • 训练panx/udpos前,train.sh会自动调用 preprocess_panx.sh、preprocess_udpos.sh 做二次预处理(按最大长度切分、生成labels.txt),无需手动干预(见 xtune/scripts/train.sh#L29-L33)。

2.2 平行句翻译数据

XTREME 官方提供 SQuAD v1.1(仅 train/dev)、MLQA、PAWS-X、TyDiQA-GoldP、XNLI、XQuAD 的平行翻译,下载后将xtreme_translations文件夹整体移入download/目录即可。

panx 与 udpos 的目标语言翻译官方未提供,xTune 用 Google 翻译补齐了这部分(论文方提供了处理好的版本供下载),并与xtreme_translations合并存放。以 XNLI 为例,脚本从$DATA_DIR/xtreme_translations/XNLI/读取翻译文件(见 train_xnli.sh#L27);panx 则使用xtreme_translations/translate_train.panx.txt(见 train_panx.sh#L47)。

2.3 双语词典(code-switching 用)

cross-lingual-transfer设置下的数据增广使用词级 code-switching,需要从 MUSE 仓库获得英-目标语言平行词典,按download/dicts/en-<lang>.txt的组织方式放入下载目录。源码在 NoisedDataGenerator 初始化 中逐语言读取en-{lang}.txt,每行以src\ttgt解析,构建成lang2dict映射;缺失词典的语言会被自动剔除并打日志。

2.4 预训练模型

仅支持 XLM-RoBERTa(xlm-roberta-base/xlm-roberta-large),采用 HuggingFace 格式,一键下载:

bash scripts/download_model.sh

download_model.sh 会从 HuggingFace 拉取两个模型目录下的pytorch_model.binconfig.jsonsentencepiece.bpe.modeltokenizer.json四个文件到download/xlm-roberta-{base,large}/

三、两阶段微调:train.sh完全参数解析

xTune 的完整调用入口只有两个层级:

bash ./scripts/train.sh [setting] [dataset] [model] [stage] [gpu] [data_dir] [output_dir]

train.sh本身只是参数转发器(xtune/scripts/train.sh),7 个位置参数均有默认值,另支持第 8 个可选参数SEED(默认 1):

位置参数说明默认值 / 可选值
[setting]数据设置translate-train-all:除英语外使用官方平行翻译参与训练;cross-lingual-transfer:只用英语训练,零样本跨语言迁移默认cross-lingual-transfer
[dataset]XTREME 任务名xnlipanxpawsxudposmlqatydiqaxquad;默认xnli
[model]预训练模型xlm-roberta-basexlm-roberta-large
[stage]训练阶段12;默认1
[gpu]设置CUDA_VISIBLE_DEVICES默认0
[data_dir]训练数据目录默认$REPO/download/
[output_dir]微调输出目录默认$REPO/outputs/

脚本随后分发到scripts/$SETTING/train_${TASK}.sh(共 7 个任务 × 2 个设置 = 14 个任务脚本)。以 XNLI 分类为例,两个设置下的默认超参(translate-train-all/train_xnli.sh 与 cross-lingual-transfer/train_xnli.sh):

超参取值含义
EPOCH10训练轮数
MAXL256最大序列长度
LANGSar,bg,de,el,en,es,fr,hi,ru,sw,th,tr,ur,vi,zh评估语言(XNLI 的 15 种语言,含 en)
EVALUATE_STEPS5000每多少步在训练中途评估一次
BATCH_SIZE/GRAD_ACCbase: 32/1;large: 16/2每卡 batch 与梯度累积
LRbase: 7e-6;large: 5e-6AdamW 学习率
R1_LAMBDA5.0样本一致性损失权重 λ1
R2_LAMBDAtranslate-train-all: 1.0;cross-lingual-transfer: 5.0模型一致性损失权重 λ2
CSR(仅 cross-lingual-transfer)0.3code-switching 比例

各任务脚本按语言数量与序列长度调整超参,例如 panx 的 40 语言、MAX_LENGTH=128EVALUATE_STEPS=1000、base 模型LR=1e-5(translate-train-all/train_panx.sh#L26-L45)。

3.1 两阶段训练的语义

  • Stage 1:在英语训练集上带「样本一致性(example consistency)」微调——每条原始样本都会生成一个加噪/翻译/码切换后的变体,要求两个视角下的模型输出分布保持一致(R1 损失)。
  • Stage 2:在「英语 + 增广」的训练集上继续训练(增广方式按设置而定:translate-train-allmt,即用官方平行翻译增广;cross-lingual-transfercs,即 code-switching),并额外加载 Stage 1 的最优 checkpoint 作为冻结教师模型,对增广样本施加「模型一致性(model consistency)」正则(R2 损失)。

官方建议:token 级任务(序列标注 panx/udpos、问答 mlqa/tydiqa/xquad)务必两个阶段都跑;文本分类任务在算力受限时可以只跑 Stage 1。

3.2 Stage 2 如何衔接 Stage 1

Stage 2 脚本会显式指定 Stage 1 产物,例如 XNLI translate-train-all 的 Stage 2(train_xnli.sh#L78-L116):

FIRST_STAGE_MODEL_PATH="${OUT_DIR}/xnli/xlm-roberta-base-LR7e-6-epoch10-MaxLen256-Translate-R1_LAMBDA5.0/checkpoint-best" python ./src/run_cls.py ... \ --first_stage_model_path $FIRST_STAGE_MODEL_PATH \ --enable_data_augmentation \ --augment_ratio 1.0 \ --augment_method mt \ --r2_lambda $R2_LAMBDA

训练过程中,每当验证集平均指标超过历史最优,会把模型另存为checkpoint-best(见 save_checkpoint_best,分类任务以valid_avg.acc为选择标准,rel任务用 ndcg)。checkpoint-best正是 Stage 2 加载的教师模型来源,因此Stage 2 必须在 Stage 1 同一OUT_DIR下运行

四、示例:XNLI 的两种数据设置

4.1 translate-train-all:利用各语言平行翻译

# Stage 1(必跑) bash ./scripts/train.sh translate-train-all xnli xlm-roberta-base 1 # Stage 2(可选,推荐) bash ./scripts/train.sh translate-train-all xnli xlm-roberta-base 2

该设置下 Stage 1 开启--enable_translate_data --translation_path $DATA_DIR/xtreme_translations/XNLI/,即在 R1 一致性配对中直接随机替换成其他语言译文;Stage 2 再以--augment_method mt --augment_ratio 1.0把等量的翻译样本加入训练集。

4.2 cross-lingual-transfer:只用英语,零样本迁移

# Stage 1(必跑) bash ./scripts/train.sh cross-lingual-transfer xnli xlm-roberta-base 1 # Stage 2(可选,推荐) bash ./scripts/train.sh cross-lingual-transfer xnli xlm-roberta-base 2

该设置下训练数据完全来自英语,增广手段是词级 code-switching:--overall_ratio 1.0 --enable_code_switch --code_switch_ratio 0.3 --dict_dir $DATA_DIR/dicts --dict_languages ar,bg,de,el,es,fr,hi,ru,sw,th,tr,ur,vi,zh(cross-lingual-transfer/train_xnli.sh#L77-L81)。Stage 2 中增广方法切换为cs,并且 Stage 1/Stage 2 的R2_LAMBDA均为 5.0。

panx、udpos、mlqa、tydiqa、xquad、pawsx 的调用方式完全一致,只是把[dataset]换成对应任务名;token 级任务入口是 xtune/src/run_tag.py、问答任务入口是 xtune/src/run_qa.py,分类任务入口是 xtune/src/run_cls.py,参数体系相同。

五、源码级原理:R1 与 R2 一致性损失

5.1 数据侧:NoisedDataGenerator 如何构造「噪声视图」

run_cls.py 中的NoisedDataGenerator负责为每条样本生成一致性配对,支持多种扰动手段(命令行参数在 main() 中定义):

  • enable_translate_data/translation_path:通过get_translation_pair(run_cls.py#L499-L533)把当前句随机换成某个目标语言的官方平行译文;tgt2src_dict保证从目标语言视角也能映射回英语原文,实现「en↔tgt」双向替换。
  • enable_code_switch/code_switch_ratio/dict_dir/dict_languages:在encode_sentence(run_cls.py#L240-L277)中逐 token 以overall_ratio × code_switch_ratio的概率把英文词替换为双语词典中的目标语言对应词,并统计实际码切换比例(训练日志会打印XX.XX% tokens have been code-switched)。
  • enable_bpe_sampling:用 SentencePiece 的nbest_size+alpha采样替代词级扰动;enable_random_noise:在词嵌入上叠加 uniform/normal 噪声(noise_eps控制幅度);enable_word_dropout:按word_dropout_rate将 token 替换为[UNK]
  • enable_data_augmentation+augment_ratio+augment_method:Stage 2 专用。augment_examples(run_cls.py#L204-L215)按ceil(N × augment_ratio)复制样本并打乱,mt方法把复制件替换为译文、cs方法对复制件做码切换编码;被复制的样本被标记is_augmented=1r1_mask=1,原始样本同样标r1_mask=1

每条样本最终被编码为 9 元张量数据集:original_input_ids / attention_mask / token_type_ids / labels / is_augmented / noised_input_ids / noised_attention_mask / noised_token_type_ids / r1_mask(convert_examples_to_dataset)。

5.2 模型侧:总损失 = 原始 CE + 噪声 CE + R1 + R2

自定义模型XLMRobertaForSequenceClassificationStable(modeling_xlm_roberta.py#L207-L390)在一次 forward 中同时计算原始输入与噪声输入的两路 logits,总损失为:

loss = original_loss + noised_loss + r1_loss + r2_loss

其中:

  • original_loss:由--original_loss开启,对原始输入的交叉熵(L364-L367);

  • noised_loss:由--noised_loss开启,对噪声输入的交叉熵(默认脚本不启用,仅靠一致性约束);

  • r1_loss(样本一致性,--enable_r1_loss+--r1_lambda:对r1_mask=1的样本,计算两路 logits 概率分布的双向 KL 散度之和再乘 λ1(L374-L383):

    r1_loss_f = KL(noised_logits, logits.detach()) r1_loss_b = KL(logits, noised_logits.detach()) r1_loss = (r1_loss_b + r1_loss_f) * r1_lambda
  • r2_loss(模型一致性,Stage 2 专用):当传入first_stage_model_logits且 batch 中存在is_augmented=1的样本时,用当前模型在这些增广样本上的 logits 对Stage 1 冻结模型torch.no_grad()下计算,见 train())的输出做 KL 散度,乘 λ2;也可通过--use_hard_labels改用教师模型的 argmax 硬标签(L322-L333)。

这个设计对应论文的两个核心正则:Stage 1 让模型对「同一句话的不同语言/噪声视角」给出一致预测;Stage 2 让模型在扩充(含翻译/码切换)数据上学习时,不偏离 Stage 1 已经建立的跨语言一致解。run_tag.py/run_qa.py对应的 Stable 模型类以同样模式在 token 级(起始/结束位置、token 对齐项)与句级上实现 R1/R2(modeling_xlm_roberta.py#L1125-L1176)。

5.3 训练循环与评估

  • 优化器为 AdamW(biasLayerNorm.weight不衰减,train()#L594-L605),线性 warmup + 线性衰减,--warmup_steps -1时以 0 warmup 直接衰减;fp16 通过 Apexamp.initialize+opt_level O2启用。
  • 训练中途评估:--evaluate_during_training --evaluate_steps 5000触发evaluate(),对--language列表里每种语言的 valid + test 集逐语言计算 acc/F1(xtreme_compute_metrics),并聚合valid_avg/test_avg;评估结果写入evaluate_logs.txt与 TensorBoard(run_cls.py#L937-L1015)。训练日志中会逐行打印loss / original_loss / noised_loss / r1_loss / r2_loss,便于观察正则项的收敛情况(L683-L697)。
  • 缓存:特征按cached_{split}_xlmr-base-final_{maxlen}_{task}_{lang}缓存在data_dir下(load_and_cache_examples),重复运行可省去重新 tokenize 的开销。

六、复现建议与常见坑

  1. OOM 处理:README 给出的官方策略是降低per_gpu_train_batch_size、提高gradient_accumulation_steps或多卡;脚本中 large 模型默认BATCH_SIZE=16, GRAD_ACC=2(XNLI)或32/1(panx),可以照此比例调整。
  2. 目录约定download/下必须同时具备xnlipawsxudpospanxmlqatydiqaxquadxtreme_translationsdictsxlm-roberta-base|large十类目录,缺一项对应设置(尤其是cross-lingual-transferdictstranslate-train-allxtreme_translations)都会直接失败。
  3. 输出目录:每次运行的OUTPUT_DIR命名中包含 LR、epoch、MaxLen、R1_LAMBDA、增广方式等超参指纹(如...-Translate-R1_LAMBDA5.0...-Aug1.0-MT-R2_Lambda1.0),Stage 2 会去同指纹的 Stage 1 目录下找checkpoint-best;如果 Stage 1 超参被改过,务必保证两个阶段的 LR/epoch/MaxLen 等指纹一致,否则路径对不上。
  4. 依赖版本:仓库内 transformers 为 2.5.1 定制版(xtune/setup.py#L78-L81),run_cls.py顶层from transformers import ...导入的正是本目录src/transformers,请勿用新版 transformers 覆盖安装,否则XLMRobertaForSequenceClassificationStablextreme_*系列符号会缺失。
  5. 种子SEEDtrain.sh第 8 个可选参数(默认 1),会同步到 Python/NumPy/PyTorch(set_seed)。

七、引用

若使用了 xTune 的资源,请引用 ACL 2021 论文(xtune/README.md):

@inproceedings{bo2021xtune, author = {Bo Zheng, Li Dong, Shaohan Huang, Wenhui Wang, Zewen Chi, Saksham Singhal, Wanxiang Che, Ting Liu, Xia Song, Furu Wei}, booktitle = {Proceedings of ACL 2021}, title = {{Consistency Regularization for Cross-Lingual Fine-Tuning}}, year = {2021} }

主要参考的仓库文件:xtune/README.md、xtune/scripts/train.sh、xtune/scripts/download_data.sh、xtune/scripts/download_model.sh、xtune/src/run_cls.py、xtune/src/transformers/modeling_xlm_roberta.py、xtune/setup.py。

【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询