GluonCV - 对象检测,将 mx.ctx 设置为 GPU,但仍使用所有 CPU 核心
GluonCV - Object detection, set mx.ctx to GPU, but still using all CPU cores
我正在 运行在服务器上执行对象检测例程。
我将上下文设置为 GPU,并在 GPU 上加载模型、参数和数据。该程序正在使用 OpenCV 从视频文件或 rtsp 流中读取。
使用nvidia-smi时,我看到选择的GPU使用率是20%,这是合理的。但是,对象检测例程仍在使用 CPU 的 750-1200%(基本上是服务器的所有可用内核)。
这是代码:
def main():
ctx = mx.gpu(3)
# -------------------------
# Load a pretrained model
# -------------------------
net = gcv.model_zoo.get_model('ssd_512_mobilenet1.0_coco', pretrained=True)
# Load the webcam handler
cap = cv2.VideoCapture("video/video_01.mp4")
count_frame = 0
while(True):
print(f"Frame: {count_frame}")
# Load frame from the camera
ret, frame = cap.read()
if (cv2.waitKey(25) & 0xFF == ord('q')) or (ret == False):
cv2.destroyAllWindows()
cap.release()
print("Done!!!")
break
# Image pre-processing
frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8')
frame_nd, frame_np = gcv.data.transforms.presets.ssd.transform_test(frame, short=512, max_size=700)
if isinstance(frame_nd, mx.ndarray.ndarray.NDArray):
frame_nd.wait_to_read()
# Run frame through network
frame_nd = frame_nd.as_in_context(ctx)
class_IDs, scores, bounding_boxes = net(frame_nd)
if isinstance(class_IDs, mx.ndarray.ndarray.NDArray):
class_IDs.wait_to_read()
if isinstance(scores, mx.ndarray.ndarray.NDArray):
scores.wait_to_read()
if isinstance(bounding_boxes, mx.ndarray.ndarray.NDArray):
bounding_boxes.wait_to_read()
count_frame += 1
cv2.destroyAllWindows()
cap.release()
这是 nvidia-smi 的输出:
虽然这是 top 的输出:
预处理操作 运行ning 在 CPU:
frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8')
frame_nd, frame_np = gcv.data.transforms.presets.ssd.transform_test(frame, short=512, max_size=700)
但这足以证明 CPU 如此高的使用率吗?以防万一,我也可以 运行 在 GPU 上使用它们吗?
编辑:我修改并复制了整个代码,以回应 Olivier_Cruchant 的评论(谢谢!)
你的 CPU 可能很忙,因为预处理负载和从内存到 GPU 的频繁来回,因为推理似乎是 运行 逐帧
我建议尝试以下操作:
- 运行 一个批量推理(向网络发送一批 N 帧)到
增加 GPU 使用率并减少通信
- 尝试使用 NVIDIA DALI 来
更好地使用 GPU 进行数据摄取和预处理 (DALI MXNet reference, DALI mp4 ingestion pytorch example)
我正在 运行在服务器上执行对象检测例程。
我将上下文设置为 GPU,并在 GPU 上加载模型、参数和数据。该程序正在使用 OpenCV 从视频文件或 rtsp 流中读取。
使用nvidia-smi时,我看到选择的GPU使用率是20%,这是合理的。但是,对象检测例程仍在使用 CPU 的 750-1200%(基本上是服务器的所有可用内核)。
这是代码:
def main():
ctx = mx.gpu(3)
# -------------------------
# Load a pretrained model
# -------------------------
net = gcv.model_zoo.get_model('ssd_512_mobilenet1.0_coco', pretrained=True)
# Load the webcam handler
cap = cv2.VideoCapture("video/video_01.mp4")
count_frame = 0
while(True):
print(f"Frame: {count_frame}")
# Load frame from the camera
ret, frame = cap.read()
if (cv2.waitKey(25) & 0xFF == ord('q')) or (ret == False):
cv2.destroyAllWindows()
cap.release()
print("Done!!!")
break
# Image pre-processing
frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8')
frame_nd, frame_np = gcv.data.transforms.presets.ssd.transform_test(frame, short=512, max_size=700)
if isinstance(frame_nd, mx.ndarray.ndarray.NDArray):
frame_nd.wait_to_read()
# Run frame through network
frame_nd = frame_nd.as_in_context(ctx)
class_IDs, scores, bounding_boxes = net(frame_nd)
if isinstance(class_IDs, mx.ndarray.ndarray.NDArray):
class_IDs.wait_to_read()
if isinstance(scores, mx.ndarray.ndarray.NDArray):
scores.wait_to_read()
if isinstance(bounding_boxes, mx.ndarray.ndarray.NDArray):
bounding_boxes.wait_to_read()
count_frame += 1
cv2.destroyAllWindows()
cap.release()
这是 nvidia-smi 的输出:
虽然这是 top 的输出:
预处理操作 运行ning 在 CPU:
frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8')
frame_nd, frame_np = gcv.data.transforms.presets.ssd.transform_test(frame, short=512, max_size=700)
但这足以证明 CPU 如此高的使用率吗?以防万一,我也可以 运行 在 GPU 上使用它们吗?
编辑:我修改并复制了整个代码,以回应 Olivier_Cruchant 的评论(谢谢!)
你的 CPU 可能很忙,因为预处理负载和从内存到 GPU 的频繁来回,因为推理似乎是 运行 逐帧 我建议尝试以下操作:
- 运行 一个批量推理(向网络发送一批 N 帧)到 增加 GPU 使用率并减少通信
- 尝试使用 NVIDIA DALI 来 更好地使用 GPU 进行数据摄取和预处理 (DALI MXNet reference, DALI mp4 ingestion pytorch example)