在 Triton 中部署 Hugging Face Transformer 模型#

以下教程演示了如何使用 Triton 的 Python 后端 在 Triton 推理服务器上部署任意 Hugging Face Transformer 模型。为了本示例的目的,将部署以下 Transformer 模型

选择这些模型是因为它们的受欢迎程度和一致的响应质量。但是,如果基础设施充足,本教程也适用于任何 Transformer 模型。

注意:本教程仅作为参考示例。可能未针对最佳性能进行调整。

注意:下面的步骤中未特别提及 Llama 2 模型,但如果将 tiiuae/falcon-7b 替换为 meta-llama/Llama-2-7b-hf,并将 falcon7b 文件夹替换为 llama7b 文件夹,则可以运行。

步骤 1:创建模型仓库#

第一步是创建一个模型仓库,其中包含我们希望 Triton 推理服务器加载并用于推理处理的模型。为了完成此操作,创建一个名为 model_repository 的目录,并将 falcon7b 模型文件夹复制到其中

mkdir -p model_repository
cp -r falcon7b/ model_repository/

我们复制的 falcon7b/ 文件夹以 Triton 期望的方式组织,并包含在 Triton 中服务模型所需的两个重要文件

  • config.pbtxt - 概述要使用的后端、模型输入/输出详细信息以及用于执行的自定义参数。有关 Triton 支持的完整模型配置属性的更多信息,请参见此处

  • model.py - 实现了 Triton 应如何在初始化、执行和最终化阶段处理模型。有关 Python 后端用法的更多信息,请参见此处

步骤 2:构建 Triton 容器镜像#

第二步是创建一个镜像,其中包含在 Triton 推理服务器上部署 Hugging Face Transformer 模型所需的所有依赖项。这可以通过从提供的 Dockerfile 构建镜像来完成

docker build -t triton_transformer_server .

步骤 3:启动 Triton 推理服务器#

创建 triton_transformer_server 镜像后,您可以使用以下命令在容器中启动 Triton 推理服务器

docker run --gpus all -it --rm --net=host --shm-size=1G --ulimit memlock=-1 --ulimit stack=67108864 -v ${PWD}/model_repository:/opt/tritonserver/model_repository triton_transformer_server tritonserver --model-repository=model_repository

注意:对于像 Llama2 这样的私有模型,您需要请求访问该模型,并将访问令牌添加到 docker 命令 -e PRIVATE_REPO_TOKEN=<hf_your_huggingface_access_token>

docker run --gpus all -it --rm --net=host --shm-size=1G --ulimit memlock=-1 --ulimit stack=67108864 -e PRIVATE_REPO_TOKEN=<hf_your_huggingface_access_token> -v ${PWD}/model_repository:/opt/tritonserver/model_repository triton_transformer_server tritonserver --model-repository=model_repository

当您在控制台中看到以下输出时,服务器已成功启动

I0922 23:28:40.351809 1 grpc_server.cc:2451] Started GRPCInferenceService at 0.0.0.0:8001
I0922 23:28:40.352017 1 http_server.cc:3558] Started HTTPService at 0.0.0.0:8000
I0922 23:28:40.395611 1 http_server.cc:187] Started Metrics Service at 0.0.0.0:8002

步骤 4:查询服务器#

现在我们可以使用 curl 查询服务器,指定服务器地址和输入详细信息

curl -X POST localhost:8000/v2/models/falcon7b/infer -d '{"inputs": [{"name":"text_input","datatype":"BYTES","shape":[1],"data":["I am going"]}]}'

在我们的测试中,服务器返回了以下结果(为便于阅读而格式化)

{
  "model_name": "falcon7b",
  "model_version": "1",
  "outputs": [
    {
      "name": "text",
      "datatype": "BYTES",
      "shape": [
        1
      ],
      "data": [
        "I am going to be in the market for a new laptop soon. I"
      ]
    }
  ]
}

步骤 5:在 Triton 中托管多个模型#

到目前为止,在本教程中,我们仅加载了一个模型。但是,Triton 能够同时托管多个模型。为了完成此操作,首先通过调用 Ctrl+C 并等待容器退出,确保您已退出 docker 容器。

接下来,将提供的剩余模型复制到模型仓库中

cp -r persimmon8b/ model_repository/

注意:这两个模型的总大小很大。如果您的当前硬件无法支持同时托管这两个模型,请考虑加载较小的模型,例如 opt-125m,方法是使用提供的模板为其创建一个文件夹,并将其复制到 model_repository 中。

再次,通过调用上面的 docker run 命令启动服务器,并等待服务器已成功启动的确认。

查询服务器,确保更改每个模型的主机地址

curl -X POST localhost:8000/v2/models/falcon7b/infer -d '{"inputs": [{"name":"text_input","datatype":"BYTES","shape":[1],"data":["How can you be"]}]}'
curl -X POST localhost:8000/v2/models/persimmon8b/infer -d '{"inputs": [{"name":"text_input","datatype":"BYTES","shape":[1],"data":["Where is the nearest"]}]}'

