Развертывание ИИ-приложений на микросерверах NVIDIA Jetson Xavier NX

с помощью платформы NVIDIA EGX

Анкита Шарма, Эрик Бонхорст, Анураг Гуда (NVIDIA)

Оригинал статьи здесь.

Современные ожидания от возможностей гибкой разработки и постоянных инноваций – одновременно с требованиями непрерывной доступности сервисов – требуют изменений в методах разработки и развертывания программного обеспечения для встраиваемых и оконечных устройств. Следующим шагом в развитии оконечных устройств могла бы быть реализация в них таких парадигм из сферы облачных вычислений как микросервисы, контейнеризация и оркестрация контейнеров, однако сложность развертывания, управления и обеспечения безопасности мешают масштабному внедрению данных технологий.

NVIDIA EGX – это облачная контейнерная платформа с поддержкой Kubernetes, позволяющая легко и быстро разворачивать целевое ПО на микросерверах или оконечных IoT-системах на базе вычислительных модулей NVIDIA Jetson. Обеспечивая оконечные устройства на базе Jetson Xavier NX гибкостью за счет облачной платформы EGX, предприятия могут использовать технологии и процессы, совершившие революцию в облачных вычислениях, для широкомасштабной разработки, развертывания и управления оконечными устройствами.

В данной статье описаны ключевые компоненты облачного программного стека, порядок установки стека EGX на комплект разработчика Jetson Xavier NX и его использование для развертывания приложений интеллектуальной видеоаналитики (IVA) на оконечных устройствах.

Контейнеры для задач искусственного интеллекта

Сегодня предприятия переносят искусственный интеллект на оконечные устройства и разворачивают краевую инфраструктуру в географически распределенных точках присутствия (PoP), чтобы снизить расходы на обслуживание сети и сократить время отклика. Контейнеры обеспечивают гибкость процессам разработки и развертывания ПО, а также снижают потребление полосы пропускания, уменьшая стоимость передачи данных.

Платформа EGX запускает ИИ-контейнеры из каталога NGC – облачного хранилища GPU-оптимизированного ПО для машинного обучения и анализа данных. Это хранилище было создано для упрощения и ускорения рабочих процессов. Оно содержит более 150 контейнеров корпоративного класса и 100+ моделей, отраслевых SDK и Helm-диаграмм, которые могут быть развернуты на локальном сервере, в облаке или на оконечных устройствах. Это ПО можно использовать «как есть» или дорабатывать и настраивать под собственные нужды, что позволяет как развертывать готовые решения, так и разрабатывать свои собственные и искать новые подходы к созданию добавленной стоимости.

Платформа EGX также включает в себя доступ к частному реестру NGC, который позволяет пользователю безопасно хранить свою уникальную интеллектуальную собственность и доработанные решения, совместно использовать ПО и развертывать его на оконечных устройствах, на локальном сервере или в облаке.

Kubernetes

На сегодняшний день система для оркестрации контейнеров Kubernetes – один из наиболее активных проектов с открытым исходным кодом, как в облаке, так и на локальных серверах. Она играет роль важного основополагающего компонента и по сути является стандартом де-факто для оконечных устройств с поддержкой таких функций, как автоматическое развертывание контейнеров и самовосстановление.

Основным элементом облачно-ориентированной стратегии EGX является обеспечение отказоустойчивости ПО, выполняемого на графических процессорах, с помощью Kubernetes. В состав платформы EGX входит т.н. оператор GPU (GPU Operator), который автоматизирует установку и настройку всех компонентов, необходимых для использования GPU в кластере Kubernetes.

Платформа EGX значительно упрощает работу ИТ-подразделений на ранних стадиях жизненного цикла ПО (Day 0) и позволяет полностью автоматизировать последующие стадии (Day 1..N). Все необходимые компоненты, такие как драйвер NVIDIA, среда выполнения контейнеров (NVIDIA Container Runtime), надстройка Kubernetes для устройств (Kubernetes device plugin) и компонент для мониторинга GPU (NVIDIA GPU Monitoring), контейнеризированы и запускаются в Kubernetes как сервисы. В результате ИТ-специалистам нужно сопровождать только один образ ПО  —  как для узлов, работающих на CPU, так и для узлов с поддержкой GPU.

