8、多设备和异构插件

多设备插件

多设备插件会在运行时检查当前各个计算设备的利用率,然后决定应该把哪个推理计算请求放到哪个计算设备中取,从而实现负载均衡。例如,有 4 个推理计算请求,电脑上有一个 CPU、一个 GPU、两个英特尔神经计算棒二代,则 4 个推理请求可以在 4 个计算设备上并行执行。

指定使用哪些设备

例如,配置为 MULTI:CPU, GPU, MYRID,意思是指定 Inference Engine 使用多设备插件,可以在 CPU、GPU、MYRID 上并行执行推理计算,排在前面的计算设备优先级高。

代码实例

// --------------------------- 5. 创建Infer Request--------------------------------------------
	std::cout << "5.Create Infer Request..." << std::endl;
	InferRequest::Ptr infer_request1 = executable_network.CreateInferRequestPtr();
	InferRequest::Ptr infer_request2 = executable_network.CreateInferRequestPtr();
	InferRequest::Ptr infer_request3 = executable_network.CreateInferRequestPtr();
	InferRequest::Ptr infer_request4 = executable_network.CreateInferRequestPtr();

	// --------------------------------------------------------------------------------------------

	// --------------------------- 6. 准备输入数据 ------------------------------------------------
	std::cout << "6.Prepare Input..." << std::endl;
	cv::Mat img1 = cv::imread(imageFile);
	cv::Mat img2 = cv::imread(imageFile);
	cv::Mat img3 = cv::imread(imageFile);
	cv::Mat img4 = cv::imread(imageFile);
	frameToBlob(img1, infer_request1, imageInputName);
	frameToBlob(img2, infer_request2, imageInputName);
	frameToBlob(img3, infer_request3, imageInputName);
	frameToBlob(img4, infer_request4, imageInputName);
	const size_t width = (size_t)img1.cols;
	const size_t height = (size_t)img1.rows;
	// --------------------------------------------------------------------------------------------

	// --------------------------- 7. 执行推理计算 ------------------------------------------------
	std::cout << "7.Start inference..." << std::endl;
	std::clock_t begin, end;
	begin = std::clock();
	for (auto i = 0; i <= 1000; i++)
	{
		img1 = cv::imread(imageFile);
		frameToBlob(img1, infer_request1, imageInputName);
		infer_request1->StartAsync();
		img2 = cv::imread(imageFile);
		frameToBlob(img2, infer_request2, imageInputName);
		infer_request2->StartAsync();
		img3 = cv::imread(imageFile);
		frameToBlob(img3, infer_request3, imageInputName);
		infer_request3->StartAsync();
		img4 = cv::imread(imageFile);
		frameToBlob(img4, infer_request4, imageInputName);
		infer_request4->StartAsync();
		
		infer_request1->Wait(IInferRequest::WaitMode::RESULT_READY);		
		infer_request2->Wait(IInferRequest::WaitMode::RESULT_READY);		
		infer_request3->Wait(IInferRequest::WaitMode::RESULT_READY);		
		infer_request4->Wait(IInferRequest::WaitMode::RESULT_READY);
	}
	
	end = std::clock();
	std::ostringstream infer_time;//计算推理计算所花费的时间
	infer_time << "Infer Time:" << (double)(end - begin) << "ms";
	cv::putText(img1, infer_time.str(), cv::Point2f(0, 12), cv::FONT_HERSHEY_TRIPLEX, 0.6, cv::Scalar(0, 255, 0));
	// --------------------------------------------------------------------------------------------

	// --------------------------- 8. 处理输出 ----------------------------------------------------
	std::cout << "8.Process output blobs..." << std::endl;
	const float *detections = infer_request1->GetBlob(outputName)->buffer().as<PrecisionTrait<Precision::FP32>::value_type*>();
	for (int i = 0; i < maxProposalCount; i++) {
		float image_id = detections[i * objectSize + 0];

		float confidence = detections[i * objectSize + 2];
		auto label = static_cast<int>(detections[i * objectSize + 1]);
		float xmin = detections[i * objectSize + 3] * width;
		float ymin = detections[i * objectSize + 4] * height;
		float xmax = detections[i * objectSize + 5] * width;
		float ymax = detections[i * objectSize + 6] * height;

		if (confidence > confidence_threshold) {
			/** 仅当> confidence_threshold值时,显示推理计算结果 **/
			std::ostringstream conf;
			conf << ":" << std::fixed << std::setprecision(3) << confidence;
			cv::putText(img1, (labels[label] + conf.str()),
				cv::Point2f(xmin, ymax - 5), cv::FONT_HERSHEY_COMPLEX_SMALL, 1,
				cv::Scalar(0, 0, 255));
			cv::rectangle(img1, cv::Point2f(xmin, ymin), cv::Point2f(xmax, ymax), cv::Scalar(0, 0, 255));
		}
	}
	std::cout << "Infer done!" << std::endl;
	cv::imshow("Detection results", img1);
	cv::waitKey(0);
	cv::destroyAllWindows();

异构插件

异构插件的核心思想是协同不同类型的计算资源,做各自擅长的计算,共同完成一个计算任务。

配置异构插件

例如,MULTI:CPU, GPU, MYRIAD,意思是指定 Inference Engine 使用异构插件,在多个计算硬件 CPU、GPU 和英特尔神经计算棒二代上进行异构计算。排在前面的计算硬件优先级高,同时异构插件会自动分配神经网络的计算任务到各个硬件。

代码实例

和最普通的推理计算流程一样,只是在指定推理设备的时候指定为 MULTI:CPU, GPU, MYRIAD。

两个对比

Inference Engine 可以通过调用不同的插件,实现在不同的硬件上执行 AI 推理计算的功能。 Inference Engine 提供多设备插件(MULTI)来实现多个硬件自动并行计算多个神经网络,也提供了异构插件(HETERO)来实现多个硬件各自分担一部分神经网络层的计算任务。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值