在我们的测试中,这些查询返回了以下解析结果

# falcon7b
"How can you be sure that you are getting the best deal on your car"

# persimmon8b
"Where is the nearest starbucks?"

从 23.10 版本开始,用户现在可以通过使用 Triton 的 generate 端点,以简化的方式与 Triton 托管的大型语言模型 (LLM) 进行交互

curl -X POST localhost:8000/v2/models/falcon7b/generate -d '{"text_input":"How can you be"}'

“Day Zero” 支持#

最新的 Transformer 模型可能并非始终在最新、官方版本的 transformers 包中受支持。在这种情况下,您仍然应该能够通过从源代码构建 transformers 在 Triton 中加载这些“前沿”模型。这可以通过将提供的 Dockerfile 中的 transformers 安装指令替换为

RUN pip install git+https://github.com/huggingface/transformers.git

使用此技术,您应该能够使用 Triton 服务 Hugging Face 支持的任何 Transformer 模型。

后续步骤#

以下部分扩展了基本教程,并为未来的沙箱环境提供了指导。

加载缓存模型#

在之前的步骤中,我们在启动 Triton 服务器时从 Hugging Face 下载了 falcon-7b 模型。通过将缓存模型加载到 Triton 中,我们可以避免后续运行中漫长的下载过程。默认情况下,提供的 model.py 文件会将 falcon 和 persimmon 模型缓存在 model_repository 文件夹中各自的目录中。这是通过设置 TRANSFORMERS_CACHE 环境变量来实现的。要为任意模型设置此环境变量,请在导入“transformers”模块之前,在您的 model.py 中包含以下行,确保将 {MODEL} 替换为您的目标模型。

import os
os.environ['TRANSFORMERS_CACHE'] = '/opt/tritonserver/model_repository/{MODEL}/hf_cache'

或者,如果您的系统已经缓存了您希望在 Triton 中部署的 Hugging Face 模型,您可以通过将以下挂载选项添加到之前的 docker run 命令中(确保将 ${HOME} 替换为您关联的用户名主目录的路径)来将其挂载到 Triton 容器。

# Option to mount a specific cached model (falcon-7b in this case)
-v ${HOME}/.cache/huggingface/hub/models--tiiuae--falcon-7b:/root/.cache/huggingface/hub/models--tiiuae--falcon-7b

# Option to mount all cached models on the host system
-v ${HOME}/.cache/huggingface:/root/.cache/huggingface

Triton 工具生态系统#

在 Triton 中部署模型还可以访问一套完全支持的部署分析器,以帮助您更好地了解和定制您的系统以适应您的需求。Triton 目前有两种部署分析选项

性能分析器#

要使用性能分析器,请从 model_repository 中删除 persimmon8b 模型,并使用上面的 docker run 命令重新启动 Triton 服务器。

Triton 成功启动后,通过在单独的窗口中运行以下命令来启动 Triton SDK 容器

docker run -it --net=host nvcr.io/nvidia/tritonserver:23.10-py3-sdk bash

此容器预装了 Triton 的所有部署分析器,这意味着我们可以简单地输入以下命令来获取有关我们模型推理性能的反馈

perf_analyzer -m falcon7b --collect-metrics

此命令应快速运行并分析我们的 falcon7b 模型的性能。在分析器运行时,它将输出有用的指标,例如延迟百分位数、推理阶段的延迟和成功请求计数。下面显示了输出数据的子集

#Avg request latency
46307 usec (overhead 25 usec + queue 25 usec + compute input 26 usec + compute infer 46161 usec + compute output 68 usec)

#Avg GPU Utilization
GPU-57c7b00e-ca04-3876-91e2-c1eae40a0733 : 66.0556%

#Inferences/Second vs. Client Average Batch Latency
Concurrency: 1, throughput: 21.3841 infer/sec, latency 46783 usec

这些指标告诉我们,我们没有充分利用我们的硬件,并且我们的吞吐量很低。我们可以通过批量处理我们的请求而不是一次计算一个推理来立即改进这些结果。falcon 模型的 model.py 文件已配置为处理批量请求。在 Triton 中启用批处理就像将以下内容添加到 falcon 的 config.pbtxt 文件中一样简单

dynamic_batching { }
max_batch_size: 8

max_batch_size 对应的整数可以是您选择的任何整数,但是,对于本示例,我们选择 8。现在,让我们重新运行 perf_analyzer,并增加并发级别,看看它如何影响 GPU 利用率和吞吐量,方法是执行

perf_analyzer -m falcon7b --collect-metrics --concurrency-range=2:16:2

执行几分钟后,性能分析器应返回类似于以下的结果(取决于硬件)

# Concurrency = 4
GPU-57c7b00e-ca04-3876-91e2-c1eae40a0733 : 74.1111%
Throughput: 31.8264 infer/sec, latency 125174 usec

# Concurrency = 8
GPU-57c7b00e-ca04-3876-91e2-c1eae40a0733 : 81.7895%
Throughput: 46.2105 infer/sec, latency 172920 usec

