32

NVIDIA英伟达嵌入式系统 · 2022年09月06日 · 北京市

NVIDIA Jetson 系列文章(10):从头创建Jetson的容器(1)

使用 Docker 容器的最大好处就是 “独立性强”,在前面文章中我们教大家如何使用 NVIDIA 在 NGC 提供创建好的 l4t-ml 系列镜像为基础,去创建各种机器学习 / 深度学习的开发或部署用途的独立容器,包括各种基于 TensorRT 的推理应用、基于 PyTorch 的各种 YOLO 相关应用等等。

但是 l4t-ml 容器内将大部分深度学习所需要的工具全部涵盖进去,使得这个容器镜像变得十分庞大,例如配合 JetPack 5.0 DP 版本的 nvcr.io/nvidia/l4t-ml:r34.1.1-py3 镜像需要占用 16.2G 空间,这对大部分存储空间较为紧凑的 Jetson 边缘设备来说是个不小的负担,需要进一步的优化。

熟悉 Docker 创建容器的人都知道,只要使用 “docker build -f DOCKERFILE” 方式就能创建容器,不过 Dockerfile 内容是有复杂度的,至少包含以下两大部分:

  • 基础镜像

这是相对神奇的环节,我们至少得先在一个“以操作系统为基础”的基础镜像文件之上去创建新的容器,不过还好操作系统源头都会提供这些基础镜像,只要我们能找到这些基础镜像的发行位置,就能在 Dockerfile 一开始使用 “FROM” 指令进行导入。

在 Jetson 设备上使用的 L4T(Linxun for Tegra)版本 Ubuntu 操作系统是由 NVIDIA 所维护,因此操作系统基础镜像也由 NVIDIA 所提供,并且存放在 NGC 云中心提供下载,可以在 https://catalog.ngc.nvidia.co... 上找到详细的内容与下载的指令。

l4t-base 容器内只有最基础的操作系统、驱动与 Python 开发环境,并未安装 CUDA、cuDNN 或 TensorRT 等开发库,L4T 版本与 JetPack 版本是对应的,请参考下表:

image.png

如果要使用 l4t-base 镜像为基础,去创建与深度学习相关应用的镜像文件,就需要自行在 Dockerfile 内加入 CUDA / cuDNN / TensorRT 以及其他所需要的依赖库与软件的安装步骤,以下整理出不同 JetPack 版本所对应的 CUDA / cuDNN / TensorRT / OpenCV 的版本,提供读者在创建相关镜像时候可以参考:

image.png

从上面简表可以看出,在 JetPack 4.4 至 4.6 版本的操作系统都是 Ubuntu 18.04、CUDA 版本都是 10.2、Python3 的版本都是 3.6、OpenCV 版本都是 4.1.1,至于 cuDNN 与 TensoRT 则有些微的差异,基本上镜像文件的兼容性比较高。不过到了 JetPack 5.0 之后,操作系统升级至 Ubuntu 20.04 版之后,包括 Python、OpenCV、CUDA 版本的变化就比较大,与 JetPack 4.x 版本的镜像

基础容器的版本编号是对应 L4T 版本号,如下图:

image.png

因此要创建 Jetson 容器的首要工作,就是先确认系统的 L4T 版本,然后再挑选合适的基础镜像来进行创建的任务。

  • 添加所需软件的安装步骤与其他细节:

这部分就是将平常安装软件的正确步骤加入 Dockerfile,使用 “RUN” 指令来执行所有安装内容,为了要让容器结构更加简化,通常会将所有需要的依赖库全部放在一个 “RUN” 指令里操作,因此创建者需要先收集并确认所需要的内容。

由于创建的容器会以 root 用户进行操作,因此过程都不需要用 “sudo” 去取得权限,可以直接使用 apt-get、pip 或 dpkg 等安装方式,有些需要预先下载的 .deb、.whl 或压缩文件,在使用过后最好删除以减少空间的占用。

这部分的细节内容相当繁琐,需要比较多的执行经验与整理过程,对初学者来说难度较大,因此本文特别挑选 NVIDIA 高级工程师所维护的 jetson-container 开源项目,针对在 Jetson 设备上创建深度学习与 ROS 两大类应用,提供各种对应的 Dockerfile 参考内容,包括安装 CUDA、cuDNN、TensorRT、OpenCV、PyTorch、TensorFlow 以及 ROS 相关环境的细节,读者可以参考这些内容再进行调整。

接下来就是下载 jetson-container 项目,并且以创建 l4t-ml 容为示范来进行讲解其操作的重点,读者只要比照相同的逻辑进行调整与修改,就能轻松地创建自己的应用与开发用途的容器镜像。

1、下载开源项目

项目开源仓位置在 https://github.com/dusty-nv/j...,请执行以下指令下载到 Jetson 设备上:

