由NVIDIA资深工程师DustinFranklin为Jetson设备所搭建的jetson-container开发环境,以Docker容器为基础去提供各种所需的应用环境,这还需要nvidia-docker的配合,所幸Jetpack安装工具已经都配置完成了。
不过Jetpack疏漏一个对runtime的设定,因此要在Jetson让容器调用NVIDIA GPU的话,还需要先执行下面指令:
sudo nvidia-ctk runtime configure --runtime=docker
这个指令会在 /etc/docker/daemon.json里添加以下代码:
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
}
因此我们可以执行上面指令,或者直接在daemon.json里添加上面的代码块,效果是一样的。添加这个内容之后,记得执行以下指令让其生效:
$ sudo systemctl deamon-reload && sudo systemctl restart docker.service
完成上述工作之后,就可以开始安装jetson-container开发环境,整个过程很简单,只要按照以下步骤即可:
$ cd <你要安装的目录,如果有装NVME SSD的话,推荐安装到这里>
$ git clone https://github.com/dusty-nv/jetson-containers
$ bash jetson-containers/install.sh
安装完之后,会在 /usr/local/bin 目录下创建”jetson-containers”脚本文件,有兴趣的朋友可以自行今天了解脚本内容。
由于 Jetson-container项目更新十分频繁,因此每次要创建项目时,建议先执行以下指令进行更新:
$ jetson-container update
如果项目有所更新的话,就会看到类似下面画面的信息:
现在我们就可以用jetson-containers指令,来创建我们所需要的docker容器环境,包括下载已经创建好的镜像文件,或者从头创建新的镜像文件。
接下来就进一步挖掘jetson-containers的用法,当我们输入以下指令时,会看到如下图的信息:
$ jetson-containers
表示在jetson-containers指令后面,总共有8个指令选项,其中”update”在前面已经使用过了,另外的”list”、”show”、”root”、”data”都是比较基础的信息用途,现在就做个简单的说明:
root 与 data:分别显示jetson-containers项目的根路径与data路径:
$ jetson-containers root && jetson-containers data
显示的信息如下:
list [PACKAGES]*:显示个别package的基本信息
$ jetson-containers list # 会显示完整的packages列表
目前这个项目的总package数量已经超过230个,这里就不展现列表信息。
$ jetson-containers list deepstream # [PACKAGES]=deepstream
显示的信息如下,
show [PACKAGES]*:显示个别package的完整信息,包括依赖的容器
$ jetson-containers show deepstream # [PACKAGES]*=deepstream
显示的信息,包括上来 list 的内容之外,再加上下图所显示的信息,包括这个项目所依赖的软件、路径、编译版本等等,相对更加清楚些。
上面4个指令主要是信息用途,与实际的执行并没有太大关系,因此使用频率并不高。下面三个指令的组合是jetson-containers的灵魂,并且在jetson-containers目录下有个别对应的脚步,来配合其工作。
autotag [CONTAINER]:自动适配版本,并作进一步处理
由于容器镜像与设备环境版本存在紧密对应的关系,每个package会针对各种Jetpack版本去创建对应版本的镜像文件,例如deepstream package就有如下图5种版本镜像文件,前面提到目前已经有超过230个packages,那所需要管理的镜像文件就大概有近千个,在管理上就会造成很大的负担,大部分的新手通常不知道该使用哪个版本?
为了解决这个比较头痛的问题,项目作者提供 ”autotag” 自动判断脚本,帮开发者直接确认该使用的镜像版本。请执行以下指令:
$ echo $(autotag deepstream) # [CONTAINER]=deepstream
执行信息中的“Found compatible container dustynv/deepstream:r36.2.0”,就是告诉我们已经发现到“r36.2.0这个兼容版本”,虽然与前面 ”list” 指令所找到的“L4T_VERSION=36.3.0”不完全一致,但系统告诉我们这里有个可用的兼容版本,如果发现系统里没有对应的镜像文件,还会询问“是否下载(pull)?”、“是否创建(build)?”之类的问题,非常贴心。
”autotag”这个指令通常不会独立使用,而是与下面的”run”或”build”组合使用,不过”build”对新手来说使用的机会并不高,接下去就是说明以下”run”的使用。
run 执行容器指令:标准格式如下
$ jetson-containers run OPTIONS [CONTAINER:TAG] CMD
如果按照指令的要求,我们需要自行提供[CONTAINER:TAG]的完整内容,例如“dustynv/deepstream:r36.2.0”。但如同前面所提到的,初学者经常搞不清楚能搭配的版本,因此我们可以使用“$(autotag deepstream)”来协作,如下指令:
$ jetson-containers run OPTIONS $(autotag deepstream) CMD
至于命令中间的”OPTIONS”,就是与”docker run”后面所接的选项一样,通常是添加容器内外路径映射用途的,例如添加“-v ${HOME}:/home”这样的映射关系。
在Docker应用中,周边设备的映射通常是最令人头痛且容易出错的环节,因此作者在run.sh脚本中,为大家提供非常好的防护措施。主要部分如下:
1. 检查可能连接的USB摄像头(check for V4L2 devices)
在 run.sh 第6-14行中,检查设备上已经连接的USB摄像头,只要能发现到的都添加到列表中,最多数量为10个(编号0-9),应该不会再多了。
2. 检查I2C设备(check for I2C devices)
同样的原理,第17-25行检查设备上已经接上的I2C设备,并添加到设备列表中。
3. 检查显示(check for display)
第27-41行为容器配置显示能力,这段牵涉到几个指令,是大部分初学者容易忽略的部分。作者将这部分添加到run.sh里面,为大家做好预防措施,降低出错的机率。
4.指令汇总
从第75-86行的内容(如下图),就是将执行容器所需要的完整指令进行汇总,里面会看到许多我们所不熟悉的映射,例如“--volume /etc/enctune.conf:/etc/enctune.conf ”是什么用途?这里不多做探索。
如此一来,我们只要使用“jetson-containers run OPTIONS [CONTAINER:TAG]”指令,就能替代十多行繁琐的指令,我们只需要专注在deepstream、agent_studio这些要使用的项目名称,其他事情就交给jetson-containers指令去处理就行了。
近期活动