为什么使用GPU上的Faster RCNN进行自定义目标检测时预测速率只有25-40 [秒/1]?

6
我已经训练了一个自定义物体检测的 faster_rcnn_inception_resnet_v2_atrous_coco 模型(可在此处找到:链接)。在预测时,我使用了物体检测演示jupyter笔记本文件来处理我的图像。同时,我检查了每个步骤所消耗的时间,并发现sess.run占用了所有时间。
但是,在GPU上对于一张大小为(3000 x 2000)像素(大约1-2 [MB])的图片进行预测需要25-40 [秒]有人能找出问题所在吗? 我已经进行了分析,下载链接如下:分析文件
完整的分析报告系统信息:
在Azure门户中创建的虚拟机上进行训练和预测,使用了Standard_NV6(详见此处),该虚拟机使用了NVIDIA Tesla M60 GPU。
  • 操作系统及版本 - Windows 10
  • TensorFlow 安装方式 - 使用pip安装pip3 install --upgrade tensorflow-gpu
  • TensorFlow 版本 - 1.8.0
  • Python 版本 - 3.6.5
  • GPU/CPU - GPU
  • CUDA/cuDNN 版本 - CUDA 9/cuDNN 7

即使在大型图像上,预测速度也应该非常快,因为您只需应用函数(模型)。有两件事需要检查: (1)确认tensorflow实际上正在使用GPU (2)对tensorflow进行分析,可以参考https://towardsdatascience.com/howto-profile-tensorflow-1a49fb18073d - Lukasz Tracewski
顺便提一下,正如在此处所证明的那样 https://learn.microsoft.com/en-us/azure/virtual-machines/windows/n-series-driver-setup ,VM默认情况下没有安装驱动程序和CUDA,因此除非您完成了这些步骤,否则您的tensorflow将在CPU上运行 - 并且比在GPU上运行要慢得多。 - Lukasz Tracewski
1
这正是我们需要的。性能分析信息清楚地显示您正在使用GPU…… 这需要1.5秒钟,这是合理的。您可以亲自查看:https://drive.google.com/open?id=1CsrV6YkIyQ9KYtgoS6YLePxTgPXOxGmM 如果您有Chrome浏览器,可以转到chrome://tracing/ 并加载该文件(假设您已经这样做了)。无论如何,阻止您的不是TensorFlow,或者至少数据是这样说的。我建议将其重构为脚本并运行性能分析: python -m cProfile yourscript.py - Lukasz Tracewski
是的,这就是谜团所在,因为分析显示它只需要1.5秒,但是命令sess.run本身需要20多秒。 - Sachin Patel
完整的性能分析可以在此处找到:https://s3-us-west-2.amazonaws.com/forchetan/Sachin_Support_Docs_Object_Detection/Full_Profilling_Tensorflow_Object_Detection.zip - Sachin Patel
显示剩余5条评论
4个回答

2

有人能找出这里的问题吗?

很抱歉,我要直截了当地说出
观察到性能问题的根本原因:

对于这样一个计算密集型(既注重性能又注重吞吐量)的任务来说,Azure产品组合中没有比Azure NV6更糟糕的VM设置。就是没有 - 在菜单上没有更少配置的选项。

Azure NV6专门为虚拟桌面用户提供优势,在这种情况下,NVidia GRID(R)驱动程序提供了一层软件服务,用于“共享”图像/视频的部分(桌面图形像素、最大SP端点),在团队成员之间共享,无论他们使用的终端设备如何(但每个板载GPU最多仅支持15个用户,而它也被明确宣传和推广为Azure的关键卖点。NVidia甚至更进一步,明确将此设备推广给(引自)办公室用户)。

M60缺乏显然,因为它是针对非常不同的市场细分而定义的)任何智能AI / ML / DL / Tensor处理功能,其DP性能约低20倍,比专门用于AI / ML / DL / Tensor处理的计算GPU设备低。

enter image description here

如果我可以引述:

..."GRID"是覆盖给定一组(目前为M10、M6、M60)(以前为Quadro(K1/K2))GPU的软件组件。在最基本的形式下(如果你能称之为这样),GRID软件当前用于在“图形”模式下使用GPU时创建FrameBuffer配置文件,允许用户在访问同一物理GPU时共享GPU的FrameBuffer的一部分。

,M10、M6和M60并不特别适用于AI。然而,它们可以工作,只是不如其他GPU那样高效。NVIDIA为不同的工作负载和行业(技术)使用领域创建特定的GPU,因为每个领域都有不同的要求。(感谢BJones)