git clone https://github.com/dusty-nv/jetson-containers
cd jetson-containers

项目仓的内容总共有将近 60 个文件,主要分为以下三大类:

  • 在主目录下有 12 个以 “Dockerfile.xxx” 格式命名的文件,作为创建各种容器所需要的配置文件;
  • 在 scripts 目录下有 16 个创建容器与确认各项相关软件版本的 .sh 脚本文件;
  • 在 test 目录下有 21 个测试用的 Python 代码。

接下来分析执行的重点。

2、分析创建容器的脚本

这个项目主要提供深度学习与 ROS 两大应用类别的容器创建资源,真正的使用入口就是 scripts 目录下的 docker_build_ml.sh 与 docker_build_ros.sh 这两个脚本,其余脚本多是辅助用途的,用来协助判断相关软件版本,然后甚至对应变量给执行脚本进行完整的镜像创建步骤。

现在以 docker_build_ml.sh 为例来进行说明,后面可以加上 all、TensorFlow 或 PyTorch 等机器学习框架选项,现在来看看脚本的主要内容:

(1)确认基础镜像版本:

前面说过,创建 Docker 镜像的首要任务就是要确认 L4T 版本,然后指定 NGC 中合适的基础镜像版本,作为 Dockerfile 中第一个 “FROM” 的参数,在 “docker build” 过程中下载这个镜像。

  • 脚本第 4 行 “source scripts/docker_base.sh” 会启动 docker_base.sh 脚本以确认需要下载的基础镜像版本;
  • 而 docker_base.sh 第 3 行又呼叫 l4t_version.sh 脚本,获取本系统上的 l4t 版本,例如为 r34.1.1,分别存入以下 5 个变量之中:

    • $L4T_VERSION=34.1.1
    • $L4T_RELEASE=34
    • $L4T_REVISION=1.1
    • $L4T_REVISION_MAJOR=1
    • $L4T_REVISION_MINOR=1

然后传回给 docker_bash.sh 脚本使用;

  • docker_base.sh 根据上面变量决定基础镜像版本,存放到 $BASE_IMAGE_L4T 里,例如 “nvcr.io/nvidia/l4t-base:r34.1.1”,这样就完成了第一个最重要的工作。

(2)确认 OpenCV 与 Python 版本:

脚本第 6、7 行分别执行 opencv_version.sh 与 python_version.sh,去决定这两个部分的版本。

其中 OpenCV 部分经过作者修改之后固定为 4.5.0 版本,并以 $OPENCV_DEB与$OPENCV_URL 变量存放安装包的下载路径与名称。而 Python 版本则指定于所使用的 Jetson 设备上的版本,如果是 JetPack 4.x 版本的设备则 Python 版本为 3.6,如果是 JetPack 5.0 以后版本的设备则 Python 版本为 3.8。

(3)确认各容器相关应用版本:

这部分主要是 PyTorch 与 TensorFlow 的版本,因为这两个是目前深度学习领域使用率最高的框架,因此这里就以这两个工具为主来创建深度学习的容器镜像。

脚本第 37~137 行与 160~221 行的内容,会根据 $L4T_RELEASE 变量,分别针对创建 PyTorch 与 TensorFlow 镜像所需要的配套资源,提供完整的对应参数,包括需要赋予对应的下载链接、文件名称、镜像标签(tag)等等信息,在 PyTorch 部分还需要提供 torchvision 与 torchaudio 的版本。

下表是根据 NGC 提供的 l4t-ml 镜像所整理的各项版本信息:

image.png

前面判断好相关版本信息之后,就会分别调用第 14 行 build_pytorch() 与第 142 行 build_tensorflow() 分别创建 l4t-pytorch 与 l4t-tensorflow 容器镜像。

下面截屏是 build_pytorch() 的主要内容,会调用 scripts/docker_build.sh 脚本与目录下的 Dockerfile.pytorch 配置文件,然后套用 6 个 “--build-arg” 参数进行实际创建的工作,这样就完成对 l4t-pytorch 镜像的创建任务。

image.png

创建 l4t-tensorflow 镜像的方式也是大致相同,就不重复说明。脚本最后第 229~235 行是创建包含 PyTorch 与 TensorFlow 两种框架的 l4t-ml 镜像,主要指令如下:

image.png

这样就完成在 Jetson 上从头创建深度学习相关的容器镜像任务,另一个创建 ROS 应用的 docker_build_ros.sh 脚本内容也是雷同,所有的关键就是先确认 $L4T_RELEASE 版本信息,其他的软件版本都会根据这个参数进行调整。

本文先讲解这个开源项目内的脚本内容,下一篇文章会进一步说明 Dockerfile 的主要细节,这样就能很轻松地掌握容器镜像的创建过程。

推荐阅读
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息