はじめに
BioEmu(Biomolecular Emulator)は Microsoft Research AI for Science チームが開発した、タンパク質のコンフォメーションアンサンブル(構造動態)を生成する生成 AI モデルです。
従来の分子動力学(MD)シミュレーションでは、タンパク質の機能的運動を再現するのにマイクロ秒〜ミリ秒スケールの計算が必要で、スーパーコンピュータでも数週間〜数ヶ月を要しました。BioEmu は単一 GPU で 1 時間に数千のコンフォメーション構造をサンプリングでき、従来 MD の 10万倍高速 で熱力学的に妥当なアンサンブルを生成します。
本記事では、BioEmu を使った構造アンサンブル生成の手順を、ローカル GPU と Azure AI Foundry の両パターンで解説します。
BioEmu のモデルバージョン
| チェックポイント | 特徴 | 用途 |
|---|---|---|
bioemu-v1.0 |
preprint 時の重み | 再現実験用 |
bioemu-v1.1(デフォルト) |
Science 論文(2025年7月)のモデル | 推奨 |
bioemu-v1.2 |
拡張 MD + 実験データで学習 | 最高精度 |
📝 本シリーズの他の記事もあわせてご覧ください:
前提条件
ハードウェア要件
| 配列長 | 1,000 サンプルの所要時間(A100 80GB) |
|---|---|
| 100残基 | 約 4分 |
| 300残基 | 約 40分 |
| 600残基 | 約 150分 |
ソフトウェア要件
# Python 3.10 以上
pip install bioemu
# CUDA サポート付きでインストール(推奨)
pip install bioemu[cuda]
# 側鎖再構成・MD平衡化も行う場合
pip install bioemu[md]
注意: 初回使用時に AlphaFold2 のモデル重み(約 3.5 GB)が
~/.cache/colabfold/に自動ダウンロードされます。
Step 1 — 基本的なサンプリング
CLI から実行
最もシンプルな実行方法は CLI です。Chignolin(10残基の超小型タンパク質)を例に試します。
python -m bioemu.sample \
--sequence GYDPETGTWG \
--num_samples 100 \
--output_dir ~/bioemu-chignolin
Python API から実行
from bioemu.sample import main as sample
# Chignolin(10残基)─ タンパク質折りたたみのベンチマーク
sample(
sequence='GYDPETGTWG',
num_samples=100,
output_dir='~/bioemu-chignolin',
)
モデル重みは Hugging Face から自動ダウンロードされます。
出力ファイル
| ファイル | 説明 |
|---|---|
topology.pdb |
トポロジ(原子結合情報) |
samples.xtc |
サンプリングされた構造トラジェクトリ |
sequence.fasta |
入力配列 |
Step 2 — Steering によるサンプリング品質の向上
BioEmu には Sequential Monte Carlo(SMC)ベースの Steering システム が実装されており、物理的に妥当な構造を優先的にサンプリングできます。
Steering の仕組み
| パラメータ | 説明 | デフォルト |
|---|---|---|
num_steering_particles |
出力サンプルあたりの候補粒子数 | 1(Steering 無効) |
steering_start_time |
Steering 開始時刻(0.0〜1.0) | 0.1 |
steering_end_time |
Steering 終了時刻 | 0.0 |
resampling_interval |
リサンプリング頻度 | 1 |
利用可能なポテンシャル
- ChainBreak: 主鎖の不連続を防止
- ChainClash: 非隣接残基間のステリッククラッシュを回避
Steering 付きサンプリングの実行
python -m bioemu.sample \
--sequence GYDPETGTWG \
--num_samples 100 \
--output_dir ~/bioemu-steered \
--steering_config src/bioemu/config/steering/physical_steering.yaml \
--denoiser_config src/bioemu/config/denoiser/stochastic_dpm.yaml
Python API の場合:
from bioemu.sample import main as sample
sample(
sequence='GYDPETGTWG',
num_samples=100,
output_dir='~/bioemu-steered',
denoiser_config='src/bioemu/config/denoiser/stochastic_dpm.yaml',
steering_config='src/bioemu/config/steering/physicality_steering.yaml',
)
推奨: 3〜10 個の Steering パーティクルを使用すると、非物理的なサンプル(鎖断裂やクラッシュ)が大幅に減少します。
Step 3 — Azure AI Foundry で実行
ローカルに GPU がない場合、Azure AI Foundry の Managed Endpoint を使って推論できます。
エンドポイントの作成
- Azure AI Foundry にアクセス
- Models Catalog → 「BioEmu」を選択
- Deploy → プロジェクトを選択(なければ新規作成)
- VM サイズ: Standard_NC24ads_A100_v4(デフォルト)を 1 インスタンス
- Deploy をクリック(準備に約30分)
- 「Consume」タブからエンドポイント URL と API キーを取得
注意: リージョンの容量不足で「Creating」状態のまま進まない場合は、別のリージョンで再試行してください。
Foundry エンドポイントにリクエストを送信
import base64
import os
import requests
ENDPOINT_URL = "https://<ENDPOINT_NAME>.<REGION>.inference.ml.azure.com/score"
ENDPOINT_API_KEY = os.environ["BIOEMU_API_KEY"] # 環境変数で管理
OUTPUT_DIR = os.path.expanduser("~/bioemu-foundry-output")
SEQUENCE = "GYDPETGTWG" # Chignolin
NUM_SAMPLES = 100
def base64_decode_results(output_dir: str, result: dict[str, str]) -> None:
"""レスポンスの Base64 エンコードされた結果をファイルに保存"""
os.makedirs(output_dir, exist_ok=True)
for file_name, raw_data in result.items():
with open(os.path.join(output_dir, file_name), "wb") as f:
f.write(base64.b64decode(raw_data.encode("utf-8")))
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": f"Bearer {ENDPOINT_API_KEY}",
}
data = {
"input_data": {
"sequence": SEQUENCE,
"num_samples": NUM_SAMPLES,
}
}
response = requests.post(url=ENDPOINT_URL, headers=headers, json=data)
result = response.json()
if result["status"] != "success":
raise RuntimeError(f"推論失敗: {result['message']}")
print(f"結果を {OUTPUT_DIR} に保存します")
base64_decode_results(output_dir=OUTPUT_DIR, result=result["results"])
出力ファイル(samples.xtc, topology.pdb, sequence.fasta)が OUTPUT_DIR に保存されます。
Step 4 — 構造アンサンブルの解析と可視化
MDAnalysis による解析
import MDAnalysis as mda
import numpy as np
# トラジェクトリの読み込み
u = mda.Universe(
os.path.expanduser("~/bioemu-chignolin/topology.pdb"),
os.path.expanduser("~/bioemu-chignolin/samples.xtc"),
)
print(f"原子数: {u.atoms.n_atoms}")
print(f"フレーム数: {len(u.trajectory)}")
# Cα 原子を選択
ca_atoms = u.select_atoms("name CA")
print(f"Cα 原子数: {ca_atoms.n_atoms}")
RMSD 分布の計算
各サンプル構造の RMSD(Root Mean Square Deviation)を計算して、コンフォメーションの多様性を評価します。
from MDAnalysis.analysis import rms
# 最初のフレームを参照構造として RMSD を計算
ref = mda.Universe(
os.path.expanduser("~/bioemu-chignolin/topology.pdb"),
os.path.expanduser("~/bioemu-chignolin/samples.xtc"),
)
rmsd_analysis = rms.RMSD(u, ref, select="name CA")
rmsd_analysis.run()
rmsd_values = rmsd_analysis.results.rmsd[:, 2] # Cα RMSD
print(f"RMSD 平均: {np.mean(rmsd_values):.2f} Å")
print(f"RMSD 標準偏差: {np.std(rmsd_values):.2f} Å")
RMSD の可視化
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# RMSD ヒストグラム
axes[0].hist(rmsd_values, bins=30, edgecolor='black', alpha=0.7)
axes[0].set_xlabel("RMSD (Å)")
axes[0].set_ylabel("頻度")
axes[0].set_title("Cα RMSD 分布")
axes[0].axvline(np.mean(rmsd_values), color='red', linestyle='--',
label=f"平均: {np.mean(rmsd_values):.2f} Å")
axes[0].legend()
# RMSD 時系列(サンプル番号順)
axes[1].scatter(range(len(rmsd_values)), rmsd_values, s=5, alpha=0.5)
axes[1].set_xlabel("サンプル番号")
axes[1].set_ylabel("RMSD (Å)")
axes[1].set_title("サンプルごとの Cα RMSD")
plt.tight_layout()
plt.savefig("bioemu_rmsd_analysis.png", dpi=150, bbox_inches="tight")
plt.show()
PCA による構造空間の可視化
主成分分析(PCA)を使って、生成されたアンサンブルの構造空間分布を可視化します。
from MDAnalysis.analysis import pca
# Cα 原子の PCA
pca_analysis = pca.PCA(u, select="name CA")
pca_analysis.run()
# 寄与率
cumvar = np.cumsum(pca_analysis.results.variance / pca_analysis.results.variance.sum())
print(f"PC1 寄与率: {cumvar[0]*100:.1f}%")
print(f"PC2 寄与率: {(cumvar[1]-cumvar[0])*100:.1f}%")
# PC1-PC2 空間にプロット
transformed = pca_analysis.transform(u.select_atoms("name CA"), n_components=2)
plt.figure(figsize=(8, 6))
scatter = plt.scatter(
transformed[:, 0], transformed[:, 1],
c=range(len(transformed)), cmap="viridis", s=10, alpha=0.6,
)
plt.colorbar(scatter, label="サンプル番号")
plt.xlabel(f"PC1 ({cumvar[0]*100:.1f}%)")
plt.ylabel(f"PC2 ({(cumvar[1]-cumvar[0])*100:.1f}%)")
plt.title("BioEmu コンフォメーションアンサンブル ─ PCA")
plt.tight_layout()
plt.savefig("bioemu_pca.png", dpi=150, bbox_inches="tight")
plt.show()
Step 5 — 側鎖再構成と MD 平衡化
BioEmu の出力は主鎖(backbone)の構造のみです。側鎖を含む全原子モデルが必要な場合は、HPacker による側鎖再構成と、短時間の MD 平衡化を実行します。
# 側鎖再構成 + エネルギー最小化(デフォルト)
python -m bioemu.sidechain_relax \
--pdb-path ~/bioemu-chignolin/topology.pdb \
--xtc-path ~/bioemu-chignolin/samples.xtc
# 側鎖再構成のみ(MD なし)
python -m bioemu.sidechain_relax \
--pdb-path ~/bioemu-chignolin/topology.pdb \
--xtc-path ~/bioemu-chignolin/samples.xtc \
--no-md-equil
# 側鎖再構成 + NVT 平衡化(0.1 ns)
python -m bioemu.sidechain_relax \
--pdb-path ~/bioemu-chignolin/topology.pdb \
--xtc-path ~/bioemu-chignolin/samples.xtc \
--md-protocol nvt_equil
出力:
-
samples_sidechain_rec.{pdb,xtc}— 側鎖再構成後の構造 -
samples_md_equil.{pdb,xtc}— MD 平衡化後の構造
注意: 初回実行時に HPacker が自動インストールされます。
condaが PATH に必要です。
Step 6 — 応用ユースケース
ユースケース 1: Cryptic Pocket の発見
Cryptic pocket とは、通常は閉じているが薬剤結合時に開く結合部位です。BioEmu でアンサンブルを生成すると、開いた状態の構造をサンプリングできる可能性があります。
# 創薬ターゲットのタンパク質配列(例: p38α MAP キナーゼの一部)
target_sequence = "MSQERPTFYRQELNKTIWEVPERYQNLSP..." # 実際の配列を使用
sample(
sequence=target_sequence,
num_samples=1000,
output_dir='~/bioemu-p38alpha',
model_name='bioemu-v1.2', # 最高精度モデルを使用
steering_config='src/bioemu/config/steering/physicality_steering.yaml',
denoiser_config='src/bioemu/config/denoiser/stochastic_dpm.yaml',
)
生成された構造の中から結合ポケット体積が大きいものを選別することで、cryptic pocket のコンフォメーションを発見できます。
ユースケース 2: 折りたたみ自由エネルギーの推定
BioEmu は熱力学的に妥当なボルツマン分布からサンプリングするため、folded/unfolded 状態の存在比から折りたたみ自由エネルギー(ΔG)を推定できます。
# 折りたたみ状態と非折りたたみ状態の分類
# PDB の native 構造との RMSD が閾値以下なら folded
RMSD_THRESHOLD = 3.0 # Å
folded_count = np.sum(rmsd_values < RMSD_THRESHOLD)
unfolded_count = len(rmsd_values) - folded_count
# 折りたたみ自由エネルギーの推定
kB_T = 0.592 # kcal/mol at 300K
if unfolded_count > 0 and folded_count > 0:
delta_G = -kB_T * np.log(folded_count / unfolded_count)
print(f"ΔG_folding ≈ {delta_G:.2f} kcal/mol")
print(f"Folded: {folded_count}, Unfolded: {unfolded_count}")
BioEmu の相対自由エネルギー誤差は約 1 kcal/mol と報告されています。
ユースケース 3: 独自の MSA を使用
ColabFold のデフォルト MSA サーバーではなく、自分で作成した MSA(A3M 形式)を使用できます。
sample(
sequence='path/to/my_alignment.a3m', # A3M ファイルのパス
num_samples=500,
output_dir='~/bioemu-custom-msa',
)
パフォーマンス比較
| 手法 | 300残基・1000構造の所要時間 | コスト目安 | 熱力学的妥当性 |
|---|---|---|---|
| 従来 MD(Anton-2) | 数週間〜数ヶ月 | 数百万円 | 高 |
| BioEmu (A100 ローカル) | 約40分 | ~$5 | 中〜高 |
| BioEmu (Foundry) | 約60分 | 従量課金 | 中〜高 |
| AlphaFold2 | 数分(1構造のみ) | - | 静的構造のみ |
注意事項
- モノマー限定: 現行バージョンはモノマー(単量体)のみ対応。マルチマーは Linker trick で試行可能ですが精度は限定的
- 天然変性領域(IDR): 大きな天然変性領域を含むタンパク質では、クラッシュフィルタリングにより有効サンプルが大幅に減少する場合があります
- 側鎖の精度: 出力は主鎖構造のみ。側鎖再構成には HPacker + conda 環境が必要
- 学習データバイアス: 学習に使用された MD シミュレーションの力場(フォースフィールド)に依存するバイアスが存在します
まとめ
本記事では、BioEmu を使ったタンパク質コンフォメーションアンサンブル生成の実践手順を紹介しました。
- 基本サンプリング — CLI / Python API でアミノ酸配列から構造アンサンブルを生成
- Steering — 物理的制約(鎖断裂・クラッシュ回避)で高品質サンプリング
- Azure AI Foundry — GPU 不要でクラウド推論
- 解析・可視化 — RMSD 分布、PCA による構造空間の探索
- 側鎖再構成 — HPacker + MD 平衡化で全原子モデルを取得
- 応用 — Cryptic pocket 発見、折りたたみ自由エネルギー推定
BioEmu は AlphaFold2 が「静的な最安定構造の予測」であるのに対して、「動的なコンフォメーション分布の生成」を実現するツールです。特に創薬における動的な結合部位の探索に大きな可能性を持っています。
📝 本シリーズの他の記事もあわせてご覧ください:
References
[1] Scalable emulation of protein equilibrium ensembles with generative deep learning - Science, 2025
[2] microsoft/bioemu (GitHub) - Microsoft Research, 2025
[3] BioEmu on Azure AI Foundry - Microsoft, 2025
[4] How to run BioEmu on Azure AI Foundry - Microsoft, 2025
[5] BioEmu Model Weights (Hugging Face) - Microsoft, 2025