rospyでPyTorchを使うためのDocker環境構築方法をご紹介します。

【Docker】rospyでPyTorchを使う

PyTorchをrospyで使うのに苦労したため、その解決策をまとめます。

この記事では、Dockerを用いた環境構築をご紹介します。Dockerを使わずローカルで環境構築する方々もDockerfileの中身は参考になると思います。

何が問題か?

以下のようなPyTorch、ROSのバージョン対応・非対応が環境構築をややこしくしています。

  • PyTorch
    • ほとんどのバージョンがPython3
    • 最新バージョン(v1.6.0)ではCUDA11に非対応
  • ROS
    • Noeticより前のrospyのデフォルトがPython2
      • OpenCV(cv2)やcv_bridgeもPython2
    • NoeticはCUDA11

紹介する環境構築

この記事では、2種類の仮想環境構築をご紹介します。それぞれDocker(バージョン19.03以降)用、Nvidia Docker 1用、Nvidia Docker 2用の実装例を載せます。

  • ROS Kinetic on Ubuntu 16.04
    • Docker(バージョン19.03以降)の場合
    • Nvidia Docker 1の場合
    • Nvidia Docker 2の場合
  • ROS Noetic on Ubuntu 20.04
    • Docker(バージョン19.03以降)の場合
    • Nvidia Docker 1の場合
    • Nvidia Docker 2の場合

事前準備

Dockerコンテナ内でCUDAを利用するために、バージョン19.03以降のDocker、もしくはNvidia Dockerが必要です。

具体的には以下をインストールする必要があります。

  • Nvidia driver
  • Docker(バージョン19.03以降)
    or
    Docker+Nvidia Docker 1 or 2

※Docker19.03以降はNvidia dockerなしで、コンテナ内でCUDAを利用できます。

仮想環境:ROS Kinetic on Ubuntu 16.04

ROS KineticのデフォルトはPython2なので、対処すべき課題がたくさんあります。

Docker(バージョン19.03以降)の場合

Dockerfile

########## Pull ##########
FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04
########## BASIS ##########
RUN apt-get update && apt-get install -y \
	vim \
	wget \
	unzip \
	git \
	build-essential
########## ROS Kinetic insatall ##########
RUN apt-get update && \
	apt-get install -y \
		lsb-release && \
	sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' && \
	apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 && \
	apt-get update && \
	apt-get install -y \
		ros-kinetic-ros-base
########## ROS setup ##########
RUN mkdir -p /home/ros_catkin_ws/src && \
	cd /home/ros_catkin_ws/src && \
	/bin/bash -c "source /opt/ros/kinetic/setup.bash; catkin_init_workspace" && \
	cd /home/ros_catkin_ws && \
	/bin/bash -c "source /opt/ros/kinetic/setup.bash; catkin_make" && \
	echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc && \
	echo "source /home/ros_catkin_ws/devel/setup.bash" >> ~/.bashrc && \
	echo "export ROS_PACKAGE_PATH=\${ROS_PACKAGE_PATH}:/home/ros_catkin_ws" >> ~/.bashrc && \
	echo "export ROS_WORKSPACE=/home/ros_catkin_ws" >> ~/.bashrc
########## PyTorch & Python3 on rospy ##########
RUN apt-get update && \
	apt-get install -y \
		python3-pip && \
	pip3 install --upgrade pip && \
	pip3 install \
		torch==1.1.0 \
		torchvision==0.3.0 \
		rospkg \
		catkin_pkg
########## cv_bridge on Python3 ##########
RUN apt-get update && \
	apt-get install -y \
		python-catkin-tools \
		python3-dev \
		python3-catkin-pkg-modules \
		python3-numpy \
		python3-yaml \
		ros-kinetic-cv-bridge && \
	pip3 install \
		opencv-python && \
	mkdir -p /home/catkin_build_ws/src && \
	cd /home/catkin_build_ws && \
	catkin init && \
	catkin config -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.5m -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.5m.so && \
	catkin config --install && \
	cd /home/catkin_build_ws/src && \
	git clone https://github.com/ros-perception/vision_opencv.git && \
	cd vision_opencv && \
	git checkout 1.12.8 && \
	ln -s \
		/usr/lib/x86_64-linux-gnu/libboost_python-py35.so \
		/usr/lib/x86_64-linux-gnu/libboost_python3.so && \
	cd /home/catkin_build_ws && \
	/bin/bash -c "source /opt/ros/kinetic/setup.bash; catkin build cv_bridge" && \
	/bin/bash -c "source install/setup.bash --extend" && \
	echo "source /home/catkin_build_ws/install/setup.bash --extend" >> ~/.bashrc && \
	rm /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so

