Transformers 4.37 中文文档(五)(7)https://developer.aliyun.com/article/1565247
评估
文档问题回答的评估需要大量的后处理。为了避免占用太多时间,本指南跳过了评估步骤。Trainer 在训练过程中仍会计算评估损失,因此您不会完全不了解模型的性能。提取式问答通常使用 F1/完全匹配进行评估。如果您想自己实现,请查看 Hugging Face 课程的问答章节获取灵感。
训练
恭喜!您已成功完成本指南中最困难的部分,现在您已经准备好训练自己的模型。训练包括以下步骤:
- 使用与预处理相同的检查点加载 AutoModelForDocumentQuestionAnswering 模型。
- 在 TrainingArguments 中定义您的训练超参数。
- 定义一个将示例批处理在一起的函数,这里 DefaultDataCollator 将做得很好
- 将训练参数传递给 Trainer,以及模型、数据集和数据收集器。
- 调用 train()来微调您的模型。
>>> from transformers import AutoModelForDocumentQuestionAnswering >>> model = AutoModelForDocumentQuestionAnswering.from_pretrained(model_checkpoint)
在 TrainingArguments 中使用output_dir
指定保存模型的位置,并根据需要配置超参数。如果希望与社区分享模型,请将push_to_hub
设置为True
(您必须登录 Hugging Face 才能上传模型)。在这种情况下,output_dir
也将是将推送模型检查点的存储库的名称。
>>> from transformers import TrainingArguments >>> # REPLACE THIS WITH YOUR REPO ID >>> repo_id = "MariaK/layoutlmv2-base-uncased_finetuned_docvqa" >>> training_args = TrainingArguments( ... output_dir=repo_id, ... per_device_train_batch_size=4, ... num_train_epochs=20, ... save_steps=200, ... logging_steps=50, ... evaluation_strategy="steps", ... learning_rate=5e-5, ... save_total_limit=2, ... remove_unused_columns=False, ... push_to_hub=True, ... )
定义一个简单的数据收集器来将示例批处理在一起。
>>> from transformers import DefaultDataCollator >>> data_collator = DefaultDataCollator()
最后,将所有内容汇总,并调用 train():
>>> from transformers import Trainer >>> trainer = Trainer( ... model=model, ... args=training_args, ... data_collator=data_collator, ... train_dataset=encoded_train_dataset, ... eval_dataset=encoded_test_dataset, ... tokenizer=processor, ... ) >>> trainer.train()
要将最终模型添加到🤗 Hub,创建一个模型卡并调用push_to_hub
:
>>> trainer.create_model_card() >>> trainer.push_to_hub()
推理
现在您已经微调了一个 LayoutLMv2 模型,并将其上传到🤗 Hub,您可以用它进行推理。尝试使用微调模型进行推理的最简单方法是在 Pipeline 中使用它。
让我们举个例子:
>>> example = dataset["test"][2] >>> question = example["query"]["en"] >>> image = example["image"] >>> print(question) >>> print(example["answers"]) 'Who is ‘presiding’ TRRF GENERAL SESSION (PART 1)?' ['TRRF Vice President', 'lee a. waller']
接下来,使用您的模型为文档问题回答实例化一个流水线,并将图像+问题组合传递给它。
>>> from transformers import pipeline >>> qa_pipeline = pipeline("document-question-answering", model="MariaK/layoutlmv2-base-uncased_finetuned_docvqa") >>> qa_pipeline(image, question) [{'score': 0.9949808120727539, 'answer': 'Lee A. Waller', 'start': 55, 'end': 57}]
如果愿意,也可以手动复制流水线的结果:
- 将一张图片和一个问题,使用模型的处理器为其准备好。
- 将结果或预处理通过模型前向传递。
- 模型返回
start_logits
和end_logits
,指示答案起始处和答案结束处的标记。两者的形状都是(batch_size, sequence_length)。 - 对
start_logits
和end_logits
的最后一个维度进行 argmax 操作,以获取预测的start_idx
和end_idx
。 - 使用分词器解码答案。
>>> import torch >>> from transformers import AutoProcessor >>> from transformers import AutoModelForDocumentQuestionAnswering >>> processor = AutoProcessor.from_pretrained("MariaK/layoutlmv2-base-uncased_finetuned_docvqa") >>> model = AutoModelForDocumentQuestionAnswering.from_pretrained("MariaK/layoutlmv2-base-uncased_finetuned_docvqa") >>> with torch.no_grad(): ... encoding = processor(image.convert("RGB"), question, return_tensors="pt") ... outputs = model(**encoding) ... start_logits = outputs.start_logits ... end_logits = outputs.end_logits ... predicted_start_idx = start_logits.argmax(-1).item() ... predicted_end_idx = end_logits.argmax(-1).item() >>> processor.tokenizer.decode(encoding.input_ids.squeeze()[predicted_start_idx : predicted_end_idx + 1]) 'lee a. waller'
ataset, … tokenizer=processor, … ) trainer.train()
要将最终模型添加到🤗 Hub,创建一个模型卡并调用`push_to_hub`: ```py >>> trainer.create_model_card() >>> trainer.push_to_hub()
推理
现在您已经微调了一个 LayoutLMv2 模型,并将其上传到🤗 Hub,您可以用它进行推理。尝试使用微调模型进行推理的最简单方法是在 Pipeline 中使用它。
让我们举个例子:
>>> example = dataset["test"][2] >>> question = example["query"]["en"] >>> image = example["image"] >>> print(question) >>> print(example["answers"]) 'Who is ‘presiding’ TRRF GENERAL SESSION (PART 1)?' ['TRRF Vice President', 'lee a. waller']
接下来,使用您的模型为文档问题回答实例化一个流水线,并将图像+问题组合传递给它。
>>> from transformers import pipeline >>> qa_pipeline = pipeline("document-question-answering", model="MariaK/layoutlmv2-base-uncased_finetuned_docvqa") >>> qa_pipeline(image, question) [{'score': 0.9949808120727539, 'answer': 'Lee A. Waller', 'start': 55, 'end': 57}]
如果愿意,也可以手动复制流水线的结果:
- 将一张图片和一个问题,使用模型的处理器为其准备好。
- 将结果或预处理通过模型前向传递。
- 模型返回
start_logits
和end_logits
,指示答案起始处和答案结束处的标记。两者的形状都是(batch_size, sequence_length)。 - 对
start_logits
和end_logits
的最后一个维度进行 argmax 操作,以获取预测的start_idx
和end_idx
。 - 使用分词器解码答案。
>>> import torch >>> from transformers import AutoProcessor >>> from transformers import AutoModelForDocumentQuestionAnswering >>> processor = AutoProcessor.from_pretrained("MariaK/layoutlmv2-base-uncased_finetuned_docvqa") >>> model = AutoModelForDocumentQuestionAnswering.from_pretrained("MariaK/layoutlmv2-base-uncased_finetuned_docvqa") >>> with torch.no_grad(): ... encoding = processor(image.convert("RGB"), question, return_tensors="pt") ... outputs = model(**encoding) ... start_logits = outputs.start_logits ... end_logits = outputs.end_logits ... predicted_start_idx = start_logits.argmax(-1).item() ... predicted_end_idx = end_logits.argmax(-1).item() >>> processor.tokenizer.decode(encoding.input_ids.squeeze()[predicted_start_idx : predicted_end_idx + 1]) 'lee a. waller'