Palmsonntagmorgen

NGSデータを使った解析と、その周辺。

NGS解析のための共有サーバ環境構築を考える(2022年度版)(2022/9/12追記)

5年前にこんな記事を書きました。 この時はPython2系と3系の共存(というか、Anaconda環境構築のベストプラクティス)に苦労していました。

rnakato.hatenablog.jp

今はほとんどPython3系のみで事足りますが、依然としてdependenciesの問題は解決されていません。 特に、bioconda から多数のツールをインストールしようとするとconflictが多発します。conda-forge と比べて、登録されたツールのdependencyがきちんと管理されていないような印象です。 また、Pythonの公式ライブラリも後方互換をあまり重視していない感じであり、Python3.7で書かれたツールをPython3.9にインストールしても動かないというようなこともあります。

私のようなサーバ管理者からすると、不特定多数の一般ユーザが共有できる解析環境をサーバ上に構築・管理したいものです。 うちはローカルサーバですが、クラウドでも基本的に変わらないでしょう。 色々な管理ツールを使ってツール群を管理していますが、Pythonは特に維持が大変です。

Rは管理者と一般ユーザでインストールされるディレクトリが分かれるのでわかりやすいですね。 Pythonの場合も共有ディレクトリにanacondaやpyenvをインストールしてパスを通すことで環境を共有することは可能です。 管理者ユーザでインストールすれば、一般ユーザに環境を書き換えられることもありません。 ただしRと異なり、このやり方だと一般ユーザが自分でツールをインストールすることができません。 毎回管理者にpipやcondaのインストールをお願いするということになります。これはお互いにとって負担です(管理者ユーザが十分数いれば別ですが)。

(2022/9/12追記)anacondaでも、管理者ユーザでインストールした環境にユーザがpipでインストールした場合は~/.local/binにインストールされるようです。そういえば pip --userってオプションがありましたね。

代替案として、各ユーザが自分のホームディレクトリにanacondaをインストールし、自力で管理するという方式が考えられます。 この場合、「自分でanacondaや各種ツールをインストール・管理できるユーザである」ことがサーバ利用の必要条件になります。 しかし実際にはそういうユーザばかりではありません。とにかく教えられた・決まった作業しかできないユーザもいます。 そのようなユーザは解析を行う資格なし、と厳しいポリシーで運用するというのは一案ですが(管理者は楽ですが)、実際にはそうも言っていられません。 ラボに入った学生は卒業させなければいけませんし、解析を習いに来たウェット研究者に環境構築から行わせていたらそれだけに日数が取られ、それは本意ではありません。

また、正しく運用したとしても上述のconflictは解決しません。 condaとpipを共存させてはいけないというのはよく言われることですが、condaのみに限ってもconflictは不可避です。 特にbiocondaはかなりの鬼門です。今の私のローカル環境にはもうdeepToolsはインストールできません。

まだ問題があります。「pipとcondaは共存できない」時にどちらかひとつに限るとしたならばおそらくcondaになるのですが、condaでインストールできるツールのバージョンはしばしば古いものになります(aptと似たような問題)。最新バージョンをインストールするためにpipを使いたいという場合があり得ます。 また、pipと違ってcondaはdependencyとしてRやらperlやらも一緒にインストールしてしまう「行儀が悪い」インストーラなので、既に構築した既存の解析環境を上書きし、破壊する危険性があります。様々なユーザが様々な用途で様々なツールをインストールしていくことになると、完全に制御することはほとんど不可能です。

これらの問題回避策としてよく利用されるのが、condaまたはvenvで仮想環境を構築するという方法です(「conda 仮想環境 」でググるとたくさん出てきます)。 たとえばreadのアダプタ配列をトリミングする cutadaptのインストールページ を見ると、仮想環境にcutadaptを入れる方法が例示されています。 現状では、この仮想環境構築がベストソリューションのように感じます。試してみましたが、仮想環境もちゃんとユーザ間で共有できるようです。 この方式では、base環境には必要最低限の(たとえばAnaconda同梱の)パッケージのみにとどめ、各解析ツールは全て個別の仮想環境に切り分ける、という運用が考えられます。

