Press "Enter" to skip to content

“Patsnap如何在Amazon SageMaker上使用低延迟和成本的GPT-2推理”

这篇博文由Patsnap的高级自然语言处理工程师Zilong Bai共同撰写和介绍。

你可能对在Google或亚马逊上搜索时出现的自动完成建议功能很熟悉。虽然这些场景中的搜索词通常是我们日常生活中常见的关键词或表达方式,但在某些情况下,搜索词与场景非常特定。专利搜索就是其中之一。最近,AWS创新人工智能中心与Patsnap合作,实施了一个自动建议搜索关键词的功能,作为创新探索,以提高用户在其平台上的体验。

Patsnap提供了一个全球一站式专利搜索、分析和管理平台。他们利用大数据(如过去搜索查询的历史记录)提供了许多功能强大且易于使用的专利工具。这些工具使得Patsnap的全球客户能够更好地理解专利、追踪最新技术进展、识别创新趋势并实时分析竞争对手。

与此同时,Patsnap正在借助机器学习(ML)的力量开发能够不断改进平台用户体验的功能。最近的一个举措是通过使用最先进的文本生成模型来自动填充专利搜索查询,以简化构建搜索表达式的难度。Patsnap为此训练了定制的GPT-2模型。由于在专利搜索引擎中没有这样的现有功能(据他们所知),Patsnap相信添加此功能将增加终端用户的粘性。

然而,在他们最近的实验中,基于PyTorch的GPT-2模型的推理延迟和每秒查询数(QPS)无法满足能够证明其商业价值的某些阈值。为了解决这个挑战,AWS创新人工智能中心的科学家们探索了多种解决方案,以优化GPT-2模型的推理性能,从而平均降低了模型延迟50%,提高了QPS 200%。

大型语言模型推理挑战和优化方法

通常情况下,在实际的生产环境中应用如此大型的模型并不容易。基于PyTorch的GPT-2的计算成本和延迟使得从业务运营角度难以广泛采用。在本项目中,我们的目标是显著提高延迟,并保持合理的计算成本。具体而言,Patsnap的要求如下:

  • 在实时搜索场景中,生成搜索表达式的模型推理的平均延迟需要控制在600毫秒以内
  • 模型需要具有高吞吐量和QPS,在高峰业务时间内能够进行大量搜索

在本文中,我们将使用Amazon Elastic Compute Cloud(Amazon EC2)实例,使用基于NVIDIA TensorRT的GPU实例,来讨论我们的研究结果。

简而言之,我们使用NVIDIA TensorRT来优化GPT-2的延迟,并将其部署到Amazon SageMaker端点进行模型服务,从而将平均延迟从1,172毫秒降低到531毫秒。

在接下来的几节中,我们将详细介绍所提出解决方案的技术细节,并通过关键指标的对比展示与客户现状的差异。

GPT-2模型概述

Open AI的GPT-2是一个拥有15亿参数的大型基于transformer的语言模型,使用8百万个网页的WebText数据集进行训练。GPT-2的训练目标很简单:在给定文本的所有先前词汇的情况下,预测下一个词汇。数据集的多样性使得这一简单目标包含了各个领域中许多任务的自然示例。GPT-2展示了广泛的能力,包括生成条件合成文本样本的能力,其中我们使用输入来引导模型并让其生成较长的延续。在这种情况下,我们利用它来生成搜索查询。随着GPT模型的不断增大,推理成本也在不断上升,这增加了以可接受的成本部署这些模型的需求。

通过TensorRT在GPU实例上实现低延迟

TensorRT是一个用于在NVIDIA GPU和深度学习加速器上进行高性能推理的C++库,支持PyTorch和TensorFlow等主要深度学习框架。以前的研究已经证明了模型延迟方面的出色性能改进。因此,对于我们来说,将目标模型在NVIDIA GPU上的延迟降到最低,TensorRT是一个理想的选择。

我们能够通过在NVIDIA GPU上部署基于TensorRT的模型,显著降低GPT-2模型的推理延迟。基于TensorRT的模型通过SageMaker进行性能测试。在本文中,我们展示了将原始基于PyTorch的GPT-2模型转换为基于TensorRT的模型的步骤。

通过NVIDIA提供的官方工具,将基于PyTorch的GPT-2转换为基于TensorRT的模型并不困难。此外,通过这种简单的转换,没有观察到明显的模型精度下降。一般而言,需要遵循以下三个步骤:

  1. 分析您的GPT-2。截至本文撰写时,NVIDIA的转换工具仅支持Hugging Face版本的GPT-2模型。如果当前的GPT-2模型不是原始版本,则需要相应地进行修改。建议从Hugging Face的原始GPT-2实现中删除自定义代码,这对于转换非常有帮助。
  2. 安装所需的Python包。转换过程首先将基于PyTorch的模型转换为ONNX模型,然后将ONNX模型转换为基于TensorRT的模型。此两步转换需要以下Python包:
tabulate
toml
torch
sentencepiece==0.1.95
onnx==1.9.0
onnx_graphsurgeon
polygraphy
transformers
  1. 转换您的模型。以下代码包含了这两步转换的函数:
def torch2onnx():
    metadata = NetworkMetadata(variant=GPT2_VARIANT, precision=Precision(fp16=True), other=GPT2Metadata(kv_cache=False))
    gpt2 = GPT2TorchFile(model.to('cpu'), metadata)
    onnx_path = ('您自己保存ONNX模型的路径') # 例如,./model_fp16.onnx
    gpt2.as_onnx_model(onnx_path, force_overwrite=False)
    return onnx_path, metadata
   
def onnx2trt(onnx_path, metadata):
    trt_path = '您自己保存TensorRT模型的路径' # 例如,./model_fp16.onnx.engine
    batch_size = 10
    max_sequence_length = 42
    profiles = [Profile().add(
        "input_ids",
        min=(1, 1),
        opt=(batch_size, max_sequence_length // 2),
        max=(batch_size, max_sequence_length),
    )]
    gpt2_engine = GPT2ONNXFile(onnx_path, metadata).as_trt_engine(output_fpath=trt_path, profiles=profiles)
    gpt2_trt = GPT2TRTDecoder(gpt2_engine, metadata, config, max_sequence_length=42, batch_size=10)

延迟比较:PyTorch vs. TensorRT

本项目使用JMeter进行性能基准测试。JMeter是一个Apache项目,可用作负载测试工具,用于分析和测量各种服务的性能。我们在AWS P3.2xlarge实例上记录了原始基于PyTorch的模型和我们转换的基于TensorRT的GPT-2模型的QPS和延迟。正如本文后面所展示的,由于TensorRT的强大加速能力,GPT-2的延迟大大降低。当请求并发数为1时,平均延迟减少了274毫秒(速度提高了2.9倍)。从QPS的角度来看,从2.4增加到7,与原始基于PyTorch的模型相比,约有2.9倍的提升。此外,随着并发数的增加,QPS也在增加。这意味着在可接受的延迟增加的情况下降低了成本(但仍比原始模型快得多)。

下表比较了延迟:

. 并发数 QPS 最大延迟 最小延迟 平均延迟
客户端PyTorch版本(在p3.2xlarge上) 1 2.4 632 105 417
2 3.1 919 168 636
3 3.4 1911 222 890
4 3.4 2458 277 1172
AWS TensorRT版本(在p3.2xlarge上) 1 7(+4.6) 275 22 143(-274 ms)
2 7.2(+4.1) 274 51 361(-275 ms)
3 7.3(+3.9) 548 49 404(-486 ms)
4 7.5(+4.1) 765 62 531(-641 ms)

使用SageMaker和自定义容器部署基于TensorRT的GPT-2模型

基于TensorRT的GPT-2模型需要相对较新的TensorRT版本,因此我们选择使用SageMaker的自定义容器(BYOC)模式来部署我们的模型。BYOC模式提供了一种灵活的部署方式,您可以在自己的Docker容器中构建自定义环境。在本节中,我们将展示如何构建自己的容器,部署自己的GPT-2模型,并使用SageMaker端点API进行测试。

构建自己的容器

以下代码展示了容器的文件目录。具体来说,Dockerfilebuild.sh用于构建Docker容器。gpt2predictor.py实现了模型和推断API。servenginx.confwsgi.py为NGINX Web服务器的配置提供了设置。

container
├── Dockerfile    # 用于构建我们的Docker容器的文件
├── build.sh      # 创建自己的镜像并将其推送到Amazon ECR
├── gpt2          # 模型目录
├── predictor.py  # 调用模型的后端函数
├── serve         # Web服务器设置文件
├── nginx.conf    # Web服务器设置文件
└── wsgi.py       # Web服务器设置文件

您可以运行sh ./build.sh来构建容器。

部署到SageMaker端点

在构建用于运行基于TensorRT的GPT-2模型的容器之后,您可以通过SageMaker端点启用实时推断。使用以下代码片段使用相应的SageMaker API创建端点并将模型部署到端点:

import boto3
from time import gmtime, strftime
from sagemaker import get_execution_role

sm_client = boto3.client(service_name='sagemaker')
runtime_sm_client = boto3.client(service_name='sagemaker-runtime')
account_id = boto3.client('sts').get_caller_identity()['Account']
region = boto3.Session().region_name
s3_bucket = '${Your s3 bucket}'
role = get_execution_role()
model_name = '${Your Model Name}'
# 您需要先将容器上传到S3
container = '${Your Image Path}'
instance_type = 'ml.p3.2xlarge'
container = {
    'Image': container
}
create_model_response = sm_client.create_model(
    ModelName=model_name,
    ExecutionRoleArn=role,
    Containers=[container])

# 设置端点
endpoint_config_name = '${Your Endpoint Config Name}'
print('端点配置名称:' + endpoint_config_name)
create_endpoint_config_response = sm_client.create_endpoint_config(
    EndpointConfigName=endpoint_config_name,
    ProductionVariants=[{
        'InstanceType': instance_type,
        'InitialInstanceCount': 1,
        'InitialVariantWeight': 1,
        'ModelName': model_name,
        'VariantName': 'AllTraffic'}])
print("端点配置ARN:" + create_endpoint_config_response['EndpointConfigArn'])

# 部署模型
endpoint_name = '${Your Endpoint Name}'
print('端点名称:' + endpoint_name)
create_endpoint_response = sm_client.create_endpoint(
    EndpointName=endpoint_name,
    EndpointConfigName=endpoint_config_name)
print('端点ARN:' + create_endpoint_response['EndpointArn'])
resp = sm_client.describe_endpoint(EndpointName=endpoint_name)
status = resp['EndpointStatus']
print("端点状态:" + status)
print('等待{}端点进入服务状态...'.format(endpoint_name))
waiter = sm_client.get_waiter('endpoint_in_service')
waiter.wait(EndpointName=endpoint_name)

测试部署的模型

成功部署模型之后,您可以使用以下代码通过SageMaker笔记本实例测试端点:

import json
import boto3

sagemaker_runtime = boto3.client("sagemaker-runtime", region_name='us-east-2')
endpoint_name = "${Your Endpoint Name}"
request_body = {"input": "amazon"}
payload = json.dumps(request_body)
content_type = "application/json"
response = sagemaker_runtime.invoke_endpoint(
    EndpointName=endpoint_name,
    ContentType=content_type,
    Body=payload # 替换为您自己的数据
)
result = json.loads(response['Body'].read().decode())
print(result)

结论

在本篇文章中,我们描述了如何在SageMaker上实现低延迟的GPT-2推理,以创造商业价值。具体来说,借助NVIDIA TensorRT的支持,我们可以在SageMaker上的NVIDIA GPU实例上,为自定义的GPT-2模型实现2.9倍的加速。

如果您需要加速在产品和服务中使用GenAI模型的帮助,请联系AWS生成AI创新中心。AWS生成AI创新中心可以帮助您更快更有效地将您的想法变为现实。要开始使用生成AI创新中心,请访问这里。

Leave a Reply

Your email address will not be published. Required fields are marked *