现代对敏捷能力和零停机时间持续创新的期望要求改变嵌入式和边缘设备软件的开发和部署方式。在边缘采用诸如微服务、容器化和容器编排之类的云原生范式是前进的方向,但是部署、管理和安全问题的复杂性阻碍了扩展。
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 。这些模型可以作为您的人工智能应用程序开发的构建块,并帮助您在今天的边缘计算中实现下一个飞跃!