Build

$ docker build . -t pytorch_rospy_kinetic:docker

Run

$ docker run -it --rm --gpus all pytorch_rospy_kinetic:docker

Nvidia Docker 1の場合

Dockerfile

########## Pull ##########
FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04
########## nvidia-docker1 hooks ##########
LABEL com.nvidia.volumes.needed="nvidia_driver"
ENV PATH /usr/local/nvidia/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64:${LD_LIBRARY_PATH}
########## BASIS ##########
# ~ OMITTED ~ #
########## ROS Kinetic insatall ##########
# ~ OMITTED ~ #
########## ROS setup ##########
# ~ OMITTED ~ #
########## PyTorch & Python3 on rospy ##########
# ~ OMITTED ~ #
########## cv_bridge on Python3 ##########
# ~ OMITTED ~ #

「# ~ OMITTED ~ #」の部分は、Docker(バージョン19.03以降)の場合と同じなので、この節内では省略しました。

Build

$ docker build . -t pytorch_rospy_kinetic:nvidia_docker1

Run

$ nvidia-docker run -it --rm pytorch_rospy_kinetic:nvidia_docker1

Nvidia Docker 2の場合

Dockerfile

########## Pull ##########
FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04
########## nvidia-docker2 hooks ##########
ENV NVIDIA_VISIBLE_DEVICES ${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
########## BASIS ##########
# ~ OMITTED ~ #
########## ROS Kinetic insatall ##########
# ~ OMITTED ~ #
########## ROS setup ##########
# ~ OMITTED ~ #
########## PyTorch & Python3 on rospy ##########
# ~ OMITTED ~ #
########## cv_bridge on Python3 ##########
# ~ OMITTED ~ #

「# ~ OMITTED ~ #」の部分は、Docker(バージョン19.03以降)の場合と同じなので、この節内では省略しました。

Build

$ docker build . -t pytorch_rospy_kinetic:nvidia_docker2

Run

$ docker run -it --rm --runtime=nvidia pytorch_rospy_kinetic:nvidia_docker2

解説

ベースイメージ:nvidia/cuda

ベースイメージはnvidia/cudaから取得(pull)します。使用予定のPyTorchのバージョンに合ったCUDAのタグを選択します。

▶︎nvidia/cuda Supported tags

ROS Kineticのインストール

「ROS kinetic insatall」ブロックと「ROS setup」ブロックでROS Kineticのインストールを実装しています。

インストールの詳細はROS Wikiで確認できます。

▶︎ROS Wiki:ROS Kinetic の Ubuntu へのインストール

PyTorchのインストール

ベースイメージで指定したCUDAに対応するバージョンのPyTorchをインストールします。

pip3 install \
	torch==1.1.0 \
	torchvision==0.3.0

▶︎PyTorch公式

rospy on Python3

ROS KineticのrospyはPython2がデフォルトなので、Python3でimportできるようにpip3でインストールします。

pip3 install \
	rospkg \
	catkin_pkg

cv_bridge on Python3

OpenCV(cv2)やcv_bridgeをPython3で使うために、ソースコードからビルドする必要があります。

詳細は以下のページが参考になると思います。

▶︎How to setup ROS with Python 3
▶︎ERROR: Cv_bridge for Python3

以下のBoostのエラーを回避するためにリンクを設定します。

Unable to find the requested Boost libraries.
ln -s \
	/usr/lib/x86_64-linux-gnu/libboost_python-py35.so \
	/usr/lib/x86_64-linux-gnu/libboost_python3.so

また、cv2をimportすると、Python2用のcv2が呼ばれてエラーが出るので、以下のように削除します。

$ python3
>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: PyCObject_Type
rm /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so

仮想環境:ROS Noetic on Ubuntu 20.04

ROS NoeticのデフォルトはもともとPython3なので、煩わしい問題は少ないです。

Docker(バージョン19.03以降)の場合

Dockerfile

########## Pull ##########
FROM vistart/cuda:10.0-cudnn7-devel-ubuntu20.04
########## non-interactive ##########
## Avoiding "Country of origin for the keyboard" 
## in "apt-get install -y ros-noetic-desktop-full"
ENV DEBIAN_FRONTEND=noninteractive
########## time zone ##########
##### UTC #####
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/*
########## BASIS ##########
RUN apt-get update && apt-get install -y \
	vim \
	wget \
	unzip \
	git \
	build-essential
########## ROS Noetic insatall ##########
RUN apt-get update && apt-get install -y lsb-release &&\
	sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' &&\
	apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 &&\
	apt-get update && apt-get install -y ros-noetic-desktop-full
########## ROS setup ##########
RUN mkdir -p /home/ros_catkin_ws/src && \
	cd /home/ros_catkin_ws/src && \
	/bin/bash -c "source /opt/ros/noetic/setup.bash; catkin_init_workspace" && \
	cd /home/ros_catkin_ws && \
	/bin/bash -c "source /opt/ros/noetic/setup.bash; catkin_make" && \
	echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc && \
	echo "source /home/ros_catkin_ws/devel/setup.bash" >> ~/.bashrc && \
	echo "export ROS_PACKAGE_PATH=\${ROS_PACKAGE_PATH}:/home/ros_catkin_ws" >> ~/.bashrc && \
	echo "export ROS_WORKSPACE=/home/ros_catkin_ws" >> ~/.bashrc
########## PyTorch ##########
RUN apt-get update && \
	apt-get install -y \
		python3-pip && \
	pip3 install \
		torch==1.5.0 \
		torchvision==0.6.0

Build

$ docker build . -t pytorch_rospy_noetic:docker

Run

$ docker run -it --rm --gpus all pytorch_rospy_noetic:docker

Nvidia Docker 1の場合

Dockerfile

########## Pull ##########
FROM vistart/cuda:10.0-cudnn7-devel-ubuntu20.04
########## nvidia-docker1 hooks ##########
LABEL com.nvidia.volumes.needed="nvidia_driver"
ENV PATH /usr/local/nvidia/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64:${LD_LIBRARY_PATH}
########## non-interactive ##########
# ~ OMITTED ~ #
########## time zone ##########
##### UTC #####
# ~ OMITTED ~ #
########## BASIS ##########
# ~ OMITTED ~ #
########## ROS Noetic insatall ##########
# ~ OMITTED ~ #
########## ROS setup ##########
# ~ OMITTED ~ #
########## PyTorch ##########
# ~ OMITTED ~ #

「# ~ OMITTED ~ #」の部分は、Docker(バージョン19.03以降)の場合と同じなので、この節内では省略しました。

Build

$ docker build . -t pytorch_rospy_noetic:nvidia_docker1

Run

$ nvidia-docker run -it --rm pytorch_rospy_noetic:nvidia_docker1

Nvidia Docker 2の場合

Dockerfile

########## Pull ##########
FROM vistart/cuda:10.0-cudnn7-devel-ubuntu20.04
########## nvidia-docker2 hooks ##########
ENV NVIDIA_VISIBLE_DEVICES ${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
########## non-interactive ##########
# ~ OMITTED ~ #
########## time zone ##########
##### UTC #####
# ~ OMITTED ~ #
########## BASIS ##########
# ~ OMITTED ~ #
########## ROS Noetic insatall ##########
# ~ OMITTED ~ #
########## ROS setup ##########
# ~ OMITTED ~ #
########## PyTorch ##########
# ~ OMITTED ~ #

「# ~ OMITTED ~ #」の部分は、Docker(バージョン19.03以降)の場合と同じなので、この節内では省略しました。

Build

$ docker build . -t pytorch_rospy_noetic:nvidia_docker2

Run

$ docker run -it --rm --runtime=nvidia pytorch_rospy_noetic:nvidia_docker2

解説

ベースイメージ:vistart/cuda

ベースイメージはvistart/cudaから取得(pull)します。使用予定のPyTorchのバージョンに合ったCUDAのタグを選択します。

vistart/cudaは、Tsinghua Universityが提供しているイメージだそうです。PyTorch1.6.0時点ではCUDA11に対応していないので、このようなCUDA10以下のUbuntu20.04イメージが役立ちます。

vistart/cuda

PyTorchがCUDA11に対応したら「nvidia/cuda:11.0-devel-ubuntu20.04」などを使えば良いでしょう。

ROS Noeticのインストール

「ROS Noetic insatall」ブロックと「ROS setup」ブロックでROS Noeticのインストールを実装しています。

インストールの詳細はROS Wikiで確認できます。

▶︎ROS Wiki:Ubuntu install of ROS Noetic

PyTorchのインストール

ベースイメージで指定したCUDAに対応するバージョンのPyTorchをインストールします。

pip3 install \
	torch==1.5.0 \
	torchvision==0.6.0

▶︎PyTorch公式

テスト

以下を試してエラーが出なけれOKです。

$ (イメージのbuild)
$ (コンテナのrun)
$ python3
>> import rospy
>> import cv_bridge
>> import cv2
>> import torch
>> print(torch.cuda.is_available())

補足

  • PyTorchがCUDA11に対応したら迷わずROS Noeticの仮想環境が良いでしょう。

さいごに

rospyでPyTorchを使うための環境構築をご紹介しました。参考になれば幸いです。


以上です。

Ad.