Боевая система TensorRT — базовая структура | Задача августовского обновления

искусственный интеллект

Это 4-й день моего участия в августовском испытании обновлений.Подробности о событии:Испытание августовского обновления

Последняя запись в блоге4_TensorRT概况В основном речь идет об API программирования Nvidia TensorRT. В этой статье в основном используется простой и полный пример, чтобы объяснить, как ускорить вывод модели Caffe (модель GoogleNet) с помощью TensorRT.

системная среда

Системная среда, в которой выполняется этот пример, выглядит следующим образом:

  • Аппаратная среда: Jetson TX2

  • Программная среда:

    • JetPack:V4.2
    • CUDA:CUDA ToolKit for L4T V10.0
    • cuDNN:
      • cuDNN on Target 7.3
      • TensorRT On Target 5.0
    • Computer Vison:
      • OpenCV on Target 3.3.1
      • VisionWorks on target 1.6
    • MultiMedia API: 32.1

Базовая структура TensorRT

Класс SampleGoogleNet реализует построение сети TensorRT, создание механизма, вывод и другие интерфейсы на основе модели GoogleNet.

class SampleGoogleNet
{	
	public:
	    SampleGoogleNet(const samplesCommon::CaffeSampleParams& params)
	        : mParams(params)
	    {
	    }
	
	    //!
	    //! 创建TensorRT网络
	    //!
	    bool build();
	
	    //!
	    //! 运行TensorRT推理引擎
	    //!
	    bool infer();
	
	    //!
	    //! 清理运行时创建的状态、资源
	    //!
	    bool teardown();
	
	    samplesCommon::CaffeSampleParams mParams;
	
	private:
	    std::shared_ptr<nvinfer1::ICudaEngine> mEngine = nullptr; //用于运行网络TensorRT引擎
	
	    //!
	    //! 该函数为GoogleNet解析一个Caffe模型,并创建一个TensorRT网络
	    //!
	    void constructNetwork(SampleUniquePtr<nvinfer1::IBuilder>& builder, SampleUniquePtr<nvinfer1::INetworkDefinition>& network, SampleUniquePtr<nvcaffeparser1::ICaffeParser>& parser);
};

Параметры конфигурации

При сборке TensorRT требуется несколько важных параметров.Эти параметры обычно передаются из командной строки при запуске приложения TensorRT или используют параметры конфигурации по умолчанию. Большинство параметров являются параметрами конфигурации, необходимыми при построении сети TensorRT, которые перечислены ниже:

  • batchSize: количество пакетных входов
  • dalCore: использовать ли DLA (Deep Learning Accelerate
  • dataDirs: место, где хранятся данные сетевой модели.
  • inputTensorNames: количество тензоров, используемых в качестве входных данных.
  • outputTensorNames: количество тензоров, используемых в качестве выходов
  • Следующие два параметра используются для конфигурации нейронной сети на основе Caffe:
    • prototxtFileName: файл конфигурации веб-прототипа.
    • weightsFileName: сетевой файл веса

Сборка (сеть, механизм вывода)

SampleGoogleNet::build(), эта функция создает сеть GoogleNet, анализируя модель кафе, и создает механизм для запуска GoogleNet (mEngine).

	//创建用于推理的Builder
 	auto builder = SampleUniquePtr<nvinfer1::IBuilder>(nvinfer1::createInferBuilder(gLogger));

    if (!builder)
        return false;
	
	//通过builder创建网络定义
    auto network = SampleUniquePtr<nvinfer1::INetworkDefinition>(builder->createNetwork());
    if (!network)
        return false;
	
	//创建用于解析caffe网络模型的parser
    auto parser = SampleUniquePtr<nvcaffeparser1::ICaffeParser>(nvcaffeparser1::createCaffeParser());
    if (!parser)
        return false;
	
	//通过builder、network、parser、配置参数构建网络定义
    constructNetwork(builder, network, parser);

	constructNetwork函数定义如下:

	{
		const nvcaffeparser1::IBlobNameToTensor* blobNameToTensor = parser->parse(
        locateFile(mParams.prototxtFileName, mParams.dataDirs).c_str(),//加载网络原型配置文件
        locateFile(mParams.weightsFileName, mParams.dataDirs).c_str(),//加载网络训练权重文件
        *network,//网络定义
        nvinfer1::DataType::kFLOAT);//权重和张量的精度类型为FP32 format
		
		//遍历outputTensorNames,通过blobNameToTensor->find函数转换为对应的Tensor,最后通过markOutput将该Tensor标记为网络的输出量。
	    for (auto& s : mParams.outputTensorNames)
	        network->markOutput(*blobNameToTensor->find(s.c_str()));
		
		//根据batchSize设置最大的batchsize。
	    builder->setMaxBatchSize(mParams.batchSize);
		//设置最大的工作空间大小。
	    builder->setMaxWorkspaceSize(16_MB);
		//根据dlaCore决定是否启用DLA功能。
	    samplesCommon::enableDLA(builder.get(), mParams.dlaCore);
	}
	
	//根据构建好的网络定义创建Cuda推理引擎。
    mEngine = std::shared_ptr<nvinfer1::ICudaEngine>(builder->buildCudaEngine(*network), samplesCommon::InferDeleter());
    if (!mEngine)
        return false;

рассуждение

SampleGoogleNet::infer(), эта функция является основной функцией выполнения примера. Он выделяет буферы, устанавливает входные данные и запускает движок.

	//创建RAII缓冲区(BufferManager类处理主机和设备(GPU)缓冲区分配和释放)管理结构。

	//BufferManager这个RAII类处理主机和设备缓冲区的分配和释放,主机和设备缓冲区之间的memcpy来辅助推理,调试转储来验证推
    //理。BufferManager类用于简化缓冲区管理以及缓冲区与引擎之间的任何交互
    samplesCommon::BufferManager buffers(mEngine, mParams.batchSize);

	//创建推理引擎运行上下文
    auto context = SampleUniquePtr<nvinfer1::IExecutionContext>(mEngine->createExecutionContext());
    if (!context)
        return false;

    //获取主机缓冲区并将主机输入缓冲区设置为所有零
    for (auto& input : mParams.inputTensorNames)
        memset(buffers.getHostBuffer(input), 0, buffers.size(input));
	
    //将数据通过memory从主机输入缓冲区拷贝到设备输入缓冲区
    buffers.copyInputToDevice();
	
	//执行推理 
    bool status = context->execute(mParams.batchSize, buffers.getDeviceBindings().data());
    if (!status)
        return false;

    //推理完成之后,将数据通过memcopy从设备输出缓冲区拷贝到主机输出缓冲区
    buffers.copyOutputToHost();

Очистка ресурсов

nvcaffeparser1::shutdownProtobufLibrary(); Очистка ресурсов в основном включает в себя очистку protobuf, используемого синтаксическим анализатором.

Суммировать

В этой статье используется очень простой пример для объяснения процесса кодирования того, как развернуть сетевую модель в TensorRT. Следует отметить, что сетевая модель, используемая в этой статье, — Caffe, а используемый синтаксический анализатор — также ICaffeParser.TensorRT также поддерживает синтаксические анализаторы формата ONX и UFF.Позже мы обобщим, как импортировать другие различные сетевые модели через эти два типа синтаксических анализаторов. , такие как , тензорный поток и т. д. При выполнении логического вывода необходимо задействовать процесс копирования данных между кешем GPU и кешем ЦП. Этот процесс является громоздким. В этой статье для очень хорошей инкапсуляции этих процессов используется BufferMannager. Эта идея может быть использована для справки в последующее развитие сети TensorRT.