AWS ParallelCluster で Apptainer と Mountpoint for Amazon S3 の組み合わせて Trinity を実行してみた

2024.04.27

AWS ParallelCluster 環境において Apptainer と Mountpoint for Amazon S3 を利用し、S3 をストレージとして利用した Trinity の実行方法を検証します。

確認結果

本検証では、Apptainer が利用可能な AWS ParallelCluster 環境において、Mountpoint for Amazon S3 を使用して S3 バケットをマウントし、Trinity を実行しました。主な確認結果は以下の通りです。

  1. Apptainer のコンテナイメージを S3 に保存し、コンピュートノードに S3 マウントすることで問題なく起動できました
  2. Trinity の実行に必要なリードデータのインプットファイルも S3 に保存し、マウントすることで正常に読み込めました
  3. 解析結果の出力先として EFS を指定し、問題なく結果が保存されました

大容量データの読み取りが多いゲノム解析のワークロードで Apptainer on ParallelCluster を構築する場合は本構成もご検討ください。

クラスターのコンフィグ

コンピュートノードで Apptainer と Mountpoint for Amazon S3 が利用可能なクラスターを構成します。本検証環境を構築したクラスターのコンフィグファイルは以下です。

Region: ap-northeast-1
Image:
  Os: ubuntu2204
Tags:
  - Key: Name
    Value: Apptainer-Cluster-v391
# ----------------------------------------------------------------
# Head Node Settings
# ----------------------------------------------------------------
HeadNode:
  InstanceType: m7i-flex.large
  Networking:
    ElasticIp: false
    SubnetId: subnet-0c82bb28e119e2aa8
  Ssh:
    KeyName: org-sandbox-keypair
  LocalStorage:
    RootVolume:
      Size: 40
      Encrypted: true
      VolumeType: gp3
      Iops: 3000
      Throughput: 125
  Iam:
    AdditionalIamPolicies:
      - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
    S3Access:
      - BucketName: hpc-custom-boostrap-files
        EnableWriteAccess: false
  CustomActions:
    OnNodeConfigured:
      Sequence:
        - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh
        - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh
          Args:
            - hpc-dev-mountpoint-sample-1
            - /mnt/s3-readonly
            - "--allow-delete --allow-other"
        - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh
          Args:
            - hpc-dev-mountpoint-sample-2
            - /mnt/s3
            - "--allow-delete --allow-other"
        - Script: s3://hpc-custom-boostrap-files/apptainer/install.sh
# ----------------------------------------------------------------
# Compute Node Settings
# ----------------------------------------------------------------
Scheduling:
  Scheduler: slurm
  SlurmSettings:
    ScaledownIdletime: 5
  SlurmQueues:
    # ------ Test 1 ------
    - Name: t1
      ComputeResources:
        - Name: t1
          Instances:
            - InstanceType: t3.micro
            - InstanceType: t3a.micro
          MinCount: 0
          MaxCount: 20
          DisableSimultaneousMultithreading: true
      ComputeSettings:
        LocalStorage:
          RootVolume:
            Size: 40
            Encrypted: true
            VolumeType: gp3
            Iops: 3000
            Throughput: 125
      CapacityType: SPOT
      AllocationStrategy: capacity-optimized
      Networking:
        SubnetIds:
          - subnet-0c82bb28e119e2aa8
          - subnet-0296a0c8515ed3bdc
          - subnet-0089ff187d1f54258
        PlacementGroup:
          Enabled: false
      Iam:
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        S3Access:
          - BucketName: hpc-custom-boostrap-files
            EnableWriteAccess: false
    # ------ Compute 1 ------
    - Name: p1
      ComputeResources:
        - Name: p1-m7ixlarge
          Instances:
            - InstanceType: m7i-flex.xlarge
          MinCount: 0
          MaxCount: 10
          DisableSimultaneousMultithreading: true
      ComputeSettings:
        LocalStorage:
          RootVolume:
            Size: 40
            Encrypted: true
            VolumeType: gp3
            Iops: 3000
            Throughput: 125
      CapacityType: SPOT
      AllocationStrategy: capacity-optimized
      Networking:
        SubnetIds:
          - subnet-0c82bb28e119e2aa8
          - subnet-0296a0c8515ed3bdc
          - subnet-0089ff187d1f54258
        PlacementGroup:
          Enabled: false
      CustomActions:
        OnNodeConfigured:
          Sequence:
            - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh
            - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh
              Args:
                - hpc-dev-mountpoint-sample-1
                - /mnt/s3-readonly
                - "--read-only --allow-other"
            - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh
              Args:
                - hpc-dev-mountpoint-sample-2
                - /mnt/s3
                - "--allow-delete --allow-other"
            - Script: s3://hpc-custom-boostrap-files/apptainer/install.sh
      Iam:
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
          - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
        S3Access:
          - BucketName: hpc-custom-boostrap-files
            EnableWriteAccess: false
# ----------------------------------------------------------------
# Shared Storage Settings
# ----------------------------------------------------------------
SharedStorage:
  - MountDir: /mnt/efs
    Name: efs1
    StorageType: Efs
    EfsSettings:
      FileSystemId: fs-0846dc947572a66a1

# ----------------------------------------------------------------
#  Other Settings
# ----------------------------------------------------------------
Monitoring:
  Logs:
    CloudWatch:
      Enabled: true
      RetentionInDays: 180
      DeletionPolicy: "Delete"
  Dashboards:
    CloudWatch:
      Enabled: true

こちらのコンフィグから構築したクラスターを元に以降の検証を進めます。

検証環境情報

項目
AWS ParallelCluster 3.9.1
OS Ubuntu 22.04 LTS
CPU Arch Intel(x86_64)
HeadNode m7i-flex.large
ComputeNode m7i-flex.xlarge

各種スクリプト参考

Apptainer インストールスクリプト、Mountpoint for Amazon S3 インストールスクリプトは各紹介記事を参考にしてください。

ヘッドノードの設定

コンピュートノードはカスタムブートストラップ処理で Mountpoint for Amazon S3 がインストールされます。クラスターを構築後にヘッドノードは手動で設定します。

Mountpoint for Amazon S3 設定

Mountpoint for Amazon S3 をインストールします。

sudo apt update
sudo apt install libfuse2 -y

wget -P /tmp https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.deb
sudo apt-get install /tmp/mount-s3.deb -y

コンピュートノードと同じ S3 バケットをコンピュートノードにマウントしたパスと同じくマウントします。コンピュートノードは/mnt/s3-readonlyと名付けて、その通り読み取り専用でマウントしました。ヘッドノードからは書き込み権限があると都合がよかったため、ディレクトリ名はreadonlyだけど書き込みも可能な権限にしています。ヘッドノード、コンピュートノードともに/mnt/s3に別の S3 バケットをマウントしたのですが今回は使う機会がありませんでした。

sudo mkdir /mnt/s3-readonly
sudo mkdir /mnt/s3
sudo mount-s3 --allow-delete --allow-other hpc-dev-mountpoint-sample-1 /mnt/s3-readonly
sudo mount-s3 --allow-delete --allow-other hpc-dev-mountpoint-sample-2 /mnt/s3

Apptainer のコンテナイメージと、サンプルのリードデータをダウンロードし、すべてマウントした S3 バケットに保存します。

sudo wget -P /mnt/s3-readonly/images/ https://data.broadinstitute.org/Trinity/TRINITY_SINGULARITY/trinityrnaseq.v2.15.1.simg
sudo wget -P /mnt/s3-readonly/reads https://github.com/trinityrnaseq/trinityrnaseq/raw/master/Docker/test_data/reads.left.fq.gz
sudo wget -P /mnt/s3-readonly/reads https://github.com/trinityrnaseq/trinityrnaseq/raw/master/Docker/test_data/reads.right.fq.gz

Trinity の実行

検証環境では Apptainer の実行環境をセットアップする設定が入っているのは p1 です。Trinity の実行はこちらのパーティションを利用して、コンピュートノードを起動します。

$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
t1*          up   infinite     20  idle~ t1-dy-t1-[1-20]
p1           up   infinite     10  idle~ p1-dy-p1-m7ixlarge-[1-10]

Trinity を実行するために、以下のスクリプト(trinity.sh) を作成しました。マウントした S3 に保存した Trinity のコンテナイメージを指定し、同じ S3 に保存したサンプルのリードデータを入力ファイルとして使用します。また、出力結果の保存先はマウントしている EFS を指定しています。

#! /bin/bash

#SBATCH -p p1
#SBATCH -N 1

MOUNT_PATH="/mnt"
IMAGE_PATH="/mnt/s3-readonly/images"
USE_IMAGE="trinityrnaseq.v2.15.1.simg"
READ_FILE_PATH="/mnt/s3-readonly/reads"

apptainer exec --bind ${MOUNT_PATH}:/mnt \
      -e ${IMAGE_PATH}/${USE_IMAGE} \
          Trinity \
          --seqType fq \
          --left ${READ_FILE_PATH}/reads.left.fq.gz \
          --right ${READ_FILE_PATH}/reads.right.fq.gz \
          --NO_SEQTK \
          --max_memory 16G --CPU 2 \
          --output /mnt/efs/result_trinity/$(date +"%Y%m%d%H%M")/trinity_out_dir

このスクリプトをジョブとしてサブミットすることで、Trinity の解析処理が開始されます。

$ sbatch trinity.sh

コンピュートノードが起動し、スクリプトが実行されると標準出力をモニタリングしていると進行状況を確認できます。コンピュートノードにもマウントしている S3 バケットに保存した Trinity のコンテナイメージから起動できました。サンプルのリードデータも読み込めています。

     ______  ____   ____  ____   ____  ______  __ __
    |      ||    \ |    ||    \ |    ||      ||  |  |
    |      ||  D  ) |  | |  _  | |  | |      ||  |  |
    |_|  |_||    /  |  | |  |  | |  | |_|  |_||  ~  |
      |  |  |    \  |  | |  |  | |  |   |  |  |___, |
      |  |  |  .  \ |  | |  |  | |  |   |  |  |     |
      |__|  |__|\_||____||__|__||____|  |__|  |____/

    Trinity-v2.15.1



Left read files: $VAR1 = [
          '/mnt/s3-readonly/reads/reads.left.fq.gz'
        ];
Right read files: $VAR1 = [
          '/mnt/s3-readonly/reads/reads.right.fq.gz'
        ];
Trinity version: Trinity-v2.15.1
-currently using the latest production release of Trinity.

Friday, April 26, 2024: 10:12:06        CMD: java -Xmx64m -XX:ParallelGCThreads=2  -jar /usr/local/bin/util/support_scripts/ExitTester.jar0
Friday, April 26, 2024: 10:12:11        CMD: java -Xmx4g -XX:ParallelGCThreads=2  -jar /usr/local/bin/util/support_scripts/ExitTester.jar 1
Friday, April 26, 2024: 10:12:11        CMD: mkdir -p /mnt/efs/result_trinity/202404261011/trinity_out_dir
Friday, April 26, 2024: 10:12:12        CMD: mkdir -p /mnt/efs/result_trinity/202404261011/trinity_out_dir/chrysalis


----------------------------------------------------------------------------------
-------------- Trinity Phase 1: Clustering of RNA-Seq Reads  ---------------------
----------------------------------------------------------------------------------

しばらく待つと終了しました。実行結果の保存先パスは EFS になっていました。こちらも問題ありませんでした。

#############################################################################
Finished.  Final Trinity assemblies are written to /mnt/efs/result_trinity/202404261011/trinity_out_dir.Trinity.fasta
#############################################################################

実行結果確認

EFS 配下にスクリプト内で指定した名前で保存されていました。

ubuntu@ip-10-0-1-135:/mnt/efs/result_trinity/202404261011$ pwd
/mnt/efs/result_trinity/202404261011

ubuntu@ip-10-0-1-135:/mnt/efs/result_trinity/202404261011$ ll
total 168
drwxrwxr-x 3 ubuntu ubuntu   6144 Apr 26 10:14 ./
drwxrwxr-x 3 ubuntu ubuntu   6144 Apr 26 10:12 ../
drwxrwxr-x 8 ubuntu ubuntu   6144 Apr 26 10:14 trinity_out_dir/
-rw-rw-r-- 1 ubuntu ubuntu 152747 Apr 26 10:14 trinity_out_dir.Trinity.fasta
-rw-rw-r-- 1 ubuntu ubuntu   2906 Apr 26 10:14 trinity_out_dir.Trinity.fasta.gene_trans_map

