多设备插件
多设备插件会在运行时检查当前各个计算设备的利用率,然后决定应该把哪个推理计算请求放到哪个计算设备中取,从而实现负载均衡。例如,有 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)来实现多个硬件各自分担一部分神经网络层的计算任务。