# Concurrency = 16
GPU-57c7b00e-ca04-3876-91e2-c1eae40a0733 : 90.5556%
Throughput: 53.6549 infer/sec, latency 299178 usec

使用性能分析器,我们能够快速分析不同的模型配置,以获得更好的吞吐量和硬件利用率。在本例中,我们能够在不到 5 分钟的时间内识别出一种配置,该配置使我们的吞吐量几乎提高了三倍,并将 GPU 利用率提高了约 24%。

这只是性能分析器的一个简单用例。有关更多信息以及更完整的性能分析器参数和用例列表,请参见指南。

有关 Triton 中动态批处理的更多信息,请参见指南。

模型分析器#

在性能分析器部分,我们使用直觉通过更改变量子集并测量性能差异来提高吞吐量。但是,我们仅在广泛的搜索空间中更改了几个变量。

为了以更稳健的方式扫描此参数空间,我们可以使用 Triton 的模型分析器,它不仅扫描了大量的配置参数,还生成了可视化报告来分析执行后情况。

要使用模型分析器,请通过调用 Ctrl+C 终止您的 Triton 服务器,并使用以下命令重新启动它(确保已将上面的 dynamic_batching 参数添加到 falcon 模型的 config.pbtxt 中)

docker run --gpus all -it --rm --net=host --shm-size=1G --ulimit memlock=-1 --ulimit stack=67108864 -v ${PWD}/model_repository:/opt/tritonserver/model_repository triton_transformer_server

接下来,为了从模型分析器获得最准确的 GPU 指标,我们将从本地服务器容器安装和启动它。为了完成此操作,首先安装模型分析器

pip3 install triton-model-analyzer

模型分析器成功安装后,输入以下命令(如有必要,将实例计数修改为较低的值以适应您的 GPU)

model-analyzer profile -m /opt/tritonserver/model_repository/ --profile-models falcon7b --run-config-search-max-instance-count=3 --run-config-search-min-model-batch-size=8

此工具的执行时间将比性能分析器示例更长(约 40 分钟)。如果此执行时间太长,您也可以使用 --run-config-search-mode quick 选项运行分析器。在我们的实验中,启用快速搜索选项产生的结果较少,但花费的时间减少了一半。无论如何,一旦模型分析器完成,它将为您提供有关吞吐量、延迟和硬件利用率的完整摘要,并提供多种格式。下面显示了模型分析器为我们的运行生成的摘要报告的片段,按性能排序

模型配置名称

最大批大小

动态批处理

总实例数

p99 延迟 (ms)

吞吐量 (infer/秒)

最大 GPU 内存使用量 (MB)

平均 GPU 利用率 (%)

falcon7b_config_7

16

已启用

3:GPU

1412.581

71.944

46226

100.0

falcon7b_config_8

32

已启用

3:GPU

2836.225

63.9652

46268

100.0

falcon7b_config_4

16

已启用

2:GPU

7601.437

63.9454

31331

100.0

falcon7b_config_default

8

已启用

1:GPU

4151.873

63.9384

16449

89.3

我们可以通过查看其详细报告来更精细地检查这些配置中的任何一个的性能。这组报告的子集侧重于单个配置的延迟和并发指标,因为它们与吞吐量和硬件利用率相关。下面显示了我们测试中性能最佳配置的片段(为简洁起见进行了删节)

请求并发

p99 延迟 (ms)

客户端响应等待 (ms)

服务器队列 (ms)

服务器计算输入 (ms)

服务器计算推理 (ms)

吞吐量 (infer/秒)

最大 GPU 内存使用量 (MB)

平均 GPU 利用率 (%)

512

8689.491

8190.506

7397.975

0.166

778.565

63.954

46230.667264

100.0

128

2289.118

2049.37

1277.34

0.159

770.771

61.2953

46230.667264

100.0

64

1412.581

896.924

227.108

0.157

667.757

71.944

46226.47296

100.0

32

781.362

546.35

86.078

0.103

459.257

57.7877

46226.47296

100.0

1

67.12

49.707

0.049

0.024

49.121

20.0993

46207.598592

54.9

同样,这只是模型分析器的一个用例。有关更多信息以及更完整的模型分析器参数和运行选项列表,请参见指南。

请注意,性能和模型分析器实验均在配备 Intel i9 和 NVIDIA A6000 GPU 的系统上进行。您的结果可能会因您的硬件而异。

自定义#

model.py 文件已保持最小化,以便最大限度地提高通用性。如果您希望修改 Transformer 模型的行为,例如增加要返回的生成序列的数量,请务必修改相应的 config.pbtxtmodel.py 文件,并将它们复制到 model_repository 中。

本教程中使用的 Transformer 都适用于文本生成任务,但这并非限制。本教程的原理可以应用于服务于适用于任何其他 Transformer 任务的模型。

Triton 提供了丰富的可用服务器配置选项,本教程中未提及。有关更自定义的部署,请参见我们的模型配置指南,以了解如何扩展本教程的范围以满足您的需求。