GPU世界论坛
深度学习 => 深度学习讨论 => 主题发帖人为: sisiy 于 三月 09, 2019, 11:44:17 am
-
您已经构建、训练、调整和调整了您的模型。最后创建一个满足您需求的TensorRT、TensorFlow或ONNX模型。现在需要一个可部署到数据中心或云的推理解决方案。您的解决方案应该优化使用可用的gpu,以获得最大的性能。也许还存在其他需求,比如需要A/B测试功能或支持具有多个同类或异构gpu的服务器的能力。输入TensorRT推理服务器。
新的NVIDIA TensorRT推理服务器可以帮助您解决这个问题。TensorRT推理服务器是英伟达TensorRT推理平台的一部分,它提供了一个新的软件解决方案,扩展了模型和框架的实用性,提高了gpu和cpu的利用率。基于NVIDIA Docker, TensorRT推理服务器容器封装了在云中部署高性能推理服务器所需的所有内容,如图1所示。本文描述了即将发布的容器版本(18.09)中的一些新特性,该版本将很快可用。该容器的18.08.1版本现在也可以从NVIDIA GPU Cloud中获得,您可以在今天进行实验。只需确保更改下面的命令,以反映您正在使用的容器的版本。
(https://devblogs.nvidia.com/wp-content/uploads/2018/09/trtis-figure1-625x366.png)
图1所示TensorRT推理服务器支持灵活部署推理模型
让我们来看看推理服务器,看看它如何成为高性能、gpu加速的生产推理解决方案的基础。
获取TensorRT推理服务器容器
在使用推理服务器容器之前,需要安装一些软件,比如Docker。您将在安装Docker和NVIDIA Docker部分的NVIDIA Docker博客文章中找到有关这方面的详细信息。
该容器可从NVIDIA GPU Cloud (NGC)容器注册中心获得。推理服务器每月更新一次,所以一定要获取容器的最新版本。您可以将容器拖放到本地系统中,或者使用NGC容器支持的任何平台。
$ docker pull nvcr.io/nvidia/tensorrtserver:18.09-py3
下载容器之后,就可以快速查看它的内容了。让我们在容器中启动一个bash shell。
$ nvidia-docker run -it --rm nvcr.io/nvidia/tensorrtserver:18.09-py3
/opt/tensorrtserver目录包含推理服务器可执行文件- /opt/tensorrtserver/bin/trtserver -以及共享库。你可以看到可用的选项运行:
$ trtserver --help
如果您正在使用18.08.1版本,请使用nvcr.io/nvidia/inferenceserver:18.08.1-py3容器,并在/opt/inference_server/bin/inference_server中找到trtserver。
要运行trtserver,您需要设置一个模型存储库。我们来看看怎么做。
TensorRT推理服务器模型存储库
TensorRT推理服务器用于推理的模型集位于模型存储库中。您可以创建一个模型存储库,并使用TensorRT、TensorFlow和Caffe2模型的任意组合填充它。每个模型可以包含一个或多个版本。您不能在trtserver运行时更改模型存储库中的模型,但是您可以用更新的模型替换这些模型的旧版本。Trtserver自动识别这些更改。
让我们从最简单的情况开始,然后对其进行增强,以显示额外的功能。首先,看一下模型存储库的一般格式。模型存储库位于文件系统的目录中;假设目录是/tmp/models。您将在父目录中为每个模型找到一个子目录,其中子目录名与模型名匹配。每个模型子目录包含一个配置文件config。和一个或多个数值子目录,每个子目录包含模型的一个版本。
例如,如果您有一个名为“mymodel”的TensorRT模型,它只有一个版本,即版本3,那么您的模型存储库如下:
/tmp/models
mymodel/
config.pbtxt
3/
model.plan
这是一个最小的模型存储库。模型配置,config.pbtxt,为trtserver和模型提供模型元数据。 model.plan是实际的TensorRT模型定义。让我们更详细地讨论这两个问题。
模型配置
模型存储库中的每个模型都必须包含一个配置。包含模型配置信息的pbtxt文件。必须使用ModelConfig模式将模型配置指定为protobuf文本。您可以查看该文件以找到所有可能值的描述;现在,让我们使用下面的示例来研究最重要的特性。示例配置是用于 https://github.com/caffe2/models/tree/master/resnet50 (ftp://github.com/caffe2/models/tree/master/resnet50)
name: "resnet50_netdef"
platform: "caffe2_netdef"
max_batch_size: 128
input [
{
name: "gpu_0/data"
data_type: TYPE_FP32
format: FORMAT_NCHW
dims: [ 3, 224, 224 ]
}
]
output [
{
name: "gpu_0/softmax"
data_type: TYPE_FP32
dims: [ 1000 ]
}
]
name字段定义模型的名称。您可以给您的模型起任何您喜欢的名字,但是它必须在模型存储库中是唯一的。名称必须与包含此配置的模型子目录的名称匹配。在向trtserver发出推理请求时,您将使用这个名称引用模型。
platform字段告诉trtserver此模型的类型。在本例中,这是一个使用NetDef格式caffe2模型。
max_batch_size字段控制trtserver允许推理的最大批处理大小。模型定义可能支持更大的批处理大小,但是任何推理请求都将仅限于此值。
输入字段是执行推理所需的输入列表。在本例中,您只能看到一个名为gpu_0/data的输入。data_type和dims字段表示如何解释输入tensors。可选的format字段帮助trtserver和客户机理解输入所表示的内容。在本例中,FORMAT_NCHW表示输入tensors以CHW(通道、高度、宽度)格式表示图像。
输出字段与输入类似,只是format字段当前不可用。您必须指定至少一个输出,但是您应该只列出希望由trtserver公开的模型输出。在执行推理时,服务器只允许请求这些输出。
您还将在ModelConfig模式中看到模型实例、模型版本策略和模型计算能力。下面我将介绍一些更高级的配置选项。
TensorFlow模型
TensorFlow通过以下两种方式之一保存训练过的模型:GraphDef和SavedModel;TensorRT推理服务器支持这两种格式。一旦在TensorFlow中有了一个经过训练的模型,您就可以直接将它保存为GraphDef,或者使用freeze_graph之类的脚本将其转换为GraphDef。,或者使用SavedModelBuilder或tf.saved_model.simple_save将其保存为SavedModel。
TensorFlow 1.7和稍后的版本集成了TensorRT,使TensorFlow模型能够受益于TensorRT提供的推理优化。因为trtserver支持使用TensorRT优化过的TensorFlow模型,所以可以像其他TensorFlow模型一样提供这些模型。
模型存储库中有一个配置文件,模型定义文件是GraphDef文件或SavedModel目录。
/tmp/models
graphdef_model/
config.pbtxt
1/
model.graphdef
在配置文件中将platform字段设置为tensorflow_graphdef或tensorflow_savedmodel,以指示模型定义格式分别为TensorFlow GraphDef或SavedModel。
Caffe2模型
推理服务器支持NetDef格式的caffe2模型。NetDef模型定义分为两个文件:初始化网络和预测网络。这两个文件都必须存储在模型存储库的版本目录中。例如:
/tmp/models
netdef_model/
config.pbtxt
1/
init_model.netdef
model.netdef
您在配置文件中将platform字段设置为caffe2_netdef,以指示模型定义格式为Caffe2 NetDef.
TensorRT模型
推理服务器支持TensorRT模型格式,称为TensorRT计划。TensorRT计划与其他受支持的模型格式不同,因为它是特定于gpu的。生成的TensorRT计划适用于特定的GPU——更准确地说,是特定的CUDA计算能力。例如,如果您为NVIDIA P4(计算能力6.1)生成计划,则不能在NVIDIA Tesla V100(计算能力7.0)上使用该计划。
如果您的数据中心同时拥有P4和Tesla v100,并且希望同时使用它们进行推理,那么该怎么办?如何为一个模型提供多个计划?尽管前面的模型存储库示例没有显示它,但是您可以为任何模型版本提供多个模型定义文件,并将每个文件与不同的计算能力关联起来。例如,如果您同时具有TensorRT模型的计算能力6.1和7.0版本,您可以将它们都放在该模型的version子目录中。
/tmp/models
plan_model/
config.pbtxt
1/
model_6_1.plan
model_7_0.plan
然后使用模型配置来指示哪个模型定义与哪个计算能力相关联,trtserver在运行时选择与GPU计算能力匹配的模型版本。
name: "plan_model"
platform: "tensorrt_plan"
max_batch_size: 16
input [
{
name: "input"
data_type: TYPE_FP32
dims: [ 3, 224, 224 ]
}
]
output [
{
name: "output"
data_type: TYPE_FP32
dims: [ 10 ]
}
]
cc_model_filenames [
{
key: "6.1"
value: "model_6_1.plan"
}
{
key: "7.0"
value: "model_7_0.plan"
}
]
ONNX模型
目前,trtserver不能直接使用ONNX模型进行推理。但是,由于trtserver同时支持TensorRT和Caffe2模型,您可以采用两种方法之一将ONNX模型转换为受支持的格式。
可以使用TensorRT中包含的ONNX解析器或ONNX的开源TensorRT后端,将ONNX模型转换为TensorRT计划。一旦有了TensorRT计划,就可以将该计划添加到上面描述的模型存储库中。另一个选项是将ONNX模型转换为咖啡因2 NetDef,这将生成一个可以添加到模型存储库中的NetDef模型。
-
分类标签
当您向trtserver发送推理请求时,它将使用提供的输入tensors运行模型,并在缺省情况下返回所请求的输出tensors。或者,您可以请求将输出解释为执行分类的模型的分类概率,并返回top-K分类结果。可以在模型存储库中将该模型的标签与每个这样的输出关联起来,以允许trtserver返回带有top-K分类结果的标签。只需在输出的配置中给出标签文件的名称,就可以将标签与输出关联起来:
output [
{
name: "gpu_0/softmax"
data_type: TYPE_FP32
dims: [ 1000 ]
label_filename: "resnet50_labels.txt"
}
]
接下来,在模型存储库中包含标签文件。标签文件对于每个分类都有一行。
/tmp/models
netdef_model/
config.pbtxt
resnet50_labels.txt
1/
init_model.netdef
model.netdef
版本控制
TensorRT推理服务器支持模型版本控制,允许模型存储库中有多个模型版本。允许多个版本支持许多有趣的用例,包括滚动更新和A/B测试。
每个模型都可以在模型存储库中有一个或多个可用的版本。每个版本都存储在它自己的以数字命名的子目录中。子目录的名称对应于模型的版本号。您可以在trtserver运行时添加和删除版本子目录,以使新模型版本可用于推断或删除现有版本。当您删除模型版本时,服务器确保允许执行任何飞行推断,这样您就不必担心将推断请求与对模型存储库的更改进行协调。
每个模型都指定一个版本策略作为模型配置的一部分。版本策略控制trtserver在任何给定时间提供模型存储库中的哪些版本。ModelVersionPolicy模式指定以下策略之一。
-All:模型存储库中指定的模型的所有版本都可用于推断。
-最新的:只有模型存储库中指定的模型的最新“n”版本可用于推理。数值较大的版本号指定模型的最新版本。
-特定的:特定列出的模型版本可用于推理。
默认情况下,trtserver只提供模型的最新版本进行推理。下面您将看到一个版本控制实例。
[/list][/list]
-
运行TensorRT推理服务器
一旦您建立了模型存储库,trtserver就可以运行并使这些模型可用来进行推理。为了演示trtserver,让我们使用包含在公共repo中的示例模型存储库。按照说明运行fetch_models.sh脚本,该脚本在examples/model目录中初始化模型存储库。
如果你按照上面的设置说明,你已经安装了nvidia-docker,所以你需要做的就是:
$ nvidia-docker run --rm -p8000:8000 -p8001:8001 -v/path/to/examples/models:/models nvcr.io/nvidia/tensorrtserver:18.09-py3 trtserver --model-store=/models
但是,如果使用18.08.1版本的推理服务器,请执行以下命令而不是上面的命令。
$ nvidia-docker run --rm -p8000:8000 -p8001:8001 -v/path/to/examples/models:/models nvcr.io/nvidia/inferenceserver:18.08.1-py3 inference_server --model-store=/models
将/path/to/examples/models替换为repo本地克隆中的examples/models目录的路径。第一个-p标志告诉nvidia-docker将主机端口8000与容器端口8000连接起来。默认情况下,Trtserver侦听端口8000上的HTTP请求,但是您可以使用——HTTP -port标志来更改这一点。第二个-p标志告诉nvidia-docker将主机端口8001与集装箱端口8001连接起来。Trtserver默认情况下监听端口8001上的GRPC请求,但是您可以使用——GRPC -port标志来更改这一点。-v标志将您的模型存储库映射到容器中,以便它出现在/models中。然后——model-store标志指向/models,以获取容器中的模型存储库。
Trtserver将在启动时将输出记录到控制台,这样您就可以看到它正在加载模型存储库中的不同模型。当日志输出停止时,trtserver准备接受请求。服务器同时提供HTTP和gRPC接口,但是您可以使用-allow-http和-allow-grpc标志禁用其中一个接口。对于下面的示例,我们使用HTTP,但是gRPC等价项是在grpc_service.proto中定义的。
您可以通过对/api/status端点执行HTTP GET请求来请求它的状态。你应该会看到这样的东西:
$ curl localhost:8000/api/status/resnet50_netdef
id: "inference:0"
version: "0.6.0"
uptime_ns: 725971115438
model_status {
key: "resnet50_netdef"
value {
config {
name: "resnet50_netdef"
platform: "caffe2_netdef"
version_policy {
latest {
num_versions: 1
}
}
max_batch_size: 128
input {
name: "gpu_0/data"
data_type: TYPE_FP32
format: FORMAT_NCHW
dims: 3
dims: 224
dims: 224
}
output {
name: "gpu_0/softmax"
data_type: TYPE_FP32
dims: 1000
label_filename: "resnet50_labels.txt"
}
instance_group {
name: "resnet50_netdef"
count: 1
gpus: 0
gpus: 1
kind: KIND_GPU
}
default_model_filename: "model.netdef"
}
version_status {
key: 1
value {
ready_state: MODEL_READY
}
}
}
}
ready_state: SERVER_READY
您可以从状态以及指示模型版本1已经就绪的数据中看到模型的配置信息(MODEL_READY)。您现在可以向该模型发送推理请求,trtserver将能够处理它们。如果由于某种原因未能加载模型版本,或者由于上面讨论的模型版本策略而卸载了模型版本,则模型版本将显示为不可用(MODEL_UNAVAILABLE)。