🎄

ProteinMPNN実行環境の構築 | Apptainer (on WSL2 & with GPU)

2023/12/27に公開

コードブロック における 🎄 は、プロンプトを表している

いまさらながら、蛋白質デザインにおける深層学習ベースの側鎖 (アミノ酸配列) 設計ツール ProteinMPNN自宅のマシン環境で使えるようにした。あいかわらず WSL2 上で Apptainer (旧Singularity) を用いて構築。

🎄 はじめに

以下、本記事を執筆した際の環境。

specifications
CPU Ryzen 7 5700X (AMD)
グラフィックボード GeForce RTX 2080 Ti VENTUS GP OC (MSI)
メモリ DDR4-3200 16 GB×2 (Crucial)
version
Windows 10 22H2
NVIDIA グラフィクス ドライバー 546.33
WSL2 2.0.14.0
Ubuntu 22.04 on WLS2 22.04.3 LTS
Apptainer 1.2.5

なお、WSL2 上の Ubuntu 22.04Apptainer 環境を構築する手順については、 以下の記事をご参照ください。
Zenn | WSL2にApptainer環境 (with GPU) を構築する

🎄 ProteinMPNNについて

詳しくは論文を読もう! (自戒)

Although deep learning has revolutionized protein structure prediction, almost all experimentally characterized de novo protein designs have been generated using physically based approaches such as Rosetta. Here, we describe a deep learning–based protein sequence design method, ProteinMPNN, that has outstanding performance in both in silico and experimental tests. On native protein backbones, ProteinMPNN has a sequence recovery of 52.4% compared with 32.9% for Rosetta. The amino acid sequence at different positions can be coupled between single or multiple chains, enabling application to a wide range of current protein design challenges. We demonstrate the broad utility and high accuracy of ProteinMPNN using x-ray crystallography, cryo–electron microscopy, and functional studies by rescuing previously failed designs, which were made using Rosetta or AlphaFold, of protein monomers, cyclic homo-oligomers, tetrahedral nanoparticles, and target-binding proteins.
Dauparas, J. et al. Science 378, 49–56 (2022). | Robust deep learning–based protein sequence design using ProteinMPNN

蛋白質デザインにおいて

主鎖 (backbone) 設計 👉 側鎖 (side chain) 設計 (アミノ酸配列生成)

という流れがあるらしい。いわゆるde novoデザインの場合は主鎖から設計する必要があり、一方天然の蛋白質構造をredesignする場合には主鎖設計が必要ない (こともある)。

ProteinMPNN は蛋白質の主鎖構造をインプットとして、その主鎖構造にフォールディングするアミノ酸配列を出力することができる ( AlphaFold の逆である)。「主鎖構造にフォールディングするアミノ酸配列を出力」とさらっと記述したが、これまでの Rosetta などの物理化学に基づいた計算手法ではこれがなかなか困難であったそうだ (設計したアミノ酸配列が、wet実験でそもそも発現・精製できないとか)。

その他 ProteinMPNN で生成したアミノ酸配列を AlphaFold で予測した際の pLDDT スコアがどうなるか、など興味深い特徴もあるが、本記事で詳細には触れない (論文を読もう!)。

🎄 ProteinMPNN実行コンテナの構築

本記事では以下のオリジナル版 ProteinMPNN の環境を構築する。
GitHub | ProteinMPNN

ちなみにオリジナル版のほかにOvchinnikov, S.氏が開発しているjax版 ProteinMPNN も存在している (こちらの方がスループットが高いらしい)。
GitHub | ProteinMPNN in jax!

以下のように ProteinMPNN を実行する Apptainer コンテナイメージ ( ProteinMPNN.sif ) をビルドするためのレシピファイル ( ProteinMPNN.def ) を作成する。

~/apps/apptainer_build/def_file/ProteinMPNN.def
BootStrap: docker
From: nvidia/cuda:11.3.1-cudnn8-devel-ubuntu20.04

