使用 Hugging Face Amazon SageMaker 容器微调和部署汇总器模型,并带来您自己的脚本

NLP 领域最近取得了许多进展。 预训练模型和完全托管的 NLP 服务使 NLP 的访问和采用民主化。 亚马逊领悟 是一项完全托管的服务,可以执行自定义实体识别、主题建模、情感分析等 NLP 任务,以从数据中提取洞察力,而无需任何先前的 ML 经验。

去年,AWS 宣布了一项 合伙 拥抱脸 帮助将自然语言处理 (NLP) 模型更快地投入生产。 Hugging Face 是一个专注于 NLP 的开源 AI 社区。 他们基于 Python 的库(变压器) 提供工具来轻松使用流行的最先进的 Transformer 架构,如 BERT、RoBERTa 和 GPT。 您可以将这些模型应用于各种 NLP 任务,例如文本分类、信息提取和问答等。 其他类.

亚马逊SageMaker 是一项完全托管的服务,可为开发人员和数据科学家提供快速构建、训练和部署机器学习 (ML) 模型的能力。 SageMaker 消除了 ML 流程每个步骤的繁重工作,从而更轻松地开发高质量模型。 SageMaker Python SDK 提供开源 API 和容器,以使用多种不同的 ML 和深度学习框架在 SageMaker 上训练和部署模型。

Hugging Face 与 SageMaker 的集成允许您在自己的特定领域用例上大规模构建 Hugging Face 模型。

在这篇文章中,我们将向您介绍如何在 SageMaker 上构建和部署自定义拥抱脸文本摘要器的示例。 为此,我们使用 Pegasus [1],这是第一个基于 Transformer 的模型,专门针对为抽象文本摘要量身定制的目标进行了预训练。 BERT 预先训练了屏蔽句子中的随机词; 相反,在 Pegasus 的预训练期间,句子被从输入文档中屏蔽。 然后,该模型使用所有未屏蔽的句子作为上下文,将缺失的句子生成为单个输出序列,从而创建文档的执行摘要。

由于 HuggingFace 库的灵活性,您可以轻松地将本文中显示的代码调整为其他类型的变压器模型,例如 t5、BART 等。

加载您自己的数据集以微调 Hugging Face 模型

要从 CSV 文件加载自定义数据集,我们使用 load_dataset Transformers 包中的方法。 我们可以使用 datasets.Dataset.map 功能。 的 map 函数迭代加载的数据集并将标记化函数应用于每个示例。 然后可以将标记化的数据集传递给训练器以微调模型。 请参阅以下代码:

# Python
def tokenize(batch):
    tokenized_input = tokenizer(batch[args.input_column], padding='max_length', truncation=True, max_length=args.max_source)
    tokenized_target = tokenizer(batch[args.target_column], padding='max_length', truncation=True, max_length=args.max_target)
    tokenized_input['target'] = tokenized_target['input_ids']

    return tokenized_input
    

def load_and_tokenize_dataset(data_dir):
    for file in os.listdir(data_dir):
        dataset = load_dataset("csv", data_files=os.path.join(data_dir, file), split='train')
    tokenized_dataset = dataset.map(lambda batch: tokenize(batch), batched=True, batch_size=512)
    tokenized_dataset.set_format('numpy', columns=['input_ids', 'attention_mask', 'labels'])
    
    return tokenized_dataset

为 Hugging Face SageMaker 估计器构建训练脚本

如帖子中所述 AWS和Hugging Face合作以简化和加速自然语言处理模型的采用,在 SageMaker 上训练 Hugging Face 模型从未如此简单。 我们可以通过使用 Hugging Face 估计器来做到这一点 SageMaker 开发工具包.

以下代码片段在我们的数据集上微调 Pegasus。 你还可以找到很多 样本笔记本 指导您对不同类型的模型进行微调,这些模型直接在 Transformers GitHub 存储库中可用。 为了启用分布式训练,我们可以使用 数据并行库 在 SageMaker 中,它已内置在 HuggingFace Trainer API 中。 为了启用数据并行性,我们需要定义 distribution Hugging Face 估计器中的参数。

# Python
from sagemaker.huggingface import HuggingFace
# configuration for running training on smdistributed Data Parallel
distribution = {'smdistributed':{'dataparallel':{ 'enabled': True }}}
huggingface_estimator = HuggingFace(entry_point='train.py',
                                    source_dir='code',
                                    base_job_name='huggingface-pegasus',
                                    instance_type= 'ml.g4dn.16xlarge',
                                    instance_count=1,
                                    transformers_version='4.6',
                                    pytorch_version='1.7',
                                    py_version='py36',
                                    output_path=output_path,
                                    role=role,
                                    hyperparameters = {
                                        'model_name': 'google/pegasus-xsum',
                                        'epoch': 10,
                                        'per_device_train_batch_size': 2
                                    },
                                    distribution=distribution)
