Amazon SageMaker 文档

将模型部署到 Amazon SageMaker

Hugging Face's logo
加入 Hugging Face 社区

并获取增强型文档体验

以开始

将模型部署到 Amazon SageMaker

在 SageMaker 中部署 🤗 Transformers 模型以进行推理就像

from sagemaker.huggingface import HuggingFaceModel

# create Hugging Face Model Class and deploy it as SageMaker endpoint
huggingface_model = HuggingFaceModel(...).deploy()

本指南将向您展示如何使用 推理工具包 以零代码方式部署模型。推理工具包建立在 🤗 Transformers 的 pipeline 功能 之上。了解如何

安装和设置

在将 🤗 Transformers 模型部署到 SageMaker 之前,您需要注册一个 AWS 帐户。如果您还没有 AWS 帐户,请了解有关 此处 的更多信息。

拥有 AWS 帐户后,请使用以下方法之一开始使用

要开始在本地进行训练,您需要设置一个适当的 IAM 角色

升级到最新的 sagemaker 版本。

pip install sagemaker --upgrade

SageMaker 环境

按照以下步骤设置您的 SageMaker 环境

import sagemaker
sess = sagemaker.Session()
role = sagemaker.get_execution_role()

注意:执行角色仅在笔记本在 SageMaker 中运行时可用。如果您在不在 SageMaker 上的笔记本中运行 get_execution_role,则会遇到 region 错误。

本地环境

按照以下步骤设置您的本地环境

import sagemaker
import boto3

iam_client = boto3.client('iam')
role = iam_client.get_role(RoleName='role-name-of-your-iam-role-with-right-permissions')['Role']['Arn']
sess = sagemaker.Session()

部署在 SageMaker 中训练的 🤗 Transformers 模型

有两种方法可以部署在 SageMaker 中训练的 Hugging Face 模型

  • 在训练完成后部署它。
  • 稍后使用 model_data 从 S3 部署您的保存模型。

📓 打开 deploy_transformer_model_from_s3.ipynb 笔记本 以了解如何将模型从 S3 部署到 SageMaker 以进行推理的示例。

训练后部署

要直接在训练后部署模型,请确保所有必需文件都已保存在您的训练脚本中,包括标记器和模型。

如果您使用 Hugging Face Trainer,您可以将标记器作为参数传递给 Trainer。在您调用 trainer.save_model() 时,它将被自动保存。

from sagemaker.huggingface import HuggingFace

############ pseudo code start ############

# create Hugging Face Estimator for training
huggingface_estimator = HuggingFace(....)

# start the train job with our uploaded datasets as input
huggingface_estimator.fit(...)

############ pseudo code end ############

# deploy model to SageMaker Inference
predictor = hf_estimator.deploy(initial_instance_count=1, instance_type="ml.m5.xlarge")

# example request: you always need to define "inputs"
data = {
   "inputs": "Camera - You are awarded a SiPix Digital Camera! call 09061221066 fromm landline. Delivery within 28 days."
}

# request
predictor.predict(data)

在运行请求后,您可以删除端点,如下所示

# delete endpoint
predictor.delete_endpoint()

使用 model_data 部署

如果您已经训练了模型,并且想稍后部署它,请使用 model_data 参数指定标记器和模型权重的存储位置。

from sagemaker.huggingface.model import HuggingFaceModel

# create Hugging Face Model Class
huggingface_model = HuggingFaceModel(
   model_data="s3://models/my-bert-model/model.tar.gz",  # path to your trained SageMaker model
   role=role,                                            # IAM role with permissions to create an endpoint
   transformers_version="4.26",                           # Transformers version used
   pytorch_version="1.13",                                # PyTorch version used
   py_version='py39',                                    # Python version used
)

# deploy model to SageMaker Inference
predictor = huggingface_model.deploy(
   initial_instance_count=1,
   instance_type="ml.m5.xlarge"
)

# example request: you always need to define "inputs"
data = {
   "inputs": "Camera - You are awarded a SiPix Digital Camera! call 09061221066 fromm landline. Delivery within 28 days."
}

# request
predictor.predict(data)

在运行请求后,可以使用以下命令再次删除端点

# delete endpoint
predictor.delete_endpoint()

创建用于部署的模型工件

