Skip to content

Instantly share code, notes, and snippets.

@kokitsuyuzaki
Created December 1, 2020 01:20
Show Gist options
  • Save kokitsuyuzaki/c24656f277a8fba8242d698349514421 to your computer and use it in GitHub Desktop.
Save kokitsuyuzaki/c24656f277a8fba8242d698349514421 to your computer and use it in GitHub Desktop.
Anacondaか、Dockerか

この記事はWorkflow Advent Calendar 2020の二日目の記事です。

自分は最近Snakemakeでワークフローを書いている。それまではシェルスクリプト → make → Rakeという風に、色々なやり方でワークフローを書いてきてたが、環境構築・再現性や分散処理の対応がしやすいSnakemakeに現在のところは落ち着いている。Snakemakeでコードの再現性に関わる技術はAnacondaとDocker(Singularity)である。ここでは、両方の技術は一長一短であり、両技術共に痒いところに手が届かない状況があるという話しをする。なお、自分はデータ解析を生業としており、データを前処理、解析、可視化しては、使うパッケージを適宜加えたり、減らしたりする探索的データ解析(EDA)の過程でSnakemakeを使っているため、事前に処理が決まっていて、あとはワークフロー化するだけの人とは状況がかなり違っている可能性があるので注意されたし。

Anacondaのメリット

Snakemake内でのAnacondaの使い方は簡単で、Snakemakeを実行する上で必要なSnakefileの中で、実行するruleにcondaタグを追加する。condaタグの中では、conda環境を構築する上で必要な共有ライブラリやらR,Pythonのパッケージやらを記述する。 https://snakemake.readthedocs.io/en/stable/snakefiles/deployment.html#integrated-package-management

あとは、snakemakeコマンドを実行する際に、--use-condaオプションを加えるだけで良い。

snakemake -j 4 --use-conda

これにより、作業ディレクトリ以下の.snakemake/conda以下にconda環境が構築され、各ruleはconda環境内にあるツールで実行される。

ただし、このYAMLをどのように作るのかが自明ではない。Snakemakeのドキュメントとには、

channels:
 - r
dependencies:
 - r=3.3.1
 - r-ggplot2=2.1.0

みたいにかなり簡素なYAMLが紹介されているが、これに従い2,30個のRパッケージを、このYAMLに記述して利用してみたところ、「必要なlib*が無い」みたいなことを言われて、snakemakeが実行できなかった。おそらくLinuxの共有ライブラリ(例: libxml)も、このYAMLに書かないといけないらしい。

そのため、次の方針としては、conda installで以下のように、必要なパッケージをインストールした後に、conda env exportであらゆる依存ツールを記入したYAMLを生成して、これをsnakemakeで利用することで、正常に動くことが確認できた。

conda install -c bioconda bioconductor-sctensor
conda install -c bioconda bioconductor-sctgif
...
conda env export myenv.yaml

EDAの現場では、事前にどのツールをインストールするのかがわからないが、このやり方なら、必要なパッケージが1つ増えるたびに、conda installとconda env exportをするだけなので、テンポよく解析ができる。

Anacondaのデメリット

しかしながら、Acacondaにもデメリットを感じている。端的に言って、Anacondaの再現性は「なんちゃって」である。 例えば、上記のYAMLをLinuxサーバ上で生成し、それをmacOS上で利用しようとしてもSnakemakeは動かない。つまりOSを跨げない場合がある。Linux固有のライブラリが書かれていたりするのだからある意味当たり前である。

それどころか、同じLinux同士であっても、再現性がとれない場合があった。これはconda install & env exportよりも前の段階の

conda config --add channels チャンネル名

での、チャンネルのaddの順番などにも影響しているらしいと知り合いに言われた。

Dockerのメリット

Snakemake内でのDocker(Singularity)の使い方も簡単で、snakemakeを実行する上で必要なSnakefileの中で、実行するruleにcontainerタグを追加する。または、Snakefile上の全ruleでそのコンテナを利用したい場合は、グローバル変数的にSnakefileの上の方に書いても良い。 https://snakemake.readthedocs.io/en/stable/snakefiles/deployment.html#combining-conda-package-management-with-containers

containerタグの中では、DockerHubやSingualrityHub, Quayに登録されたDockerコンテナイメージ名を指定する。 https://snakemake.readthedocs.io/en/stable/snakefiles/deployment.html#running-jobs-in-containers

あとは、snakemakeコマンドを実行する際に、--use-singularityオプションを加えるだけで良い。

snakemake -j 4 --use-singularity

これにより、作業ディレクトリ以下の.snakemake/singularity以下に、Singularityイメージが生成され、各ruleはこのコンテナ内にあるツールで実行される。Anacondaと違い、--use-singularityを使ったやり方で失敗したことはほとんど無い。コケた場合は、コンテナ内のツールが正常に実行されていなかったか、データの渡し方がまずかったか、計算機の状況が悪かったかみたいなところであり、Anacondaと比べるとかなり安定感がある。

Dockerのデメリット

しかしながら、Dockerにも不満がある。 はっきり言って、Dockerfileを書くのがダルい。 他人が作ってくれたDockerイメージをDockerHubからpullするだけなら楽だが、BioContainerが提供しているRやPythonのパッケージは、1個のパッケージずつDockerイメージになっているだけである。 例えば、scTensorのDockerイメージは、scTensor1個がインストールされただけの環境である。

docker pull quay.io/biocontainers/bioconductor-sctensor:<tag>

https://bioconda.github.io/recipes/bioconductor-sctensor/README.html

データ解析が1個のパッケージで済むならいいが、EDAの場合、ほぼ間違いなく複数のパッケージを組み合わせて使うことになるため、これでは実用的ではない。かといって、複数のパッケージをインストールした環境を提供すべきかというと、2個入れるだけでも組み合わせ爆発するので、全く現実的では無いだろう。 Dockerの話しは、コマンドライクに実行するツールとは相性が良いが、ツールを組み合わせて使うEDAとは相性が悪い気がしている。

一応、作者おすすめのパッケージの組み合わせを提供するという流れで、Rockerや、Docker containers for Bioconductorなどはあるが、自分の解析に必要なツールは自分で用意するしかないだろう。 https://hub.docker.com/r/rocker/rstudio https://www.bioconductor.org/help/docker/

なので、自分でDockerfileを書き、docker buildでDocker環境を作り、docker pushでDockerHubに送り、docker pullで他の環境で使うという手順を踏むことになるのだが、かなりテンポが悪い。 1個追加するパッケージが増えるだけで、最初からやり直しになるのだが、パッケージが2,30個あると、ビルドも数時間になり、サイズも10GBを超える。明らかにおかしい使い方をしている気がしている。

まとめ

上記のように、どちらの技術にも満足はしていない。 今のところAnacondaは再現性が全然ダメなので、解析の処理を、大雑把に前処理、データ解析、可視化ぐらいの粒度に区切って、Dockerイメージを作るか、普段の作業はAnacondaでやって、落ち着いてきたらDockerに切り替えるみたいな運用になるかもしれない。condaでインストールしたパッケージが確実に動く環境を置く"CondaHub"みたいなものや、はたまたdockerが色々作業した履歴を記録して、"docker env export"みたいな使い方ができると良いのだが...

@kokitsuyuzaki
Copy link
Author

あと、.snakemake/以下に古いcondaやsingularityイメージが残っていると、古いツール群のままで解析しようとするため、毎回

rm -rf .snakemake

をするのがだるい(たまにやり忘れて、数日間の作業日数を棒に振るう

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment