実現したいこと
Ubuntu22.04 のOSにNVIDIA ドライバをインストールし、
GPUコンテナの動作確認を行いたい。
LLMの fine-tuning やら GPUを活用したコンテナを準備する機会が増えたので、ネット上になかなかまとまっていないGPUコンテナの作成手順を整理して高速で環境準備できるようにしたい。
前提として、AWS上でEC2 インスタンスを利用して動作検証を進める。
作業ステップ
- step1. EC2インスタンスの作成
- step2. Ubuntu22.04 の初期設定
- step3. Ubuntu22.04 でドライバの確認を行う
- step4. Ubuntu22.04 でドライバのインストールを行う
- step5. GPUの動作確認
- step6. GPUコンテナのサンプル
EC2 インスタンスタイプの注意
https://aws.amazon.com/jp/ec2/instance-types/g4/
-
g4ad.xlarge NG
ubuntu@ip-192-168-2-76:~$ sudo lspci | grep NVIDIA
NVIDIA driver が認識しない -
g4dn.xlarge OK
ubuntu@ip-192-168-2-76:~$ sudo lspci | grep NVIDIA
00:1e.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)
G4シリーズでも、g4adは NVIDIAドライバがなく、g4dnはNVIDIAドライバが認識する。間違いやすいので注意。
費用見積もり
g4dn.xlarge インスタンスは 1h 0.626$
https://aws.amazon.com/jp/ec2/instance-types/g4/
1$=147円換算(2023/09/16現在)で
1h 0.626$ → 1h 92.022円 → 1day(24h) 2208円 → 1month(30days) 66,255円
もし一日 6時間、週5日使うとしたら
92.022 * 6h * 5 days * 4 weeks = 11,042.64円/月
step1. EC2インスタンスの作成
必要なら vCPU 制限緩和申請を行う。
デフォルトでは利用可能な インスタンスタイプの利用可能な vCPUが0の場合もあるので。
https://repost.aws/ja/knowledge-center/ec2-on-demand-instance-vcpu-increase
EC2→制限→制限計算ツールのインスタンスタイプを入力。
現在の制限が4未満だった場合、g5/g4シリーズのインスタンスを立ち上げることができません。
画像右下の「オンデマンド制限の引き上げをリクエスト」からvCPU引き上げをリクエストしてください。
次に実際にインスタンスの作成をしていきます。
- OS選択:Ubuntu22.04
- インスタンスタイプの選択:g4dn.xlarge
- キーペア:必要なら選択、作成する
- セキュリティグループ:セキュリティグループの設定で作成したもの
- ボリューム:最低でも30GBはほしいので、ここでは 50GB指定
- インスタンスプロファイル:EC2用の IAMロールを作成して設定
基本的な動作確認をするのが目的なので、インスタンスタイプは最小(g4dn.xlarge)で確認してます。GPUコンテナの基本的な動作が確認できたら、後ほど必要なインスタンスタイプに切り替えます。
step2. Ubuntu22.04 の初期設定
Ubuntu22.04 に対して、docker/docker compose を使える設定を行います。
https://github.com/docker/compose/releases/
で最新の docker compose のバージョンを確認する。
2023/09/14現在は 2.21.0
なので以下のスクリプトを作成して、
$ bash setup-ubuntu22.sh
を実行する。
setup-ubuntu22.sh
#!/bin/bash
sudo apt update
sudo apt-get install -y build-essential
# gccインストールの確認
gcc --version
sudo apt-get install -y git
sudo apt-get install -y docker.io
## netstat コマンドを入れる。portチェック等で利用
sudo apt-get install -y net-tools
## ubuntu-drivers コマンドを入れる。ドライバ確認で利用
sudo apt-get install -y ubuntu-drivers-common alsa-base
sudo service docker start
# docker バージョンの確認
docker --version
sudo mkdir -p /usr/local/lib/docker/cli-plugins
# 環境変数 VERにDocker Composeのバージョンを入れる
VER=2.21.0
sudo curl \
-L https://github.com/docker/compose/releases/download/v${VER}/docker-compose-$(uname -s)-$(uname -m) \
-o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
sudo ln -s /usr/local/lib/docker/cli-plugins/docker-compose /usr/bin/docker-compose
# docker compose バージョンの確認
docker-compose --version
step3. Ubuntu22.04 でドライバの確認を行う
VGA が NVIDIA のものであるか確認します。
$ lspci | grep NVIDIA
その他のマシンの状況確認
CPUを確認する
$ cat /proc/cpuinfo
CPU のコア数をチェックする
$ cat /proc/cpuinfo | grep processor | wc -l
MEMORYを確認する
$ cat /proc/meminfo
$ free -h でも OK
推奨のドライバを確認します。
$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:1e.0 ==
modalias : pci:v000010DEd00001EB8sv000010DEsd000012A2bc03sc02i00
vendor : NVIDIA Corporation
model : TU104GL [Tesla T4]
manual_install: True
driver : nvidia-driver-525-server - distro non-free
driver : nvidia-driver-535 - distro non-free recommended
driver : nvidia-driver-535-server - distro non-free
driver : nvidia-driver-525 - distro non-free
driver : nvidia-driver-418-server - distro non-free
driver : nvidia-driver-450-server - distro non-free
driver : nvidia-driver-470 - distro non-free
driver : nvidia-driver-470-server - distro non-free
driver : xserver-xorg-video-nouveau - distro free builtin
ドライバ確認時にエラーが表示される場合
ubuntu-drivers コマンドは ubuntu-drivers-common を入れると認識します。
alsa-base を追加すると、ubuntu-drivers実行に
「aplay command not found」のエラーは消えます。
したがって、以下のコマンドでライブラリをインストールします。
setup-ubuntu22.sh に記載しています。
sudo apt-get install -y ubuntu-drivers-common alsa-base
ライブラリ alsa-base をインストールしていない場合のアラート表示
$ ubuntu-drivers devices
ERROR:root:aplay command not found
== /sys/devices/pci0000:00/0000:00:1e.0 ==
modalias : pci:v000010DEd00001EB8sv000010DEsd000012A2bc03sc02i00
vendor : NVIDIA Corporation
model : TU104GL [Tesla T4]
manual_install: True
driver : nvidia-driver-525-server - distro non-free
…
「ubuntu-drivers devices」実行結果の model 行を確認すると
TU104GL [Tesla T4]のように NVIDIA デバイスのプロダクトタイプ、シリーズが分かります。
https://www.nvidia.com/Download/index.aspx?lang=en-us
にアクセスして、上記で調べた内容を選択すると、Nvidia Driver の正確な
バージョンを把握できます。
Product Type/Product Series/Product/OS/CUDA Toolkitを選択して「Search」ボタンを押下すると、以下のような表示になる。
ここでは、バージョンは 535.104.05 であると確認できます。
step4. Ubuntu22.04 でドライバのインストールを行う
4-1. NVIDIA ドライバのインストール
https://www.nvidia.com/Download/index.aspx?lang=en-us
で確認したドライババージョンを DRIVER_VERSION 変数に設定し、以下の
スクリプトを準備、NVIDIA ドライバのインストールを行います。
$ bash nvidia-driver-install.sh
nvidia-driver-install.sh
#!/bin/bash
BASE_URL=https://us.download.nvidia.com/tesla
# 確認したバージョンを指定
DRIVER_VERSION=535.104.05
curl -fSsl -O ${BASE_URL}/${DRIVER_VERSION}/NVIDIA-Linux-x86_64-${DRIVER_VERSION}.run
sudo bash NVIDIA-Linux-x86_64-${DRIVER_VERSION}.run
32bit互換のライブラリをインストールするかを問われますが、Noを選択。
これでインストールは完了。
4-2. nvidia-container-toolkit のインストール
Docker上でもGPUを認識させるためにnvidia-container-toolkitも入れます。
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
bash nvidia-controller-toolkit-install.sh
nvidia-controller-toolkit-install.sh
#!/bin/bash
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& 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/$distribution/libnvidia-container.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 update
sudo apt-get install -y nvidia-docker2
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
sudo apt-get install -y nvidia-cuda-toolkit
# GPU認識確認
nvidia-smi
インストールが終わると、OSの再起動を実施します。ついでにライブラリの更新も実行。
$ sudo reboot
$ sudo apt-get dist-upgrade -y
step5. GPUの動作確認
5.1 ドライバとCUDAの確認
コンテナ上でドライバが認識されているか確認します。
$ nvidia-smi
Wed Sep 13 09:33:11 2023
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.104.05 Driver Version: 535.104.05 CUDA Version: 12.2 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 Tesla T4 Off | 00000000:00:1E.0 Off | 0 |
| N/A 42C P0 26W / 70W | 2MiB / 15360MiB | 5% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| No running processes found |
+---------------------------------------------------------------------------------------+
CUDAの確認を行います。
$ nvcc -V
5.2 コンテナの動作確認
Ubuntu22.04 でドライバの認識、CUDAの動作確認が終わったら、
以下のコマンドを実行して、Docker内でGPUを動かせるかどうかを確認します。
「--gpus all」を付与し忘れないように注意。
$ bash gpu-run-test.sh
gpu-run-test.sh
docker run --rm --gpus all \
nvcr.io/nvidia/cuda:11.8.0-cudnn8-devel-ubuntu22.04 \
bash -c "nvidia-smi; nvcc -V"
ここで、ホストOS同様にコンテナの中でも NVIDIAドライバが認識され、CUDAも認識できて入ればOKです。
ここではベースのコンテナとして以下を利用しています。
nvidia/cuda:11.8.0-cudnn8-devel-ubuntu22.04
https://hub.docker.com/layers/nvidia/cuda/11.8.0-cudnn8-devel-ubuntu22.04/images/sha256-5079d0d0f36cc63050a0f5c010d769c68b8e959c2d2a45f8ec44dd7e5c1bf7f9?context=explore
step6. GPUコンテナのサンプル
Docker内でGPUを動かせるようになったら、次はGPUコンテナをプロジェクトで
利用するための Dockerfile/docker-compose の設定を作成してみます。
ここでは、Pythonでいくつかライブラリを入れたGPUコンテナを準備してみます。
6.1 Dockerfile の準備
ファイル構成
+ Dockerfile
+ requirements.txt
requirements.txt
pandas==2.1.0
numpy
matplotlib
scikit-learn
Dockerfile
# Ubuntu22.04 + CUDA11.8 のGPUコンテナ
FROM nvidia/cuda:11.8.0-cudnn8-devel-ubuntu22.04
LABEL maintainer="mshinoda"
RUN apt-get update && apt-get dist-upgrade -y
RUN apt-get -y install apt-utils
RUN apt-get -y install locales && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV TZ=Asia/Tokyo
ENV DEBIAN_FRONTEND=noninteractive
ENV PROJECT_ROOTDIR /var/batch/
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get install -y apt-file software-properties-common
# coreutils for cat /meld for diff
RUN apt-get install -y coreutils vim less nkf jq zip unzip wget meld sudo git curl telnet locate
RUN apt-get install -y python3-ldb-dev gcc libffi-dev libcurl4-openssl-dev
RUN apt-get install -y tmux
# for pip install
RUN apt-get install -y python3-distutils python3-testresources
RUN apt-get install -y python3-pip
# add sudo user
RUN groupadd -g 1100 developer && \
useradd -g developer -G sudo -m -s /bin/bash operator && \
echo 'operator:operatorpass' | chpasswd
RUN echo 'Defaults visiblepw' >> /etc/sudoers
RUN echo 'operator ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER operator
RUN sudo mkdir -p ${PROJECT_ROOTDIR} && sudo chmod 777 -R ${PROJECT_ROOTDIR}
WORKDIR /var/batch
RUN echo 'alias ll="ls -al"' >> /home/operator/.bashrc
RUN echo 'export PATH=${PATH}:/home/operator/.local/bin' >> /home/operator/.bashrc
RUN export PATH=${PATH}:/home/operator/.local/bin
ENV DIR_PIP /home/operator/.local/bin
# install application materials
USER root
COPY requirements.txt ${PROJECT_ROOTDIR}/requirements.txt
RUN pip3 install --upgrade pip
RUN pip3 install --trusted-host pypi.python.org --no-cache-dir -r ${PROJECT_ROOTDIR}/requirements.txt
ビルド実行
$ docker build -t container01 .
起動確認
$ export image_id=`docker images|grep ^container01| sed -e 's/ */ /g'|cut -d" " -f3`
$ docker run --gpus all --name container01 -itd ${image_id}
コンテナの中に入る
$ export container_id=`docker ps -a |grep -v CONTAINER |grep "container01"|cut -d" " -f1`
$ docker exec -it ${container_id} bash
コンテナの中で改めてドライバが認識されているか確認します。
# ドライバ確認
(container01)$ nvidia-smi
# CUDAの確認
(container01)$ nvcc -V
6.2 docker compose でGPUアクセス
GPUコンテナを実現するDockerfileが準備できたら、docker composeでその制御についても整理しておきます。
赤字の部分の設定を追加して、GPUアクセスの設定を行います。
services:
test:
image: tensorflow/tensorflow:latest-gpu
command: python -c "import tensorflow as tf;tf.test.gpu_device_name()"
deploy:
resources:
reservations:
devices:
- capabilities: [gpu]
詳細はこちら。
docker compose でGPUアクセス
https://docs.docker.jp/compose/gpu-support.html
以下は steamlit を使った GPUコンテナと mysql コンテナを内部ネットワークで接続させる場合の docker-compose.yml ファイル例
version: "3.8"
services:
# Web Application(streamlit)
web:
restart: always
build:
context: web
dockerfile: Dockerfile
container_name: streamlit
env_file:
- ./env-file/stg.env
working_dir: /usr/src/app
tty: true
volumes:
- ./web/app:/usr/src/app
ports:
- 80:8501
networks:
shared-nw:
deploy:
resources:
reservations:
devices:
- capabilities: [gpu]
command: streamlit run main.py --server.port 8501
# mysql
mysqldb:
image: mysql:8.0
container_name: mysql_container
env_file:
- ./env-file/stg.env
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- ./mysql/sql:/docker-entrypoint-initdb.d
ports:
- 3306:3306
networks:
shared-nw:
networks:
shared-nw:
driver: bridge
env-file/stg.env
# for mysql
MYSQL_DATABASE=db01
MYSQL_ROOT_PASSWORD=passw0rd
MYSQL_USER=db_user
MYSQL_PASSWORD=passw0rd
TZ=Asia/Tokyo
これでGPUコンテナを高速で準備できるようになります。
参考文献
AWS EC2 G4インスタンス
https://aws.amazon.com/jp/ec2/instance-types/g4/
vCPU 制限緩和申請
https://repost.aws/ja/knowledge-center/ec2-on-demand-instance-vcpu-increase
docker compose
https://github.com/docker/compose/releases/
Nvidia Driver の正確なバージョンを確認
https://www.nvidia.com/Download/index.aspx?lang=en-us
nvidia-container-toolkit
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
AWS EC2 GPUインスタンスでStable Diffusionを使う
https://qiita.com/nijigen_plot/items/27f8e987dda6aea5836d
nvidia/cuda:11.8.0-devel-ubuntu22.04
https://hub.docker.com/layers/nvidia/cuda/11.8.0-devel-ubuntu22.04/images/sha256-2ce1115b4dcc0c7ca6454695fbb959b08d3ac5be4dcc2b8c99df1e225223d326?context=explore
nvidia/cuda:12.2.0-devel-ubuntu22.04
https://hub.docker.com/layers/nvidia/cuda/12.2.0-devel-ubuntu22.04/images/sha256-6950bd04caba9bf0fa75f8242ece9d34550685bfaa4b42d9ac341acbac7d6608?context=explore
nvidia/cuda:11.8.0-cudnn8-devel-ubuntu22.04
https://hub.docker.com/layers/nvidia/cuda/11.8.0-cudnn8-devel-ubuntu22.04/images/sha256-5079d0d0f36cc63050a0f5c010d769c68b8e959c2d2a45f8ec44dd7e5c1bf7f9?context=explore