为了以后部署,您可以创建一个 model.tar.gz 文件,其中包含所有必需文件,例如

  • pytorch_model.bin
  • tf_model.h5
  • tokenizer.json
  • tokenizer_config.json

例如,您的文件应如下所示

model.tar.gz/
|- pytorch_model.bin
|- vocab.txt
|- tokenizer_config.json
|- config.json
|- special_tokens_map.json

从 🤗 中心创建您自己的 model.tar.gz

  1. 下载模型
git lfs install
git clone [email protected]:{repository}
  1. 创建 tar 文件
cd {repository}
tar zcvf model.tar.gz *
  1. model.tar.gz 上传到 S3
aws s3 cp model.tar.gz <s3://{my-s3-path}>

现在,您可以向 model_data 参数提供 S3 URI 以稍后部署模型。

从 🤗 中心部署模型

要将模型直接从 🤗 中心部署到 SageMaker,请在创建 HuggingFaceModel 时定义两个环境变量

  • HF_MODEL_ID 定义模型 ID,该 ID 在您创建 SageMaker 端点时会自动从 huggingface.co/models 加载。通过此环境变量访问 🤗 中心上的 10,000 多个模型。
  • HF_TASK 定义 🤗 Transformers pipeline 的任务。可以在 此处 找到任务的完整列表。

⚠️ ** 管道没有针对并行(多线程)进行优化,并且往往会消耗大量内存。例如,在基于 GPU 的实例上,管道在一个 vCPU 上运行。当该 vCPU 因推理请求预处理而变得饱和时,就会产生瓶颈,阻止 GPU 被充分利用来进行模型推理。了解更多信息 这里

from sagemaker.huggingface.model import HuggingFaceModel

# Hub model configuration <https://huggingface.co/models>
hub = {
  'HF_MODEL_ID':'distilbert-base-uncased-distilled-squad', # model_id from hf.co/models
  'HF_TASK':'question-answering'                           # NLP task you want to use for predictions
}

# create Hugging Face Model Class
huggingface_model = HuggingFaceModel(
   env=hub,                                                # configuration for loading model from Hub
   role=role,                                              # IAM role with permissions to create an endpoint
   transformers_version="4.26",                             # Transformers version used
   pytorch_version="1.13",                                  # PyTorch version used
   py_version='py39',                                      # Python version used
)

# deploy model to SageMaker Inference
predictor = huggingface_model.deploy(
   initial_instance_count=1,
   instance_type="ml.m5.xlarge"
)

# example request: you always need to define "inputs"
data = {
"inputs": {
	"question": "What is used for inference?",
	"context": "My Name is Philipp and I live in Nuremberg. This model is used with sagemaker for inference."
	}
}

# request
predictor.predict(data)

在运行请求后,可以使用以下命令再次删除端点

# delete endpoint
predictor.delete_endpoint()

📓 打开 deploy_transformer_model_from_hf_hub.ipynb 笔记本 获取有关如何将 🤗 Hub 上的模型部署到 SageMaker 进行推理的示例。

使用 🤗 Transformers 和 SageMaker 运行批量转换

在训练完模型后,可以使用 SageMaker 批量转换 来使用该模型执行推理。批量转换接受您的推理数据作为 S3 URI,然后 SageMaker 会负责下载数据、运行预测并将结果上传到 S3。有关批量转换的更多详细信息,请查看 这里

⚠️ Hugging Face 推理 DLC 目前仅支持 .jsonl 用于批量转换,因为文本数据的结构复杂。

注意:确保您的 inputs 在预处理过程中适合模型的 max_length

如果您使用 Hugging Face Estimator 训练了一个模型,请调用 transformer() 方法为基于训练作业的模型创建一个转换作业(有关更多详细信息,请查看 这里)。

batch_job = huggingface_estimator.transformer(
    instance_count=1,
    instance_type='ml.p3.2xlarge',
    strategy='SingleRecord')


batch_job.transform(
    data='s3://s3-uri-to-batch-data',
    content_type='application/json',    
    split_type='Line')

如果您想稍后运行批量转换作业或使用 🤗 Hub 中的模型,请创建一个 HuggingFaceModel 实例,然后调用 transformer() 方法。

from sagemaker.huggingface.model import HuggingFaceModel

