
Transformers 多选任务实战指南用 BERT 微调 SWAG 数据集实现选项筛选与推理【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers多选Multiple Choice任务是自然语言理解中的经典范式模型在给定上下文与若干候选答案时需要从中选出唯一正确的选项。本指南以 Transformers 为核心完整演示如何加载 SWAG 数据集的regular配置、用 BERT 进行微调Finetune、接入准确率评估并将训练好的模型投入推理。读完本文你将掌握AutoModelForMultipleChoice、DataCollatorForMultipleChoice与Trainer的完整配合链路能够独立复现一套可落地的多选微调方案。1. 多选任务与 SWAG 数据集概览多选任务与问答Question Answering非常相似区别在于问答要求模型生成或抽取答案文本而多选任务会预先给出多个候选答案模型的任务是结合上下文从中选出正确的那个。本指南采用的标准数据集是SWAGSituations With Adversarial Generations。SWAG 的每条样本包含一句开头的句子由sent1与sent2拼接而成以及 4 个候选结尾ending0~ending3其中只有一个是正确的。训练目标即让模型学会在这些选项中挑出正确的结尾。阅读本指南前请确认已安装所需依赖库pip install transformers datasets evaluate建议同时登录 Hugging Face 账号以便将微调后的模型上传分享给社区。按提示输入 token 即可完成登录 from huggingface_hub import notebook_login notebook_login()2. 加载 SWAG 数据集从 Datasets 库中加载 SWAG 数据集的regular配置 from datasets import load_dataset swag load_dataset(swag, regular)查看训练集的第一条样本理解数据形态 swag[train][0] {ending0: passes by walking down the street playing their instruments., ending1: has heard approaching them., ending2: arrives and theyre outside dancing and asleep., ending3: turns the lead singer watches the performance., fold-ind: 3416, gold-source: gold, label: 0, sent1: Members of the procession walk down the street holding small horn brass instruments., sent2: A drum line, startphrase: Members of the procession walk down the street holding small horn brass instruments. A drum line, video-id: anetv_jkn6uvmqwh4}字段虽多但结构其实非常简单sent1与sent2共同描述句子的开头将两者拼接即可得到startphrase字段。endingending0~ending34 个可能的句子结尾其中只有 1 个是正确的。label标注正确结尾的索引即监督信号。从源码角度看SWAG 这类“上下文 候选集”的结构正是多选任务的标准形态下面的预处理、数据整理、模型前向逻辑都围绕这一形态展开。3. 预处理将上下文与候选答案组织成 4 路输入3.1 加载 BERT 分词器多选微调以 BERT 为基座模型先加载其分词器 from transformers import AutoTokenizer tokenizer AutoTokenizer.from_pretrained(google-bert/bert-base-uncased)3.2 编写预处理函数预处理函数需要完成三件事将sent1复制 4 份分别与sent2组合还原句子的开头将sent2与 4 个候选结尾逐一组合将上述两个列表展平Flatten以便一次性批量分词之后再把结果还原Unflatten使每条样本对应一组input_ids、attention_mask与labels字段。 ending_names [ending0, ending1, ending2, ending3] def preprocess_function(examples): ... first_sentences [[context] * 4 for context in examples[sent1]] ... question_headers examples[sent2] ... second_sentences [ ... [f{header} {examples[end][i]} for end in ending_names] for i, header in enumerate(question_headers) ... ] ... first_sentences sum(first_sentences, []) ... second_sentences sum(second_sentences, []) ... tokenized_examples tokenizer(first_sentences, second_sentences, truncationTrue) ... return {k: [v[i : i 4] for i in range(0, len(v), 4)] for k, v in tokenized_examples.items()}要点说明分词器接收的是“第一句”与“第二句”两个列表对应 BERT 的句子对输入配合token_type_ids区分句子 A 与句子 B详见 BERT 实现 中token_type_ids的说明。truncationTrue会在超过模型最大长度时截断此处未显式设置max_length可后续在DataCollatorForMultipleChoice中统一控制。展平后再按每 4 个切分还原最终每条样本的每个字段都是一个长度为 4 的列表分别对应 4 个候选选项。对整个数据集应用预处理函数时使用 Datasets 的map方法并设置batchedTrue以批量处理、加速运行 tokenized_swag swag.map(preprocess_function, batchedTrue)3.3 使用 DataCollatorForMultipleChoice 动态填充相比将整个数据集统一填充到最大长度更高效的做法是在组 batch 阶段动态填充只把同一 batch 内的句子填充到该 batch 的最长长度。DataCollatorForMultipleChoice正是为此设计——它会展平所有模型输入、执行填充、再将结果还原为多选所需形状 from transformers import DataCollatorForMultipleChoice collator DataCollatorForMultipleChoice(tokenizertokenizer)从 collator 源码 可以看出它的完整工作流先把label从样本中取出标签不参与嵌套填充计算batch_size与num_choices将形如B 个样本 × C 个选项的嵌套样本展平为B*C条普通样本例如 2 个样本 × 2 个选项变为 4 条样本调用tokenizer.pad进行动态填充将结果重塑为B × C × L的三维张量并重新加回labels。最终得到的 batch 形状为(batch_size, num_choices, sequence_length)与BertForMultipleChoice对input_ids等输入的预期完全一致见 forward 文档。DataCollatorForMultipleChoice还支持以下常用参数来自 类定义padding默认True即longest填充到 batch 内最长序列可设为max_length按max_length填充或False/do_not_pad不填充。max_length可选限制填充的最大长度。pad_to_multiple_of将序列填充到该数值的整数倍便于在支持 Tensor CoresNVIDIA 计算能力 ≥ 7.5的硬件上获得更优性能。return_tensors返回张量类型默认ptPyTorch也可选np。4. 评估指标准确率训练过程中引入评估指标有助于实时观察模型性能。使用 Evaluate 库加载 accuracy 指标 import evaluate accuracy evaluate.load(accuracy)编写compute_metrics函数将模型预测与标签传给compute计算准确率 import numpy as np def compute_metrics(eval_pred): ... predictions, labels eval_pred ... predictions np.argmax(predictions, axis1) ... return accuracy.compute(predictionspredictions, referenceslabels)np.argmax(predictions, axis1)会在每个样本的多个选项上取 logits 最大的索引得到预测的选项编号再与真实label比较得出准确率。该函数将在配置训练时传入Trainer。5. 微调用 Trainer 训练 BERT5.1 加载模型使用AutoModelForMultipleChoice加载 BERT from transformers import AutoModelForMultipleChoice, TrainingArguments, Trainer model AutoModelForMultipleChoice.from_pretrained(google-bert/bert-base-uncased)AutoModelForMultipleChoice会依据配置自动解析为对应的*ForMultipleChoice架构。从 映射表 可以看到当前仓库中已有 30 种架构提供多选实现包括bert、roberta、albert、distilbert、electra、deberta-v2、big_bird、longformer、fnet、xlnet、xlm-roberta、modernbert等。也就是说只需更换model_name即可将下述训练流程复用到其他模型上。以BertForMultipleChoice为例其结构在 BERT 实现 中非常清晰底层是完整 BERT 编码器顶层由classifier_dropout缺省时回退到hidden_dropout_prob与一个nn.Linear(config.hidden_size, 1)分类头构成。前向时模型先把三维输入(batch_size, num_choices, sequence_length)展平为(batch_size * num_choices, sequence_length)送入 BERT随后在 forward 后半段 将结果重排为(batch_size, num_choices)对每个选项输出一个 logit再在选项维度上计算交叉熵损失。这正解释了为什么输入必须保持(B, C, L)的形状——DataCollatorForMultipleChoice的输出形状与之严格对齐。5.2 配置训练参数并启动训练接下来只剩三步在TrainingArguments中定义训练超参数。唯一必填参数是output_dir模型保存路径设置push_to_hubTrue可将模型推送到 Hub需要已登录。每个 epoch 结束时Trainer会评估准确率并保存训练检查点。将训练参数与模型、数据集、分词器、数据收集器、compute_metrics一起传给Trainer。调用trainer.train()启动微调。 training_args TrainingArguments( ... output_dirmy_awesome_swag_model, ... eval_strategyepoch, ... save_strategyepoch, ... load_best_model_at_endTrue, ... learning_rate5e-5, ... per_device_train_batch_size16, ... per_device_eval_batch_size16, ... num_train_epochs3, ... weight_decay0.01, ... push_to_hubTrue, ... ) trainer Trainer( ... modelmodel, ... argstraining_args, ... train_datasettokenized_swag[train], ... eval_datasettokenized_swag[validation], ... processing_classtokenizer, ... data_collatorcollator, ... compute_metricscompute_metrics, ... ) trainer.train()关键超参数说明eval_strategyepoch与save_strategyepoch每个 epoch 结束时分别执行一次评估与检查点保存load_best_model_at_endTrue训练结束后自动加载评估指标最好的检查点learning_rate5e-5BERT 系微调常用的学习率量级per_device_train_batch_size16/per_device_eval_batch_size16每个设备上的训练/评估 batch 大小num_train_epochs3训练轮数weight_decay0.01权重衰减用于缓解过拟合。训练完成后通过trainer.push_to_hub()将模型分享到 Hub供社区直接使用 trainer.push_to_hub()5.3 用官方脚本直接跑通全流程如果你希望跳过手动拼装代码仓库在 examples/pytorch/multiple-choice 下提供了开箱即用的脚本run_swag.py基于Trainer的完整微调脚本适用于 SWAG 数据集也支持与你自定义的、结构一致的 csv/jsonlines 数据自定义数据集需相应调整脚本内的preprocess_function。参考 README 中的用法python run_swag.py \ --model_name_or_path FacebookAI/roberta-base \ --do_train \ --do_eval \ --learning_rate 5e-5 \ --num_train_epochs 3 \ --output_dir /tmp/swag_base \ --per_device_eval_batch_size16 \ --per_device_train_batch_size16 \ --overwrite_output该 README 同时给出了使用上述超参数在roberta-base上的参考评估结果eval_acc ≈ 0.834、eval_loss ≈ 0.445可作为复现时的对照基线。run_swag_no_trainer.py基于 Accelerate 的裸训练循环版本暴露了底层训练逻辑便于自行定制优化器与数据加载器同时天然支持分布式训练、TPU 与混合精度。按 README 中的方式运行pip install githttps://github.com/huggingface/accelerateexport DATASET_NAMEswag python run_swag_no_trainer.py \ --model_name_or_path google-bert/bert-base-cased \ --dataset_name $DATASET_NAME \ --max_seq_length 128 \ --per_device_train_batch_size 32 \ --learning_rate 2e-5 \ --num_train_epochs 3 \ --output_dir /tmp/$DATASET_NAME/在分布式环境中先执行accelerate config完成交互式配置再用accelerate test验证环境最后通过accelerate launch启动训练accelerate launch run_swag_no_trainer.py \ --model_name_or_path google-bert/bert-base-cased \ --dataset_name $DATASET_NAME \ --max_seq_length 128 \ --per_device_train_batch_size 32 \ --learning_rate 2e-5 \ --num_train_epochs 3 \ --output_dir /tmp/$DATASET_NAME/accelerate launch同一套命令即可适配纯 CPU、单 GPU、多 GPU单机或多机以及 TPU 等不同环境。6. 推理用微调后的模型做多选预测微调完成后即可投入推理。假设有一段文本和两个候选答案 prompt France has a bread law, Le Décret Pain, with strict rules on what is allowed in a traditional baguette. candidate1 The law does not apply to croissants and brioche. candidate2 The law applies to baguettes.将每个“提示词 候选答案”组成一对进行分词返回 PyTorch 张量并构造labels from transformers import AutoTokenizer tokenizer AutoTokenizer.from_pretrained(my_awesome_swag_model) inputs tokenizer([[prompt, candidate1], [prompt, candidate2]], return_tensorspt, paddingTrue) labels torch.tensor(0).unsqueeze(0)把输入与标签传给模型得到logits from transformers import AutoModelForMultipleChoice model AutoModelForMultipleChoice.from_pretrained(my_awesome_swag_model) outputs model(**{k: v.unsqueeze(0) for k, v in inputs.items()}, labelslabels) logits outputs.logits取出概率最高的类别即模型认为正确的选项索引 predicted_class logits.argmax().item() predicted_class 0推理细节说明tokenizer(...)接收的是[[prompt, candidate1], [prompt, candidate2]]这样的嵌套列表——外层是样本内层是同一样本的多个选项这与训练阶段预处理函数展平前的数据形态一致inputs中每个张量的形状为(num_choices, seq_len)通过unsqueeze(0)补上 batch 维后变为(1, num_choices, seq_len)与模型前向期望的(batch_size, num_choices, sequence_length)对齐labels仅在需要同时计算 loss 时传入若只做预测可以省略。这里使用的是本地保存的my_awesome_swag_model若模型已通过push_to_hub上传也可将路径替换为 Hub 上的用户名/模型名来加载。7. 总结与进阶方向通过本指南你可以完整复现一条多选微调链路用load_dataset(swag, regular)加载数据理解sent1/sent2/ending*/label的字段语义用AutoTokenizer配合自定义preprocess_function把上下文与 4 个候选答案组织成句子对并展平/还原用DataCollatorForMultipleChoice动态填充产出(B, C, L)形状的 batch用evaluate库加载 accuracy 作为评估指标用AutoModelForMultipleChoiceTrainer完成微调并可选择推送到 Hub 共享推理时按同样的“多选项”结构组织输入直接取logits.argmax()作为答案。进一步探索可以关注自动模型映射表确认你的目标模型是否具备ForMultipleChoice版本直接替换模型名即可迁移训练流程DataCollatorForMultipleChoice 源码深入理解展平、填充、重塑三阶段的具体实现便于针对长序列或特殊填充策略做定制官方多选示例脚本run_swag.py与run_swag_no_trainer.py分别演示了 Trainer 与 Accelerate 两条训练路线可作为生产环境的起点模板。【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考