合作伙伴关系:Amazon SageMaker 和 Hugging Face

看看这些笑容!
今天,我们宣布 Hugging Face 与 Amazon 建立战略合作伙伴关系,旨在帮助企业更轻松地利用最先进的机器学习模型,并更快地推出尖端 NLP 功能。
通过此次合作,Hugging Face 将亚马逊网络服务作为其首选云提供商,为客户提供服务。
作为双方共同客户的第一个赋能步骤,Hugging Face 和 Amazon 正在推出新的 Hugging Face 深度学习容器(DLC),让在 Amazon SageMaker 中训练 Hugging Face Transformer 模型变得前所未有的简单。
要了解如何使用 Amazon SageMaker Python SDK 访问和使用新的 Hugging Face DLC,请查看下面的指南和资源。
2021 年 7 月 8 日,我们扩展了 Amazon SageMaker 集成,增加了 Transformers 模型的轻松部署和推理。如果您想了解如何使用 Amazon SageMaker 轻松部署 Hugging Face 模型,请查看新博客文章和文档。
特性与优势 🔥
仅需一条命令
通过 Amazon SageMaker 中提供的新的 Hugging Face 深度学习容器,训练尖端的基于 Transformer 的 NLP 模型从未如此简单。有针对 TensorFlow 和 PyTorch 专门优化的变体,适用于单 GPU、单节点多 GPU 和多节点集群。
加速机器学习从科学到生产的转化
除了 Hugging Face DLC,我们还为 SageMaker Python SDK 创建了一流的 Hugging Face 扩展,以加速数据科学团队,将设置和运行实验所需的时间从数天缩短到数分钟。
您可以将 Hugging Face DLC 与 Amazon SageMaker 的自动模型调优功能结合使用,以便自动优化训练超参数并快速提高模型的准确性。
借助基于 SageMaker Studio 的集成开发环境(IDE),您可以轻松跟踪和比较您的实验和训练工件。
内置性能
通过 Hugging Face DLC,SageMaker 客户将受益于针对 PyTorch 或 TensorFlow 的内置性能优化,从而更快地训练 NLP 模型,并灵活选择训练基础设施,为您的工作负载提供最佳性价比。
Hugging Face DLC 完全集成了 SageMaker 分布式训练库,可以使用 Amazon EC2 上可用的最新一代实例,比以往任何时候都更快地训练模型。
资源、文档与示例 📄
您可以在下方找到所有重要资源,包括已发布的博客文章、视频、文档和示例 Notebook/脚本。
博客/视频
- AWS:拥抱 Hugging Face 的自然语言处理
- 使用 Amazon SageMaker 轻松部署 Hugging Face 模型
- AWS 和 Hugging Face 合作,简化和加速自然语言处理模型的采用
- 演练:端到端文本分类
- 在 Amazon SageMaker 上使用 Hugging Face 模型
- 分布式训练:使用 🤗 Transformers 和 Amazon SageMaker 训练用于摘要任务的 BART/T5
- 从 S3 部署 Hugging Face Transformers 模型到 Amazon SageMaker
- 从 Model Hub 部署 Hugging Face Transformers 模型到 Amazon SageMaker
文档
- Amazon SageMaker 的 Hugging Face 文档
- 在 Amazon SageMaker 上运行训练
- 将模型部署到 Amazon SageMaker
- 常见问题
- Amazon SageMaker 关于 Hugging Face 的文档
- Python SDK SageMaker 关于 Hugging Face 的文档
- 深度学习容器
- SageMaker 的分布式数据并行库
- SageMaker 的分布式模型并行库
示例 Notebook
- 所有 Notebook
- PyTorch 入门
- Tensorflow 入门
- 分布式训练数据并行
- 分布式训练模型并行
- 竞价型实例并继续训练
- SageMaker 指标
- 分布式训练数据并行 Tensorflow
- 分布式训练摘要
- 使用 Vision Transformer 进行图像分类
- 将 10,000 多个 Hugging Face Transformers 模型部署到 Amazon SageMaker 进行推理
- 从 S3 部署 Hugging Face Transformer 模型到 SageMaker 进行推理
入门:端到端文本分类 🧭
在本入门指南中,我们将使用新的 Hugging Face DLC 和 Amazon SageMaker 扩展,通过 Transformers 和 Datasets 库训练用于二元文本分类的 Transformer 模型。
我们将使用 Amazon SageMaker Notebook 实例作为示例。您可以在此处了解如何设置 Notebook 实例。
我们将要做什么
- 设置开发环境并安装 SageMaker
- 创建训练脚本
train.py
- 预处理我们的数据并将其上传到 Amazon S3
- 创建 HuggingFace Estimator 并训练我们的模型
设置开发环境并安装 sagemaker
如上所述,我们将使用 SageMaker Notebook 实例进行此操作。要开始,您需要进入您的 Jupyter Notebook 或 JupyterLab 并使用 conda_pytorch_p36 内核创建一个新的 Notebook。
注意:使用 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 会话并提供具有正确权限的 IAM 角色。此 IAM 角色稍后将附加到训练作业,使其能够下载数据,例如从 Amazon S3。
import sagemaker
sess = sagemaker.Session()
# sagemaker session bucket -> used for uploading data, models and logs
# sagemaker will automatically create this bucket if it not exists
sagemaker_session_bucket=None
if sagemaker_session_bucket is None and sess is not None:
# set to default bucket if a bucket name is not given
sagemaker_session_bucket = sess.default_bucket()
role = sagemaker.get_execution_role()
sess = sagemaker.Session(default_bucket=sagemaker_session_bucket)
print(f"sagemaker role arn: {role}")
print(f"sagemaker bucket: {sess.default_bucket()}")
print(f"sagemaker session region: {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()
# hyperparameters sent by the client are passed as command-line arguments to the script.
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)
# Data, model, and output directories
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()
# Set up logging
logger = logging.getLogger(__name__)
logging.basicConfig(
level=logging.getLevelName("INFO"),
handlers=[logging.StreamHandler(sys.stdout)],
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
# load datasets
train_dataset = load_from_disk(args.training_dir)
test_dataset = load_from_disk(args.test_dir)
logger.info(f" loaded train_dataset length is: {len(train_dataset)}")
logger.info(f" loaded test_dataset length is: {len(test_dataset)}")
# compute metrics function for binary classification
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}
# download model from model hub
model = AutoModelForSequenceClassification.from_pretrained(args.model_name)
# define training args
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),
)
# create Trainer instance
trainer = Trainer(
model=model,
args=training_args,
compute_metrics=compute_metrics,
train_dataset=train_dataset,
eval_dataset=test_dataset,
)
# train model
trainer.train()
# evaluate model
eval_result = trainer.evaluate(eval_dataset=test_dataset)
# writes eval result to file which can be accessed later in s3 output
with open(os.path.join(args.output_data_dir, "eval_results.txt"), "w") as writer:
print(f"***** Eval results *****")
for key, value in sorted(eval_result.items()):
writer.write(f"{key} = {value}\\n")
# Saves the model to s3; default is /opt/ml/model which SageMaker sends to 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 used in preprocessing
tokenizer_name = 'distilbert-base-uncased'
# filesystem client for s3
s3 = S3FileSystem()
# dataset used
dataset_name = 'imdb'
# s3 key prefix for the data
s3_prefix = 'datasets/imdb'
# load dataset
dataset = load_dataset(dataset_name)
# download tokenizer
tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)
# tokenizer helper function
def tokenize(batch):
return tokenizer(batch['text'], padding='max_length', truncation=True)
# load dataset
train_dataset, test_dataset = load_dataset('imdb', split=['train', 'test'])
test_dataset = test_dataset.shuffle().select(range(10000)) # smaller the size for test dataset to 10k
# tokenize dataset
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))
# set format for 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'])
# save train_dataset to s3
training_input_path = f's3://{sess.default_bucket()}/{s3_prefix}/train'
train_dataset.save_to_disk(training_input_path,fs=s3)
# save test_dataset to 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 负责为我们启动和管理所有必需的带有 Hugging Face DLC 的 Amazon EC2 实例,它上传提供的微调脚本,例如我们的 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, which are passed into the training job
hyperparameters={'epochs': 1,
'train_batch_size': 32,
'model_name':'distilbert-base-uncased'
}
# create the 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 作为输入。
# starting the train job with our uploaded datasets as input
huggingface_estimator.fit({'train': training_input_path, 'test': test_input_path})
附加功能 🚀
除了深度学习容器和 SageMaker SDK,我们还实现了其他附加功能。
分布式训练:数据并行
您可以直接使用 SageMaker 数据并行库进行分布式训练。我们已将数据并行功能直接添加到 Trainer 中。如果您的 train.py 使用 Trainer API,您只需在 HuggingFace Estimator 中定义 distribution 参数即可。
# configuration for running training on smdistributed Data Parallel
distribution = {'smdistributed':{'dataparallel':{ 'enabled': True }}}
# create the 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 中定义 distribution 参数即可。
有关调整的详细信息,请查看此处。
# configuration for running training on smdistributed Model Parallel
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
}
# create the 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 Python SDK 创建 HuggingFace 框架扩展,我们还可以利用完全托管的 EC2 竞价型实例的优势,节省高达 90% 的训练成本。
注意:除非您的训练作业能很快完成,否则我们建议您在托管式竞价型训练中使用检查点,因此您需要定义checkpoint_s3_uri
。
要将竞价型实例与 HuggingFace
Estimator 配合使用,我们必须将 use_spot_instances
参数设置为 True
,并定义您的 max_wait
和 max_run
时间。您可以在此处阅读有关托管式竞价型训练生命周期的更多信息。
# hyperparameters, which are passed into the training job
hyperparameters={'epochs': 1,
'train_batch_size': 32,
'model_name':'distilbert-base-uncased',
'output_dir':'/opt/ml/checkpoints'
}
# create the 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, # This should be equal to or greater than max_run in seconds'
max_run=1000,
role=role,
transformers_version='4.4',
pytorch_version='1.6',
py_version='py36',
hyperparameters = hyperparameters
)
# Training seconds: 874
# Billable seconds: 105
# Managed Spot Training savings: 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。
# configure git settings
git_config = {'repo': 'https://github.com/huggingface/transformers.git','branch': 'master'}
# create the 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 解析日志,您必须在配置训练作业时指定您希望 SageMaker 发送到 CloudWatch 的指标。您指定要发送的指标名称和 SageMaker 用于解析算法发出的日志以查找这些指标的正则表达式。
# define metrics definitions
metric_definitions = [
{"Name": "train_runtime", "Regex": "train_runtime.*=\D*(.*?)$"},
{"Name": "eval_accuracy", "Regex": "eval_accuracy.*=\D*(.*?)$"},
{"Name": "eval_loss", "Regex": "eval_loss.*=\D*(.*?)$"},
]
# create the 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
)
常见问题解答 🎯
问:什么是深度学习容器?
答:深度学习容器(DLC)是预装了深度学习框架和库(如 transformers、datasets、tokenizers)的 Docker 镜像,通过让您跳过从头构建和优化环境的复杂过程,从而轻松训练模型。
问:我必须使用 SageMaker Python SDK 才能使用 Hugging Face 深度学习容器吗?
答:您可以在不使用 SageMaker Python SDK 的情况下使用 HF DLC,并使用其他 SDK 启动 SageMaker 训练作业,例如 AWS CLI 或 boto3。DLC 也可通过 Amazon ECR 获得,可以拉取并在任何选择的环境中使用。
问:为什么我应该使用 Hugging Face 深度学习容器?
答:DLC 是经过全面测试、维护和优化的深度学习环境,无需安装、配置或维护。
问:为什么我应该使用 SageMaker Training 来训练 Hugging Face 模型?
答:SageMaker Training 提供许多优势,将提高您使用 Hugging Face 的生产力:(1) 首先,它具有成本效益:训练实例仅在作业持续期间存在,并按秒付费。不再有整晚让 GPU 实例运行的风险:训练集群在作业结束时立即停止!它还支持 EC2 竞价容量,可将成本降低多达 90%。(2) SageMaker 还附带许多内置自动化功能,可促进团队协作和 MLOps:训练元数据和日志会自动持久化到无服务器托管的元数据存储,并且与 S3 的 I/O(用于数据集、检查点和模型工件)完全托管。最后,SageMaker 还允许大幅扩展和扩展:您可以并行启动多个训练作业,还可以启动大规模分布式训练作业。
问:我用 Amazon SageMaker 训练了模型,能用 🤗/Transformers 吗?
答:是的,您可以从 S3 下载训练好的模型,并直接与 transformers 一起使用,或将其上传到 Hugging Face 模型中心。
问:Amazon SageMaker 如何保护我的数据和代码?
答:Amazon SageMaker 提供多种安全机制,包括静态加密和传输中加密、虚拟私有云 (VPC) 连接和身份和访问管理 (IAM)。要了解更多关于 AWS 云和 Amazon SageMaker 中的安全,您可以访问Amazon SageMaker 中的安全和AWS 云安全。
问:这在我的地区可用吗?
答:有关受支持的区域列表,请访问AWS 区域表,了解所有 AWS 全球基础设施。
问:我需要向 Hugging Face 支付许可费才能使用 DLC 吗?
答:不需要——Hugging Face DLC 是开源的,并根据 Apache 2.0 许可。
问:如何在训练好的模型上运行推理?
答:您有多种选项可以在训练好的模型上运行推理。一种选择是使用 Hugging Face 加速推理 API 托管服务:首先将训练好的模型上传到您的 Hugging Face 帐户以公开或私有部署它们。另一个不错的选择是使用 SageMaker Inference 在 Amazon SageMaker 中运行您自己的推理代码。我们正在努力将来提供 Amazon SageMaker 与 Hugging Face Inference DLC 的集成解决方案——敬请期待!
问:你们为该解决方案提供高级支持或支持 SLA 吗?
答:AWS 提供 AWS 技术支持等级,涵盖 AWS 产品和服务的开发和生产问题——请参阅 AWS 支持了解具体细节和范围。
如果您有 Hugging Face 社区可以帮助回答和/或从中受益的问题,请在 Hugging Face 论坛中发布。
如果您需要 Hugging Face 团队提供高级支持以加速您的 NLP 路线图,我们的专家加速计划提供来自我们开源、科学和机器学习工程团队的直接指导——联系我们了解更多信息。
问:通过此次合作,你们接下来计划做什么?
答:我们的共同目标是使最先进的机器学习普及化。我们将继续创新,使研究人员、数据科学家和机器学习从业人员能够更轻松地管理、训练和运行最先进的模型。如果您对 AWS 与 Hugging Face 的集成有功能请求,请在Hugging Face 社区论坛中告诉我们。
问:我使用 Hugging Face 与 Azure Machine Learning 或 Google Cloud Platform,这项合作对我意味着什么?
答:Hugging Face 的一个基本目标是让尽可能多的人能够使用最新的人工智能,无论他们使用何种框架或开发环境。虽然我们正在将集成工作重点放在 Amazon Web Services 作为我们的首选云提供商上,但我们将继续努力为所有 Hugging Face 用户和客户提供服务,无论他们运行在何种计算环境中。