Helm-диаграммы

Helm-диаграммы являются рекомендованным форматом пакетов для Kubernetes, так как они позволяют легко настраивать, развертывать и обновлять приложения в кластерах Kubernetes всего одним щелчком мыши и парой команд командной строки.

В каталоге NGC хранятся готовые для использования в Kubernetes Helm-диаграммы, позволяющие развертывать стороннее ПО корпоративного класса. DevOps-инженеры также могут загружать свои диаграммы в реестр и публиковать их для совместного использования, чтобы команды могли воспользоваться преимуществами согласованных, безопасных и надежных конфигураций для ускорения циклов разработки ПО и его ввода в эксплуатацию.

Установка программного стека EGX 2.0

Комплект средств разработки NVIDIA Jetson Xavier NX Developer Kit делает вычислительные мощности суперкомпьютеров доступными на оконечных устройствах, обеспечивая их производительностью 21 TOPS при энергопотреблении 15 Вт и компактном форм-факторе. Модуль Jetson Xavier NX подходит для таких высокопроизводительных ИИ-систем, как коммерческие роботы, медицинские приборы, интеллектуальные камеры, датчики с высоким разрешением, системы автоматического визуального контроля, составляющие элементы «умного предприятия» и прочие встраиваемые IoT-системы.

Теперь, обновив программный стек EGX до последней версии, вы можете добавить вашим модулям Jetson Xavier NX еще и поддержку облачных технологий. Этот стек, входящий в состав комплекта разработчика, представляет собой эталонное решение от NVIDIA, прошедшее функциональное и нагрузочное тестирование, которое поддерживает быстрое развертывание облачно-ориентированного ПО на встраиваемых устройствах.

Ниже приведены шаги по установке стека EGX 2.0 на комплект средств разработки Jetson Xavier NX Developer Kit. После успешной установки комплект будет содержать следующие компоненты:

  • Комплект разработчика ПО NVIDIA JetPack SDK 4.4;
  • Kubernetes версии 1.17.5;
  • Helm/Tiller 3.1.0;
  • Среду выполнения контейнеров NVIDIA Container Runtime 1.0.1-dev.

В данной статье авторы использовали комплект средств разработки Jetson Xavier NX Developer Kit с картой памяти microSD 32 Гб.

Настройка комплекта средств разработки и установка JetPack 4.4

Комплект разработчика ПО JetPack SDK содержит библиотеки, инструментарий и базовую ОС для разработки ИИ-приложений на платформе Jetson. Для более подробной информации о настройке комплекта Jetson Xavier NX Developer Kit и установке на JetPack SDK 4.4 см. раздел «Начало работы с комплектом средств разработки Jetson Xavier NX Developer Kit».

Обновление конфигурации Docker

Отредактируйте файл конфигурации демона Docker, добавив следующую строку и сохранив изменения:

"default-runtime" : "nvidia"

Пример блока конфигурации: 

$ sudo nano /etc/docker/daemon.json

 

{

   "runtimes": {

      "nvidia": {

            "path": "nvidia-container-runtime",

           "runtimeArgs": []

      }

   },

   "default-runtime" : "nvidia"

}

Перезапустите демон Docker:

sudo systemctl daemon-reload && sudo systemctl restart docker

Проверка среды исполнения по умолчанию

Проверьте, чтобы по умолчанию в Docker стояла среда исполнения NVIDIA:

$ sudo docker info | grep -i runtime

Пример вывода:

Runtimes: nvidia runc

Default Runtime: nvidia

Установка Kubernetes версии 1.17.5 

Прежде чем начинать установку, удостоверьтесь, что Docker запущен и добавлен в автозагрузку:

