アプトポッド 組み込みエンジニアの久保田です。
連載の前回 では、ROSの開発においてDockerをどのように活用するかを紹介しました。その中で触れた通り、Dockerコンテナを使ってホストのハードウェアリソースにアクセスすることが可能です。例えば、当社で販売している車載向けエッジコンピュータ EDGEPLANT T1 はNVIDIA Jetson TX2を搭載しています。NVIDIA Jetsonシリーズは、GPUを搭載しており、AIやディープラーニングのタスクに適しています。このJetsonのGPUをDockerコンテナ内で最大限に活用するために、NVIDIAが提供する公式Dockerイメージの使用が推奨されています。
ROS開発において、この公式Dockerイメージは導入しやすい反面、ROS自体がソースコードからビルドされており、ROS公式に提供されているdebianパッケージを利用することができません。この制限を解消するためには、NVIDIA GPU資源を利用でき、かつROS公式に提供されているdebianパッケージの利用可能なDockerイメージの作成が必要となります。
連載ROS Tips第3回目となる今回は、ROSのDockerコンテナからのNVIDIA GPU利用方法を紹介します。
なお、連載の予定として、以下のようなコンテンツを予定しております。(連載内容は、変更・追加の可能性があります。ご了承ください)
- そもそもROSとは?
- ROS開発におけるDocker活用テクニック
- ROSのDockerコンテナからNVIDIA GPUを利用するには(本記事)
- 大量伝送シナリオにおけるROS/DDSのチューニング
本連載の投稿済みの記事はこちらからご覧いただけます。
- コンテナからNVIDIA GPUを利用するには
- ROSコンテナからNVIDIA GPUを利用するには(NVIDIA公式イメージの使用)
- NVIDIA GPUを使用しつつ、ROSパッケージをリポジトリ追加可能にするには
- まとめ
- 当社プロダクトのご案内
コンテナからNVIDIA GPUを利用するには
DockerコンテナからNVIDIA GPUを利用するには、NVIDIA Container Runtimeが必要です。
Enabling GPUs with NVIDIA Docker Container Runtime
NVIDIA Container Runtimeは、Dockerなどのコンテナ技術とNVIDIA GPUを統合するためのツールです。これにより、GPUを活用したアプリケーションをコンテナ内で簡単に実行することができます。NVIDIAのGPUドライバと連携して、コンテナ内からGPUリソースにアクセスするために必要なライブラリやバイナリを提供し、ディープラーニングや機械学習、高性能計算などのGPUを活用したタスクを、コンテナ化された環境で効率的に実行することができます。
NVIDIA Container Runtimeの特徴:
- GPUアクセス: コンテナからNVIDIA GPUへの直接アクセスが可能になります。
- 互換性: DockerやKubernetesなどの主要なコンテナ技術との互換性があります。
- 柔軟性: 複数のGPUや異なるGPUアーキテクチャに対応しています。
NVIDIA Container Runtimeの使用方法
NVIDIA公式サイトで示されている手順を紹介します。
NVIDIA Container RuntimeによりDockerコンテナ内でGPUを利用するためには、Dockerコンテナを実行するホストでインストール・設定などの準備が必要です。 なお、JetsonシリーズではJetPackをインストールすることによりNVIDIA Container Runtimeを利用することができますので、ここでご紹介する手順でのインストール・設定は不要です。
まず、リポジトリを設定します。
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \ && \ sudo apt-get update
次に、NVIDIA Container Runtimeをインストールします。
sudo apt-get install -y nvidia-container-toolkit
さらに、Dockerの設定を変更します。
sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker
最後に、NVIDIA Container Runtimeを実行します。
docker run --rm \ --runtime=nvidia \ --gpus all \ arm64v8/ubuntu:22.04 \ nvidia-smi
上記で使用するコマンドの引数は以下の情報を参考にしてください。
引数 | 説明 |
---|---|
runtime | ランタイムの指定 (nvidia) |
gpus | 使用GPU指定 ( all : すべてのGPU ) |
GPU状態の確認方法
GPUの状態を確認するために通常はnvidia-smiコマンドが使用されますが、Jetsonシリーズでは使用できません。 JetsonシリーズでGPUの状態を表示するためには、jtopコマンドが便利です。
jtopコマンドを実行するには、json-stats をインストールが必要です。
sudo apt install -y python3-pip sudo pip3 install -U jetson-stats
jtopコマンドを実行します。
jtop
ROSコンテナからNVIDIA GPUを利用するには(NVIDIA公式イメージの使用)
JetsonシリーズでROSのDockerコンテナを起動しコンテナ内からGPUを活用する場合、NVIDIA公式イメージの使用が推奨されています。
公式イメージの提供サイト:
ROS安定版に対して、NVIDIA公式イメージで使用できるタグ
公式イメージでは、ROSの各ディストリビューション用にタグがいくつか公開されています。 ここでは、ROSの最新の安定版ディストリビューション(LTS)に対応するタグを紹介します。
ROS Distro | L4T | Ubuntu | イメージのタグ |
---|---|---|---|
ROS Noetic | R32.7.1 | 18.04 | dustynv/ros:noetic-ros-base-l4t-r32.7.1 |
R34.1.1 | 20.04 | dustynv/ros:noetic-ros-base-l4t-r34.1.1 | |
R35.4.1 | 20.04 | dustynv/ros:noetic-ros-base-l4t-r35.4.1 | |
ROS2 Humble | R32.7.1 | 18.04 | dustynv/ros:humble-ros-base-l4t-r32.7.1 |
R34.1.1 | 20.04 | dustynv/ros:humble-ros-base-l4t-r34.1.1 | |
R35.4.1 | 20.04 | dustynv/ros:humble-ros-base-l4t-r35.4.1 |
公式イメージではROSパッケージをリポジトリから追加できない
これらの公式イメージは、ベースとするUbuntuのイメージにROSをソースコードビルドでインストールして構成されています。ROSは各ディストリビューションで前提とするUbuntuバージョンがそれぞれ決まっていますが、NVIDIA公式イメージではROSディストリビューションが前提としているUbuntuバージョンとベースイメージのUbuntuバージョンが異なる場合があり、そういった場合にdebパッケージによるROSのインストールが行えなえません。
この影響により、公式イメージに新しいROSパッケージを追加する際、Ubuntuの公式リポジトリを用いてaptコマンドで直接追加することができません。ROSの追加機能やパッケージを導入したい場合は、GitHubなどからソースコードを取得して手動でビルドする必要があります。
NVIDIA公式イメージの仕組み
先のセクションで利用するために、公式イメージがどのように作られているのか、中身を調べていきます。
NVIDIAが提供している公式イメージは、L4T rootファイルシステムに含まれるパッケージのサブセットで構成された l4t-base というイメージをベースにしています。l4t-base は、Jetsonシリーズで実行することを想定しており、NVIDIA Container Runtime を使用してコンテナ内でL4Tアプリケーションを実行できるようにします。
ハードウェア依存性を提供するプラットフォーム固有のライブラリと、特定デバイスのデバイスファイルをNVIDIA Container Runtimeによってコンテナにマウントし、コンテナ内で実行するL4Tアプリケーションに提供します。マウントされるライブラリは /etc/nvidia-container-runtime/host-files-for-container.d/l4t.csv に記載されています。
ベースイメージの提供サイト:
l4t-baseイメージの Dockerfile は次のような構成となっており、以降ではこの Dockerfile について解説します。
- ベースイメージの指定
- パッケージのインストール
- NVIDIAの公開鍵の追加
- NVIDIAのリポジトリの追加
- Tegraライブラリの設定
- EGLの設定
- GPU関連環境変数の設定
ベースイメージの指定
FROM docker.io/arm64v8/ubuntu:18.04
ARM64アーキテクチャのUbuntuイメージをベースイメージとして指定します。 Ubuntuの安定版(LTS)のイメージとして、以下のようなものがあります。
Ubuntu バージョン | Distro | イメージのタグ |
---|---|---|
22.04 | Jammy | arm64v8/ubuntu:22.04 |
20.04 | Focal | arm64v8/ubuntu:20.04 |
18.04 | Bionic | arm64v8/ubuntu:18.04 |
パッケージのインストール
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -qq -y --no-install-recommends \
bc \
bzip2 \
can-utils \
freeglut3-dev \
gstreamer1.0-alsa \
gstreamer1.0-libav \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-ugly \
gstreamer1.0-tools \
i2c-tools \
iw \
kbd \
kmod \
language-pack-en-base \
libapt-inst2.0 \
libcanberra-gtk3-module \
libgles2 \
libglu1-mesa-dev \
libglvnd-dev \
libgtk-3-0 \
libpython2.7 \
libudev1 \
libvulkan1 \
libzmq5 \
mtd-utils \
parted \
pciutils \
python \
python-pexpect \
python3-distutils \
sox \
udev \
vulkan-utils \
wget \
wireless-tools wpasupplicant && \
rm -rf /var/lib/apt/lists/* && apt-get clean
GstreamerやOpenGL関連のライブラリ、ワイヤレスツール、PythonなどGPU利用に関連するパッケージをインストールします。L4Tアプリケーションの実行に必要な最低限のパッケージとなっています。
NVIDIAの公開鍵の追加
COPY jetson-ota-public.key /etc/jetson-ota-public.key RUN apt-key add /etc/jetson-ota-public.key
NVIDIAの公開鍵をコンテナにコピーし、パッケージ管理ツール apt に鍵を追加します。
NVIDIAのリポジトリの追加
RUN echo "deb https://repo.download.nvidia.com/jetson/common $RELEASE main" >> /etc/apt/sources.list
NVIDIAのJetson用リポジトリを追加します。環境変数 RELEASE には r32.7 などリリースバージョンを指定します。
Tegraライブラリの設定
RUN echo "/usr/lib/aarch64-linux-gnu/tegra" >> /etc/ld.so.conf.d/nvidia-tegra.conf && \ echo "/usr/lib/aarch64-linux-gnu/tegra-egl" >> /etc/ld.so.conf.d/nvidia-tegra.conf
Tegra関連のライブラリのパスをldconfigの設定に追加します。
EGLの設定
RUN rm /usr/share/glvnd/egl_vendor.d/50_mesa.json RUN mkdir -p /usr/share/glvnd/egl_vendor.d/ && echo '\ {\ "file_format_version" : "1.0.0",\ "ICD" : {\ "library_path" : "libEGL_nvidia.so.0"\ }\ }' > /usr/share/glvnd/egl_vendor.d/10_nvidia.json RUN mkdir -p /usr/share/egl/egl_external_platform.d/ && echo '\ {\ "file_format_version" : "1.0.0",\ "ICD" : {\ "library_path" : "libnvidia-egl-wayland.so.1"\ }\ }' > /usr/share/egl/egl_external_platform.d/nvidia_wayland.json RUN ldconfig
NVIDIAのEGL (Embedded-System Graphics Library)とWaylandの設定を追加します。
GPU関連環境変数の設定
ENV NVIDIA_VISIBLE_DEVICES all ENV NVIDIA_DRIVER_CAPABILITIES all
NVIDIA Container Runtimeから使用できるデバイスとドライバの機能をすべて有効にします。
NVIDIA GPUを使用しつつ、ROSパッケージをリポジトリ追加可能にするには
前述した通り、Jetsonシリーズでは、NVIDIAの公式イメージの使用が推奨されています。このイメージでは、ベースとするUbuntuイメージのバージョンとROSディストリビューションが前提とするUbuntuバージョンが異なることが理由でROSをソースコードからビルドしてインストールしているため、本来対応しているUbuntuバージョンの公式リポジトリを用いてaptコマンドでROSパッケージを直接追加することはできません。
この制限を克服する方法として、ホストOSのUbuntuバージョンとは異なるバージョンをベースにした非公式イメージを使用する方法が考えられます。
非公式Ubuntu 20.04ベースイメージの提供サイト
非公式Ubuntu 22.04ベースイメージの提供サイト
これらの非公式イメージは、任意のバージョンのUbuntuイメージをNVIDIA GPUに対応させるために、任意のバージョンのUbuntuイメージをベースとして、NVIDIA Container Runtimeを使用するために必要なツールをインストールしています。これらのNVIDIA GPU対応のUbuntuベースイメージに、さらにROSディストリビューションをインストールすればNVIDIA GPUに対応したROSコンテナができあがります。
当社リポジトリで提供開始するイメージのご紹介
上記で紹介した非公式イメージは、別々の開発者が Ubuntu 20.04、Ubuntu 22.04 それぞれに向けて、各自のリポジトリで提供しているものです。
今回、より汎用的に任意のUbuntuバージョンで利用できるコンテナイメージ用のDockerfileを当社にて作成し、提供を開始いたしますのでご紹介します。
Dockerfileの提供サイト
GitHub - aptpod/l4t-ros: NVIDIA L4T (Linux for Tegra) enabled ROS Container Image
こちらは、当社が販売している Jetson TX2 を搭載したエッジコンピュータ EDGEPLANT T1 でご利用いただくことを想定して作成したものですが、Jetsonシリーズを搭載したコンピュータであれば同様にご利用いただけるはずです。
GitHubには、ROS 2用だけでなく、ROS 1用のDockerfileも用意しています。GPUを活用したROSコンテナを利用したい場合に是非ご活用ください。
なお、今回GitHubで公開したDockerfileは Apache 2.0 ライセンスにて公開しており、基本的には自己責任にて使用していただく想定です。とはいえ、なるべく当社でメンテナンスしていく予定ですので、もし不具合等ございましたら当社までご連絡ください。
より詳しい技術情報は、リポジトリのREADMEをご覧ください。
Jetson TX2搭載エッジコンピュータ EDGEPLANT T1 のご紹介
上記のDockerfileにて作成したイメージは、Jetsonシリーズを搭載したコンピュータであればご利用いただけるはずですが、基本的には当社が販売している Jetson TX2 を搭載したエッジコンピュータ EDGEPLANT T1 でご利用いただくことを想定したものになります。
EDGEPLANT T1はNVIDIA Jetson TX2を搭載したエッジコンピュータで、映像のエンコードやデコードなどGPUを使用する処理や、デバイスエッジでのAIモデルの実行用途にお使いいただけます。また、SIMスロット、GPSモジュールなど、IoT端末として必要な様々な機能を備えています。車載機器に求められるEMC規格(Eマーク)、信頼性規格(JASO D014)などにも準拠しており、ROSを使用したロボット開発、自動運転システムの開発にもおすすめです。
EDGEPLANT T1は、当社の販売パートナー様または、Amazon.co.jp からご購入いただけます。詳しくは、製品ページをご覧ください。
今回ご紹介したイメージを EDGEPLANT T1 上でご利用いただく場合であれば当社からの技術サポートも可能です。 コンテナイメージ上でのNVIDIA GPUを活用したROSアプリケーションの開発をご検討の方は、EDGEPLANT T1 の採用も是非ご検討ください。
当社提供イメージの仕組み
以降では、提供開始するDockerfileの構成について解説します。
ご紹介するコンテナイメージは、これまでにご紹介したUbuntuの任意のバージョンをNVIDIA GPUに対応させる方法に加え、ROSの利用に必要なセットアップを行ったものです。 ROSコンテナの公式イメージの Dockerfile は次のサイトで提供されていますので、こちらを参考にセットアップを行います。
ROSの公式イメージの提供サイト:
このテックブログでは、NVIDIA GPUを利用できる ROS2 Humble - L4T 32.7.1 のコンテナ構成ファイルを紹介します。
L4Tベースイメージ (Container tag: l4t-base:jammy-r32.7)
FROM docker.io/arm64v8/ubuntu:22.04 ARG RELEASE="r32.7" ARG SOC="t186" ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -qq -y --no-install-recommends \ bc \ bzip2 \ can-utils \ ca-certificates \ freeglut3-dev \ gstreamer1.0-alsa \ gstreamer1.0-libav \ gstreamer1.0-plugins-bad \ gstreamer1.0-plugins-base \ gstreamer1.0-plugins-good \ gstreamer1.0-plugins-ugly \ gstreamer1.0-tools \ i2c-tools \ iw \ kbd \ kmod \ language-pack-en-base \ libapt-inst2.0 \ libcanberra-gtk3-module \ libgles2 \ libglu1-mesa-dev \ libglvnd-dev \ libgtk-3-0 \ libpython2.7 \ libudev1 \ libvulkan1 \ libzmq5 \ mtd-utils \ parted \ pciutils \ python \ python-pexpect \ python3-distutils \ sox \ udev \ vulkan-utils \ wget \ wireless-tools wpasupplicant && \ rm -rf /var/lib/apt/lists/* && apt-get clean ADD --chown=root:root https://repo.download.nvidia.com/jetson/jetson-ota-public.asc /etc/apt/trusted.gpg.d/jetson-ota-public.asc RUN chmod 644 /etc/apt/trusted.gpg.d/jetson-ota-public.asc && \ echo "deb https://repo.download.nvidia.com/jetson/common $RELEASE main" >> /etc/apt/sources.list && \ echo "deb https://repo.download.nvidia.com/jetson/$SOC $RELEASE main" >> /etc/apt/sources.list RUN echo "/usr/lib/aarch64-linux-gnu/tegra" >> /etc/ld.so.conf.d/nvidia-tegra.conf && \ echo "/usr/lib/aarch64-linux-gnu/tegra-egl" >> /etc/ld.so.conf.d/nvidia-tegra.conf RUN rm /usr/share/glvnd/egl_vendor.d/50_mesa.json RUN mkdir -p /usr/share/glvnd/egl_vendor.d/ && echo '\ {\ "file_format_version" : "1.0.0",\ "ICD" : {\ "library_path" : "libEGL_nvidia.so.0"\ }\ }' > /usr/share/glvnd/egl_vendor.d/10_nvidia.json RUN mkdir -p /usr/share/egl/egl_external_platform.d/ && echo '\ {\ "file_format_version" : "1.0.0",\ "ICD" : {\ "library_path" : "libnvidia-egl-wayland.so.1"\ }\ }' > /usr/share/egl/egl_external_platform.d/nvidia_wayland.json RUN echo "/usr/local/cuda-10.0/targets/aarch64-linux/lib" >> /etc/ld.so.conf.d/nvidia.conf ARG CUDA=invalid COPY ./dst/bin /usr/local/cuda-$CUDA/bin COPY ./dst/nvvm /usr/local/cuda-$CUDA/nvvm COPY ./dst/nvvmx /usr/local/cuda-$CUDA/nvvmx COPY ./dst/include /usr/local/cuda-$CUDA/targets/aarch64-linux/include COPY ./dst/lib64/stubs /usr/local/cuda-$CUDA/targets/aarch64-linux/lib/stubs COPY ./dst/lib64/libcudadevrt.a /usr/local/cuda-$CUDA/targets/aarch64-linux/lib/ COPY ./dst/lib64/libcudart_static.a /usr/local/cuda-$CUDA/targets/aarch64-linux/lib/ RUN ln -s /usr/local/cuda-$CUDA /usr/local/cuda && \ ln -s /usr/local/cuda-$CUDA/targets/aarch64-linux/include /usr/local/cuda/include && \ ln -s /usr/local/cuda-$CUDA/targets/aarch64-linux/lib /usr/local/cuda/lib64 ENV PATH /usr/local/cuda-$CUDA/bin:/usr/local/cuda/bin:${PATH} ENV LD_LIBRARY_PATH /usr/local/cuda-$CUDA/targets/aarch64-linux/lib:${LD_LIBRARY_PATH} RUN ldconfig ENV NVIDIA_VISIBLE_DEVICES all ENV NVIDIA_DRIVER_CAPABILITIES all CMD ["/bin/bash"]
ベースイメージを利用したROS2 Humbleイメージ (l4t-ros:humble-ros-core-r32.7)
また、L4Tベースイメージを利用して、任意のROSコンテナを作成するためのDockerfileのテンプレートも用意しました。
FROM l4t-base:jammy-r32.7 # setup timezone RUN echo 'Etc/UTC' > /etc/timezone && \ ln -s /usr/share/zoneinfo/Etc/UTC /etc/localtime && \ apt-get update && \ apt-get install -q -y --no-install-recommends tzdata && \ rm -rf /var/lib/apt/lists/* # install packages RUN apt-get update && apt-get install -q -y --no-install-recommends \ dirmngr \ gnupg2 \ && rm -rf /var/lib/apt/lists/* # setup sources.list RUN echo "deb http://packages.ros.org/ros2/ubuntu jammy main" > /etc/apt/sources.list.d/ros2-latest.list # setup keys RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 # setup environment ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 ENV ROS_DISTRO humble # install ros2 packages RUN apt-get update && apt-get install -y --no-install-recommends \ ros-humble-ros-core=0.10.0-1* \ && rm -rf /var/lib/apt/lists/* # setup entrypoint COPY ./ros_entrypoint.sh / ENTRYPOINT ["/ros_entrypoint.sh"] CMD ["bash"]
ご紹介したイメージは、コンテナ内でGPUを利用するためにNVIDIA Container Runtimeを使用しています。 このため、一部のdebパッケージ・ライブラリはNVIDIA Container Runtimeが想定しているソフトウェアのバージョンとの不整合によりうまく動作しない場合があります。 現時点で、以下のパッケージが正常に動作しないことを確認しております。(今後、こちらのパッケージも使用可能となるよう修正を加えていく予定です)
バージョン不整合により動作しないパッケージ(記事公開時点で確認済みのもの)
- GStreamer
- OpenCV
まとめ
今回は、ROSのDockerコンテナでのNVIDIA GPUの利用方法について解説しました。 NVIDIA は Machine Learning やAI用の公式イメージを提供していますが、このGPU利用の仕組みを理解することで、 まだ提供されていない機能を持つコンテナイメージを作成することもできる用になります。
また、当社によるDockerfileの提供開始についてもお知らせしました。 Ubuntuの公式リポジトリを通じてROSパッケージを追加することが可能になることで、皆様の開発効率向上の手助けになれば幸いです。
連載の次回は
- ROS 2を利用する上での大容量データ転送シナリオにおけるチューニングについての紹介
を予定しています。
当社プロダクトのご案内
先日行われた ROSConJP 2023 では、ROSの開発ワークフローを効率化するDXソリューションとして、新たなソリューションを発表いたしました。詳細については、ROSConJP 2023の参加報告記事をご覧ください。
また、ROS開発において、当社プロダクトをどの様にご活用いただけるかは、連載1日目にて当社のVPoPがより詳しく紹介しておりますので、こちらもご覧ください。
さらに、当社では、モビリティ・ロボットのフリート管理や遠隔監視、遠隔制御を実現するための管制制御システム向けのソリューションフレームワーク「intdash CONTROL CENTER」を提供しています。
スマートシティにおける自動運転車、工場や物流倉庫における搬送ロボット、建設現場における建設機械など、モビリティ群の統合遠隔監視・管理、遠隔制御システムな どでお困りのことがあれば、ぜひお声掛けください。
お問合せフォームは こちら です。