huggingface_estimator.fit({'train': training_input_path, 'validation': validation_input_path, 'test': test_input_path})

您可以配置的最大训练批量大小取决于模型大小和所用实例的 GPU 内存。 如果启用 SageMaker 分布式训练,则总批次大小是分布在每个设备/GPU 上的每个批次的总和。 如果我们使用 ml.g4dn.16xlarge 进行分布式训练而不是 ml.g4dn.xlarge 实例,我们的内存是 ml.g8dn.xlarge 实例(4 个 GPU)的八倍(1 个 GPU)。 每个设备的批量大小保持不变,但有八个设备在并行训练。

与 SageMaker 一样,我们创建了一个 train.py 脚本与脚本模式一起使用并传递超参数进行训练。 Pegasus 的以下代码片段加载模型并使用 Transformer 对其进行训练 Trainer 类:

# Python
from transformers import (
    AutoModelForSeq2SeqLM,
    AutoTokenizer,
    Seq2SeqTrainer,
    Seq2seqTrainingArguments
)

model = AutoModelForSeq2SeqLM.from_pretrained(model_name).to(device)
    
training_args = Seq2seqTrainingArguments(
    output_dir=args.model_dir,
    num_train_epochs=args.epoch,
    per_device_train_batch_size=args.train_batch_size,
    per_device_eval_batch_size=args.eval_batch_size,
    warmup_steps=args.warmup_steps,
    weight_decay=args.weight_decay,
    logging_dir=f"{args.output_data_dir}/logs",
    logging_strategy='epoch',
    evaluation_strategy='epoch',
    saving_strategy='epoch',
    adafactor=True,
    do_train=True,
    do_eval=True,
    do_predict=True,
    save_total_limit = 3,
    load_best_model_at_end=True,
    metric_for_best_model='eval_loss'
    # With the goal to deploy the best checkpoint to production
    # it is important to set load_best_model_at_end=True,
    # this makes sure that the last model is saved at the root
    # of the model_dir” directory
)
    
trainer = Seq2SeqTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset['train'],
    eval_dataset=dataset['validation']
)

trainer.train()
trainer.save_model()

# Get rid of unused checkpoints inside the container to limit the model.tar.gz size
os.system(f"rm -rf {args.model_dir}/checkpoint-*/")

完整代码可在 GitHub上.

将经过训练的 Hugging Face 模型部署到 SageMaker

我们 Hugging Face 的朋友在 SageMaker for Transformers 模型上的推理比以往任何时候都更简单,这要归功于 SageMaker 拥抱人脸推理工具包. 只需设置环境变量即可直接部署之前训练好的模型 "HF_TASK":"summarization" (有关说明,请参阅 飞马模型), 选择 部署,然后选择 亚马逊SageMaker,无需编写推理脚本。

但是,如果您需要某种特定的方法来生成或后处理预测,例如根据不同文本生成参数的列表生成几个摘要建议,那么编写自己的推理脚本可能很有用且相对简单:

# Python
# inference.py script

import os
import json
import torch
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def model_fn(model_dir):
    # Create the model and tokenizer and load weights
    # from the previous training Job, passed here through "model_dir"
    # that is reflected in HuggingFaceModel "model_data"
    tokenizer = AutoTokenizer.from_pretrained(model_dir)
    model = AutoModelForSeq2SeqLM.from_pretrained(model_dir).to(device).eval()
    
    model_dict = {'model':model, 'tokenizer':tokenizer}
    
    return model_dict
        

def predict_fn(input_data, model_dict):
    # Return predictions/generated summaries
    # using the loaded model and tokenizer on input_data
    text = input_data.pop('inputs')
    parameters_list = input_data.pop('parameters_list', None)
    
    tokenizer = model_dict['tokenizer']
    model = model_dict['model']

    # Parameters may or may not be passed    
    input_ids = tokenizer(text, truncation=True, padding='longest', return_tensors="pt").input_ids.to(device)
    
    if parameters_list:
        predictions = []
        for parameters in parameters_list:
            output = model.generate(input_ids, **parameters)
            predictions.append(tokenizer.batch_decode(output, skip_special_tokens=True))
    else:
        output = model.generate(input_ids)
        predictions = tokenizer.batch_decode(output, skip_special_tokens=True)
    
    return predictions
    
    
def input_fn(request_body, request_content_type):
    # Transform the input request to a dictionary
    request = json.loads(request_body)
    return request