$ kubectl get pods --all-namespaces

Пример вывода:

NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE

kube-system   kube-flannel-ds-arm64-gz28t                1/1     Running   0          2m8s

kube-system   coredns-5c98db65d4-d4kgh                   1/1     Running   0          9m8s

kube-system   coredns-5c98db65d4-h6x8m                   1/1     Running   0          9m8s

kube-system   etcd-#yourhost                             1/1     Running   0          8m25s

kube-system   kube-apiserver-#yourhost                   1/1     Running   0          8m7s

kube-system   kube-controller-manager-#yourhost          1/1     Running   0          8m3s

kube-system   kube-proxy-6sh42                           1/1     Running   0          9m7s

kube-system   kube-scheduler-#yourhost                   1/1     Running   0          8m26s

 Команда get nodes показывает, что мастер-узел готов к работе:

$ kubectl get nodes

Пример вывода:

NAME      STATUS   ROLES    AGE   VERSION

#yournodes   Ready    master   10m   v1.17.5

Так как используемый кластер Kubernetes содержит только один узел, то на этом узле по умолчанию нельзя планировать поды, поскольку он относится к плоскости управления. Чтобы разрешить планирование, необходимо снять отметку (taint) с помощью следующей команды:

$ kubectl taint nodes --all node-role.kubernetes.io/master-

Для более подробной информации см. Установка компонента kubeadm.

Установка Helm/Tiller 3.1.0

Скачайте Helm 3.1.0:

$ sudo wget https://get.helm.sh/helm-v3.1.0-linux-arm64.tar.gz

$ sudo tar -zxvf helm-v3.1.0-linux-arm64.tar.gz

$ sudo mv linux-arm64/helm /usr/local/bin/helm

Для более подробной информации см. Релизы Helm и Введение в Helm.

Проверка успешной установки EGX 2.0 

Чтобы проверить, что стек EGX работает корректно, выполните следующие инструкции для создания YAML-файла описания пода. Если команда get pods показывает статус пода «завершен» (completed), то установка прошла успешно. Также в случае успешного запуска файла cuda-samples.yaml вывод будет содержать подтверждение «Result=PASS».

Создайте YAML-файл описания пода:

$ sudo nano cuda-samples.yaml

Добавьте в файл следующее содержимое и сохраните его как cuda-samples.yaml:

apiVersion: v1

kind: Pod

metadata:

  name: nvidia-l4t-base

spec:

  restartPolicy: OnFailure

  containers:

  - name: nvidia-l4t-base

    image: "nvcr.io/nvidia/l4t-base:r32.4.2"

    args:

       - /usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQuery

Скомпилируйте пример CUDA, который будет использоваться для проверки:

$ cd /usr/local/cuda/samples/1_Utilities/deviceQuery

$ sudo make

$ cd ~

Создайте под с поддержкой GPU:

$ sudo kubectl apply -f cuda-samples.yaml

Проверьте, что под успешно создан:

$ kubectl get pods

Пример вывода:

nvidia-l4t-base  0/1 Completed 2m

Проверьте системный журнал созданного пода, чтобы убедиться, что он поддерживает библиотеки CUDA:

kubectl logs nvidia-l4t-base

Пример вывода:

/usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQuery Starting...

 CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 1 CUDA Capable device(s)

 

Device 0: "Xavier"

  CUDA Driver Version / Runtime Version          10.2 / 10.2

  CUDA Capability Major/Minor version number:    7.2

  Total amount of global memory:                 7764 MBytes (8140709888 bytes)

  ( 6) Multiprocessors, ( 64) CUDA Cores/MP:     384 CUDA Cores

  GPU Max Clock rate:                            1109 MHz (1.11 GHz)

  Memory Clock rate:                             1109 Mhz

  Memory Bus Width:                              256-bit

  L2 Cache Size:                                 524288 bytes

  Maximum Texture Dimension Size (x,y,z)         1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384)

  Maximum Layered 1D Texture Size, (num) layers  1D=(32768), 2048 layers

  Maximum Layered 2D Texture Size, (num) layers  2D=(32768, 32768), 2048 layers

  Total amount of constant memory:               65536 bytes

