人工智能/深度学习

使用 NVIDIA EGX 在 NVIDIA Jetson Xavier NX 微型服务器上部署 AI 应用程序

现代对敏捷能力和零停机时间持续创新的期望要求改变嵌入式和边缘设备软件的开发和部署方式。在边缘采用诸如微服务、容器化和容器编排之类的云原生范式是前进的方向,但是部署、管理和安全问题的复杂性阻碍了扩展。

NVIDIA EGX 平台是一个基于云的 Kubernetes 和基于容器的软件平台,使您能够快速、轻松地为基于 NVIDIA Jetson 的微服务器或边缘物联网系统提供资源。通过为 Jetson Xavier NX 边缘设备带来 EGX 云本地敏捷性,企业可以使用与云革命相同的技术和工作流来大规模构建、部署和管理边缘设备。

在本文中,您将了解云原生软件栈的关键组件,如何在 Jetson Xavier NX 开发者工具包上安装 EGX DIY 堆栈,并使用它在边缘轻松部署智能视频分析( IVA )应用程序。

人工智能容器

如今的企业正在将智能转移到边缘,并在地理位置不同的存在点( POP )部署边缘基础设施,以实现更低的网络成本和更好的响应时间。容器是敏捷软件开发和交付的促成因素,并节省带宽以帮助降低传输成本。

EGX 从 NGC 运行 AI 容器,这是一个为 AI 和数据分析软件优化的集线器。 NGC 旨在简化和加速端到端工作流。 NGC 拥有 150 多个企业级容器, 100 多个模型,以及行业特定的 sdk 和 Helm 图表,可以部署在本地、云中或边缘。您可以按原样使用软件或“优化和定制”,使部署功能强大的软件或构建定制的解决方案变得容易,并收集见解以实现业务价值。

EGX 还包括对 NGC 私人注册 的访问,在这里您可以安全地存储您独特的 IP 和定制的解决方案,以最大的安全性在边缘、本地或云上共享和部署。

库伯涅茨

Kubernetes 是一个容器编排系统,是当今云计算和企业中最活跃的开源项目之一。它已经成为阿德事实标准和边缘计算的重要基础,具有自动容器部署和自我修复的特性。

EGX 云本地软件策略的一个核心组件是使 GPUs 具有 Kubernetes 的弹性。 EGX 包括一个 GPU 操作符,它自动安装和配置 Kubernetes 集群中使用 GPUs 所需的所有组件。

这大大简化了第 0 天的 IT 操作,并完全自动化了第 1 天的操作… n 操作。所有必需的组件,如 NVIDIA 驱动程序、 NVIDIA 容器运行时、 Kubernetes 设备插件和监控都是容器化的,并作为服务在 Kubernetes 上运行,这导致 IT 部门只需为 CPU 和 GPU 节点管理一个映像。

舵面图

Helm 图表是 Kubernetes 推荐的包格式,因为它允许您通过单击按钮和几个 CLI 命令在 Kubernetes 集群上轻松地配置、部署和更新应用程序。

NGC 托管这些库伯内特斯准备好的头盔图表来部署强大的第三方软件。 DevOps 还可以在 NGC 上推送和共享他们的舵图,这样团队就可以利用一致、安全和可靠的环境来加快开发到生产周期。

安装 EGX 2 . 0 堆栈

NVIDIA Jetson Xavier NX 开发工具包 将超级计算机的性能提升到了极致,在 15W 的功率和较小的外形尺寸下,提供了 21 个顶级的 AI 计算。 Jetson Xavier NX 非常适合高性能人工智能系统,如商业机器人、医疗器械、智能相机、高分辨率传感器、自动光学检测、智能工厂和其他物联网嵌入式系统。

对 Jetson Xavier NX 的云本地支持现在也可以通过 EGX 软件栈的最新更新实现。 Jetson Xavier NX 开发工具包上的这个堆栈是 NVIDIA 功能和性能验证的参考设计,可以在嵌入式设备上实现快速的云本地部署。

下面是在 Jetson Xavier NX 开发工具包上安装 egx2 . 0 堆栈的步骤。成功安装后, EGX 2 . 0 平台 就绪 Jetson Xavier NX 开发工具包包括以下内容:

  • NVIDIA Jetpack SDK 4 . 4
  • 管理版本 1 . 17 . 5
  • 舵手/舵柄 3 . 1 . 0
  • NVIDIA 容器运行时 1 . 0 . 1-dev

在本文中,我们使用了一个带有 Jetson Xavier NX 开发工具包的 32gb microSD 卡。

设置开发工具包并安装 JetPack 4 . 4

