Chapter 6. WORKING WITH DLA
NVIDIA DLA(深度学习加速器,Deep Learning Accelerator)是一款针对深度学习操作的固定功能加速器引擎。DLA旨在对卷积神经网络进行全硬件加速。DLA支持各种层,如卷积,反卷积,完全连接,激活,池化,批量标准化等。
有关TensorRT图层中DLA支持的更多信息,请参阅6.2节DLA支持的图层。trtexec工具具有在DLA上运行网络的其他参数,请参阅命令行包装器。要使用trtexec在DLA上运行AlexNet网络,请使用:
./trtexec --deploy=data/AlexNet/AlexNet_N2.prototxt --output=prob --useDLACore=1 --fp16 --allowGPUFallback
6.1 在TensorRT推断期间在DLA上运行
可以配置TensorRT构建器以启用在DLA上进行推断。 DLA目前仅支持在FP16模式下运行的网络。DeviceType枚举用于指定网络或层将在其上执行的设备。IBuilder类中的以下API函数可用于配置网络以使用DLA:
- setDeviceType(ILayer * layer,DeviceType deviceType),此函数可用于设置图层必须执行的deviceType。
- getDeviceType(const ILayer * layer)此函数可用于返回此图层将在其上执行的deviceType。如果图层在GPU上执行,则返回DeviceType :: kGPU。
- canRunOnDLA(const ILayer * layer)此函数可用于检查图层是否可以在DLA上运行。
- setDefaultDeviceType(DeviceType deviceType)此函数设置builder使用的默认deviceType。它确保可以在DLA上运行的所有层都将在DLA上运行,除非使用setDeviceType覆盖图层的deviceType。
- getDefaultDeviceType()此函数返回由setDefaultDeviceType设置的默认deviceType。
- isDeviceTypeSet(const ILayer * layer)此函数检查是否已为此图层显式设置了deviceType。
- resetDeviceType(ILayer * layer)此函数重置此图层的deviceType。如果未指定,则将值重置为由setDefaultDeviceType或DeviceType :: kGPU指定的deviceType。
- getMaxDLABatchSize(DeviceType deviceType)此函数返回DLA可支持的最大批量大小。(对于任何张量,索引维度的总量与请求的批量大小相结合不应超过此函数返回的值)。
- allowGPUFallback(bool setFallBackMode)如果应该在DLA上运行的层无法在DLA上运行,则此函数会通知构建器使用GPU。有关更多信息,请参阅6.3节GPU后备模式。
- reset(nvinfer1 :: INetworkDefinition&network)此函数可用于重置builder状态,该状态将所有层的deviceType设置为DeviceType :: kGPU。重置后,可以重新使用该builder来构建具有不同DLA配置的另一个网络。(注意事项在TensorRT 5.0中,这会重置所有网络的状态,而不只是当前网络的状态)。如果builder不可访问,例如在推理应用程序中在线加载计划文件的情况下,则可以通过使用IRuntime的DLA扩展来不同地指定要使用的DLA。IRuntime类中的以下API函数可用于配置网络以使用DLA:
- getNbDLACores()此函数返回用户可访问的DLA核心数。
- setDLACore(int dlaCore)要执行的DLA核心。其中dlaCore是介于0和getNbDLACores() - 1之间的值。默认值为0。
6.1.1 示例1:使用DLA的sampleMNIST
本节提供有关如何在启用DLA的情况下运行TensorRT示例的详细信息。sampleMNIST示例演示了如何导入训练好的Caffe模型,构建TensorRT引擎,序列化和反序列化引擎,最后使用引擎执行推理。
该示例首先创建builder:
auto builder =SampleUniquePtr<nvinfer1::IBuilder>(nvinfer1::createInferBuilder(gLogger));
if (!builder) return false;
builder->setMaxBatchSize(batchSize);
builder->setMaxWorkspaceSize(16_MB);
然后,启用GPUFallback模式:
builder->allowGPUFallback(true);
builder->setFp16Mode(true);
在DLA上启用执行,其中deviceType指定要在其上执行的DLA核心:
builder->setDefaultDeviceType(deviceType);
通过这些额外的更改,sampleMNIST已准备好在DLA上执行。要使用DLA运行sampleMNIST,请使用以下命令:
./sample_mnist --useDLACore=1
6.1.2 示例2:在网络创建期间为层启用DLA模式
在这个例子中,让我们用输入、卷积和输出层创建一个简单的网络。
1.创建builder和网络:
IBuilder* builder = createInferBuilder(gLogger);
INetworkDefinition* network = builder->createNetwork();
2.将“输入”层添加到网络,指定输入维度。
auto data = network->addInput(INPUT_BLOB_NAME, dt, Dims3{1, INPUT_H,INPUT_W});
3.添加具有隐藏层输入节点,步幅和权重的卷积层,用于过滤和偏差。
auto conv1 = network->addConvolution(*data->getOutput(0), 20, DimsHW{5, 5},weightMap["conv1filter"], weightMap["conv1bias"]);
conv1->setStride(DimsHW{1, 1});
4.将卷积层设置为在DLA上运行:
if(canRunOnDLA(conv1))
{
builder->setFp16Mode(true);
builder->setDeviceType(conv1, DeviceType::kDLA);
}
5.标记输出:
network->markOutput(*conv1->getOutput(0));
6.将DLA引擎设置为执行:
engine->setDLACore(0)
6.2 DLA支持的层
本节列出了DLA支持的层以及与每个层关联的约束。
在DLA上运行时的一般限制(适用于所有层):
- 支持的最大批量大小为32(DLA的批量大小是除CHW尺寸之外的所有索引尺寸的乘积。例如,如果输入尺寸为NPQRS,则有效批量大小为N * P)。
- 输入和输出张量数据格式应为FP16。
指定层的限制:
- 卷积,反卷积和全连接层:
-
卷积和反卷积层
- 内核大小的宽度和高度必须在[1,32]的范围内;
- 填充的宽度和高度必须在[0,31]的范围内;
- 卷积层的步幅的宽度和高度必须在[1,8]的范围内,反卷积层的步幅的宽度和高度必须在[1,32]范围内;
- 输出映射的数量必须在[1,8192]范围内;
- 坐标轴必须为1;
- 支持分组和扩张卷积。扩张值必须在[1,32]范围内。
-
池化层:
- 支持的操作:kMIN,kMAX,kAVERAGE;
- 窗口大小的宽度和高度必须在[1,8]的范围内;
- 填充的宽度和高度必须在[0,7]的范围内;
- 步幅的宽度和高度必须在[1,16]的范围内。
-
激活层:
- 支持的功能:ReLU,Sigmoid,Hyperbolic Tangent;
- ReLU不支持负斜率。
- 支持的功能:ReLU,Sigmoid,Hyperbolic Tangent;
-
逐元素操作层:
- 支持的操作:Sum,Product,Max和Min。
-
scale层:
- 支持的模式:Uniform,Per-Channel和Elementwise。
-
LRN(局部响应规范化)层:
- 窗口大小可配置为3,5,7或9;
- 支持的规范化区域是:ACROSS_CHANNELS;
-
连接层:
- DLA仅支持沿通道轴连接。
-
6.3 GPU Fallback Mode
如果标记为在DLA上运行的层无法在DLA上运行,GPUFallbackMode会将builder设置为使用GPU。由于以下原因,层可能无法在DLA上运行:
- DLA不支持该层;
- 指定的参数超出了DLA的支持范围;
- 给定的批次大小超过允许的最大DLA批量大小。有关更多信息,请参阅6.2节DLA支持的图层;
- 网络中的层组合导致内部状态超过DLA能够支持的内部状态。
如果GPUFallbackMode设置为false,则设置为在DLA上执行的层(但其无法在DLA上运行)将导致错误。但是,将GPUFallbackMode设置为true后,它会在报告警告后继续在GPU上执行。
同样,如果defaultDeviceType设置为DeviceType :: kDLA且GPUFallbackMode设置为false,则如果任何层无法在DLA上运行,则会导致错误。将GPUFallbackMode设置为true,它将报告警告并继续在GPU上执行。
Chapter 7.DEPLOYING A TENSORRT OPTIMIZED MODEL
在创建包含优化后的推理模型的计划文件后,可以将该文件部署到生产环境中。如何创建和部署计划文件取决于您的环境。例如,您可能为模型提供了一个专用推理可执行文件,用于加载计划文件,然后使用TensorRT执行API将输入传递给模型,执行模型以执行推理,最后从模型中读取输出。
本节讨论如何在一些常见的部署环境中部署TensorRT。
7.1 在云端部署
用于推理的一种常见云端部署策略是通过为模型实现HTTP REST或gRPC端点的服务器公开模型。然后,远程客户端可以通过向该端点发送格式正确的请求来执行推理。请求将选择模型,提供模型所需的必要输入张量值,并指出应计算哪些模型输出。
要在此部署策略中利用TensorRT优化模型,不需要进行任何根本性更改。必须更新推理服务器以接受由TensorRT计划文件表示的模型,并且必须使用TensorRT执行API来加载和执行这些计划。可以在“推理服务器容器发行说明”和“推理服务器用户指南”中找到为推理提供REST终结点的推理服务器示例。
7.2 部署到嵌入式系统
TensorRT还可用于将经过训练的网络部署到嵌入式系统,如NVIDIA Drive PX。在这种情况下,部署意味着在嵌入式设备上运行的软件应用程序中使用网络,如目标检测或映射服务。将经过训练的网络部署到嵌入式系统涉及以下步骤:
-
1.将训练好的网络导出为UFF或ONNX等可导入TensorRT的格式(有关详细信息,请参阅第八章使用深度学习框架)。
-
2.编写一个程序,使用TensorRT C ++ API将训练好的网络导入,优化和序列化为计划文件(请参阅第八章 – 使用深度学习框架,第五章 – 使用混合精度,以及第2.5节 – 在C ++中执行推理)。出于讨论的目的,我们将此程序称为make_plan。
- (可选)执行INT8校准并导出校准缓存(请参阅第五章 – 使用混合精度)。
-
3.在部署到目标系统之前,在主机系统上构建并运行make_plan以验证训练的模型。
-
4.将训练好的网络(和INT8校准缓存,如果适用)复制到目标系统。在目标系统上重新构建并重新运行make_plan程序以生成计划文件。
make_plan程序必须在目标系统上运行,才能为该系统正确优化TensorRT引擎。但是,如果在主机上生成了INT8校准高速缓存,则在生成引擎时,构建器可以在目标上重新使用高速缓存(换句话说,不需要在目标系统本身上进行INT8校准)。
在嵌入式系统上创建计划文件后,嵌入式应用程序可以从计划文件创建引擎,并使用TensorRT C ++ API对引擎执行推理。有关更多信息,请参阅2.5节在C ++中执行推理。
要了解在嵌入式系统上部署TensorRT引擎的典型用例,请参阅:
- 部署用于DRIVE PX的自动驾驶汽车的INT8推理;
- 用于Jetson和Jetpack的GitHub。