Total amount of shared memory per block:       49152 bytes

  Total number of registers available per block: 65536

  Warp size:                                     32

  Maximum number of threads per multiprocessor:  2048

  Maximum number of threads per block:           1024

  Max dimension size of a thread block (x,y,z): (1024, 1024, 64)

  Max dimension size of a grid size    (x,y,z): (2147483647, 65535, 65535)

  Maximum memory pitch:                          2147483647 bytes

  Texture alignment:                             512 bytes

  Concurrent copy and kernel execution:          Yes with 1 copy engine(s)

  Run time limit on kernels:                     No

  Integrated GPU sharing Host Memory:            Yes

  Support host page-locked memory mapping:       Yes

  Alignment requirement for Surfaces:            Yes

  Device has ECC support:                        Disabled

  Device supports Unified Addressing (UVA):      Yes

  Device supports Compute Preemption:            Yes

  Supports Cooperative Kernel Launch:            Yes

  Supports MultiDevice Co-op Kernel Launch:      Yes

  Device PCI Domain ID / Bus ID / location ID:   0 / 0 / 0

  Compute Mode:

     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

 

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 10.2, CUDA Runtime Version = 10.2, NumDevs = 1

Result = PASS

 Для более подробной информации о релизах программного стека EGX и инструкциях по его установке см. Стек EGX – v2.0. Инструкции по установке для комплекта средств разработки Jetson Xavier NX.

Пример: использование стека EGX для упрощения развертывания приложений интеллектуальной видеоаналитики

Комплект средств разработки ПО NVIDIA DeepStream позволяет разрабатывать и разворачивать ИИ-приложения и сервисы для интеллектуальной видеоаналитики на вычислителях Jetson Xavier NX с установленной платформой EGX. DeepStream предлагает масштабируемый аппаратно-ускоренный фреймворк с поддержкой безопасного протокола TLS для развертывания ПО на оконечных устройствах и подключения к любым облачным сервисам.

Создайте на своем устройстве Jetson с установленной EGX директорию для Helm-диаграмм DeepStream:

$ mkdir deepstream-helmchart

Создайте в директории /deepstream-helmchart папку для шаблонов, чтобы хранить в ней файлы описаний (манифесты) Kubernetes:

$ mkdir -p deepstream-helmchart/templates

Создайте файл Chart.yaml, добавьте в него следующее содержимое и сохраните в директории /deepstream-helmchart:

$ nano Chart.yaml

apiVersion: v1

name: deepstream-helmchart

version: 1.0.0

appVersion: 0.1

Создайте новый файл configmap.yaml в директории /deepstream-helmchart/templates и добавьте в него следующее содержимое:

$ nano configmap.yaml

 

apiVersion: v1

kind: ConfigMap

metadata:

  name: deepstream-configmap

