GluonCV - обнаружение объектов, установите mx.ctx в GPU, но все еще используя все ядра ЦП - PullRequest
1 голос
/ 09 апреля 2020

Я запускаю процедуру обнаружения объектов на сервере.
Я установил контекст для графического процессора, и я загружаю модель, параметры и данные в графическом процессоре. Программа читает из видеофайла или из потока rtsp, используя OpenCV.

При использовании nvidia-smi я вижу, что выбранное использование графического процессора составляет 20%, что является разумным. Тем не менее, процедура обнаружения объектов все еще использует 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: GPU usage

, а вывод top: CPU usage

Предварительная обработка операции выполняются на процессоре:

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)

но достаточно ли этого для оправдания такой высокой загрузки процессора? В случае, если я могу запустить их также на GPU?

РЕДАКТИРОВАТЬ: я изменил и скопировал весь код, в ответ на комментарий Olivier_Cruchant (спасибо!)

1 Ответ

1 голос
/ 15 апреля 2020

Ваш ЦП, вероятно, занят из-за нагрузки предварительной обработки и частой обратной передачи из памяти в графический процессор, поскольку кажется, что вывод выполняется покадрово, я бы предложил следующее:

  1. Запустите пакетный вывод (отправьте пакет из N кадров в сеть), чтобы увеличить использование графического процессора и уменьшить связь
  2. Попробуйте использовать NVIDIA DALI , чтобы лучше использовать графический процессор для приема данных и предварительная обработка ( DALI M XNet ссылка , DALI mp4 пример с питанием при проглатывании )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...