# Hub model configuration <https://huggingface.co/models>
hub = {
	'HF_MODEL_ID':'distilbert/distilbert-base-uncased-finetuned-sst-2-english',
	'HF_TASK':'text-classification'
}

# create Hugging Face Model Class
huggingface_model = HuggingFaceModel(
   env=hub,                                                # configuration for loading model from Hub
   role=role,                                              # IAM role with permissions to create an endpoint
   transformers_version="4.26",                             # Transformers version used
   pytorch_version="1.13",                                  # PyTorch version used
   py_version='py39',                                      # Python version used
)

# create transformer to run a batch job
batch_job = huggingface_model.transformer(
    instance_count=1,
    instance_type='ml.p3.2xlarge',
    strategy='SingleRecord'
)

# starts batch transform job and uses S3 data as input
batch_job.transform(
    data='s3://sagemaker-s3-demo-test/samples/input.jsonl',
    content_type='application/json',    
    split_type='Line'
)

input.jsonl 的格式如下:

{"inputs":"this movie is terrible"}
{"inputs":"this movie is amazing"}
{"inputs":"SageMaker is pretty cool"}
{"inputs":"SageMaker is pretty cool"}
{"inputs":"this movie is terrible"}
{"inputs":"this movie is amazing"}

📓 打开 sagemaker-notebook.ipynb 笔记本 获取有关如何运行批量转换作业以进行推理的示例。

使用 TGI 将 LLM 部署到 SageMaker

如果您有兴趣为 LLM 使用高性能服务容器,可以使用 Hugging Face TGI 容器。这利用了 文本生成推理 库。可以在 这里 找到兼容模型列表。

首先,确保已安装最新版本的 SageMaker SDK。

pip install sagemaker>=2.231.0

然后,导入 SageMaker Python SDK 并实例化一个 sagemaker_session 以查找当前区域和执行角色。

import sagemaker
from sagemaker.huggingface import HuggingFaceModel, get_huggingface_llm_image_uri
import time

sagemaker_session = sagemaker.Session()
region = sagemaker_session.boto_region_name
role = sagemaker.get_execution_role()

接下来检索 LLM 镜像 URI。使用辅助函数 get_huggingface_llm_image_uri() 为 Hugging Face 大型语言模型 (LLM) 推理生成相应的镜像 URI。该函数需要一个必填参数 backend 和几个可选参数。backend 指定要用于模型的后端类型:“huggingface” 指使用 Hugging Face TGI 后端。

image_uri = get_huggingface_llm_image_uri(
  backend="huggingface",
  region=region
)

现在我们有了镜像 URI,下一步是配置模型对象。指定一个唯一名称、用于托管 TGI 容器的 image_uri 以及端点的执行角色。此外,指定一些环境变量,包括 HF_MODEL_ID(对应于要部署的 HuggingFace Hub 上的模型)和 HF_TASK(配置模型要执行的推理任务)。

您还应该定义 SM_NUM_GPUS,它指定模型的张量并行度。张量并行可以用于将模型拆分到多个 GPU 上,这在处理单个 GPU 无法容纳的 LLM 时是必需的。若要详细了解推理中的张量并行,请查看我们之前的博文。在这里,您应该将 SM_NUM_GPUS 设置为所选实例类型上的可用 GPU 数量。例如,在本教程中,我们将其设置为 4,因为我们选择的实例类型 ml.g4dn.12xlarge 有 4 个可用 GPU。

请注意,您可以通过将 HF_MODEL_QUANTIZE 环境变量设置为 true 来选择性地减少模型的内存和计算占用,但这较低的权重精度可能会影响某些模型的输出质量。

model_name = "llama-3.1-8b-instruct" + time.strftime("%Y-%m-%d-%H-%M-%S", time.gmtime())

hub = {
    'HF_MODEL_ID':'EleutherAI/gpt-neox-20b',
    'SM_NUM_GPUS':'1',
	'HUGGING_FACE_HUB_TOKEN': '<REPLACE WITH YOUR TOKEN>'
}

assert hub['HUGGING_FACE_HUB_TOKEN'] != '<REPLACE WITH YOUR TOKEN>', "You have to provide a token."


model = HuggingFaceModel(
    name=model_name,
    env=hub,
    role=role,
    image_uri=image_uri
)