data:

  source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt: |-

    # Copyright (c) 2018 NVIDIA Corporation.  All rights reserved.

    #

    # NVIDIA Corporation and its licensors retain all intellectual property

    # and proprietary rights in and to this software, related documentation

    # and any modifications thereto.  Any use, reproduction, disclosure or

    # distribution of this software and related documentation without an express

    # license agreement from NVIDIA Corporation is strictly prohibited.

 

    [application]

    enable-perf-measurement=1

    perf-measurement-interval-sec=5

    #gie-kitti-output-dir=streamscl

 

    [tiled-display]

    enable=1

    rows=2

    columns=2

    width=1280

    height=720

    gpu-id=0

    #(0): nvbuf-mem-default - Default memory allocated, specific to a platform

    #(1): nvbuf-mem-cuda-pinned - Allocate Pinned/Host cuda memory, applicable for Tesla

    #(2): nvbuf-mem-cuda-device - Allocate Device cuda memory, applicable for Tesla

    #(3): nvbuf-mem-cuda-unified - Allocate Unified cuda memory, applicable for Tesla

    #(4): nvbuf-mem-surface-array - Allocate Surface Array memory, applicable for Jetson

    nvbuf-memory-type=0

 

    [source0]

    enable=1

    #Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP

    type=3

    uri=file://../../streams/sample_1080p_h264.mp4

    num-sources=4

    #drop-frame-interval =2

    gpu-id=0

    # (0): memtype_device   - Memory type Device

    # (1): memtype_pinned   - Memory type Host Pinned

    # (2): memtype_unified  - Memory type Unified

    cudadec-memtype=0

 

    [sink0]

    enable=1

    type=1

    sync=0

    codec=1

    bitrate=4000000

    rtsp-port=8554

    udp-port=5400

    gpu-id=0

    nvbuf-memory-type=0

 

    [sink1]

    enable=0

    type=3

    #1=mp4 2=mkv

    container=1

    #1=h264 2=h265

    codec=3

    sync=0

    bitrate=2000000

    output-file=out.mp4

    source-id=0

    gpu-id=0

 

    [sink2]

    enable=0

    #Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming

    type=4

    #1=h264 2=h265

    codec=1

    sync=1

    bitrate=1000000

    cuda-memory-type=1

    # set below properties in case of RTSPStreaming

    rtsp-port=8554

    udp-port=5400

    gpu-id=0

 

    [osd]

    enable=1

    gpu-id=0

    border-width=1

    text-size=15

    text-color=1;1;1;1;

    text-bg-color=0.3;0.3;0.3;1

    font=Serif

    show-clock=0

    clock-x-offset=800

    clock-y-offset=820

    clock-text-size=12

    clock-color=1;0;0;0

    nvbuf-memory-type=0

 

    [streammux]

    gpu-id=0

    ##Boolean property to inform muxer that sources are live

    live-source=0

    batch-size=4

    ##time out in usec, to wait after the first buffer is available

    ##to push the batch even if the complete batch is not formed

    batched-push-timeout=40000

    ## Set muxer output width and height

    width=1920

    height=1080

    ##Enable to maintain aspect ratio wrt source, and allow black borders, works

    ##along with width, height properties

    enable-padding=0

    nvbuf-memory-type=0

 

    # config-file property is mandatory for any gie section.

    # Other properties are optional and if set will override the properties set in

    # the infer config file.

    [primary-gie]

    enable=1

    gpu-id=0

    model-engine-file=../../models/Primary_Detector/resnet10.caffemodel_b4_int8.engine

    batch-size=4

    bbox-border-color0=1;0;0;1

    bbox-border-color1=0;1;1;1

    bbox-border-color2=0;0;1;1

    bbox-border-color3=0;1;0;1

    interval=0

    gie-unique-id=1

    nvbuf-memory-type=0

    config-file=config_infer_primary.txt

 

    [tracker]

    enable=1

    tracker-width=640

    tracker-height=384

    ll-lib-file=/opt/nvidia/deepstream/deepstream-5.0/lib/libnvds_mot_iou.so

    #ll-lib-file=/opt/nvidia/deepstream/deepstream-4.0/lib/libnvds_nvdcf.so

    ll-lib-file=/opt/nvidia/deepstream/deepstream-5.0/lib/libnvds_mot_klt.so

    #ll-config-file required for DCF/IOU only

    #ll-config-file=tracker_config.yml

    #ll-config-file=iou_config.txt

    gpu-id=0

    #enable-batch-process applicable to DCF only

    enable-batch-process=1

 

    [secondary-gie0]

    enable=1

    model-engine-file=../../models/Secondary_VehicleTypes/resnet18.caffemodel_b16_int8.engine

    gpu-id=0

    batch-size=16

    gie-unique-id=4

    operate-on-gie-id=1

    operate-on-class-ids=0;

    config-file=config_infer_secondary_vehicletypes.txt

 

    [secondary-gie1]

    enable=1

    model-engine-file=../../models/Secondary_CarColor/resnet18.caffemodel_b16_int8.engine

    batch-size=16

    gpu-id=0

    gie-unique-id=5

    operate-on-gie-id=1

    operate-on-class-ids=0;

    config-file=config_infer_secondary_carcolor.txt

 

    [secondary-gie2]

    enable=1

    model-engine-file=../../models/Secondary_CarMake/resnet18.caffemodel_b16_int8.engine

    batch-size=16

    gpu-id=0

    gie-unique-id=6

    operate-on-gie-id=1

    operate-on-class-ids=0;

    config-file=config_infer_secondary_carmake.txt

 

    [tests]

    file-loop=1