接下来,
如果确实愿意花费精力在这种事先已知的最糟糕的选择上:

请确保两个GPU处于"计算"模式,而非"图形"模式,如果您正在进行人工智能方面的操作。您可以使用正确的M60驱动程序包附带的Linux启动实用程序来完成此操作,前提是在注册评估后获得它。(再次感谢BJones)

对于非Linux / Azure操作的虚拟访问设备,很明显没有这样的选项。


总结:

如果追求更高的性能和吞吐量,最好选择另一个装备了人工智能/机器学习/深度学习/张量处理的GPU设备,该设备将问题特定的计算硬件资源放置在一起,且不存在任何软件层(至少有一个可用的禁用选项),因为这些软件层可能会阻碍GPU处理性能的高水平实现。


虚拟机的所有内容都是正确的,但根据分析文件,在Chrome跟踪中查看,它显示该过程大约需要1500毫秒。 - Sachin Patel

1

TensorFlow需要长时间进行初始设置。(不要担心,这只是一次性过程)。

加载图形是一个繁重的过程。我在我的CPU上执行了此代码。 完成程序需要大约40秒钟。

像加载图形这样的初始设置所需的时间为37秒。

执行对象检测所需的实际时间为3秒,即每个图像1.5秒。

如果我提供了100张图片,那么总共需要的时间将是37 + 1.5 * 100。 我不必加载100次图形。

因此,在您的情况下,如果需要25[s],则初始设置将需要约23-24[s]。 实际时间应该为~1-2[s]。

您可以在代码中验证它。 可以使用Python中的time模块:

import time                          # used to obtain time stamps

for image_path in TEST_IMAGE_PATHS:  # iteration of images for detection
    # ------------------------------ # begins here
    start = time.time()              # saving current timestamp
    ...
    ...
    ...
    plt.imshow( image_np )
    # ------------------------------ # processing one image ends here

print( 'Time taken',
        time.time() - start          # calculating the time it has taken
        )

2
嗨,Sreeragh A R,这里加载图表不是问题(耗时约1秒);如问题所述,超过90%的时间由**sess.run**消耗。 - Sachin Patel

1
根据网站要求,图像尺寸应为600x600,代码在 Nvidia GeForce GTX TITAN X 卡上运行。但是,请确保您的代码实际上正在GPU而非CPU上运行。建议运行您的代码并打开另一个窗口,使用以下命令查看 GPU 利用率,并查看是否有任何变化。
watch nvidia-smi

2
跟踪显示OP正在使用GPU。此外,实际预测需要约1.5秒的时间,与OP的说法有些矛盾。因此请求进行完整的分析。 - Lukasz Tracewski

0

大图像需要更多时间是很自然的。即使在较低分辨率(如400*400)下,Tensorflow目标检测也表现良好。

复制原始图像,将其调整为较低分辨率以执行对象检测。您将获得边界框坐标。现在计算原始高分辨率图像的相应边界框坐标。在原始图像上绘制边界框。

i.e

假设您有一张3000*2000的图像, 复制它并将其调整为300*200。 在调整大小后的图像上执行对象检测,检测到一个带有边界框(50,100,150,150)即(ymin,xmin,ymax,xmax)的对象。

现在,原始大图像的相应框坐标将是(500,1000,1500,1500)。在其上绘制矩形。

在小图像上执行检测,然后在原始图像上绘制边界框。 性能将得到极大提升。

注意:TensorFlow支持归一化坐标。

即,如果您有一个高度为100且ymin = 50的图像,则归一化ymin为0.5。 您可以通过分别乘以高度或宽度来将归一化坐标映射到任何尺寸的图像中,用于y和x坐标。

我建议使用OpenCV(cv2)进行所有图像处理。


嗨@Sreeragh A R,感谢您的建议。早些时候,我尝试了您对(3000 * 3000)图像的建议,并将相同的图像调整为(300 * 300)和(400 * 400),对于这个较小的图像检测需要大约15-20秒,而原始图像需要20多秒。但是我的问题是为什么我无法实现接近此处所声称的速度。我无法弄清楚这里缺少什么。 - Sachin Patel
你是否收到了这样的警告信息? Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA 如果是的话,请前往 https://github.com/lakshayg/tensorflow-build。 - Sreeragh A R
@ Sreeragh A R,不,我没有收到任何警告,因为我的模型是在GPU上创建的,预测也在GPU上进行,因此不会出现关于CPU编译的警告。 - Sachin Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接