Podmanで物体検出モデルyoloxの動作環境のコンテナを作成、コンテナをイメージファイルに変換

# 1.はじめに
　本記事では、Podmanで[物体検出モデルyolox](https://github.com/Megvii-BaseDetection/YOLOX)動作環境のコンテナを作成して、コンテナをイメージファイルにして、更にそのファイルをtarファイルの方法を記述します。
　PodmanとはRedHat社が開発したコンテナ管理ツールです。PodmanのコマンドはDockerと互換性があります、詳しくは以下の記事などに詳しく記載されているので、そちらを参照してください。
* [DockerとPodman/Skopeo/Buildahは何が違うのか？](https://qiita.com/caunu-s/items/4fa0e0465ea83fcc06e4)
* [Podman](https://www.tohoho-web.com/docker/podman.html)

構築環境としては、WSLとUbuntu 22.04.1 LTSでWindows11にUbuntu環境を用意し、そのUbuntu上で構築しました。
以下、Ubuntuでのコマンドは@Ubuntu、コンテナでのコマンドは@containerと上部に記載します。

# 2. Podmanでコンテナ作成
podman pullで[コンテナイメージ（debian）](https://hub.docker.com/_/debian)を取得します。
podman runでコンテナイメージ（debian）をもとに新しいコンテナでプロセスを実行します。
```shell
# @Ubuntu
$ podman pull docker.io/debian
$ podman images
#output
"""
REPOSITORY                TAG         IMAGE ID      CREATED     SIZE
docker.io/library/debian  latest      07d9246c53a6  4 days ago  129 MB
"""

podman run -it --name=yolox docker.io/debian
```
一旦ここでコンテナから抜けます。
```shell
# @container
exit
```

# 3.コンテナに接続
コンテナ内でコマンドを実行してyoloxの環境を構築するために、podman exec を使ってコンテナに接続します。
```shell
#@Ubuntu
podman ps -a
#output
"""
CONTAINER ID  IMAGE                            COMMAND     CREATED      STATUS      PORTS       NAMES
293284215a81  docker.io/library/debian:latest  bash        8 hours ago  Created                 yolox
"""

podman start yolox
podman exec -it yolox /bin/sh
```
接続後、コンテナ内の環境を確認
```shell
#@container
cat /etc/os-release

#output
"""
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
"""

uname -a

#output
"""
Linux 293284215a81 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 GNU/Linux
"""
```

# 4.yoloxの動作環境を構築
## 4.1 パッケージインストール
パッケージ管理コマンドaptで必要なパッケージをインストール
```shell
#@container
apt update
apt upgrade
apt install build-essential libbz2-dev libffi-dev libssl-dev zlib1g-dev git wget pip
apt-get install protobuf-compiler
```

## 4.2 Cmakeのインストール
今回、[cmakeの公式ページ](https://cmake.org/download/)の[レポジトリ](https://github.com/Kitware/CMake/releases?page=11)からcmake-3.15.2をインストール
```shell
#@container
cd home
wget https://github.com/Kitware/CMake/releases/download/v3.15.2/cmake-3.15.2.tar.gz
tar -zxvf cmake-3.15.2.tar.gz
cd cmake-3.15.2
./bootstrap
make
make install
```
cmakeのバージョンを確認
```shell
#@container
cmake --version

#output
"""
cmake version 3.15.2
CMake suite maintained and supported by Kitware (kitware.com/cmake).
"""
```

## 4.3 yoloxの動作環境の構築
まず、Pythonのバージョン確認
```shell
#@container
python3 -V

#output
"""
Python 3.9.2
"""
```

yoloxのソースを[リポジトリ](https://github.com/Megvii-BaseDetection/YOLOX)から取得して、pipでライブラリをインストールする。
```shell
#@container
cd ..
git clone https://github.com/Megvii-BaseDetection/YOLOX
cd YOLOX
pip install -U pip
pip install -r requirements.txt
pip install -v -e.
```

# 5.yoloxのデモを動作
yoloxにあるデモコードを実行して、動作を確認する。
## 5.1 yoloxで用いるモデルのダウンロード
本記事では、yoloxの中で最も軽量なモデル[yolox-nano](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano.pth)を用いて動作確認する。以下のコマンドでYOLOXのmodelフォルダ内にyolox_nano.pthをダウンロードする。
```shell
#@container
mkdir model
cd model
wget https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano.pth
```

## 5.2 デモの実行
[リポジトリのREADME](https://github.com/Megvii-BaseDetection/YOLOX)にある通りにデモを実施します。実施後、正常に終了すればYOLOX_outputsフォルダに結果が出力されています。
```shell
#@container
cd ..
python3 tools/demo.py image -n yolox-nano -c model/yolox_nano.pth --path assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device cpu
```

## 5.3 PyTorch モデルを ONNX モデル形式に変換
[リポジトリのONNXRuntimeのREADME](https://github.com/Megvii-BaseDetection/YOLOX/tree/main/demo/ONNXRuntime)にある通り、PyTorchモデルを ONNX モデル形式に変換します。
```shell
#@container
python3 tools/export_onnx.py --output-name yolox_nano.onnx -n yolox-nano -c model/yolox_nano.pth
```

## 5.4 ONNX形式のモデルでデモを実行
yolox_nano.onnxをmodelフォルダに移動させて、[リポジトリのONNXRuntimeのREADME](https://github.com/Megvii-BaseDetection/YOLOX/tree/main/demo/ONNXRuntime)にある通り、デモを実行します。実行後、正常に終了していれば以下のコマンドで指定したoutputs フォルダに画像が出力されます。
```shell
#@container
mv yolox_nano.onnx model
python3 demo/ONNXRuntime/onnx_inference.py -m model/yolox_nano.onnx -i assets/dog.jpg -o outputs -s 0.3 --input_shape 416,416
```

# 6. 実行中コンテナからイメージファイルの生成とtarファイルへの変換
## 6.1 実行中コンテナからイメージファイルの生成
実行中のコンテナIDをpodman psで確認します。CONTAINER IDは293284215a81ですね。
```shell
#@ubuntu
podman ps

#output
"""
CONTAINER ID  IMAGE                            COMMAND     CREATED      STATUS             PORTS       NAMES
293284215a81  docker.io/library/debian:latest  bash        9 hours ago  Up 34 minutes ago              yolox
"""
```
以下のコマンドで、実行中のコンテナをイメージファイルにします。
podman commit [CONTAINER ID] イメージ名

```shell
#@Ubuntu
podman commit 293284215a81 yolox_demo

#output
"""
Getting image source signatures
Copying blob 9c742cd6c7a5 skipped: already exists
Copying blob e54f37d0afcf done
Copying config 65dd28fca8 done
Writing manifest to image destination
Storing signatures
65dd28fca85a11445458cd8fb32ae2bda0eb64530be56721eb437ab1569b63f2
"""
```
podman imagesでイメージファイルを確認すると以下になります。REPOSITORYにlocalhost/yolox_demoが追加されているのがわかります。
```shell
#@Ubuntu
podman images

#output
"""
REPOSITORY                TAG         IMAGE ID      CREATED        SIZE
localhost/yolox_demo      latest      65dd28fca85a  6 minutes ago  4.41 GB
docker.io/library/debian  latest      07d9246c53a6  4 days ago     129 MB
"""
```
## 6.2 イメージファイルからtarファイルの生成
最後に作成したイメージファイルをtarファイルにします。このtarファイルを他のPCなどに転送して使用することができます。
```shell
#@Ubuntu
podman save localhost/yolox_demo >yolox_demo.tar
```
終了後、lsコマンドで確認すると、yolox_demo.tarが作成されていると思います。

# 7. おわりに
　本記事では、Podmanで[物体検出モデルyolox](https://github.com/Megvii-BaseDetection/YOLOX)動作環境のコンテナ（debian）を作成して、コンテナをイメージファイルにして、更にそのファイルをtarファイルの方法を記述しました。エンジニア歴2か月で不備・不足もあるかと思いますが、ご指摘いただければ幸いです。また、類似の動作を確認する方の参考になれば幸いです。