接下来,调用 deploy 方法来部署模型。

predictor = model.deploy(
  initial_instance_count=1,
  instance_type="ml.g5.2xlarge",
  endpoint_name=model_name
)

部署模型后,可以调用它来生成文本。传递一个输入提示并运行 predict 方法以从在 TGI 容器中运行的 LLM 生成文本响应。

input_data = {
  "inputs": "The diamondback terrapin was the first reptile to",
  "parameters": {
    "do_sample": True,
    "max_new_tokens": 100,
    "temperature": 0.7,
    "watermark": True
  }
}

predictor.predict(input_data)

我们收到以下自动生成的文本响应:

[{'generated_text': 'The diamondback terrapin was the first reptile to make the list, followed by the American alligator, the American crocodile, and the American box turtle. The polecat, a ferret-like animal, and the skunk rounded out the list, both having gained their slots because they have proven to be particularly dangerous to humans.\n\nCalifornians also seemed to appreciate the new list, judging by the comments left after the election.\n\n“This is fantastic,” one commenter declared.\n\n“California is a very'}]

完成后,删除端点和模型资源。

predictor.delete_model()
predictor.delete_endpoint()

用户定义的代码和模块

Hugging Face 推理工具包允许用户覆盖 HuggingFaceHandlerService 的默认方法。您需要在名为 code/ 的文件夹中创建一个包含 inference.py 文件的文件夹。有关如何存档模型工件的更多详细信息,请查看 这里。例如:

model.tar.gz/
|- pytorch_model.bin
|- ....
|- code/
  |- inference.py
  |- requirements.txt 

inference.py 文件包含您的自定义推理模块,requirements.txt 文件包含应添加的额外依赖项。自定义模块可以覆盖以下方法:

  • model_fn(model_dir) 覆盖加载模型的默认方法。返回值 model 将在 predict 中用于进行预测。predict 接收参数 model_dir(解压缩的 model.tar.gz 文件的路径)。
  • transform_fn(model, data, content_type, accept_type) 使用您的自定义实现覆盖默认的转换函数。您需要在 transform_fn 中实现自己的 preprocesspredictpostprocess 步骤。此方法不能与下面提到的 input_fnpredict_fnoutput_fn 结合使用。
  • input_fn(input_data, content_type) 覆盖用于预处理的默认方法。返回值 data 将在 predict 中用于进行预测。输入是:
    • input_data 是您请求的原始正文。
    • content_type 是来自请求标头的内容类型。
  • predict_fn(processed_data, model) 覆盖用于预测的默认方法。返回值 predictions 将用于 postprocess。输入是 processed_data(来自 preprocess 的结果)。
  • output_fn(prediction, accept) 覆盖用于后处理的默认方法。返回值 result 将是您请求的响应(例如 JSON)。输入是:
    • predictions 是来自 predict 的结果。
    • accept 是来自 HTTP 请求的返回接受类型,例如 application/json

以下是一个包含 model_fninput_fnpredict_fnoutput_fn 的自定义推理模块的示例:

from sagemaker_huggingface_inference_toolkit import decoder_encoder

def model_fn(model_dir):
    # implement custom code to load the model
    loaded_model = ...
    
    return loaded_model 

def input_fn(input_data, content_type):
    # decode the input data  (e.g. JSON string -> dict)
    data = decoder_encoder.decode(input_data, content_type)
    return data

def predict_fn(data, model):
    # call your custom model with the data
    outputs = model(data , ... )
    return predictions

def output_fn(prediction, accept):
    # convert the model output to the desired output format (e.g. dict -> JSON string)
    response = decoder_encoder.encode(prediction, accept)
    return response

仅使用 model_fntransform_fn 自定义推理模块:

from sagemaker_huggingface_inference_toolkit import decoder_encoder

def model_fn(model_dir):
    # implement custom code to load the model
    loaded_model = ...
    
    return loaded_model 

def transform_fn(model, input_data, content_type, accept):
     # decode the input data (e.g. JSON string -> dict)
    data = decoder_encoder.decode(input_data, content_type)

    # call your custom model with the data
    outputs = model(data , ... ) 

    # convert the model output to the desired output format (e.g. dict -> JSON string)
    response = decoder_encoder.encode(output, accept)

    return response
< > 在 GitHub 上更新