Published

Ascender: Accelerator of Scientific Development and Research

Authors
sweaty-hands

"With an enthusiastic team you can achieve almost anything." - Tahir Shah

TL;DR

  • Python を用いた研究プロジェクト向け GitHub リポジトリテンプレート Ascender を公開しました.
  • チームでの研究・開発が想定されるプロジェクトにおいて有用な機能が実装されています.

Table of Contents

Background

こんにちは, @gatheluck です. この投稿は「研究コミュニティ cvpaper.challenge 〜CV 分野の今を映し,トレンドを創り出す〜 Advent Calendar 2022」 の 6 日目の投稿でもあります.

私の所属している cvpaper.challnege ではグループで研究活動を行っているため, グループメンバーがそれぞれの環境で 1 つのプロジェクトのための実験コードを開発する機会が頻繁にあります. しかし, これまで共通のテンプレートやコーディング規約が存在していなかったため, コードの共有や再利用, チームでの同時開発はあまり上手く出来ていない状況でした. そこで, MIRU メンターシッププログラムと cvpaper.challenge の連携研究グループである XCCV グループのメタサーベイ活動の一貫(メタサーベイ資料)として 2022 年の 7 月にプロジェクトテンプレート Ascender を開発, 公開しました.

公開後は Kaggle Grandmaster の @mamas さんなど複数の方からポジティブなコメントを頂き, cvpaper.challenge 内を始めとして複数の研究プロジェクトで使用して頂いています. 直近では ECCV 2022 に採択された NeDDF実装には Ascender が使用されています.

本記事の公開時の最新版は v0.1.2 で, スター数は 140 となっています (2022 年 12 月 05 日時点). また, 現在も継続的に開発・保守を行っておりますので, 新しい機能の要望や改善点などがあれば気軽に issue や pull request を作成頂ければと思います.

本記事では Ascender の機能と使い方について簡単に紹介します. 今回, 初めて知ったという方は次回以降のプロジェクトで使用を検討して頂ければ幸いです.

What is Ascender

Ascender は Python を用いた研究プロジェクト向けの GitHub リポジトリテンプレートです. 特徴としては下記のような点があります:

  • コンテナ仮想化: Docker を使用することで開発環境依存を減らし, コードの移植性を向上.
  • パッケージ管理: Poetry を使用したパッケージ管理により, 同一環境の再現性を向上.
  • コードスタイル: Black, Flake8, isort を使用してコードスタイルを自動的に統一.
  • 静的型チェック: Mypy による静的型チェックにより, コードの信頼性を向上.
  • テスト: pytest を使用したテストコードを簡単に使用可能.
  • GitHub 関連機能: Pull request 作成時の workflowissue テンプレート等を実装済.

Python を用いた ML 周りのプロジェクトテンプレートとしては, Cookiecutter Data ScienceLightning-Hydra-Template など既に広く使われているものもあるかと思いますが, 今回は特にチームでの開発を主軸とし, 開発の際に特定のライブラリの制約を出来るだけ受けないようにしました.

Prerequisites

Ascender では開発環境による影響を極力小さくするために, Docker コンテナ内で開発をすることを推奨しています. そのため, Ascender で開発を始める準備として, Docker, Docker Compose, NVIDIA Container Toolkit (nvidia-docker2) をインストールします. 一方で, 非推奨ですが Docker を使用しなくても Ascender で開発を行うことは可能です. そのため, 既にインストール済みの方や Docker を使用しない方は, 読み飛ばして下さい.

下記のインストールのコマンドは Ubuntu を想定したものです, 異なる OS で開発をする場合は, それぞれの公式ドキュメントを参考にして適宜インストールして下さい.

Docker と Docker Compose をインストールします.

% sudo apt update
% sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

sudo docker run --rm hello-world を実行して "Hello from Docker!" から始まるメッセージが表示されれば Docker をインストール出来ています.

GPU を使用して開発をする場合は NVIDIA Container Toolkit もインストールします.

% 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 install -y nvidia-docker2
% sudo systemctl restart docker

sudo docker run --rm --gpus all nvidia/cuda:11.0.3-base nvidia-smi を実行して nvidia-smi の実行結果が表示されれば NVIDIA Container Toolkit をインストール出来ています.

Start development

まず, Ascender をテンプレートとして新しい Github リポジトリを作成し, ローカルにクローンします. こちらのリンクからリポジトリの作成ページに遷移できます.

% git clone git@github.com:<YOUR_USER_NAME>/<YOUR_REPO_NAME>.git
% cd <YOUR_REPO_NAME>

Docker イメージをビルドし, コンテナを起動します. GPU 環境を使用する場合は environments/gpu, CPU のみの環境の場合は environments/cpudocker-compose.yaml を使用して下さい.

% cd environments/gpu  # CPUのみの環境の場合は`cd environments/cpu`
% sudo docker compose up -d

sudo docker compose exec core bash でコンテナの中に入り, Poetry を使用して仮想環境を作成, パッケージをインストールします. poetry install を実行するのは初回のみで大丈夫です.

% sudo docker compose exec core bash
$ poetry install

これで開発準備完了です. sudo docker compose up -d の実行によってコンテナ内の /home/challenger/ascenderホスト PC のディレクトリがボリュームされているので, ホスト PC でコードを編集するとコンテナ内に反映されます. その逆もまた然りです.

もし, 開発に Docker を使用しない場合は, リポジトリをローカルにクローンした後, Poetry をローカル PC に直接インストールし, poetry install を実行して下さい.

