合作伙伴关系:Amazon SageMaker 和 Hugging Face
合作伙伴关系:Amazon SageMaker 和 Hugging Face
看这些笑容!
今天,我们宣布Hugging Face和亚马逊之间的战略合作伙伴关系,以便让公司更容易利用最先进的机器学习模型,并更快地推出尖端的自然语言处理功能。
通过此合作伙伴关系,Hugging Face正在将亚马逊网络服务作为其首选云提供商,向其客户提供服务。
作为使我们的共同客户能够使用的第一步,Hugging Face和亚马逊正在推出新的Hugging Face深度学习容器(DLC),以便更轻松地在亚马逊SageMaker中训练Hugging Face Transformer模型。
要了解如何访问和使用带有亚马逊SageMaker Python SDK的新Hugging Face DLC,请查看下面的指南和资源。
在2021年7月8日,我们扩展了亚马逊SageMaker的集成,以添加Transformer模型的轻松部署和推断功能。如果您想了解如何轻松使用亚马逊SageMaker部署Hugging Face模型,请查看新的博客文章和文档。
功能和优势🔥
只需一条命令
借助亚马逊SageMaker中提供的新Hugging Face深度学习容器,训练尖端的基于Transformer的自然语言处理模型变得更加简单。有专门针对TensorFlow和PyTorch的变体,适用于单GPU、单节点多GPU和多节点集群。
加速从科学到生产的机器学习
除了Hugging Face DLCs,我们还为SageMaker Python SDK创建了一流的Hugging Face扩展,以加速数据科学团队,将设置和运行实验所需的时间从几天减少到几分钟。
您可以将Hugging Face DLCs与亚马逊SageMaker的自动模型调整功能结合使用,以自动优化您的训练超参数,并快速提高模型的准确性。
借助基于Web的SageMaker Studio集成开发环境(IDE),您可以轻松跟踪和比较您的实验和训练工件。
内置性能
借助Hugging Face DLCs,SageMaker客户将受益于针对PyTorch或TensorFlow的内置性能优化,以更快地训练NLP模型,并根据您的工作负载选择具有最佳价格/性能比的训练基础架构。
Hugging Face DLCs与SageMaker分布式训练库完全集成,以比以往任何时候都更快地训练模型,使用亚马逊EC2上可用的最新一代实例。
资源、文档和示例📄
下面您可以找到所有重要资源,包括所有已发布的博客文章、视频、文档和示例笔记本/脚本。
博客/视频
- AWS:与Hugging Face共同拥抱自然语言处理
- 使用亚马逊SageMaker轻松部署Hugging Face模型
- AWS和Hugging Face合作简化和加速自然语言处理模型的采用
- 步骤演练:端到端文本分类
- 在亚马逊SageMaker上使用Hugging Face模型
- 分布式训练:使用🤗 Transformers和亚马逊SageMaker训练BART/T5进行摘要
- 将Hugging Face Transformers模型从S3部署到亚马逊SageMaker
- 将Hugging Face Transformers模型从模型中心部署到亚马逊SageMaker
文档
- 亚马逊SageMaker的Hugging Face文档
- 在亚马逊SageMaker上进行训练
- 将模型部署到亚马逊SageMaker
- 常见问题解答
- Hugging Face的亚马逊SageMaker文档
- Hugging Face的Python SDK SageMaker文档
- 深度学习容器
- SageMaker的分布式数据并行库
- SageMaker的分布式模型并行库
示例笔记本/脚本
- 所有笔记本
- 入门Pytorch
- 入门Tensorflow
- 分布式训练数据并行性
- 分布式训练模型并行性
- 使用Spot实例继续训练
- SageMaker指标
- Tensorflow的分布式训练数据并行性
- 分布式训练摘要
- 使用视觉Transformer进行图像分类
- 将10000多个Hugging Face Transformers之一部署到亚马逊SageMaker进行推断
- 将Hugging Face Transformer模型从S3部署到SageMaker进行推断
入门指南:端到端文本分类 🧭
在这个入门指南中,我们将使用新的Hugging Face DLCs和Amazon SageMaker扩展,使用transformers和datasets库训练一个基于transformer的二元文本分类模型。
我们将使用Amazon SageMaker笔记本实例进行演示。您可以在这里了解如何设置笔记本实例。
我们将要做的事情:
- 设置开发环境并安装sagemaker
- 创建训练脚本
train.py
- 预处理数据并将其上传到Amazon S3
- 创建HuggingFace Estimator并训练我们的模型
设置开发环境并安装sagemaker
如上所述,我们将使用SageMaker笔记本实例。要开始,请转到您的Jupyter Notebook或JupyterLab,并使用conda_pytorch_p36内核创建一个新的笔记本。
注意:使用Jupyter是可选的:我们还可以从任何已安装SDK、连接到云端并具有适当权限的位置启动SageMaker训练作业,例如笔记本电脑、其他IDE或任务调度器,如Airflow或AWS Step Functions。
之后,我们可以安装所需的依赖项
pip install "sagemaker>=2.31.0" "transformers==4.6.1" "datasets[s3]==1.6.2" --upgrade
要在SageMaker上运行训练,我们需要创建一个sagemaker Session,并提供一个具有正确权限的IAM角色。此IAM角色将稍后附加到TrainingJob,使其能够下载数据,例如来自Amazon S3的数据。
import sagemaker
sess = sagemaker.Session()
# sagemaker session bucket -> 用于上传数据、模型和日志
# 如果不存在,sagemaker将自动创建此bucket
sagemaker_session_bucket=None
if sagemaker_session_bucket is None and sess is not None:
# 如果未指定bucket名称,则设置为默认bucket
sagemaker_session_bucket = sess.default_bucket()
role = sagemaker.get_execution_role()
sess = sagemaker.Session(default_bucket=sagemaker_session_bucket)
print(f"sagemaker角色arn: {role}")
print(f"sagemaker bucket: {sess.default_bucket()}")
print(f"sagemaker会话区域: {sess.boto_region_name}")
创建训练脚本train.py
在SageMaker的TrainingJob
中,我们执行一个带有命名参数的python脚本。在这个示例中,我们使用PyTorch和transformers。脚本将会
- 传递传入的参数(来自HuggingFace Estimator的超参数)
- 加载数据集
- 定义计算指标的函数
- 设置我们的
Trainer
- 使用
trainer.train()
进行训练 - 在训练结束时评估训练并将模型保存到S3。
from transformers import AutoModelForSequenceClassification, Trainer, TrainingArguments
from sklearn.metrics import accuracy_score, precision_recall_fscore_support
from datasets import load_from_disk
import random
import logging
import sys
import argparse
import os
import torch
if __name__ == "__main__":
parser = argparse.ArgumentParser()
# 客户端发送的超参数将作为命令行参数传递给脚本。
parser.add_argument("--epochs", type=int, default=3)
parser.add_argument("--train-batch-size", type=int, default=32)
parser.add_argument("--eval-batch-size", type=int, default=64)
parser.add_argument("--warmup_steps", type=int, default=500)
parser.add_argument("--model_name", type=str)
parser.add_argument("--learning_rate", type=str, default=5e-5)
# 数据、模型和输出目录
parser.add_argument("--output-data-dir", type=str, default=os.environ["SM_OUTPUT_DATA_DIR"])
parser.add_argument("--model-dir", type=str, default=os.environ["SM_MODEL_DIR"])
parser.add_argument("--n_gpus", type=str, default=os.environ["SM_NUM_GPUS"])
parser.add_argument("--training_dir", type=str, default=os.environ["SM_CHANNEL_TRAIN"])
parser.add_argument("--test_dir", type=str, default=os.environ["SM_CHANNEL_TEST"])
args, _ = parser.parse_known_args()
# 设置日志记录
logger = logging.getLogger(__name__)
logging.basicConfig(
level=logging.getLevelName("INFO"),
handlers=[logging.StreamHandler(sys.stdout)],
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
# 加载数据集
train_dataset = load_from_disk(args.training_dir)
test_dataset = load_from_disk(args.test_dir)
logger.info(f" 加载的train_dataset长度为: {len(train_dataset)}")
logger.info(f" 加载的test_dataset长度为: {len(test_dataset)}")
# 用于二元分类的计算指标函数
def compute_metrics(pred):
labels = pred.label_ids
preds = pred.predictions.argmax(-1)
precision, recall, f1, _ = precision_recall_fscore_support(labels, preds, average="binary")
acc = accuracy_score(labels, preds)
return {"accuracy": acc, "f1": f1, "precision": precision, "recall": recall}
# 从模型中心下载模型
model = AutoModelForSequenceClassification.from_pretrained(args.model_name)
# 定义训练参数
training_args = TrainingArguments(
output_dir=args.model_dir,
num_train_epochs=args.epochs,
per_device_train_batch_size=args.train_batch_size,
per_device_eval_batch_size=args.eval_batch_size,
warmup_steps=args.warmup_steps,
evaluation_strategy="epoch",
logging_dir=f"{args.output_data_dir}/logs",
learning_rate=float(args.learning_rate),
)
# 创建Trainer实例
trainer = Trainer(
model=model,
args=training_args,
compute_metrics=compute_metrics,
train_dataset=train_dataset,
eval_dataset=test_dataset,
)
# 训练模型
trainer.train()
# 评估模型
eval_result = trainer.evaluate(eval_dataset=test_dataset)
# 将评估结果写入文件,以便稍后在s3输出中访问
with open(os.path.join(args.output_data_dir, "eval_results.txt"), "w") as writer:
print(f"***** 评估结果 *****")
for key, value in sorted(eval_result.items()):
writer.write(f"{key} = {value}\\n")
# 将模型保存到s3;默认为/opt/ml/model,SageMaker将其发送到S3
trainer.save_model(args.model_dir)
预处理数据并上传至S3
我们使用datasets
库来下载和预处理imdb
数据集。预处理后,数据集将被上传至当前会话的默认S3桶sess.default_bucket()
,该桶将在我们的训练任务中使用。 imdb
数据集包括25000个训练样本和25000个测试样本,这些样本是高度极性的电影评论。
import botocore
from datasets import load_dataset
from transformers import AutoTokenizer
from datasets.filesystems import S3FileSystem
# 用于预处理的分词器
tokenizer_name = 'distilbert-base-uncased'
# S3文件系统客户端
s3 = S3FileSystem()
# 使用的数据集
dataset_name = 'imdb'
# 数据的S3键前缀
s3_prefix = 'datasets/imdb'
# 加载数据集
dataset = load_dataset(dataset_name)
# 下载分词器
tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)
# 分词器辅助函数
def tokenize(batch):
return tokenizer(batch['text'], padding='max_length', truncation=True)
# 加载数据集
train_dataset, test_dataset = load_dataset('imdb', split=['train', 'test'])
test_dataset = test_dataset.shuffle().select(range(10000)) # 将测试集大小缩小到10k
# 对数据集进行分词
train_dataset = train_dataset.map(tokenize, batched=True, batch_size=len(train_dataset))
test_dataset = test_dataset.map(tokenize, batched=True, batch_size=len(test_dataset))
# 设置为PyTorch格式
train_dataset = train_dataset.rename_column("label", "labels")
train_dataset.set_format('torch', columns=['input_ids', 'attention_mask', 'labels'])
test_dataset = test_dataset.rename_column("label", "labels")
test_dataset.set_format('torch', columns=['input_ids', 'attention_mask', 'labels'])
# 将train_dataset保存到S3
training_input_path = f's3://{sess.default_bucket()}/{s3_prefix}/train'
train_dataset.save_to_disk(training_input_path, fs=s3)
# 将test_dataset保存到S3
test_input_path = f's3://{sess.default_bucket()}/{s3_prefix}/test'
test_dataset.save_to_disk(test_input_path, fs=s3)
创建HuggingFace Estimator并训练模型
为了创建一个SageMaker的Trainingjob
,我们可以使用HuggingFace Estimator。Estimator负责处理完整的Amazon SageMaker训练过程。在Estimator中,我们定义了使用哪个微调脚本作为entry_point
,使用哪个instance_type
,传递了哪些超参数。此外,还提供了一些高级控制选项,如自定义输出和检查点位置、指定本地存储大小或网络配置等。
SageMaker会为我们启动和管理所有所需的Amazon EC2实例,使用Hugging Face DLC,它会上传提供的微调脚本,例如我们的train.py
,然后从S3桶sess.default_bucket()
下载数据到容器中。一旦数据准备完毕,训练任务将自动开始运行。
/opt/conda/bin/python train.py --epochs 1 --model_name distilbert-base-uncased --train_batch_size 32
在HuggingFace Estimator中定义的超参数作为命名参数传递。
from sagemaker.huggingface import HuggingFace
# 定义传递给训练任务的超参数
hyperparameters={'epochs': 1,
'train_batch_size': 32,
'model_name':'distilbert-base-uncased'
}
# 创建Estimator
huggingface_estimator = HuggingFace(
entry_point='train.py',
source_dir='./scripts',
instance_type='ml.p3.2xlarge',
instance_count=1,
role=role,
transformers_version='4.6',
pytorch_version='1.7',
py_version='py36',
hyperparameters=hyperparameters
)
调用.fit()方法并传递我们的S3 URI作为输入,开始训练。
# 使用我们上传的数据集作为输入开始训练任务
huggingface_estimator.fit({'train': training_input_path, 'test': test_input_path})
其他功能 🚀
除了深度学习容器和SageMaker SDK之外,我们还实现了其他额外的功能。
分布式训练:数据并行
您可以直接使用SageMaker数据并行库进行分布式训练。我们将数据并行功能直接加入到了Trainer中。如果您的train.py使用了Trainer API,您只需要在HuggingFace Estimator中定义分布参数即可。
- 示例笔记本PyTorch
- 示例笔记本TensorFlow
# 运行smdistributed数据并行训练的配置
distribution = {'smdistributed':{'dataparallel':{ 'enabled': True }}}
# 创建Estimator
huggingface_estimator = HuggingFace(
entry_point='train.py',
source_dir='./scripts',
instance_type='ml.p3dn.24xlarge',
instance_count=2,
role=role,
transformers_version='4.4.2',
pytorch_version='1.6.0',
py_version='py36',
hyperparameters = hyperparameters
distribution = distribution
)
“入门指南:端到端文本分类 🧭”示例可以用于分布式训练,无需任何更改。
分布式训练:模型并行
您可以直接使用SageMaker模型并行库进行分布式训练。我们将模型并行功能直接加入到了Trainer中。如果您的train.py
使用了Trainer API,您只需要在HuggingFace Estimator中定义分布参数即可。有关调整的详细信息,请参阅此处。
- 示例笔记本
# 运行smdistributed模型并行训练的配置
mpi_options = {
"enabled" : True,
"processes_per_host" : 8
}
smp_options = {
"enabled":True,
"parameters": {
"microbatches": 4,
"placement_strategy": "spread",
"pipeline": "interleaved",
"optimize": "speed",
"partitions": 4,
"ddp": True,
}
}
distribution={
"smdistributed": {"modelparallel": smp_options},
"mpi": mpi_options
}
# 创建Estimator
huggingface_estimator = HuggingFace(
entry_point='train.py',
source_dir='./scripts',
instance_type='ml.p3dn.24xlarge',
instance_count=2,
role=role,
transformers_version='4.4.2',
pytorch_version='1.6.0',
py_version='py36',
hyperparameters = hyperparameters,
distribution = distribution
)
Spot实例
通过为SageMaker Python SDK创建HuggingFace Framework扩展,我们还可以利用完全托管的EC2 Spot实例的好处,节省高达90%的训练成本。
注意:除非您的训练作业将很快完成,否则我们建议您在托管的Spot训练中使用检查点功能,因此您需要定义checkpoint_s3_uri
。
要在HuggingFace
Estimator中使用Spot实例,我们需要将use_spot_instances
参数设置为True
,并定义您的max_wait
和max_run
时间。您可以在这里阅读有关托管Spot训练生命周期的更多信息。
- 示例笔记本
# 传递给训练作业的超参数
hyperparameters={'epochs': 1,
'train_batch_size': 32,
'model_name':'distilbert-base-uncased',
'output_dir':'/opt/ml/checkpoints'
}
# 创建Estimator
huggingface_estimator = HuggingFace(
entry_point='train.py',
source_dir='./scripts',
instance_type='ml.p3.2xlarge',
instance_count=1,
checkpoint_s3_uri=f's3://{sess.default_bucket()}/checkpoints'
use_spot_instances=True,
max_wait=3600, # 此值应等于或大于以秒为单位的max_run'
max_run=1000,
role=role,
transformers_version='4.4',
pytorch_version='1.6',
py_version='py36',
hyperparameters = hyperparameters
)
# 训练时间:874秒
# 计费时间:105秒
# 托管Spot训练节省:88.0%
Git 代码仓库
当您创建一个 HuggingFace
Estimator 时,您可以指定一个存储在 GitHub 仓库中的训练脚本作为 Estimator 的入口点,这样您就不需要将脚本下载到本地。如果启用了 Git 支持,则 entry_point
和 source_dir
应为 Git 仓库中的相对路径(如果提供)。
以下是使用 git_config
与 transformers 仓库的示例脚本的示例。
请注意,您需要将 output_dir
定义为脚本的超参数,以便在训练后将模型保存到 S3 中。建议将 output_dir 定义为 /opt/ml/model
,因为它是默认的 SM_MODEL_DIR
,并且将上传到 S3。
- 示例笔记本
# 配置 git 设置
git_config = {'repo': 'https://github.com/huggingface/transformers.git','branch': 'master'}
# 创建 Estimator
huggingface_estimator = HuggingFace(
entry_point='run_glue.py',
source_dir='./examples/text-classification',
git_config=git_config,
instance_type='ml.p3.2xlarge',
instance_count=1,
role=role,
transformers_version='4.4',
pytorch_version='1.6',
py_version='py36',
hyperparameters=hyperparameters
)
SageMaker 指标
SageMaker 指标可以自动解析日志中的指标并将这些指标发送到 CloudWatch。如果您希望 SageMaker 解析日志,则在配置训练作业时必须指定要发送到 CloudWatch 的指标。您需要指定要发送的指标的名称以及 SageMaker 用于解析算法发出的日志以查找这些指标的正则表达式。
- 示例笔记本
# 定义指标定义
metric_definitions = [
{"Name": "train_runtime", "Regex": "train_runtime.*=\D*(.*?)$"},
{"Name": "eval_accuracy", "Regex": "eval_accuracy.*=\D*(.*?)$"},
{"Name": "eval_loss", "Regex": "eval_loss.*=\D*(.*?)$"},
]
# 创建 Estimator
huggingface_estimator = HuggingFace(
entry_point='train.py',
source_dir='./scripts',
instance_type='ml.p3.2xlarge',
instance_count=1,
role=role,
transformers_version='4.4',
pytorch_version='1.6',
py_version='py36',
metric_definitions=metric_definitions,
hyperparameters = hyperparameters
)
常见问题解答 🎯
您可以在文档中找到完整的常见问题解答。
Q: 什么是深度学习容器?
A: 深度学习容器(DLC)是预先安装有深度学习框架和库(例如 transformers、datasets、tokenizers)的 Docker 镜像,它们使得通过跳过从头开始构建和优化环境的复杂过程来训练模型变得容易。
Q: 我是否必须使用 SageMaker Python SDK 来使用 Hugging Face 深度学习容器?
A: 您可以在不使用 SageMaker Python SDK 的情况下使用 HF DLC,并使用其他 SDK(例如 AWS CLI 或 boto3)启动 SageMaker 训练作业。DLC 也可通过 Amazon ECR 提供,并可在任何选择的环境中拉取和使用。
Q: 为什么我应该使用 Hugging Face 深度学习容器?
A: DLC 是经过全面测试、维护和优化的深度学习环境,无需安装、配置或维护。
Q: 为什么我应该使用 SageMaker Training 来训练 Hugging Face 模型?
A: SageMaker Training 提供了许多优势,可以提升您在 Hugging Face 中的工作效率:(1)首先,它具有成本效益:训练实例仅在作业期间存在,并且按秒计费。不再有忘记关闭 GPU 实例导致整夜运行的风险:训练集群会在作业结束时立即停止!它还支持 EC2 Spot 容量,可以实现高达 90% 的成本降低。(2)SageMaker 还具有许多内置的自动化功能,有助于团队合作和 MLOps:训练元数据和日志会自动保存到无服务器的托管元存储库,并且与 S3 的 I/O(用于数据集、检查点和模型工件)是完全托管的。最后,SageMaker 还允许大幅度的扩展:您可以并行启动多个训练作业,还可以启动大规模分布式训练作业。
问:在我使用Amazon SageMaker训练了模型之后,我能在🤗/Transformers中使用它吗?
答:是的,您可以从S3下载训练好的模型,然后直接在transformers中使用它,或者上传到Hugging Face Model Hub中。
问:Amazon SageMaker如何保护我的数据和代码安全?
答:Amazon SageMaker提供了多种安全机制,包括静态加密和传输加密,虚拟私有云(VPC)连接以及身份和访问管理(IAM)。如果您想了解更多关于AWS云和Amazon SageMaker安全方面的信息,您可以访问Security in Amazon SageMaker and AWS Cloud Security。
问:这在我的地区可用吗?
答:有关受支持的地区列表,请访问AWS全球基础设施的AWS区域表。
问:我需要为使用DLCs从Hugging Face购买许可证吗?
答:不需要 – Hugging Face DLCs是开源的,并且根据Apache 2.0许可证进行许可。
问:如何在我的训练模型上运行推理?
答:您有多种选项来运行您的训练模型上的推理。其中一种选项是使用Hugging Face加速推理-API托管服务:首先将训练好的模型上传到您的Hugging Face账户以公开或私有方式部署它们。另一个很好的选择是使用SageMaker推理来在Amazon SageMaker中运行您自己的推理代码。我们正在努力提供一个集成解决方案,将Amazon SageMaker与Hugging Face推理DLCs结合起来 – 敬请关注!
问:您为这个解决方案提供高级支持或支持SLA吗?
答:AWS提供不同的技术支持层次,涵盖了AWS产品和服务的开发和生产问题 – 请参阅AWS Support以了解具体内容和范围。
如果您有问题,Hugging Face社区可以帮助回答或从中受益,请在Hugging Face论坛上发布。
如果您需要来自Hugging Face团队的高级支持,以加速您的NLP路线图,我们的专家加速计划为您提供了来自我们的开源、科学和ML工程团队的直接指导 – 请联系我们以了解更多信息。
问:通过这个合作,您下一步的计划是什么?
答:我们的共同目标是使最先进的机器学习民主化。我们将继续创新,使研究人员、数据科学家和ML从业者更容易管理、训练和运行最先进的模型。如果您对AWS与Hugging Face的集成有特性请求,请在Hugging Face社区论坛上告诉我们。
问:我在Azure Machine Learning或Google Cloud Platform中使用Hugging Face,这个合作对我有什么意义?
答:Hugging Face的一个基本目标是使最新的人工智能对尽可能多的人都可访问,无论他们使用哪个框架或开发环境。虽然我们将集中与亚马逊网络服务的集成努力作为首选云提供商,但我们将继续努力为所有的Hugging Face用户和客户提供服务,无论他们在何种计算环境中运行。