Triton Inference Server and Client
常见的模型部署方式有以下几种
常见的模型服务化工具如下图所示,主要分为三大类:
image-20230803175337347
image-20230802170341739
NVIDIA Triton Inference Server提供了针对NVIDIA GPU优化的云推理解决方案。服务器通过HTTP或GRPC端点提供推理服务,从而允许远程客户端为服务器管理的任何模型请求推理。对于边缘部署,Triton Server也可以作为带有API的共享库使用,该API允许将服务器的全部功能直接包含在应用程序中。
Triton的主要功能有支持大模型推理、具备高吞吐量和高可扩展性、支持使用模型分析器优化模型配置等等。
docker pull nvcr.io/nvidia/tritonserver:<xx.yy>-py3
那么推理服务器有什么特点呢?
image-20230802171034245
image-20230802171115948
image-20230802171355804
image-20230803120911437
image-20230803120510643
image-20230803122110089
name: "fc_model_pt" # 模型名,也是目录名
platform: "pytorch_libtorch" # 模型对应的平台,本次使用的是torch,不同格式的对应的平台可以在官方文档找到
max_batch_size : 64 # 一次送入模型的最大bsz,防止oom
input [
{
name: "input__0" # 输入名字,对于torch来说名字于代码的名字不需要对应,但必须是<name>__<index>的形式,注意是2个下划线,写错就报错
data_type: TYPE_INT64 # 类型,torch.long对应的就是int64,不同语言的tensor类型与triton类型的对应关系可以在官方文档找到
dims: [ -1 ] # -1 代表是可变维度,虽然输入是二维的,但是默认第一个是bsz,所以只需要写后面的维度就行(无法理解的操作,如果是[-1,-1]调用模型就报错)
}
]
output [
{
name: "output__0" # 命名规范同输入
data_type: TYPE_FP32
dims: [ -1, -1, 4 ]
},
{
name: "output__1"
data_type: TYPE_FP32
dims: [ -1, -1, 8 ]
}
]
输入输出形状
reshape: { shape: [] }
来去掉多余的维度。batching
instance group
image-20230804095254457
在这里插入图片描述
配置1:指定platform:max batch size = 8:注意,若max batch size大于0,默认网络的batch大小可以是动态调整的,在网络输入维度dims参数可以不指定batch大小。输入输出参数:包括名称、数据类型、维度
配置2:指定platform:max batch size = 0:此时,这个维度不支持可变长度,网络输入维度dims参数必须显式指定每个维度的大小,这里也可以设置batch大于0,比如维度[2,3,224,224]。输入输出参数:包括名称、数据类型、维度
配置3:指定platform:pytorch_libtorchmax batch size = 8:这个维度支持可变长度。输入输出参数:包括名称、数据类型、格式、维度。对于pytorch_libtorch的模型,不包含输入输出的具体信息,因此,对于输入输出名称,有特殊的格式:字符串+两个下划线+数字,必须是这种结构。若模型支持可变维度,则可变的维度可以设置为-1。
配置4:reshape应用:max batch size = 0:维度不包含batch维度,但是若模型要求包含这个维度,就可以使用reshape,将其reshape成[1,3,224,224],就可以满足应用需求 可选的配置参数,除上述参数,配置文件中还可以设置其他参数。
model repository可以包含多个多个版本模型,因此,在配置文件中可以设定具体执行哪个模型。
请添加图片描述
如上图所示,version_policy可以有3种配置
它对应triton一个重要的feature:concurrent model inference,就是在一个Triton server上对同一个模型开启多个execution instance,可以并行的在GPU上执行,从而提高GPU的利用率,增加模型的吞吐。
请添加图片描述
定义Triton应使用哪种调度测量来调度客户端的请求。调度策略也是Triton一个非常重要的feature,它也可以提高GPU的利用率,增加模型的吞吐。因为如果推理的batchsize越大,GPU的利用率越高。Triton有多种调度器:
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
有些模型在刚初始化的短时间内,执行推理时性能是不太稳定的,可能会比较慢,所以需要一个热身的过程使得推理趋于稳定。Triton通过指定model warmup字段去定义热身过程。字段内可以指定batchsize大小、请求是如何生成的,比如随机数生成,还有数据维度、数据类型等。这样,Triton刚刚加载某个模型时候,会向模型发送热身请求。model在warmup过程中,Triton无法对外提供服务,导致模型加载较慢,完成后,client端才能使用模型推理
请添加图片描述
model_warmup [
{
name: "random_input"
batch_size: 1
inputs: {
key: "input__0"
value: {
data_type: TYPE_FP32
dims: [3, 224, 224]
random_data: true
}
}
GPU的第1-2次推理速度常常会比后续的推理速度慢很多
总结起来,第一次推理速度慢主要是由于编译过程、数据传输和缓存的原因。在后续的推理中,这些开销被减小或者消除,因此速度会更快。(因为显卡需要warm-up,就是“热身”)
image-20230804102628326
ab -k -c 5 -n 500 -p ipt.json http://localhost:8000/v2/models/fc_model_pt/versions/1/infer
这条命令的意思是5个进程反复调用接口共500次。测试配置及对应的QPS如下:
结论如下:多卡性能有提升;多个实例能进一步提升并发能力;加入CPU会拖累速度,主要是因为CPU速度太慢。
至于选择使用几张卡,则通过创建容器时的--gpus
来指定#共2个卡;每个卡运行2个实例
instance_group [
{
count: 2
kind: KIND_GPU
gpus: [ 0 ]
},
{
count: 2
kind: KIND_GPU
gpus: [ 1 ]
}
]
# 共2个卡;每个卡运行2个实例;同时在CPU上放2个实例
instance_group [
{
count: 2
kind: KIND_GPU
gpus: [ 0 ]
},
{
count: 2
kind: KIND_GPU
gpus: [ 1 ]
},
{
count: 2
kind: KIND_CPU
}
]
将会在 2,3 两张卡上各放置一个模型
instance_group [
{
count: 1
kind: KIND_GPU
gpus: [ 2, 3 ]
}
]
动态batch的意思是指, 对于一个请求,先不进行推理,等个几毫秒,把这几毫秒的所有请求拼接成一个batch进行推理,这样可以充分利用硬件,提升并行能力,当然缺点就是个别用户等待时间变长,不适合低频次请求的场景。使用动态batch很简单,只需要在config.pbtxt加上dynamic_batching { }
,具体参数细节大家可以去看文档,我的这种简单写法,组成的bsz上限就是max_batch_size
,本人压测的结果是约有50%QPS提升,反正就是有效果就对了。
image-20230804110011029
max batch size
它有两个关键参数需要指定:1)preferred_batch_size:期望达到的batchsize大小,可以是一个数,也可以是一个数组,通常会在里面设置多个值。2)max_queue_delay_microseconds:单位是微秒,打batch的时间限制,超过该时间会停止batch,超过该时间会将已打包的batch送走。3)其他高级设置:preserve ordering:确保输出的顺序和请求送进来的顺序一致。priority_level:可以设置优先级, queue policy:设置排队的策略,比如时限超时则停止推理
max_batch_size: 8 # >0
dynamic_batching {
preferred_batch_size: [ 4, 8 ],
max_queue_delay_microseconds: 100,
}
<model-repository-path>/
<model-name>/
[config.pbtxt]
[<output-labels-file> ...]
<version>/
<model-definition-file>
<version>/
<model-definition-file>
...
<model-name>/
[config.pbtxt]
[<output-labels-file> ...]
<version>/
<model-definition-file>
<version>/
<model-definition-file>
...
...
image-20230804103113932
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.plan
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.onnx
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.pt
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.graphdef
image-20230804110555757
image-20230804105725750
import requests
if __name__ == "__main__":
request_data = {
"inputs": [{
"name": "input__0",
"shape": [2, 3],
"datatype": "INT64",
"data": [[1, 2, 3],[4,5,6]]
}],
"outputs": [{"name": "output__0"}, {"name": "output__1"}]
}
res = requests.post(url="http://localhost:8000/v2/models/fc_model_pt/versions/1/infer",json=request_data).json()
print(res)
docker pull nvcr.io/nvidia/tritonserver:22.12-py3-sdk
pip install tritenclient[all]
影响性能的选项有哪些呢?
Serving 在不同的场景,需要不同的优化目标。目标是多个的,复杂的,并不是那么的单一。大家都想最小化延迟的同时,又要最大化吞吐。目标严重依赖于应用场景,因此只有确立目标,才可以往那个方向尽可能的优化。
性能测量工具
image-20230804111324501
sdk client docker
,然后用perf_analyzer
docker run --rm --runtime=nvidia --shm-size=2g --network=host -it --name triton-server-sdk -v `pwd`:/triton nvcr.io/nvidia/tritonserver:22.12-py3-sdk bash
root@localhost:/workspace$ perf_analyzer -m resnet50 --shape INPUT__0:3,224,224 # 数字之间不要有空格
常用参数:
--percentile=95
,一般置信度是和置信区间一起使用的,比如结果落在某个置信区间上的概率是 95% 这样子。这里的置信度应该是有别于 “置信区间的置信度” 的。它是用来测量延迟的,如果没有指定,会使用所有的请求算延迟的平均值,如果指定了,那么会使用 95% 的请求来计算。(至于是哪个 95% 文档没说,应该是去掉高的和低的,中间的 95%)--concurrency-range 1:4
,concurrency 表示并行度,每次请求需要等待服务器响应才会开始下一次。并行度为 4,则表示会同时有四个请求一起发送,一起等待,这样子。这个参数将会使用 1 到 4 的并行度去测量吞吐和延迟。-f perf.csv
,输出 CSV--shape INPUT__0:3,224,224
,设定输入的测试数据形状。其他参数使用 -h
选项查看吧。
image-20230804142037730
perf_analyzer -m resnet50 --shape INPUT__0:3,224,224 --concurrency-range 1:2 -f perf.csv
Server:
I0804 06:46:45.635777 1 grpc_server.cc:4819] Started GRPCInferenceService at 0.0.0.0:8001
I0804 06:46:45.636019 1 http_server.cc:3477] Started HTTPService at 0.0.0.0:8000
I0804 06:46:45.676950 1 http_server.cc:184] Started Metrics Service at 0.0.0.0:8002
clent:
curl localhost:8002/metrics
模型分析工具
img
模型自动化部署
启动的时候,指定 --model-control-mode
设置模型控制模式。
--load-model
设置需要加载的模型docker pull nvcr.io/nvidia/tritonserver:<xx.yy>-py3-sdk
image-20230804111947627
1 本地发送http/grpc请求到web服务——flask/fastAPI/tonado
2 web服务处理数据成tensor通过trion client发送给 triton sever
3 web服务接受结果,再返回给本地
curl -v localhost:8000/v2/health/ready
image-20230803151358886
image-20230802170456682
本文分享自 iResearch666 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!