JetPack 包含在 Jetson 平台上构建 AI 应用程序的库、工具和核心操作系统。有关设置 Jetson Xavier NX 开发人员工具包和安装 Jetpack4 . 4 的详细信息,请参阅 Jetson Xavier NX 开发工具包入门

更新 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 默认运行时

验证 Docker 默认运行时为 NVIDIA :

$ sudo docker info | grep -i runtime

以下是示例输出:

Runtimes: nvidia runc
Default Runtime: nvidia

安装 Kubernetes 1 . 17 . 5 版

在开始安装之前,请确保 Docker 已启动并已启用:

$ sudo systemctl start docker && sudo systemctl enable docker

安装立方体、 kubeadm 和 kubectl :

$ sudo apt-get update && sudo apt-get install -y apt-transport-https curl
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
$ sudo mkdir -p /etc/apt/sources.list.d/

创建库伯内特斯列表文件:

$ sudo nano /etc/apt/sources.list.d/kubernetes.list

在库伯内特斯列表归档并保存:

deb https://apt.kubernetes.io/ kubernetes-xenial main

安装立方体、 kubectl 和 kubeadm :

$ sudo apt-get update
$ sudo apt-get install -y -q kubelet=1.17.5-00 kubectl=1.17.5-00 kubeadm=1.17.5-00
$ sudo apt-mark hold kubelet kubeadm kubectl

初始化 Kubernetes 集群以作为主服务器运行

禁用交换:

$ sudo swapoff -a

初始化群集:

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

输出显示了将 pod 网络部署到集群所需执行的命令,以及加入集群的命令。

使用输出指令,运行以下命令:

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

将 pod 网络附加组件安装到控制平面节点。使用 calico 作为 pod 网络附加组件:

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

确保所有吊舱都已启动并运行:

$ 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 集群,所以默认情况下,集群无法在控制平面节点上调度 pod 。在控制平面节点上调度 pods 。必须使用以下命令删除污点:

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

有关详细信息,请参见 安装 kubeadm

安装舵柄/舵柄 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

有关详细信息,请参见 舵手释放赫尔姆概论

验证成功的 EGX 2 . 0 安装

要验证 EGX 堆栈是否按预期工作,请按照以下步骤创建 pod yaml 文件。如果 getpods 命令显示 pod 状态为 completed ,则说明安装成功。您还可以验证 CUDA 是否成功运行 – 样品. yaml 验证输出是否显示 Result = PASS 。

创建一个 pod yaml 文件,添加以下内容,并将其另存为样品. yaml :

$ sudo nano cuda-samples.yaml

添加以下内容并将其另存为 CUDA – 样品. 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 示例以从 pod 验证:

$ cd /usr/local/cuda/samples/1_Utilities/deviceQuery
$ sudo make
$ cd ~

创建示例 GPU pod :

$ sudo kubectl apply -f cuda-samples.yaml

检查样本盒是否已创建:

$ kubectl get pods

以下是示例输出:

nvidia-l4t-base 0/1 Completed 2m

验证示例 pod 日志以支持 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 软件版本和安装指南的更多信息,请参阅 Jetson Xavier NX DevKit 的 EGX Stack – v2 . 0 安装指南

用例:简化 IVA 应用程序的部署

在基于 EGX 的 Jetson Xavier NX 上使用 NVIDIA 深溪 构建和部署 AI 驱动的 IVA 应用程序和服务。 deepstreamsdk 提供了一个具有 TLS 安全性的可扩展加速框架,可以部署在边缘并连接到任何云。

在您的 EGX Jetson 设备上创建一个 DeepStream Helm 图表目录。

$ mkdir deepstream-helmchart

在/ deepstream helmchart 中创建一个模板目录来存储 Kubernetes 清单:

$ mkdir -p deepstream-helmchart/templates

创建图表. yaml 文件,添加以下内容,并将其保存到/ deepstream helmchart 目录中:

$ nano chart.yaml apiVersion: v1
name: deepstream-helmchart
version: 1.0.0
appVersion: 0.1

将新文件创建为配置映射. 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

设置电源模式并固定 Jetson 设备上的时钟:

$ sudo nvpmodel -m 2
$ sudo jetson_clocks

在 Jetson 设备上安装 DeepStream 头盔图表:

$ 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)

清理 Jetson 设备上的 DeepStream 头盔图表:

$ helm del deepstream

结论

在本文中,您了解了云原生软件栈的关键组件。我们还向您展示了如何在 Jetson Xavier NX 开发工具包上安装 EGX DIY 堆栈。使用它可以轻松地在边缘部署 IVA 应用程序。

要了解其他 Jetson Xavier NX 支持的集装箱化、预先训练的 AI 模型的更多信息,请参见 NGC 。这些模型可以作为您的人工智能应用程序开发的构建块,并帮助您在今天的边缘计算中实现下一个飞跃!

Tags