Path: blob/main/transformers_doc/zh/pytorch/question_answering.ipynb
8775 views
问答
问答任务根据给定的问题返回答案。相信您肯定在日常生活中接触过问答模型, 比如您可能使用过 豆包、Siri 等虚拟助手询问天气情况。问答任务通常分为两种类型:
抽取式:从给定的上下文中提取答案。
生成式:根据上下文生成能够正确回答问题的答案。
本指南将向您展示如何:
在 SQuAD 数据集上微调 DistilBERT,用于抽取式问答。
使用微调后的模型进行推断。
如果您想查看所有与本任务兼容的架构和检查点,最好查看任务页。
在开始之前,请确保您已安装所有必要的库:
建议您登录 Hugging Face 账户,以便将模型上传并分享给社区。在提示时,输入您的令牌进行登录:
加载 SQuAD 数据集
首先从 🤗 Datasets 库中加载 SQuAD 数据集的一个较小子集。这样您可以先进行实验,确保一切正常,再花更多时间在完整数据集上进行训练。
使用 train_test_split 方法将数据集的 train 划分为训练集和测试集:
然后查看一个示例:
这里有几个重要字段:
answers:答案词元的起始位置及答案文本。context:模型需要从中提取答案的背景信息。question:模型应该回答的问题。
预处理
下一步是加载 DistilBERT 分词器,对 question 和 context 字段进行处理:
问答任务有一些特别的预处理步骤需要注意:
数据集中的某些示例可能具有非常长的
context,超过了模型的最大输入长度。为处理较长的序列,仅截断context部分,设置truncation="only_second"。接下来,通过设置
return_offset_mapping=True,将答案的起始和结束位置映射回原始的context。有了映射后,即可找到答案的起始和结束词元。使用
sequence_ids方法找出偏移量的哪部分对应question,哪部分对应context。
下面是创建函数以截断并将 answer 的起止词元映射到 context 的方法:
使用 🤗 Datasets 的 map 函数将预处理函数应用于整个数据集。通过设置 batched=True 一次处理数据集的多个元素,可以加速 map 函数。删除不需要的列:
现在使用 DefaultDataCollator 创建一批样本。与 🤗 Transformers 中的其他数据整理器不同,DefaultDataCollator 不会应用任何额外的预处理(如填充)。
训练
此时,只剩三个步骤:
在
TrainingArguments中定义训练超参数。唯一必需的参数是output_dir,它指定保存模型的位置。通过设置push_to_hub=True,将模型推送到 Hub(您需要登录 Hugging Face 才能上传模型)。将训练参数传递给
Trainer,同时传入模型、数据集、分词器和数据整理器。调用
train()微调您的模型。
训练完成后,使用 push_to_hub() 方法将模型分享到 Hub,让所有人都能使用您的模型:
评估
问答任务的评估需要大量后处理工作。为了不占用您太多时间,本指南跳过了评估步骤。Trainer 在训练过程中仍然会计算评估损失,因此您对模型性能并非完全一无所知。
如果您有更多时间,并且对如何评估问答模型感兴趣,可以查看 🤗 Hugging Face 课程中的问答章节!
推断
很好,现在您已经微调了模型,可以用它进行推断了!
准备一个问题和一些您希望模型作出预测的上下文:
使用微调后的模型进行推断最简单的方式是在 pipeline() 中使用它。用您的模型实例化一个问答 pipeline,并将文本传递给它:
如果您愿意,也可以手动复现 pipeline 的结果:
对文本进行分词并返回 PyTorch 张量:
将输入传递给模型并返回输出:
从模型输出中获取起始和结束位置的最高概率:
解码预测的词元以获取答案: