亚马逊AWS官方博客

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

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

当您在 Google 或 Amazon 上搜索时,您可能对自动完成建议功能并不陌生。虽然这些场景中的搜索词都是我们日常生活中常用的关键字或表达方式,但在某些情况下,搜索词与场景非常相关。专利检索就是其中之一。最近,AWS 生成式 AI 创新中心与 Patsnap 合作,实施了一项自动推荐搜索关键词的功能,作为改善其平台用户体验的创新探索。

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

与此同时,Patsnap 正在利用机器学习(ML)的力量,开发能够持续改善平台用户体验的功能。最近的一项举措是利用最先进的文本生成模型自动填写专利检索查询,从而简化了构造检索表达式的难度。Patsnap 为此训练了一个定制的 GPT-2 模型。据他们所知,现有的专利搜索引擎中还没有这样的功能,因此 Patsnap 认为增加这一功能将增加最终用户的粘性。

然而,在 Patsnap 最近的实验中,基于 PyTorch 的 GPT-2 模型的推理延迟和每秒查询次数(QPS)无法达到某些阈值,而这些阈值可以证明商业价值。为了应对这一挑战,AWS 生成式 AI 创新中心的科学家们探索了各种解决方案来优化 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 端点进行模型处理,从而将平均延迟从 1172 毫秒减少到 531 毫秒

在以下各节中,我们将通过关键代码片段详细介绍建议解决方案的技术细节,并根据关键指标与客户的现状进行比较。

GPT-2 模型概述

Open AI 的 GPT-2 是一个基于 transformer 的大型语言模型,拥有 15 亿个参数,在包含 800 万个网页的 WebText 数据集上进行训练。GPT-2 的训练目标很简单:根据某篇文本中前面所有的单词,预测下一个单词。数据集的多样性使得这个简单的目标包含了不同领域中许多任务的自然演示。GPT-2 具有广泛的功能,包括生成质量前所未有的有条件合成文本样本的能力,在这种情况下,我们为该模型提供一个输入,让该模型生成冗长的连续文本。在这种情况下,我们会利用该模型来生成搜索查询。随着 GPT 模型规模的不断扩大,推理成本也在持续上升,这就更需要以可接受的成本部署这些模型。

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

TensorRT 是一个 C++ 库,用于在 NVIDIA GPU 和深度学习加速器上进行高性能推理,支持 PyTorch 和 TensorFlow 等主要深度学习框架。以往的研究表明,在模型延迟方面,性能有了很大提高。因此,减少目标模型在 NVIDIA GPU 上的延迟是我们的理想选择。

通过在 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 = ('Your own path to save ONNX-based model') # e.g, ./model_fp16.onnx
    gpt2.as_onnx_model(onnx_path, force_overwrite=False)
    return onnx_path, metadata
   
def onnx2trt(onnx_path, metadata):
    trt_path = 'Your own path to save TensorRT-based model' # e.g., ./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 与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 毫秒)
2 7.2 (+4.1) 274 51 361(-275 毫秒)
3 7.3 (+3.9) 548 49 404(-486 毫秒)
4 7.5 (+4.1) 765 62 531(-641 毫秒)

使用 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    # build our docker based on this file.
├── build.sh      # create our own image and push it to Amazon ECR
├── gpt2          # model directory
├── predictor.py  # backend function for invoke the model
├── serve         # web server setting file
├── nginx.conf    # web server setting file
└── wsgi.py       # web server setting file

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

部署到 SageMaker 端点

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

import boto3from 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}'
# you need to upload your container to S3 first
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 Setting
endpoint_config_name = '${Your Endpoint Config Name}'
print('Endpoint config name: ' + 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("Endpoint config Arn: " + create_endpoint_config_response['EndpointConfigArn'])

# Deploy Model
endpoint_name = '${Your Endpoint Name}'
print('Endpoint name: ' + endpoint_name)
create_endpoint_response = sm_client.create_endpoint(
    EndpointName=endpoint_name,
    EndpointConfigName=endpoint_config_name)
print('Endpoint Arn: ' + create_endpoint_response['EndpointArn'])
resp = sm_client.describe_endpoint(EndpointName=endpoint_name)
status = resp['EndpointStatus']
print("Endpoint Status: " + status)
print('Waiting for {} endpoint to be in service...'.format(endpoint_name))
waiter = sm_client.get_waiter('endpoint_in_service')
waiter.wait(EndpointName=endpoint_name)

测试已部署的模型

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

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 # Replace with your own data.
                            )
result = json.loads(response['Body'].read().decode())
print(result)

总结

在这篇文章中,我们介绍了如何在 SageMaker 上启用低延迟 GPT-2 推理以创造商业价值。具体来说,在 NVIDIA TensorRT 的支持下,对于定制的 GPT-2 模型,我们可以通过 SageMaker 在 NVIDIA GPU 实例上实现 2.9 倍的加速。

如果您希望在产品和服务中加快 GenAI 模型的使用,请联系 AWS 生成式 AI 创新中心。AWS 生成式 AI 创新中心有助于您更快、更有效地将想法变为现实。要开始使用生成式 AI 创新中心,请访问此处


Original URL: https://aws.amazon.com/blogs/machine-learning/how-patsnap-used-gpt-2-inference-on-amazon-sagemaker-with-low-latency-and-cost/

关于作者


Hao Huang
是 AWS 生成式 AI 创新中心的应用科学家。他专门研究计算机视觉(CV)和视觉语言模型(VLM)。最近,他对人工智能生成技术产生了浓厚的兴趣,并且已经与客户合作,将这些尖端技术应用到客户的业务中。他还是 ICCV 和 AAAI 等人工智能会议的审稿人。

Zilong Bai 是 Patsnap 的高级自然语言处理工程师。他热衷于生成式语言模型尖端技术的研究和概念验证工作。

Yuanjun Xiao 是 AWS 的解决方案架构师。他负责 AWS 架构咨询和设计。他还热衷于构建人工智能和分析解决方案。

Xuefei Zhang 是 AWS 生成式 AI 创新中心的应用科学家,致力于 NLP 和 AGI 领域,与客户一起解决行业问题。

Guang Yang 是 AWS 生成式 AI 创新中心的高级应用科学家,他与各垂直领域的客户合作,运用创造性的问题解决方法,通过最先进的机器学习/人工智能解决方案为客户创造价值。