概述
在这里,我将演示如何使用 Hugging Face 的 transformers
库,通过微调一个预训练的语言模型(比如 bert-base-chinese
或 distilbert-base-chinese
),来创建一个能够回答问题的问答系统。这个实例将展示从数据加载、预处理、训练到评估的完整过程。
环境准备
确保已安装 Hugging Face transformers
和 datasets
库:
pip install transformers datasets
数据准备
我们可以使用 Hugging Face datasets
库中的 SQuAD 数据集(或中文翻译版本CMRC2018),这是一个常用的问答数据集,可以直接加载并用于微调。
实现代码
以下是详细代码实现,包括数据加载、数据预处理、模型微调、评估等步骤。
1. 导入必要的库
from transformers import AutoTokenizer, AutoModelForQuestionAnswering, Trainer, TrainingArguments from datasets import load_dataset, load_metric import torch
2. 加载数据集
这里我们将使用 SQuAD 的中文版(比如 CMRC2018),若没有合适的中文数据,也可以使用英文数据集进行测试。
dataset = load_dataset("cmrc2018") # 中文问答数据集CMRC2018,Hugging Face上可能已有
3. 加载预训练模型和分词器
选择一个中文支持较好的预训练模型,例如 bert-base-chinese
。
model_name = "bert-base-chinese" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForQuestionAnswering.from_pretrained(model_name)
4. 数据预处理
对于问答任务,我们需要将问题和上下文拼接成模型的输入格式。并且设置正确的标签(answer_start 和 answer_end)。
def preprocess_function(examples): questions = [q.strip() for q in examples["question"]] inputs = tokenizer( questions, examples["context"], max_length=384, truncation="only_second", return_offsets_mapping=True, padding="max_length", ) start_positions = [] end_positions = [] for i, offset in enumerate(inputs["offset_mapping"]): answer = examples["answers"][i] start_char = answer["answer_start"][0] end_char = start_char + len(answer["text"][0]) sequence_ids = inputs.sequence_ids(i) # 查找答案的起始位置和结束位置 token_start_index = 0 while sequence_ids[token_start_index] != 1: token_start_index += 1 token_end_index = len(inputs["input_ids"][i]) - 1 while sequence_ids[token_end_index] != 1: token_end_index -= 1 # 如果答案超出了上下文的范围,则设置为CLS token的索引 if offset[token_start_index][0] > end_char or offset[token_end_index][1] < start_char: start_positions.append(token_start_index) end_positions.append(token_start_index) else: while token_start_index < len(offset) and offset[token_start_index][0] <= start_char: token_start_index += 1 start_positions.append(token_start_index - 1) while offset[token_end_index][1] >= end_char: token_end_index -= 1 end_positions.append(token_end_index + 1) inputs["start_positions"] = start_positions inputs["end_positions"] = end_positions return inputs tokenized_datasets = dataset.map(preprocess_function, batched=True)
5. 设置训练参数
设定训练的超参数,例如批大小、学习率、训练轮数等。
training_args = TrainingArguments( output_dir="./results", evaluation_strategy="epoch", learning_rate=2e-5, per_device_train_batch_size=8, per_device_eval_batch_size=8, num_train_epochs=3, weight_decay=0.01, )
6. 使用 Trainer 进行训练
使用 Hugging Face 提供的 Trainer
API 来简化训练过程。
trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_datasets["train"], eval_dataset=tokenized_datasets["validation"], ) trainer.train()
7. 评估模型
使用Trainer
的evaluate
方法对模型进行评估,检查模型的回答准确性。
metrics = trainer.evaluate() print(metrics)
8. 使用模型进行预测
模型训练好后,可以使用它来回答问题。下面是一个简单的预测示例。
def answer_question(question, context): inputs = tokenizer(question, context, return_tensors="pt") outputs = model(**inputs) start_scores = outputs.start_logits end_scores = outputs.end_logits # 获取答案的起始和结束位置 answer_start = torch.argmax(start_scores) answer_end = torch.argmax(end_scores) + 1 # 将 token 转换成文本 answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(inputs["input_ids"][0][answer_start:answer_end])) return answer # 示例问题 question = "中国的首都是哪里?" context = "中国的首都是北京。北京是中国的政治、经济、文化中心。" print(answer_question(question, context))
代码运行后的效果
这段代码会输出类似以下的内容:
中国的首都是北京
最后
以上就是每日一库为你收集整理的使用Hugging Face Hub训练一个回答问题的详细代码实例的全部内容,希望文章能够帮你解决使用Hugging Face Hub训练一个回答问题的详细代码实例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复