% git clone git@github.com:<YOUR_USER_NAME>/<YOUR_REPO_NAME>.git
% cd <YOUR_REPO_NAME>
% python3 -m pip install poetry  # ローカルPCにPoetryをインストール
% poetry install

ただし, 後述の Github Actions の workflow は Dockerfile を用いて動作するため, Dockerfile を使用せずに開発を進めた場合, PR の作成時等に workflow がエラーを挙げる可能性があります. もし, エラーが出た場合は, Dockerfile を修正するか, workflow を削除するなどの対応を行う必要があります.

During development

Ascender では開発を支援するために Poetry, Black, Flake8, isort, Mypy, pytest を導入しており, Make をタスクランナーとして使用して少数のコマンドで簡単に実行出来るようにしています.

Poetry

Ascender では Poetry を使用して Python パッケージの管理を行なっています. pip と比較して Poetry は一定の学習コストがかかりますが, Poetry を使用することで, 開発環境の再現性を高めたり, PyPI へパッケージとして公開するときのコストも小さく済みます. Poetry の使い方についての詳しい説明はこちらの資料公式ドキュメントを参照して下さい.

Poetry では poetry add コマンドを使ってパッケージを追加することが出来ます.

# Poetry を用いてパッケージをインストール
$ poetry add <PACKAGE_NAME>

poetry add を実行した際に良く挙がるエラーとして SolverProblemError があります. SolverProblemError の解決については, 上記の資料の "Frequently faced error" のページを参考にしてみて下さい.

Poetry が作成した仮想環境を使用してコマンドを実行するには poetry run コマンドを使用します. Poetry でパッケージをインストールしたのに, それが見つからないと怒られるときは poetry run をつけ忘れているかもしれません.

# Poetry が作成した仮想環境を使用して hoge.py を実行
$ poetry run python hoge.py

Black, Flake8, isort

Ascender ではコードスタイルを標準化するために Black, Flake8, isort を使用しています. Makefile に定義されているコマンド(make formatmake lint)を使用することでこれらのツールを一度に適用出来るようになっています. コマンド名は PFN の pysen を参考にしています.

# Black と isort を使用してコードのスタイルをフォーマット
$ make format
# Black, Flake8, isort, mypy を使用してコードのスタイルと静的な型を確認 (コードの変更は行わない)
$ make lint

スタイルの設定を調整したい場合は, Black と isort については pyproject.toml に Flake8 については .flake8 にそれぞれ設定が記載されていますので, 必要に応じて適宜編集して下さい. 各ツールで設定可能な項目はそれぞれ下記のリンク先を参照して下さい.

Mypy

Ascender ではコードの可読性と信頼性の向上のために型アノテーションを可能な限り使用することを推奨し, Mypy による静的型チェックを導入しています. Python の型アノテーションの付け方について確認をしたい方は Mypy のチートシートPython ドキュメントの typing パッケージのページを参照して下さい. Mypy による静的型チェックは既に紹介済のコマンドである make lint によって他のツールによるチェックと合わせて実行が出来るようになっています.

# Black, Flake8, isort, mypy を使用してコードのスタイルと静的な型を確認 (コードの変更は行わない)
$ make lint

Mypy の設定については pyproject.toml に記載されています. 設定が可能な項目については Mypy の公式ドキュメントを参照して下さい.

pytest

Ascender ではテストのためのツールとして pytest を導入しています. pytest の使い方について知りたいと方は公式ドキュメントM3 Tech Blog の小本さんの記事を参考にしてみて下さい.

研究プロジェクトで開発速度を犠牲にしてまでテストを書く必要が本当にあるのか?という論点は当然あると思います. 例えば, テストのカバレッジ自体を KPI としてしまうと研究プロジェクトでは本末転倒になる場合もあるでしょう. しかし, 手法の中心となる重要な関数・クラスについてテストを書くことは致命的なバグを発見を容易にしたり, 他のチームメンバーが関数・クラスを使用する際の理解を助けたりと, 一定のリソースを割くに値する利点があると考えています.

make test コマンドを実行することで tests ディレクトリ下に配置されたテストを実行することが出来ます. また, make test-all コマンドを使用すると, これまで紹介してきた, Black, Flake8, isort, Mypy, pytest を用いたチェックを一度に行うことが出来ます.

# pytest によるテストを実行
$ make test
# Black, Flake8, isort, Mypy, pytest によるチェックを一度に実行
$ make test-all

Create pull request

Ascender では機能の開発は専用のブランチで行い, 適宜 pull request を作成してメインブランチに機能を取り込んでいく方法を推奨しています. GitHub を使用した開発や機能について知りたい場合は GitHub 公式の GitHub Skills を参照して下さい.

デフォルトの pull request のテンプレート.github/PULL_REQUEST_TEMPLATE.md に定義されていますので, 必要に応じて適宜編集して下さい. また, pull request 時にはスタイル・静的型チェックとテストコードを実行する workflow が走るようになっています. こちらは .github/workflows/lint-and-test.yaml に定義されており, デフォルトで Python 3.8 と 3.9 について走るようになっています.

Stop development

開発が終了したら必要に応じてコンテナを停止して下さい.

% cd environments/gpu  # CPU のみの環境の場合は `cd environments/cpu`
% sudo dokcer compose stop

コンテナを削除したい場合は代わりに sudo dokcer compose down を使用して下さい.

Summary

今回は Python を用いた研究プロジェクト向けの GitHub リポジトリテンプレートとして開発した Ascender について紹介をしました. Ascender の開発・保守は今後も継続的に行っていく予定ですので, 追加機能の要望や質問等につきましては GitHub の issue で受け付けています. 質問については既にいくつか FAQ として README にまとめてありますので, そちらも参照して下さい.