ubuntu@ip-10-0-1-135:/mnt/efs/result_trinity/202404261011$ ll trinity_out_dir
total 41048
drwxrwxr-x 8 ubuntu ubuntu     6144 Apr 26 10:14 ./
drwxrwxr-x 3 ubuntu ubuntu     6144 Apr 26 10:14 ../
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 .iworm.25.asm.ok
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 .iworm_renamed.25.asm.ok
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 .jellyfish_count.25.mincov1.asm.ok
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 .jellyfish_dump.25.mincov1.asm.ok
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 .jellyfish_histo.25.mincov1.asm.ok
-rw-rw-r-- 1 ubuntu ubuntu      769 Apr 26 10:14 Trinity.timing
-rw-rw-r-- 1 ubuntu ubuntu   193155 Apr 26 10:14 Trinity.tmp.fasta
drwxrwxr-x 2 ubuntu ubuntu     6144 Apr 26 10:14 Trinity.tmp.fasta.salmon.idx/
drwxrwxr-x 2 ubuntu ubuntu     6144 Apr 26 10:14 __salmon_filt.chkpts/
-rw-rw-r-- 1 ubuntu ubuntu  6838210 Apr 26 10:12 both.fa
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 both.fa.ok
-rw-rw-r-- 1 ubuntu ubuntu        6 Apr 26 10:12 both.fa.read_count
drwxrwxr-x 2 ubuntu ubuntu     6144 Apr 26 10:12 chrysalis/
-rw-rw-r-- 1 ubuntu ubuntu   217303 Apr 26 10:12 inchworm.DS.fa
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 inchworm.DS.fa.finished
-rw-rw-r-- 1 ubuntu ubuntu        7 Apr 26 10:12 inchworm.kmer_count
drwxrwxr-x 2 ubuntu ubuntu     6144 Apr 26 10:12 insilico_read_normalization/
-rw-rw-r-- 1 ubuntu ubuntu 15075968 Apr 26 10:12 jellyfish.kmers.25.asm.fa
-rw-rw-r-- 1 ubuntu ubuntu     1891 Apr 26 10:12 jellyfish.kmers.25.asm.fa.histo
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 left.fa.ok
-rw-rw-r-- 1 ubuntu ubuntu     3968 Apr 26 10:12 partitioned_reads.files.list
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 partitioned_reads.files.list.ok
-rw-rw-r-- 1 ubuntu ubuntu      381 Apr 26 10:14 pipeliner.4977.cmds
drwxrwxr-x 3 ubuntu ubuntu     6144 Apr 26 10:12 read_partitions/
-rw-rw-r-- 1 ubuntu ubuntu    15268 Apr 26 10:12 recursive_trinity.cmds
-rw-rw-r-- 1 ubuntu ubuntu    15268 Apr 26 10:14 recursive_trinity.cmds.completed
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 recursive_trinity.cmds.ok
-rw-rw-r-- 1 ubuntu ubuntu        0 Apr 26 10:12 right.fa.ok
drwxrwxr-x 5 ubuntu ubuntu     6144 Apr 26 10:14 salmon_outdir/
-rw-rw-r-- 1 ubuntu ubuntu 19560321 Apr 26 10:12 scaffolding_entries.sam

Trinity の中間データ生成

trinity コマンド--outputで指定する出力先には計算時に利用する中間データも生成されています。 EFS の Read/Write IOPS のメトリクスを確認したところ、読み込みが書き込みの 4 倍であることがわかりました。 trinity_out_dirディレクトリにはファイルが大量に生成されているため、私の予想は書き込みが多いものと予想していました。しかし、実際には読み込みの方が多いという結果になりました。

Elastic スループットモードを利用しています。最近はストレージのパフォーマンス改善アップデートも多く助かるのですが、ディスクの読み書きで課金が発生します。中間データの読み書き先のストレージは今後改めて検討します。

確認結果

AWS ParallelCluster 環境で Apptainer と Mountpoint for Amazon S3 を組み合わせ、S3 をストレージとして活用した Trinity の実行方法を紹介しました。

検証の結果、Apptainer のコンテナイメージや Trinity の実行に必要なデータを S3 に保存し、マウントすることで問題なく利用できることを確認しました。また、解析結果の出力先として EFS を使用しも可能でした。

おわりに

今後はヘッドノードの設定を自動化することでより手間のかからないクラスター構築と、Trinity の計算中の中間データの適切な保存先を検討したいと考えています。 ゲノム解析など、大規模データを扱うワークロードを AWS ParallelCluster で実行する際は、本構成を参考にしていただければ幸いです。