ただ、ここは個人的な意見になりますが、「仮想環境の切り替え」は一般ユーザにはややハードルが高いように感じます(私が仮想環境の切り替えになじんでいないだけかもしれませんが)。 cutadapt, deeptools, etc.. の個別のツールを使うたびに仮想環境切り替えするのは個人的にはわずらわしく感じます。シェルスクリプトのコーディングも書きづらいような。各仮想環境のアップデートも面倒なのでは…?

また、複数のサーバを管理している場合、各サーバでの環境統一が難しいという問題もあります(これはクラウドサーバにすれば解決する問題かもしれません)。解析環境を凍結保存したり、再構築することも難しいかもしれません。

ここで出てくるのが、切り分けしたい環境をDocker/Singularityのイメージとして保存するという方法です。 やろうとしていることはcondaの仮想環境構築と大差ないのですが、singularityイメージとして目に見えるかたちで保存することで、管理がしやすくなります。複数サーバ間での同期も簡単ですし、バージョン番号をファイル名につけておけば過去の環境をキープしつつの更新も可能です。

さらに、この方式の場合はPythonに限らず、あらゆる言語のツールをパッケージとして保存することが可能になり、NGSツール群を統一的に管理することができるようになります。 また、ツールを使うためのスクリプトを同梱しておくことでユーザビリティを高めることもできます。 例えば、ChromHMMのjarファイルと一緒に java -mx40000M -jar <path>/ChromHMM.jar "$@" と記載したシェルスクリプトを作成しパスを通しておくことで、一般ユーザはjavaファイルであることを意識せずにChromHMMが使えるようになりますし、将来的に起こりうるメモリエラーも未然に防ぐことができそうです(condaパッケージもおそらく同じようなことを目指しているのでしょう)。

ただこの場合でも、「どのくらい細かく環境を切り分けるか」という問題は残ります。 個々のツールを別々のイメージにする「1ツール1イメージ」方式が一つの案ですが、一方で、「様々な解析が可能であるイメージ」も需要が高いです。 様々なツールを内部で使うパイプラインのようなケースです。 ひとつのアイデアは、NextFlowやSnakemakeなどのワークフロー言語で全体のワークフローを記述し、「1ツール1イメージ」のイメージ群を上手に使いこなしてパイプラインを完遂する方法です。ただ、このやり方は基本的には決まったワークフローで処理することが主な目的であり、自分の研究のためにあれこれ工夫したり拡張したりという目的には向きません。

国際プロジェクトで標準となった解析フローを実行するためのDocker image」や「様々なツールをインストール済のシングルセル解析プラットフォーム」のような、オールインワン方式のイメージを作りたい場合、ではその内部でconflictをどう回避するのか?という最初の問題に戻ります。 Dockerコンテナを起動して内部で解析する場合、通常の解析環境と同じように、仮想環境の切り替えで対応可能です(ただし「仮想環境敷居が高い問題」は回避されません)。単一のツールを仮想環境でインストールする場合、その仮想環境へのパスを直接通してしまうことでツールを使えるようになります。スクリプトを用意することで、ユーザの負担なくさまざまなツールを使えるようにすることはある程度可能でしょう。Singularityでコマンド実行する場合は仮想環境の切り替えはおそらく難しいので、そのような方式になります。いずれにしても、複数の仮想環境を包含するようなイメージを維持可能かどうかは程度問題であり、個別のケースに応じて工夫を凝らすしかないと言えそうです(例外として、Jupyter notebookを使う場合は多数の仮想環境を使い分けることが可能になります)。 さらなる代替案として、「多数のsingularityイメージを内部に保存したsingularityイメージ」というのを思いつきましたが…そもそも内部に多数の個別環境を内包するイメージはコンテナ化の趣旨からは外れたものであるかもしれません。

結局、ある程度ユーザを自力で啓蒙しつつ、ある程度ローカル環境で対応しつつ、ある程度個別環境を用意する、という道を模索するしかなさそうです。 5年後にはこのあたりの微妙な感じを全て打ち払うベストソリューションが生まれるとよいのですが。