Создайте новый файл deepstream.yaml в директории /deepstream-helmchart/templates и добавьте в него следующее содержимое:

$ nano deepstream.yaml

 

apiVersion: apps/v1

kind: Deployment

metadata:

  annotations:

    deployment.kubernetes.io/revision: "1"

  generation: 1

  labels:

    app.kubernetes.io/name: deepstream

  name: deepstream

spec:

  replicas: 1

  selector:

    matchLabels:

      app.kubernetes.io/name: deepstream

  template:

    metadata:

      labels:

        app.kubernetes.io/name: deepstream

    spec:

      containers:

      - args:

        - -c

        - /opt/nvidia/deepstream/deepstream-5.0/samples/configs/deepstream-app/source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt

        command:

        - deepstream-app

        image: nvcr.io/nvidia/deepstream-l4t:5.0-dp-20.04-samples

        imagePullPolicy: IfNotPresent

        name: deepstream

        ports:

        - containerPort: 8554

          name: http

          protocol: TCP

        resources: {}

        terminationMessagePath: /dev/termination-log

        terminationMessagePolicy: File

        volumeMounts:

        - mountPath: /opt/nvidia/deepstream/deepstream-5.0/samples/configs/deepstream-app/source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt

          name: ipmount

          subPath: source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt

      dnsPolicy: ClusterFirst

      imagePullSecrets:

      - name: nvidia-registrykey-secret

      restartPolicy: Always

      schedulerName: default-scheduler

      securityContext: {}

      volumes:

      - configMap:

          defaultMode: 420

          name: deepstream-configmap

        name: ipmount

Установите режим энергопотребления и тактовые частоты на устройстве Jetson:

$ sudo nvpmodel -m 2

$ sudo jetson_clocks

Установите Helm-диаграмму для DeepStream на устройство Jetson:

$ helm install --name-template deepstream deepstream-helmchart/

Поверьте, что под для DeepStream создан и запущен:

$ kubectl get pods

NAME                          READY   STATUS    RESTARTS   AGE

deepstream-76787ffbf7-mfwk7   1/1     Running   0          1m

Проверьте журналы подов для DeepStream и оцените производительность:

$ kubectl logs <deepstream-podname>

Пример вывода:

$ kubectl logs deepstream-9f8b6b68d-rc5lq

**PERF: 101.42 (100.29) 101.42 (100.29)      101.42 (100.29)   101.42 (100.29)

Деинсталлируйте Helm-диаграмму для DeepStream с устройства Jetson:

$ helm del deepstream

Вывод 

В данной статье описаны ключевые компоненты облачного программного стека EGX. Также показан порядок его самостоятельной установки на комплект средств разработки Jetson Xavier NX Developer Kit и его использование для упрощения развертывания приложений интеллектуальной видеоаналитики на оконечных устройствах.

Чтобы узнать больше о контейнеризированных обученных ИИ-моделях, поддерживающих Jetson Xavier NX, см. каталог NGC. Эти модели могут служить стандартными блоками для разработки ваших ИИ-приложений и помочь вам совершить следующий прорыв в области вычислений на оконечных устройствах уже сегодня!