如前面的代码所示,这样的 SageMaker 上 HuggingFace 的推理脚本只需要以下模板函数:

  • 模型_fn() - 读取里面训练作业结束时保存的内容 SM_MODEL_DIR, 或从现有的模型权重目录保存为 tar.gz 文件 亚马逊简单存储服务 (亚马逊 S3)。 它用于加载经过训练的模型和相关的分词器。
  • input_fn() – 格式化从向端点发出的请求中接收到的数据。
  • Forecast_fn() – 调用的输出 model_fn() (模型和标记器)对输出进行推理 input_fn() (格式化的数据)。

或者,您可以创建一个 output_fn() 用于推理格式化的函数,使用的输出 predict_fn(),我们没有在这篇文章中展示。

然后,我们可以使用相关的推理脚本将经过训练的 Hugging Face 模型部署到 SageMaker 拥抱脸 SageMaker 模型 类:

# Python
from sagemaker.huggingface import HuggingFaceModel

model = HuggingFaceModel(model_data=huggingface_estimator.model_data,
                     role=role,
                     framework_version='1.7',
                     py_version='py36',
                     entry_point='inference.py',
                     source_dir='code')
                     
predictor = model.deploy(initial_instance_count=1,
                         instance_type='ml.g4dn.xlarge'
                         )

测试部署的模型

对于这个演示,我们在 女性电子商务服装评论数据集,其中包含对服装文章的评论(我们将其视为输入文本)及其相关标题(我们将其视为摘要)。 在我们删除缺少标题的文章后,数据集包含 19,675 条评论。 在一个 ml.p70xlarge 实例上,在包含 3.5% 文章的训练集上对 Pegasus 模型进行五个 epoch 的微调大约需要 3.16 小时。

然后,我们可以部署模型并使用测试集中的一些示例数据对其进行测试。 以下是描述毛衣的示例评论:

# Python
Review Text
"I ordered this sweater in green in petite large. The color and knit is beautiful and the shoulders and body fit comfortably; however, the sleeves were very long for a petite. I roll them, and it looks okay but would have rather had a normal petite length sleeve."

Original Title
"Long sleeves"

Rating
3

由于我们托管在 SageMaker 端点中的自定义推理脚本,我们可以使用不同的文本生成参数为此审查生成多个摘要。 例如,我们可以要求端点生成一系列非常短到中等长度的摘要,指定不同的长度惩罚(长度惩罚越小,生成的摘要越短)。 以下是一些参数输入示例,以及后续机器生成的摘要:

# Python
inputs = {
    "inputs":[
"I ordered this sweater in green in petite large. The color and knit is   beautiful and the shoulders and body fit comfortably; however, the sleeves were very long for a petite. I roll them, and it looks okay but would have rather had a normal petite length sleeve."
    ],

    "parameters_list":[
        {
            "length_penalty":2
        },
	{
            "length_penalty":1
        },
	{
            "length_penalty":0.6
        },
        {
            "length_penalty":0.4
        }
    ]

result = predictor.predict(inputs)
print(result)

[
    ["Beautiful color and knit but sleeves are very long for a petite"],
    ["Beautiful sweater, but sleeves are too long for a petite"],
    ["Cute, but sleeves are long"],
    ["Very long sleeves"]
]

你更喜欢哪个总结? 第一个生成的标题以四分之一的字数捕获了有关评论的所有重要事实。 相比之下,最后一个只用了三个字(不到原评论长度的1/10),重点突出了卫衣最重要的特点。

结论

您可以在自定义数据集上微调文本摘要器,并将其部署到 SageMaker 上的生产环境中,此简单示例可在 GitHub上。 额外 样本笔记本 还可以在 SageMaker 上训练和部署 Hugging Face 模型。

与往常一样,AWS欢迎反馈。 请提交任何意见或问题。

参考资料

[1] PEGASUS:使用提取的间隔句进行抽象摘要的预训练


关于作者

使用 Hugging Face Amazon SageMaker 容器以及您自己的脚本 PlatoBlockchain 数据智能来微调和部署摘要生成器模型。垂直搜索。人工智能。 维克多·马列舍维奇 是 AWS 专业服务的机器学习工程师,对自然语言处理和 MLOps 充满热情。 他与客户合作开发具有挑战性的深度学习模型,并在 AWS 上投入生产。 在业余时间,他喜欢与朋友分享一杯红酒和一些奶酪。

使用 Hugging Face Amazon SageMaker 容器以及您自己的脚本 PlatoBlockchain 数据智能来微调和部署摘要生成器模型。垂直搜索。人工智能。阿姆纳·纳吉米 是 AWS 专业服务的数据科学家。 她热衷于帮助客户利用大数据和人工智能技术进行创新,从数据中挖掘商业价值和洞察力。 在业余时间,她喜欢园艺和到新地方旅行。

时间戳记:

更多来自 AWS机器学习