%post
  # localtime関係のWARNINGに対処
  touch /etc/localtime

  # ProteinMPNNに必要なパッケージのインストール (冗長)
  apt update && apt upgrade -y
  apt install -y build-essential git curl wget
  
  # localeにen_US.UTF-8を追加する (WSL2だけで使用するなら不要)
  apt install -y locales
  locale-gen en_US.UTF-8
  
  # apt関係のお掃除
  rm -rf /var/lib/apt/lists/* && apt autoremove -y && apt clean

  # Pyenvを/usr/local/appsにインストール
  git clone https://github.com/yyuu/pyenv.git /usr/local/apps/pyenv
  export PYENV_ROOT="/usr/local/apps/pyenv"
  export PATH="${PYENV_ROOT}/bin:${PATH}"

  # PyenvでMiniforgeをインストールし、MiniforgeにPATHを通す
  pyenv install --list
  pyenv install miniforge3-22.9.0-3
  pyenv global miniforge3-22.9.0-3
  pyenv versions
  export MINIFORGE3_ROOT="${PYENV_ROOT}/versions/miniforge3-22.9.0-3"
  export PATH="${MINIFORGE3_ROOT}/bin:${PATH}"

  # conda自身のアップデート
  conda update -n base conda
  # conda環境proteinMPNN-condaを作成
  conda create -n proteinMPNN-conda

  # ProteinMPNNに必要なライブラリのインストール
  conda install -n proteinMPNN-conda -c pytorch \
    python=3.10 pytorch torchvision torchaudio cudatoolkit=11.3
  
  # conda関係のお掃除
  conda clean --all --force-pkgs-dirs --yes
  # conda環境proteinMPNN-condaにインストールしたパッケージの由来 (channel) を確認する
  conda list -n proteinMPNN-conda

  # ProteinMPNNを/usr/local/apps/proteinMPNNにインストール
  git clone https://github.com/dauparas/ProteinMPNN /usr/local/apps/proteinMPNN

%environment
  # ProteinMPNN実行のための環境設定
  export MINIFORGE3_ROOT="/usr/local/apps/pyenv/versions/miniforge3-22.9.0-3"
  export PROTEINMPNN_CONDA="${MINIFORGE3_ROOT}/envs/proteinMPNN-conda"
  export PATH="${PROTEINMPNN_CONDA}/bin:${PATH}"
  
  export PROTEINMPNN_HOME="/usr/local/apps/proteinMPNN"
  export PYTHONPATH="${PROTEINMPNN_HOME}/helper_scripts:${PYTHONPATH}"
  export PYTHONPATH="${PROTEINMPNN_HOME}:${PYTHONPATH}"

%runscript
  # コンテナ実行時のスクリプトを定義
  # "$@"は追加の引数を利用するための設定
  "$@"

例として ~/apps/apptainer_build/def_file に上記 ProteinMPNN.def を作成したとして進めよう。

続いて以下のように Apptainer コンテナイメージ ( ProteinMPNN.sif ) をビルドする。

🎄 cd ~/apps/apptainer_build
🎄 apptainer build ./ProteinMPNN.sif ./def_file/ProteinMPNN.def

ビルドが完了したら、任意の場所に ProteinMPNN.sif を格納する。今回は例として /mnt/d/apptainer_image に格納したとして進める。
WSL2 においてWindowsのDドライブはデフォルトで /mnt/d にマウントされる

🎄 cp ./ProteinMPNN.sif /mnt/d/apptainer_image
🎄 rm -f ./ProteinMPNN.sif

以上で ProteinMPNN 実行コンテナの構築は完了である。

🎄 ProteinMPNNの実行

ProteinMPNNのリポジトリを眺める

ProteinMPNN を実行する前にGitHub | ProteinMPNNのリポジトリ構成 (?) を眺めてみよう。

再上層にある protein_mpnn_run.py これが ProteinMPNN を実行するためのメインスクリプトである。

その他に helper_scripts ディレクトリの中には、chainの選択など補助的に利用するスクリプト類が格納されている。

vanilla_model_weights ディレクトリにはデフォルトの学習済みモデルパラメーター類が格納されている。

一方、 soluble_model_weights には以下のプレプリントで報告されている可溶性蛋白質に限定した学習済みモデルパラメーター類が格納されている。
Goverde, C. A. et al. bioRxiv (2023). | Computational design of soluble analogues of integral membrane protein structures

インプットファイル (主鎖構造) の準備

今回は実験的に決定された天然蛋白質の立体構造を用いることとする (側鎖の構造も含むが、アミノ酸配列推定には主鎖構造のみが利用される)。

ここでは例としてヒト由来リポカリン型プロスタグランジンD合成酵素 (L-PGDS、PDB code: 4ORR ) を用いる。
PDB | Threedimensional structure of the C65A mutant of Human lipocalin-type Prostaglandin D Synthase olo-form

.pdb ファイルをダウンロードし chain A のみかつ HETATM を削除したファイルを 4orr_A_noHET.pdb として /mnt/d/ProteinMPNN/LPGDS/input ディレクトリに保存する。

ちなみに上記のような .pdb ファイルの編集には pdb-tools が非常に便利である (もちろんテキストエディタで編集してもよい)。
Bonvin Lab | pdb-tools

ProteinMPNNを実行するシェルスクリプトの作成 & 実行

/mnt/d/ProteinMPNN/LPGDS ディレクトリ (上記 input ディレクトリを含む) に以下のシェルスクリプト run.sh を作成する。

/mnt/d/ProteinMPNN/LPGDS/run.sh
#!/usr/bin/bash -e

####### Apptainerの設定 #######
# .sifファイルを格納しているディレクトリの設定
APPTAINER_IMAGE="/mnt/d/apptainer_image"
# ProteinMPNNを実行するApptainerコマンドを作成
# --bindは任意 (homeディレクトリ以外で実行したいときに必要)
function proteinMPNN-apptainer() {
  apptainer run --nvccli --bind /mnt/d \
    ${APPTAINER_IMAGE}/ProteinMPNN.sif python3 -m "$@"
}

####### インプット・アウトプットディレクトリの設定 #######
# 本.shが配置されたディレクトリをワーキングディレクトリとして設定
DIR_WORK="$(cd $(dirname $0) && pwd)"

# インプットに用いる.pdbファイルを含むディレクトリを設定
DIR_INPUT="${DIR_WORK}/input"
# アウトプット先のディレクトリを設定
DIR_OUTPUT="${DIR_WORK}/output"
# アウトプット先のディレクトリを作成
mkdir ${DIR_OUTPUT}

####### 複数.pdbファイルを一度に処理するための設定 #######
parsed_pdbs_jsonl="${DIR_OUTPUT}/parsed_pdbs.jsonl"

# helper_scriptsの実行
proteinMPNN-apptainer parse_multiple_chains \
  --input_path=${DIR_INPUT} \
  --output_path=${parsed_pdbs_jsonl}

####### アミノ酸配列設計の対象とするchainの指定 #######
# chains_to_designに指定
# 複数chainに渡って指定する場合は "A C" のように指定する
chains_to_design="A"
assigned_pdbs_jsonl="${DIR_OUTPUT}/assigned_pdbs.jsonl"

# helper_scriptsの実行
proteinMPNN-apptainer assign_fixed_chains \
  --input_path=${parsed_pdbs_jsonl} \
  --output_path=${assigned_pdbs_jsonl} \
  --chain_list "${chains_to_design}"

####### アミノ酸配列設計の際に固定したい残基の指定 #######
# fixed_positionsに指定
# .pdbファイルの残基番号に対応しないことに注意 (最初の残基番号が強制的に1になる)
# 複数chainに渡って指定する場合は "2 5 7, 1 7 10" のようにコンマで区切る
fixed_positions="62 159"
fixed_pdbs_jsonl="${DIR_OUTPUT}/fixed_pdbs.jsonl"

# helper_scriptsの実行
proteinMPNN-apptainer make_fixed_positions_dict \
  --input_path=${parsed_pdbs_jsonl} \
  --output_path=${fixed_pdbs_jsonl} \
  --chain_list "${chains_to_design}" \
  --position_list "${fixed_positions}"

####### ProteinMPNNによるアミノ酸配列設計を実行 #######
# --model_nameのデフォルトはv_48_020 (version with 48 edges 0.20 Å noise)
# --use_soluble_modelを追加すると可溶性蛋白質のみで学習したモデルを利用できる
# --use_soluble_modelをつけない場合はvanilla_modelが利用される
# --omit_AAsに指定したアミノ酸は設計から除外できる (AlaとCysの場合 "AC" のように指定)
# --num_seq_per_targetで出力するアミノ酸配列数を指定
# --sampling_tempを増やすと出力されるアミノ酸配列の多様性が増す (推奨値:0.1, 0.15, 0.2, 0.25, 0.3)
# --seedでseed値を指定 (0はランダムseed)
# --batch_sizeでbatch sizeを指定 (GPUメモリに応じて調整)
proteinMPNN-apptainer protein_mpnn_run \
  --model_name "v_48_020" \
  --use_soluble_model \
  --jsonl_path ${parsed_pdbs_jsonl} \
  --chain_id_jsonl ${assigned_pdbs_jsonl} \
  --fixed_positions_jsonl ${fixed_pdbs_jsonl} \
  --omit_AAs "C" \
  --out_folder ${DIR_OUTPUT} \
  --num_seq_per_target 10 \
  --sampling_temp "0.1" \
  --seed 0 \
  --batch_size 1

以下のように ProteinMPNN を実行する。

🎄 cd /mnt/d/ProteinMPNN/LPGDS
🎄 chmod u+x ./run.sh
🎄 ./run.sh

すると /mnt/d/ProteinMPNN/LPGDS/output/seqs に以下のような 4orr_A_noHET.fa が出力される。

/mnt/d/ProteinMPNN/LPGDS/output/seqs/4orr_A_noHET.fa
>4orr_A_noHET, score=1.6658, global_score=1.6466, fixed_chains=[], designed_chains=['A'], model_name=v_48_020, git_hash=8907e6671bfbfc92303b5f79c4b5e6ce47cdef57, seed=832
VSVQPNFQQDKFLGRWFSAGLASNSSWLREKKAALSMAKSVVAPATDGGLNLTSTFLRKNQCETRTMLLQPAGSLGSYSYRSPHWGSTYSVSVVETDYDQYALLYSQGSKGPGEDFRMATLYSRTQTPRAELKEKFTAFCKAQGFTEDTIVFLPQTDKCMT
>T=0.1, sample=1, score=0.9472, global_score=0.9370, seq_recovery=0.4591
VEVQPNFDLSKFLGTWYLAGLASNSDELLAALQSRKFSKVVFSPSEDGGLNLTVTYIEDGECKTETFLLRPAGEPGRFLYEDKKRGGTFRVDVMETDYTTYMLLYSEGVEGEAKKVKVLTLYTRERNPSEEVWELFRERALELGFPEEQIVQLPQTDECMD
>T=0.1, sample=2, score=0.9590, global_score=0.9486, seq_recovery=0.4403
AEVQPDFDLEKFLGTWYLAGLATNSDELLEELESKKFSKVVISPSEDGGLNLTVRYIKDGECEETTLLLRPAGEPGVFTLEHPVRGGTFEVKVVKTDYDTYALLYAEGSEGPAKKVKVLTLLTREQNPSEEVLELFREYALSQGFPEEQIKQLAQSSECMD
>T=0.1, sample=3, score=0.9330, global_score=0.9226, seq_recovery=0.4025
VEVQPNFDASKFLGTWYLAGIATNSDELLNELLSKKFSKVVLSPSADGGLNVTVRYVKDGKCEETTFELKPAGEPGLFRYTDPVRGGTYEVRVVKTDYTTYAIVYAEGVEGEAKKEKVLLLLTREKNPSDEVVELFREEALKLGFKEEDIVLLPQSDECLD
>T=0.1, sample=4, score=0.9337, global_score=0.9232, seq_recovery=0.3836
VEVQPNFDLEKALGRWYLTGIATNSKELLEKLKSKKFSWVEISPSEDGGLLVTVTYIEDGECKSETFELRPAGEPGRFLYEDEKKGGTFEVRVVETDYNTYMIVYAEGVEGEAKKLKVVVLLTREQNPSEEIIEKFRKFALELGFKEEDIIQLEQTSECLD
>T=0.1, sample=5, score=0.9378, global_score=0.9278, seq_recovery=0.4340
VEVQPNFDMAKFLGTWYLAGLATNSEELLKALLSRKFSKVVLSPSADGGLDMTVTYVENGKCKTTTYHLKPAGEPGVFTYEHKERGGTFTVKVVKTDYTSYAILYAEGSEGEAKKIKVVLLLTREQTPSEEQLELFRKFALEQGFKEEQIVVLPQTSECLD
>T=0.1, sample=6, score=0.9424, global_score=0.9323, seq_recovery=0.4151
VEVQKDFDLSKFLGTWYLAGLATNSDELLAALQSKEFSKIVISPSANGGLNLTVTYIKDGKCETVTLELKPAGEPGVFTLEHKERGGKFEVKVVETDYDKYAIVYSEGIEGPAKALKVVLLLTRERNPSEEILEKFREFALKQGFAEENIIQLKQSDECLD
>T=0.1, sample=7, score=0.9654, global_score=0.9550, seq_recovery=0.4591
MKVQENFDAAKFLGRWYLAGLATNSDALLAALQAKKFSWVELSPSADGGLNLTVTYIQDGVCKSVTLHLSPAGEPGAFRYTDPVNGGTYEVLVVETDYETYAIFYSQGVEGPAKALKVVLLLTRERTPSPELWELFREFALEQGFAEDQIVQLAQSDECMD
>T=0.1, sample=8, score=0.8935, global_score=0.8835, seq_recovery=0.4340
MKVQENFDMSKFLGTWYLAGIASNSEELLKELESKEFSKVVISPAADGGLNLTVTYIENGECKTVTLHLSPAGEPGVFTLTDPERGGTYEVKVVETDYDKYMIVYAEGVEGPAKKEKVLLLFTREKNPSEEIIEKFREFAKSQGFAEENIKILKQSDECLD
>T=0.1, sample=9, score=0.9511, global_score=0.9408, seq_recovery=0.4465
VEVQPNFDLSKMLGTWYLAGLASNSKELLEELKSRKFSKVELSPSADGGLDWTVTYVQDGECKTTTFHLSPAGEPGRFTYEHPVRGGRYEVLFVETDYTTYALVYAQGVEGPAKEEKVLGLLTRERNPSEEVWEKFRAFALSQGFAEEDIVQLAQTDECLD
>T=0.1, sample=10, score=0.9519, global_score=0.9412, seq_recovery=0.4214
VAAQPDFDAAKFLGTWYLTGIATNSEELLKALESREFSKVVISPSADGGLDLTVTYIEDGECKTSTFHLRPAGEPGVFTLEDPEKGGTYRVVVVETDYDTYMLVYSEGSEGEAKKEKVLLLLSREKTPSEEILELFRKFALEQGFPEEQIKLLKQSDECLD

今回は10配列出力したが、いずれも seq_recovery は~0.45であり、天然型のアミノ酸配列から半分程度変化していることが分かる。これらの ProteinMPNN によって推定されたアミノ酸配列について LocalColabFold を用いて立体構造予測を行うと、元の天然型の実験的立体構造 (主鎖構造) を再現するだろうか? また、元の天然型のアミノ酸配列から LocalColabFold で予測した構造と比較するとどうだろうか? (ぜひやってみよう)

Apptainer を用いた LocalColabFold 環境構築については以下を参照ください (あえて Apptainer で環境作らなくても、という気もしますが 笑)
Zenn | LocalColabFold実行環境の構築 | Apptainer (on WSL2 & with GPU)

Discussion