合作伙伴關係:Amazon SageMaker 和 Hugging Face

釋出於2021年3月23日
在 GitHub 上更新
hugging-face-and-aws-logo

看看這些笑容!

今天,我們宣佈 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/指令碼。

部落格/影片

文件

示例 Notebook


入門:端到端文字分類 🧭

在本入門指南中,我們將使用新的 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_waitmax_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_pointsource_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 CLIboto3。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 使用者和客戶提供服務,無論他們執行在何種計算環境中。

社群

註冊登入以評論

© . This site is unofficial and not affiliated with Hugging Face, Inc.