CoreML 和 YOLOv3 性能问题

Posted

技术标签:

【中文标题】CoreML 和 YOLOv3 性能问题【英文标题】:CoreML and YOLOv3 performance issue 【发布时间】:2020-04-05 23:16:23 【问题描述】:

目前我面临在 MacOS 的 Objective-c/C++ XCode 项目中实现的 YOLOv3 的性能问题,但是性能太慢了。我对 MacOS 和 XCode 没有太多经验,所以我遵循了 this 教程。执行时间约为 0.25 秒。

设置: 我在 MacBook Pro Intel Core i5 3.1 GHz 和图形 Intel Iris Plus Graphic 650 1536MB 上运行它,性能约为 4 fps。这是可以理解的,GPU并不强大,它主要使用CPU。准确地说,它令人印象深刻,因为它比在 CPU 上运行的 Pytorch 实现更快。但是,我在 MacBook pro Intel i7 2.7GHz 和 AMD Radeon Pro 460 上运行此示例,性能仅为 6 fps。

this 网站的性能应该要好得多。您能否让我知道我在哪里做错了,或者这是我可以通过此设置获得的最佳性能吗?请注意,我已经检查了系统监视器,并且 GPU 在这两种情况下都已完全使用。

这是我的初始化:

//loading model
MLModel *model_ml = [[[YOLOv3 alloc] init] model];

float confidencerThreshold = 0.8;
NSMutableArray<Prediction*> *predictions = [[NSMutableArray alloc] init];

VNCoreMLModel *model = [VNCoreMLModel modelForMLModel:model_ml error:nil];

VNCoreMLRequest *request = [[VNCoreMLRequest alloc] initWithModel:model completionHandler:^(VNRequest * _Nonnull request, NSError * _Nullable error)
    for(VNRecognizedObjectObservation *observation in request.results)
    
        if(observation.confidence > confidencerThreshold)
            CGRect rect = observation.boundingBox;
            Prediction* prediction = [[Prediction alloc] initWithValues: 0 Confidence: observation.confidence BBox: rect];
            [predictions addObject:prediction];
        
    
];

request.imageCropAndScaleOption = VNImageCropAndScaleOptionScaleFill;

float ratio = height/CGFloat(width);

还有我的循环实现

cv::Mat frame;
int i = 0;
while(1)

    cap>>frame;

    if(frame.empty())
        break;
    

    image = CGImageFromCVMat(frame.clone());
     VNImageRequestHandler *imageHandler = [[VNImageRequestHandler alloc] initWithCGImage:image options:nil];

    NSDate *methodStart = [NSDate date];    //Measuring performance here

    NSError *error = nil;
    [imageHandler performRequests:@[request] error:&error];    //Call request

    if(error)
        NSLog(@"%@",error.localizedDescription);
    

    NSDate *methodFinish = [NSDate date];
    NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];  //get execution time

    // draw bounding boxes
    for(Prediction *prediction in predictions)
        CGRect rect = [prediction getBBox];
        cv::rectangle(frame,cv::Point(rect.origin.x * width,(1 - rect.origin.y) * height),
                      cv::Point((rect.origin.x + rect.size.width) * width, (1 - (rect.origin.y + rect.size.height)) * height),
                      cv::Scalar(0,255,0), 1,8,0);
    

    std::cout<<"Execution time "<<executionTime<<" sec"<<" Frame id: "<<i<<" with size "<<frame.size()<<std::endl;
    [predictions removeAllObjects];


cap.release();

谢谢。

【问题讨论】:

【参考方案1】:

在调用[imageHandler performRequests] 的行上设置断点并在禁用优化的情况下运行应用程序。多次使用调试器中的“Step Into”按钮。在堆栈跟踪中查找“Espresso”。

这是否显示类似Espresso::BNNSEngine 的内容?然后模型在 CPU 上运行,而不是 GPU。

堆栈跟踪是否显示类似Espresso::MPSEngine 的内容?然后你就在 GPU 上运行了。

我的猜测是 Core ML 在 CPU 上运行您的模型,而不是在 GPU 上。

【讨论】:

我去看看。在程序开始时,我得到了[espresso] [Espresso::handle_ex_] exception=Unsupported engine 类型,但我没有注意这一点。也许是相关的。 request.usesCPUOnly = true; 运行速度为 2 fps,我的 cpu 正在燃烧。我不认为有问题。 好吧,这排除了这是一个潜在问题。 :-) 请注意,您链接到的“性能应该更好”的网站仅提供 ios 设备的数字。不要误以为 Mac 应该比 iOS 设备提供更好的性能!

以上是关于CoreML 和 YOLOv3 性能问题的主要内容,如果未能解决你的问题,请参考以下文章

从远程源加载重型 CoreML 模型

AoE工程实践 —— 记CoreML模型在CocoaPods应用中的集成(上)

当应用程序进入后台时,应用程序在前台使用带有 GPU 的 CoreML 无法切换到 CPU

YOLOv3目标检测实战:交通标志识别

使用 Google Colab上的PyTorch YOLOv3

使用 Google Colab上的PyTorch YOLOv3