原文:
towardsdatascience.com/deploying-your-llama-model-via-vllm-using-sagemaker-endpoint-f02b424da124
MLOps 工作流程中需要推理端点的实例(由作者创建)。
在任何机器学习项目中,目标是训练一个模型,其他人可以使用它来得出良好的预测。为此,模型需要用于推理。此工作流程中的几个部分需要这个推理端点,即模型评估、发布到开发、预发布,最终到生产环境供最终用户消费。
在这篇文章中,我将演示如何使用 AWS 的 SageMaker 端点和其 DJL 镜像部署最新的 LLM 和服务技术,即 Llama 和 vLLM。这些组件是什么,它们是如何组成推理端点的?
这些组件如何在 AWS 中共同服务于模型。SageMaker 端点是 GPU 实例,DJL 是模板 Docker 镜像,vLLM 是模型服务器(由作者创建)。
SageMaker 是一个 AWS 服务,它包含一套庞大的工具和服务,用于管理机器学习生命周期。其推理服务被称为 SageMaker 端点。在底层,它本质上是由 AWS 自行管理的虚拟机。
DJL (Deep Java Library) 是 AWS 开发的一个开源库,用于开发 LLM 推理 Docker 镜像,包括 vLLM [2]。这个镜像用于 SageMaker 端点。
vLLM,于 2023 年推出,是一个针对 LLM 模型服务优化的开源推理框架 [1]。它使用创新的 GPU 内存管理,实现了快速推理并减少了内存使用。它预建在 DJL 的某个镜像中。
内容
安装 端点创建 预测 端点更新与删除 总结
安装
只需要两个 Python 库。boto3 是 AWS 的低级 API,用于管理所有类型的 AWS 资源。sagemaker 是他们开发的高级 API,用于管理 AWS 的 SageMaker 资源。它们经常更新,因此未来版本可能存在向后兼容性问题。
pip install boto3~=1.35.5 sagemaker~=2.229.0
创建端点
基础知识
from sagemaker import image_uris
from sagemaker.model import Model
# 1) variables
aws_region = "us-east-1"
instance_type = "ml.g5.12xlarge"
model_data = "s3-mymodel-bucket/model/"
infer_instance_role = "iamr-vllm-inference"
name = "my-vllm-endpoint"
# 2) obtain inference ECR image uri
container_uri = image_uris.retrieve(
framework="djl-lmi",
region=aws_region,
version="0.29.0"
)
# 3) create model object
model = Model(
name=name,
image_uri=container_uri,
role=infer_instance_role,
# model_data=model_data,
env={
"HF_MODEL_ID": model_data,
"TENSOR_PARALLEL_DEGREE": "max",
"OPTION_ROLLING_BATCH": "vllm",
"OPTION_MAX_ROLLING_BATCH_SIZE": "64",
}
)
# 4) deploy model endpoint
model.deploy(
instance_type=instance_type,
initial_instance_count=1,
endpoint_name=name,
wait=False
)
您只需要上述代码来部署 LLM 模型。分解每个部分:
-
变量被定义,包括 AWS 区域名称、实例类型以及 LLM 模型的 S3 目录路径。还需要创建一个实例角色,至少允许访问 S3 路径、ECR 镜像和推送至 Cloudwatch 日志。请注意,模型需要以 HuggingFace 的格式存在,才能使用 vLLM [3] 进行服务。
-
然后从 ECR 的 URI 中检索DJL 预构建推理镜像,使用框架
djl-lmi(大型模型推理)。您可以在 [4] 中找到最新和完整的镜像列表。 -
然后指定一个模型对象来指定实例角色和镜像 URI。特别重要的是使用
OPTION_ROLLING_BATCH设置环境变量,其值为vllm,以及使用 S3 存储桶设置HF_MODEL_ID。 -
最后,
model.deploy()将创建模型对象、端点配置并部署实时端点。wait=False将在脚本完成后停止,否则它将不断轮询 SageMaker,直到获得端点创建的成功或失败状态。
模型对象、端点配置、端点
如下定义,前面提到的三个组件在 SageMaker 页面上可见,它们各自有不同的用途。特别是,你可以将模型对象和端点配置视为实时端点的构造。
创建 SageMaker 端点时需要指定的三个组件(作者创建)。
模型对象、端点配置和端点的详细信息可以在 AWS 管理控制台中的 SageMaker 页面上查看(作者截图)。
交替模型下载路径
关于如何从您的 S3 存储桶检索 LLM 模型的内容,AWS 现有的文档没有涵盖的一个重要部分。前面的示例假设模型或模型存储在存储桶中的一个目录中。该目录中的所有内容都将下载到端点服务器。然而,如果您已将文件压缩为 .tar.gz 格式,可以直接调用该文件,然后将其路径包含在 Model() 对象的 model_data 参数中。
# to specify a compressed tar.gz model file
model_data = "s3-mymodel-bucket/model/model.tar.gz"
# use model_data arg instead of env var
model = Model(
name=name,
image_uri=container_uri,
role=infer_instance_role,
model_data=model_data,
env={
# "HF_MODEL_ID": model_data,
"TENSOR_PARALLEL_DEGREE": "max",
"OPTION_ROLLING_BATCH": "vllm",
"OPTION_MAX_ROLLING_BATCH_SIZE": "64",
}
)
端点架构
SageMaker 端点架构(作者创建)。
这就是 SageMaker 端点与其相关资源之间的关系。在初始启动时,预构建的推理镜像被拉入一个托管实例,模型也从 S3 存储桶下载。所有日志都将推送到自动创建的 Cloudwatch 日志组。
可选地,您还可以在模型对象中定义子网和安全组,以通过定义它们来增强托管实例的安全性。
# specify subnets and security groups
vpc_config = {
"Subnets": ["subnet-12345668", "subnet-23456789"],
"SecurityGroupIds": ["sg-12345678"]
}
# add to model object
model = Model(
name=name,
image_uri=container_uri,
role=infer_instance_role,
vpc_config=vpc_config,
env={
"HF_MODEL_ID": model_data,
"TENSOR_PARALLEL_DEGREE": "max",
"OPTION_ROLLING_BATCH": "vllm",
"OPTION_MAX_ROLLING_BATCH_SIZE": "64",
}
)
此外,还可以将自动扩展组附加到已部署的端点,根据计划或流量条件动态调整其可用性。像 S3、ECR 这样的资源创建,最好通过基础设施即代码(如 Terraform)来管理,这是一个单独的主题,因此在此不进行讨论。
预测
SageMaker SDK
import json
from sagemaker import serializers
from sagemaker import Predictor
# payload
input_data = {
"inputs": "What is LLM?",
#add your params
"parameters": {
"max_tokens": 2400,
"temperature": 0.01
}
}
# predictor class
name = "my-vllm-endpoint"
predictor = sagemaker.Predictor(
endpoint_name=name,
serializer=serializers.JSONSerializer(),
)
# post request
response = predictor.predict(input_data)
response_data = json.loads(response)
print(response_data)
使用 SageMaker SDK 的Predictor类,如上所示发送请求到创建的端点是简单的。
端点响应(作者截图)。
HTTPS 请求
在某些情况下,使用高级 SDK 发送上述请求是不可能的,因为调用它的服务需要通过 HTTPS URL 的 POST 请求使用更传统的方法。
端点 URL 在 AWS 管理控制台中的位置(作者截图)。
您可以在 AWS 管理控制台 > SageMaker > 端点 > [端点名称]中找到 URL。
import json
import boto3
import requests
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
from botocore.session import Session
# payload
payload = {
"inputs": "What is LLM?",
"parameters": {
"max_tokens": 2400,
"temperature": 0.01
}
}
# variables
region = "us-east-1"
endpoint = "my-vllm-endpoint"
endpoint_url = f"https://runtime.sagemaker.{region}.amazonaws.com/endpoints/{endpoint}/invocations"
# generate signed header
credentials = Session().get_credentials()
request = AWSRequest(
method='POST',
url=endpoint_url,
data=json.dumps(payload),
headers={"Content-Type": "application/json"}
)
SigV4Auth(credentials, 'sagemaker', region).add_auth(request)
signed_header = dict(request.headers)
# post request
response = requests.post(
request.url,
headers=signed_header,
json=payload
)
print(response.json())
因此,您需要使用boto3创建一个 AWS 签名头,并使用第三方库(如本例中的流行库requests)将签名头与有效负载一起发送。
聊天完成
最新版本的djl-lmi图像为0.29.0,支持聊天完成,其模式与 OpenAI 的格式[6]兼容。这允许我们指示模型扮演不同的角色,以便可以对响应进行特定调整。
import json
from sagemaker import Predictor, serializers
name = "my-vllm-endpoint"
predictor = Predictor(
endpoint_name=name,
serializer=serializers.JSONSerializer(),
)
system_prompt = "you are an intelligent investor"
user_prompt = "what is the best way to make a million?"
# openai chat completion format
input_data = {
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
],
"max_tokens": 2400,
"temperature": 0.01
}
response = predictor.predict(input_data)
response = json.loads(response)
print(json.dumps(response, indent=4))
在上述使用 SageMaker SDK 的示例中,一个系统提示指示模型扮演智能投资者的角色,然后向它发送有关如何赚一百万的用户提示。(请注意,这只是为了演示目的,并不构成财务建议。)
注意,要使用聊天完成,请求有效负载必须在messages键中,而不是之前提到的 SageMaker 标准模式中的input键。参数也不在parameters键中封装。
根据生成式 AI 作为智能投资者的回答如何赚一百万(作者截图)。
端点更新与删除
需要更新或销毁的 SageMaker 端点(作者创建)。
from sagemaker import Predictor
from sagemaker.model import Model
predictor = Predictor(
endpoint_name=name,
)
# delete endpoint & endpoint configuration
predictor.delete_endpoint(
delete_endpoint_config=True
)
对于您启动的每个 SageMaker 端点,您最终都需要销毁它,就像那些用于临时模型评估的端点一样。要拆除您的端点和端点配置,您可以使用 predictor.delete_endpoint()。
# update endpoint configuration, e.g, instance type -------
predictor.update_endpoint(
instance_type="ml.g5.4xlarge",
wait=False
)
# update model object -------
# e.g., use a diff model
model_name = "my-new-model"
model_data = "s3-mymodel-bucket/model/model2.tar.gz"
model = Model(
name=model_name,
image_uri=container_uri,
role=infer_instance_role,
model_data=model_data,
env={
"TENSOR_PARALLEL_DEGREE": "max",
"OPTION_ROLLING_BATCH": "vllm",
"OPTION_MAX_ROLLING_BATCH_SIZE": "64",
}
)
predictor.update_endpoint(
model_name=model_name
wait=False
)
你微调的第一个模型很少会是最终版本,通常需要更新现有的端点;无论是更新到更好的模型还是更改开发、预发布或生产环境中使用的配置。这可以通过 predictor.update_endpoint() 来完成。请注意,从这里开始对端点配置的任何更新都将导致创建一个新的端点。
摘要
本文展示了如何通过 AWS 的 SageMaker 端点使用 vLLM 来部署他们的 Llama 模型。虽然它专门针对所提到的 LLM 部署,但展示的代码和工作流程通常适用于 SageMaker 平台上所有形式的模型部署。
尽管如此,我仅覆盖了 MLOps 工程师工作范围的一个小方面,SageMaker 本身是一个复杂的平台,需要掌握。在未来文章中,我将分享更多关于如何在平台上自动化整个机器学习生命周期的内容。同时,您可以查看我在这领域写的另一篇文章。
1176

被折叠的 条评论
为什么被折叠?



