HelixFold3のインストール

![ScreenShot 2024-09-10 14.19.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224327/2c586b30-1824-53a8-16ab-f52d64bfc127.png)

![ScreenShot 2024-09-10 14.38.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224327/4e41ffba-971c-91fd-434d-26348c6f1506.png)

## Introduction

HelixFold3は中国のBaidu社が作っている[AlphaFold3](https://doi.org/10.1038/s41586-024-07487-w)のクローンです。AlphaFold3の論文は2024年5月にNatureから出版されましたが、2024年末までにコードを公開する予定ではあるものの、現在はまだ機能制限版のWebサーバーしか利用することができません。
HelixFold3はこの論文を読み解き、再実装したものとされています。学習済みのモデルは公開されているので、自分のマシンで動かすことができます。

- [公式GitHub](https://github.com/PaddlePaddle/PaddleHelix/tree/dev/apps/protein_folding/helixfold3)
- [テクニカルレポート](https://doi.org/10.48550/arXiv.2408.16975)

※ **HelixFold3は商用利用不可です**。

> HelixFold3's code and model parameters are available under the LICENSE for non-commercial use by individuals or non-commercial organizations only. Please check the usage restrictions before using HelixFold3.

## インストール手順

### 必要な計算機

HelixFold3が動くために最低限必要な計算装置は以下の通り。だいたいAlphaFold2のときと同じです。

- OS： 最近のLinux、CUDA 11.1か12.0以上が動くこと
- CPU： ここ5〜7年くらい最近のCPUであればたぶん動く
- ストレージ： 4TBのSSD（外付け可能）。2TBでもsmall_BFDなら入る。
- RAM： 64GBくらいはあったほうが良い
- GPU： 1枚以上のNVIDIA GPU、かつVRAMは最低でも16GB以上。RTX3090とか4090以上のグレードで動くことを確認。VRAMが12GBのRTX3060でも動くかは未確認

### 必要なデータベースのダウンロード

動作にはAF2のときの配列と構造データベースがまず必要です。

- [UniRef90](https://www.uniprot.org/help/uniref),
- [MGnify](https://www.ebi.ac.uk/metagenomics/),
- 
[BFD](https://bfd.mmseqs.com/)
, small_BFDの方でないと動かないように機能制限されている
- [uniref30](https://gwdu111.gwdg.de/~compbiol/uniclust/2023_02/),
- [PDB70](http://wwwuser.gwdg.de/~compbiol/data/hhsuite/databases/hhsuite_dbs/),
- [PDB mmcif](https://www.rcsb.org/) (structures in the mmCIF format).
- [PDB seqres](https://www.rcsb.org/)
- [UniProt](https://www.uniprot.org/uniprot/)

これはAlphaFold 2.3.2のインストールと同じなので[以前の記事](https://qiita.com/Ag_smith/items/7c76438906b3f665af38)を読んでインストールしてください。BFDは動作が封じられているっぽいので（なんで？）、代わりにsmall_BFDを使います。十分な数のMSAが取得できればいいみたい。

これらに追加して

- Rfam-14.9_rep_seq.fasta
- ccd_preprocessed_etkdg.pkl.gz
- HelixFold3-240814.pdparams

をダウンロードします。これらは[HelixFold3のscripts](https://github.com/PaddlePaddle/PaddleHelix/tree/dev/apps/protein_folding/helixfold3/scripts)からそれぞれ`download_rna.sh`, `download_ccd_pkl.sh`, `download_helixfold3_checkpoints.sh`を実行することでダウンロードできます。

終わったら、適当なディレクトリ`helixfold3_dbs`を作成し、中にこれを入れておきます。

```bash
├── helixfold3_dbs
│   ├── [   63650922]  ccd_preprocessed_etkdg.pkl.gz
│   ├── [ 1480918657]  HelixFold3-240814.pdparams
│   └── [  214780583]  Rfam-14.9_rep_seq.fasta
```

### MAXITのインストール

MAXITは生体分子の立体構造情報を含む.pdb形式のファイルを.cif形式に変換してくれるソフトウェアです。wwPDBが公式にひっそりと配布しています。[こちら](https://sw-tools.rcsb.org/apps/MAXIT/)にソースが置かれています。
MAXITは現在Homebrew/Linuxbrewには登録されているので、Linuxbrewがある方は

```bash
brew install brewsci/bio/maxit
```

でインストールできます（かつて私が作成して登録しました）。が、Linuxbrewは個人でいれるのはちょっと大掛かりすぎる気もするので、以下の手動コンパイルのほうがいいかもしれません。最近はbiocondaに登録されそうな動きがあります。こちらが登録されたら以下のbiocondaのときに一発で入るようになるでしょう。

ソースから自前でコンパイルするときは以下の方法を取ります。

```bash
# bisonとflexがコンパイルに必要（なくてもコンパイルできる？）
apt -y install bison flex
# インストール先の指定
MAXIT_INSTALL_DIR=/home/apps/maxit/11.200
# 一時ディレクトリの作成
cd "$(mktemp -d)"
wget https://sw-tools.rcsb.org/apps/MAXIT/maxit-v11.200-prod-src.tar.gz
tar zxvf maxit-v11.200-prod-src.tar.gz
cd maxit-v11.200-prod-src
# MAXIT_INSTALL_DIRをRCSBROOTとして固定するためのハック
sed -i -e "s|char\* rcsbroot = getenv(\"RCSBROOT\");|const char\* rcsbroot = \"$MAXIT_INSTALL_DIR\";|" maxit-v10.1/src/maxit.C
sed -i -e "s|char\* rcsbroot = getenv(\"RCSBROOT\");|const char\* rcsbroot = \"$MAXIT_INSTALL_DIR\";|" maxit-v10.1/src/process_entry.C
sed -i -e "s|char\* rcsbroot = getenv(\"RCSBROOT\");|const char\* rcsbroot = \"$MAXIT_INSTALL_DIR\";|" maxit-v10.1/src/generate_assembly_cif_file.C
# コンパイル（必ず並列数は1にする。並列コンパイルは失敗する。）
make binary -j1
# インストール
mkdir -p $MAXIT_INSTALL_DIR
mv bin data $MAXIT_INSTALL_DIR
# インストールしたユーザー以外のアカウントから使いたい場合はパーミッションを適切に設定する
# 初期状態では他のユーザーアカウントからは実行できない
chmod 755 $MAXIT_INSTALL_DIR/data
chmod 755 $MAXIT_INSTALL_DIR/data/binary
chmod 755 $MAXIT_INSTALL_DIR/data/ascii
chmod 644 $MAXIT_INSTALL_DIR/data/binary/*
chmod 644 $MAXIT_INSTALL_DIR/data/ascii/*
```

終わったら、適当なディレクトリで`maxit`が正しく動作することを確認しておきます。

```bash
wget https://files.rcsb.org/download/3QUG.pdb
$MAXIT_INSTALL_DIR/bin/maxit -input 3QUG.pdb -output 3qug.cif -o 1 -log maxit.log
```

3qug.cifが生成されて中身がcifファイルっぽいことを確認したら成功です。

```shell
$ head 3qug.cif
data_3QUG
#
loop_
_audit_author.name
_audit_author.pdbx_ordinal
"Moriwaki, Y."     1
"Caaveiro, J.M.M." 2
"Tsumoto, K."      3
#
_struct.entry_id                  3QUG
```

### HelixFold3本体とcudnnのインストール

公式のおすすめ環境は

- Python: 3.9
- CUDA: 12.0
- CuDNN: 8.4.0
- NCCL: 2.14.3
- Paddle: 2.6.1

ですが、このうちNCCLはなくても動作しているっぽい（？）のと、CUDAは11.1から12.4まで動きそうな感じ（要確認）、ただpaddlepaddle_gpuは2.6.1だと予測計算開始後のパラメータのLoadあたりでSegmentation faultになって失敗するので、2.5.1か2.5.2を使います。

cudnnのバージョンは公式では8.4.0が推奨されています。こちらはcondaで入るので入れておきましょう。

```bash
INSTALLDIR=/home/apps/

mkdir -p ${INSTALLDIR}
cd ${INSTALLDIR}
git clone https://github.com/PaddlePaddle/PaddleHelix.git

HELIXFOLD3DIR=${INSTALLDIR}/PaddleHelix/apps/protein_folding/helixfold3
cd ${HELIXFOLD3DIR}
wget -q -P . https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash ./Miniconda3-latest-Linux-x86_64.sh -b -p ${HELIXFOLD3DIR}/conda
rm Miniconda3-latest-Linux-x86_64.sh

. "${HELIXFOLD3DIR}/conda/etc/profile.d/conda.sh"
export PATH="${HELIXFOLD3DIR}/conda/condabin:${PATH}"
conda create -n helixfold -c conda-forge python=3.9 -y
conda install -y -c bioconda hmmer==3.3.2 kalign2==2.04 hhsuite==3.3.0 -n helixfold
conda install -y -c conda-forge openbabel -n helixfold
# cudnn 8.4.0のインストール
conda install -y -c conda-forge cudatoolkit==11.8.0 cudnn==8.4.1.50 -n helixfold

conda activate helixfold
python3.9 -m pip install https://paddle-wheel.bj.bcebos.com/2.5.1/linux/linux-gpu-cuda11.7-cudnn8.4.1-mkl-gcc8.2-avx/paddlepaddle_gpu-2.5.1.post117-cp39-cp39-linux_x86_64.whl
python3.9 -m pip install -r requirements.txt
```

あと、Ubuntu 22.04の場合はlibssl.so.1.1がないエラーが発生することがあります。

```
Error: Can not import paddle core while this file exists: /home/apps/PaddleHelix/apps/protein_folding/helixfold3/conda/envs/helixfold/lib/python3.9/site-packages/paddle/fluid/libpaddle.so
Traceback (most recent call last):
  File "/home/apps/PaddleHelix/apps/protein_folding/helixfold3/inference.py", line 21, in <module>
    import paddle
  File "/home/apps/PaddleHelix/apps/protein_folding/helixfold3/conda/envs/helixfold/lib/python3.9/site-packages/paddle/__init__.py", line 31, in <module>
    from .framework import monkey_patch_variable
  File "/home/apps/PaddleHelix/apps/protein_folding/helixfold3/conda/envs/helixfold/lib/python3.9/site-packages/paddle/framework/__init__.py", line 17, in <module>
    from . import random  # noqa: F401
  File "/home/apps/PaddleHelix/apps/protein_folding/helixfold3/conda/envs/helixfold/lib/python3.9/site-packages/paddle/framework/random.py", line 17, in <module>
    from paddle import fluid
  File "/home/apps/PaddleHelix/apps/protein_folding/helixfold3/conda/envs/helixfold/lib/python3.9/site-packages/paddle/fluid/__init__.py", line 36, in <module>
    from . import framework
  File "/home/apps/PaddleHelix/apps/protein_folding/helixfold3/conda/envs/helixfold/lib/python3.9/site-packages/paddle/fluid/framework.py", line 35, in <module>
    from . import core
  File "/home/apps/PaddleHelix/apps/protein_folding/helixfold3/conda/envs/helixfold/lib/python3.9/site-packages/paddle/fluid/core.py", line 356, in <module>
    raise e
  File "/home/apps/PaddleHelix/apps/protein_folding/helixfold3/conda/envs/helixfold/lib/python3.9/site-packages/paddle/fluid/core.py", line 269, in <module>
    from . import libpaddle
ImportError: libssl.so.1.1: cannot open shared object file: No such file or directory
```

これは`sudo`権限がある場合、

```bash
wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.0g-2ubuntu4_amd64.deb
sudo dpkg -i libssl1.1_1.1.0g-2ubuntu4_amd64.deb
```

でlibssl.so.1.1をインストールすれば解決します。
インストール後は`/usr/lib/x86_64-linux-gnu/libssl.so.1.1`ファイルが存在することを確認します。

### 計算の実行

以下のようなbashスクリプトと入力ファイルを書いて実行させます。公式にはdemoディレクトリの中にいくつかサンプルがあります。

予測可能なトークン（＝1アミノ酸または1核酸塩基につき1トークン、リガンド分子は1原子につき1トークン）の上限は結構短く、fp32精度での予測の場合にはV100-32G GPUで1000トークンまで、bf16精度でのA100−40G GPUでは1200トークンまでとなっているそうです。これを超えるとエラー落ちしてしまう可能性が高いです。

> We suggest a single GPU for inference has at least 32G available memory. The maximum number of tokens is around 1200 for inference on a single A100-40G GPU with precision bf16. The length of inference input tokens on a single V100-32G with precision fp32 is up to 1000. Inferring longer tokens or entities with larger atom numbers per token than normal protein residues like nucleic acids may cost more GPU memory.

実行スクリプト`run_helixfold3.sh`の例はこちら

```bash:run_helixfold3.sh
#!/bin/bash

### set your helixfold3 directory
MAXIT_INSTALL_DIR=/home/apps/maxit/11.200
HELIXFOLD3DIR=/home/apps/PaddleHelix/apps/protein_folding/helixfold3
# set your database path
DATA_DIR=/mnt/database # 配列系データベースが置かれたディレクトリ
PDB_DIR=/home/database # pdb_mmcifが置かれたディレクトリ
DB_DIR=/home/database # helixfold3_dbsが置かれたディレクトリ

ENV_BIN=${HELIXFOLD3DIR}/conda/envs/helixfold/bin
export PATH="${MAXIT_INSTALL_DIR}/bin:${PATH}"
# 公式のREADMEだとOBABEL_BIN="PATH/TO/OBABEL/BIN"となっているけれど
# 本体のobabelまで必要(2024/9/10時点)
export OBABEL_BIN="${ENV_BIN}/obabel"
# もしかしてlibcudnn.soを読み込むためには次の行も必要？
export LD_LIBRARY_PATH="${HELIXFOLD3DIR}/conda/envs/helixfold/lib:${LD_LIBRARY_PATH}"

. "${HELIXFOLD3DIR}/conda/etc/profile.d/conda.sh"
conda activate helixfold

### run helixfold3
INPUT="YOUR_INPUT_FILE"

python3.9 ${HELIXFOLD3DIR}/inference.py \
    --maxit_binary ${MAXIT_INSTALL_DIR}/bin/maxit \
    --jackhmmer_binary_path ${ENV_BIN}/jackhmmer \
    --hmmsearch_binary_path ${ENV_BIN}/hmmsearch \
    --hmmbuild_binary_path ${ENV_BIN}/hmmbuild \
    --nhmmer_binary_path ${ENV_BIN}/nhmmer \
    --hhblits_binary_path ${ENV_BIN}/hhblits \
    --hhsearch_binary_path ${ENV_BIN}/hhsearch \
    --kalign_binary_path ${ENV_BIN}/kalign \
    --preset="reduced_dbs" \
    --bfd_database_path "$DATA_DIR/bfd/bfd_metaclust_clu_complete_id30_c90_final_seq.sorted_opt" \
    --small_bfd_database_path "$DATA_DIR/small_bfd/bfd-first_non_consensus_sequences.fasta" \
    --uniclust30_database_path "$DATA_DIR/UniRef30_2023_02/UniRef30_2023_02" \
    --uniprot_database_path "$DATA_DIR/uniprot/uniprot.fasta" \
    --pdb_seqres_database_path "$DATA_DIR/pdb_seqres/pdb_seqres.txt" \
    --uniref90_database_path "$DATA_DIR/uniref90/uniref90.fasta" \
    --mgnify_database_path "$DATA_DIR/mgnify/mgy_clusters.fa" \
    --ccd_preprocessed_path "$DB_DIR/helixfold3_dbs/ccd_preprocessed_etkdg.pkl.gz" \
    --rfam_database_path "$DB_DIR/helixfold3_dbs/Rfam-14.9_rep_seq.fasta" \
    --template_mmcif_dir "$PDB_DIR/pdb_mmcif/mmcif_files" \
    --obsolete_pdbs_path "$PDB_DIR/pdb_mmcif/obsolete.dat" \
    --max_template_date=2020-05-14 \
    --input_json ${INPUT}.json \
    --output_dir . \
    --model_name allatom_demo \
    --init_model "$DB/helixfold3_dbs/HelixFold3-240814.pdparams" \
    --infer_times 3 \
    --precision "fp32"
```

上記のrunファイルの`INPUT="YOUR_INPUT_FILE"`部分は、自身のインプットファイル`YOUR_INPUT_FILE.json`と合わせる形で書き換えてください。インプットファイルのjsonはこんな感じ。

```json:YOUR_INPUT_FILE.json
{
    "entities": [
        {
            "type": "protein",
            "sequence": "MTQQPFQLPHFYLPHPARLNPHLDEARAHSTTWAREMGMLEGSGVWEQSDLEAHDYGLLCAYTHPDCDGPALSLITDWYVWVFFFDDHFLEKYKRSQDRLAGKAHLDRLPLFMPLDDAAGMPEPRNPVEAGLADLWTRTVPAMSADWRRRFAVATEHLLNESMWELSNINEGRVANPVEYIEMRRKVGGAPWSAGLVEYATAEVPAAVAGTRPLRVLMETFSDAVHLRNDLFSYQREVEDEGELSNGVLVLETFFGCTTQEAADLVNDVLTSRLHQFEHTAFTEVPAVALEKGLTPLEVAAVGAYTKGLQDWQSGGHEWHMRSSRYMNKGERPLAGWQALTGPGTSAADVGALLADAVAQRARSYTYVPFQKVGPSVIPDIRMPYPLELSPALDGARRHLSEWCREMGILSEGVWDEDKLESCDLPLCAAGLDPDATQDQLDLASGWLAFGTYGDDYYPLVYGHRRDLAAARLTTTRLSDCMPLDGEPVPPPGNAMERSLIDLWVRTTAGMTPEERRPLKKAVDDMTEAWLWELSNQIQNRVPDPVDYLEMRRATFGSDLTLGLCRAGHGPAVPPEVYRSGPVRSLENAAIDYACLLNDVFSYQKEIEYEGEIHNAVLVVQNFFGVDYPAALGVVQDLMNQRMRQFEHVVAHELPVVYDDFQLSEEARTVMRGYVTDLQNWMAGILNWHRNVPRYKAEYLAGRTHGFLPDRIPAPPVPRSSPALTH",
            "count": 1
        },
        {
            "type": "ligand",
            "ccd": "FPP",
            "count": 1
        },
        {
            "type": "ligand",
            "ccd": "MG",
            "count": 3
        }
    ]
}
```

`entities`の中には`type`が`protein`の場合は`sequence`にアミノ酸配列を、`type`が`ligand`の場合は`ccd`にChemical Component DictionaryのIDを入れます。`count`はその分子の数です。`type`が`ligand`の場合は`sequence`は不要です。
また、[公式のdemoディレクトリ](https://github.com/PaddlePaddle/PaddleHelix/tree/dev/apps/protein_folding/helixfold3/data)には核酸を使ったデモもありますので、そちらを見てください。

## 結果

400トークンくらいなら20分で、900トークンくらいなら40分くらいで結果が帰ってきました。結果のディレクトリに現れる`~~~-rank1`というものが最も良い予測結果なので、基本的にはこちらを見ましょう。予測された構造ファイルはすべて`predicted_structure.pdb`または`predicted_structure.cif`となっています（どちらでも同じです。MAXITによってpdbからcifに変換されているものと思います）。

![ScreenShot 2024-09-10 14.19.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224327/2c586b30-1824-53a8-16ab-f52d64bfc127.png)

![ScreenShot 2024-09-10 14.38.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224327/4e41ffba-971c-91fd-434d-26348c6f1506.png)

pLDDTもAF2時代と違って原子単位で値を持つようになっているので、[pLDDTカラーリング](https://qiita.com/Ag_smith/items/36cba5eb8e260c25a3d7)をすると、予測自信度が可視化できます。見る人がみたら分かるのですが、Mg2+と基質FPPがいい感じに入っています。