WandBとさくらインターネットの高火力DOKを組み合わせて使ってみた

## はじめに
株式会社晴工雨読の片山と申します。晴工雨読の概要はこちらからご覧ください。

https://seikoudoku.co.jp/

Techブログ第2弾は、Weights & Biases (W&B)とさくらインターネットの高火力DOKを組み合わせて、機械学習を効率的に実行する方法を解説していきます。まずそれぞれのツールの概要を、その後実際の手順をハンズオン形式で述べていきます。

## WandB(Weights & Biases)とは
正式名称をWeights & Biases、よくWandBと書いて「ワンドビー」とよばれているのを見聞きします。WandBは、機械学習の実験管理や可視化、モデルの管理をサポートするツール(ライブラリ)です。個人利用や小規模プロジェクトであれば、無料で利用できます。

今回は公式ドキュメントから、Kerasを利用した機械学習を例に進めていきます。WandBの基本的な使い方も知ることができますので、ぜひご一読ください。Colab Notebookも用意されています。

https://docs.wandb.ai/ja/tutorials/keras

## さくらインターネットの高火力DOK(ドック)とは
高火力DOKは、さくらインターネットが提供するコンテナサービスです。高性能GPUが従量課金制かつ比較的低価格で利用できる点が特徴のようです。今回はこのサービスを利用していきます。

https://www.sakura.ad.jp/koukaryoku-dok/

## 実行手順
### 1. Dockerイメージを作成
任意のディレクトリの中に4つのファイルを配置し、Dockerコマンドを利用して実行確認します。今回はprojectディレクトリと命名したディレクトリにファイルを配置しました。まずは、それぞれのファイルの内容を解説していきます。

```text:directory
project
├─ Dockerfile
├─ requirements.txt
├─ tutorial.py
└─ .env
```

今回は、DockerイメージをDockerfileで作成することにしました。ここはファイル内のコメントに解説を記しています。

```Dockerfile:Dockerfile
# ベースイメージとしてPython 3.9を使用
FROM python:3.9-slim

# 作業ディレクトリを作成
WORKDIR /app

# requirements.txtとローカルのPythonファイルをコンテナ内にコピー
COPY ./requirements.txt /app/
COPY ./tutorial.py /app/

# 必要なパッケージをインストール
RUN pip install --no-cache-dir -r requirements.txt

# デフォルトの実行コマンド
CMD ["python", "tutorial.py"]
```

コンテナに作成されるPython環境の中に、必要なパッケージ(ライブラリ)を入れていくための環境情報ファイルを作成します。今回はWandBとKerasを利用するのに必要なパッケージをインストールします。

```text:requirements.txt
wandb==0.15.5
tensorflow==2.12.0
tensorflow_datasets==4.8.2
```

実行するPythonファイルは、公式ドキュメントにあるColab Notebookをダウンロードして編集したものを利用します。手順は次のとおりです。

1. 公式ドキュメントのColab Notebook(ipynbファイル)をPythonファイルとしてダウンロード
1. ダウンロード時のファイル名が`use_wandbmetriclogger_in_your_keras_workflow.py`と長いので`tutorial.py`と変更
1. コードの中で`!pip install -qq -U wandb`はColab Notebookで使用する部分なのでコメントアウト

最後に環境変数ファイルです。ここには、WandBで取得したAPIキーを記載します。（GitHub等、一般に公開しないようご注意ください。）

```text:.env
WANDB_API_KEY=<ここにAPIキーを記載>
```

### 2. ローカル環境にて実行確認
ファイルを配置したディレクトリに入り、Dockerコマンドを利用して実行確認します。1行目でイメージを作成し、それを利用して2行目でコンテナを起動します。

```bash:bash
$ docker build -t myapp:latest . 
$ docker run --env-file .env myapp
```

WandBの画面を見てみましょう。「My Projects」から正常に実行できているのが確認できます。ここでは最終結果を載せていますが、実際は1エポックごとに結果がリアルタイムで更新されていきます。

![process.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900397/fde78346-c942-921a-9ef7-eb03fbd3fa64.png "進捗画面(例)")

### 3. Docker Hubへイメージをアップロード
ローカルでの実行確認が完了したので、Docker Hubへイメージをアップロードして高火力DOKで実行する準備をしていきます。

ローカル環境にて実行確認した時と同じ階層で、まずDocker(Docker Hub)にログイン後、イメージをビルドし、タグづけ、そしてプッシュを行います。`yourusername`にはユーザ名を、`yourimagename`には任意のイメージ名を入れてください。

```bash:bash
$ docker login
$ docker buildx create --use
$ docker buildx build --platform linux/amd64,linux/arm64 -t yourusername/yourimagename:latest --push .
```

`docker buildx`コマンドについて補足ですが、今回はマルチプラットフォームイメージというものを作成しています。これは私のデバイスがMacbookであることから、そのほかの環境でも正常に起動するためです。詳細な内容は参考文献からご確認ください。

ここまでの工程を経て作成したイメージは一般公開していますので、これまでの手順を踏まずに次の手順から試すことも可能です。

https://hub.docker.com/repository/docker/shikettahinachan/wandb-dok-blog/general

### 4. 高火力DOKでDockerイメージを実行
ではいよいよ、高火力DOKでDockerイメージを実行していきます。

ログイン後、「タスク」タブ(赤枠①)から「新規作成」を選択し、イメージ(赤枠②)に前の手順でアップロードしたイメージのイメージ名とタグを、環境変数(赤枠③)にはローカル環境で.envファイルに記載していたWandBのAPIキーを、それぞれ入れます。

![input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900397/dcfa3799-c84a-375c-920d-df4a97cc3ce0.png "入力画面")

今回は、先ほどのイメージを利用するので、このような内容になります。環境変数は半角英数字のものが入ります。「作成」を押すと、実行が開始されます。このとき、ローカル環境で実行確認したWandBの画面を確認すると、同様な結果を見ることができます。

![input_ex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900397/099ad67b-4c9b-030d-91a1-794bbc69df93.png "入力画面(例)")

実行が完了すると、タスクの「詳細」から、実行ログを確認することができます。

![output_ex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900397/5006d064-230a-a2a7-9721-36e131462830.png "出力画面(例)")

さらに、WandBのダッシュボードからログファイルをダウンロードすることが可能です。高火力DOKのタスクの「詳細」内にある「アーティファクト」からファイルを出力させることも可能ですが、ここでは割愛します。

![log_ex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900397/081dfe96-9760-43af-e31f-5e5dd2250815.png "ログファイル(例)")

## おわりに
今回は、機械学習の便利ツールWandBと従量課金制のコンテナサービス高火力DOKを組み合わせて使ってみました。WandBは他にもさまざまな機能を持っているようなので、今後ハックしていきたいと思います。クラウドサービスも、使い倒してみると効率的な開発ができそうでわくわくしますね。

## 参考文献
- [5行でカッコいい可視化を「WandB」入門](https://qiita.com/Yu_Mochi/items/4fc283ebc31225d4e106 "5行でカッコいい可視化を「WandB」入門")
- [さくらインターネットの「高火力 DOK」上でYOLOを学習させてみた](https://qiita.com/HidakaKoyo/items/7112ffb00a1aa1ee3fd8 "さくらインターネットの「高火力 DOK」上でYOLOを学習させてみた")
- [Docker Buildx](https://matsuand.github.io/docs.docker.jp.onthefly/buildx/working-with-buildx/ "Docker Buildx")
- [docker-buildxとmulti-platform build周りについてまとめ](https://zenn.dev/bells17/articles/docker-buildx "docker-buildxとmulti-platform build周りについてまとめ")