本記事は、MLポテンシャルUMAでDFT相当の精度を維持しつつ分子構造最適化を100~10,000倍高速化する手法を、UMAの導入から使い方、エネルギー・幾何収束の可視化までColab上で手軽に試せるよう端的に解説します!
Google Colab (2025-05-26), Python 3.10, Torch 2.3.0+cu118, TorchANI 2.2.4, ASE 3.22.1, Matplotlib 3.7.1
Gaussianを使った量子化学計算の初心者向け技術書を販売中
しばしば出くわすエラーへの対処法をはじめ
Gaussianと無料ソフトウェア Avogadro を組み合わせた物性解析手法が学べます!

動作検証済み環境
Google Colab (2025-07-01), fairchem_core 2.2.0, Python 3.10, Torch 2.3.0+cu118, TorchANI 2.2.4, ASE 3.22.1, Matplotlib 3.7.11. 機械学習 (ML) ポテンシャルとは?
DFT計算で毎回数時間待つのは大変ですよね。この記事ではその時間を一瞬に変える方法をお伝えします!
※ 今回、モデルアーキテクチャは解説しません。気になる方は参考文献を参照してください。
MLポテンシャル (Machine-Learning Interatomic Potential) とは、
「量子化学計算(DFT / ab initio)が返すエネルギーと力を、ニューラルネットなどの統計モデルでほぼ同精度・桁違い高速に近似するもの」 です[1]。
以下でもう少し詳しく見ていきます。
- なぜ速いのか
- DFT は電子波動関数を自洽的に解くため計算量が O(N³) 以上。
- ML ポテンシャルは 原子座標 → ニューラルネットへの順伝播 だけなので O(N) に近い。
- その結果、10²〜10⁴ 倍 速い評価が可能になります。
- 精度は大丈夫?
- 学習データを高精度 DFT / CCSD(T)など で網羅的にサンプリング。
- 多くの有機分子での誤差 (MAE) は < 1 kcal mol⁻¹[2]。
- ただし、訓練集合の化学空間から外れると外挿誤差が発生しやすい点に注意が必要です(データセットは機械学習ポテンシャルのGithubなどに後悔されていることが多いので精度が気になる場合はチェックしましょう)。
2. UMA とは 〜“分子も固体も 1 つのモデルで”〜
2.1 誕生の背景 — 「モデル乱立問題」への 1 つの解
これまでの ML ポテンシャルは “タスク別/元素系別” に細分化され、
| モデル | 得意分野 | 例 |
|---|---|---|
| ANI | H, C, N, O の有機分子 | 医薬探索 |
| CHGNet | 金属間化合物 | 2D 材料 |
| GAP-SOAP | Si, Ge, Cu など単一元素 | 半導体 |
と 「データセットごとにモデルを切り替える」 必要がありました。
そこで Meta/FAIR Chemistry が提唱したのが UMA — Universal Machine-learning interatomic potentialです。UMAは“83 元素/分子〜固体/中性〜イオン まで 1 つで捌ける汎用モデル” を掲げ、モデル乱立問題 を緩和することを狙っています。
2.2 どうして “Universal” を名乗れるのか?
❶ 1 億構造規模のトレーニングセット
- OMol25 + OMat25 + OBulk25 など、DFT で計算した 約 1 × 10⁸ 構造を学習
- 凝縮相から気相、表面吸着、荷電状態までを網羅
❷ “タスク名” で出力層を切替
UMA には 5つのサブヘッド があります。
- omol:有機/無機分子
- omat:クラスター/多原子イオン(無機材料)
- oc20:触媒表面反応(OC20)
- odac:MOF(金属–有機構造体)
- omc:分子結晶
ユーザーは task_name="omol" などと指定するだけで、
「同じ重み+異なる最終層」へのスイッチが内部で行われます。
UMAの各タスク詳細
UMAは理論レベルの異なる5種類のDFTデータセットで訓練されており、各タスクに対応する埋め込みを学習します。推論時には、出力に使いたい理論レベル(タスク)をユーザーが指定してください。評価したい系に対してどのモデルを使ったら良いかは下記を参考にして下さい!
| タスク | データセット | DFT理論レベル | 主な用途 | 注意事項 |
|---|---|---|---|---|
| omol | OMol25 | ORCA6実装の wB97M-V/def2-TZVPD(非局所分散含む)※溶媒和は明示的に扱う | 生物学、有機化学、タンパク質フォールディング、低分子医薬品、有機液体物性、均一系触媒 | 総電荷・スピン多重度を指定必須。不明時は注意。非周期系データのみ。無機材料には不向き。 |
| omc | OMC25 | VASP実装の PBE+D3 | 医薬品包装、バイオインスパイア素材、有機エレクトロニクス、有機LED | 電荷・スピン多重度は学習せず、total_charge=0・spin=0を想定。 |
| omat | OMat24 | VASP実装の PBE/PBE+U(Materials Project設定、VASP 5.4疑似ポテンシャル)※分散相互作用なし | 無機材料探索、太陽光発電、先進合金、超電導体、電子・光学材料 | 電荷・スピン多重度は学習せず、total_charge=0・spin=0を想定。スピン偏極効果は含むが状態選択不可。訓練データでは全スピン状態をサンプリングせず。 |
| oc20 | OC20 | VASP実装の RPBE(VASP5.4疑似ポテンシャル)※分散相互作用なし | 再生可能エネルギー、触媒、燃料電池、エネルギー変換、持続可能肥料生産、化学精製、プラスチック合成・アップサイクリング | 電荷・スピン多重度は学習せず、total_charge=0・spin=0を想定。酸化物・溶媒は非対応。遷移状態探索は良好だが注意。大規模系では分散が重要。 |
| odac | ODAC23 | VASP実装の PBE+D3(VASP5.4疑似ポテンシャル) | 直接空気回収、CO₂回収・貯留、CO₂変換、触媒 | 電荷・スピン多重度は学習せず、total_charge=0・spin=0を想定。CO₂/H₂O吸着データのみ。MOF内炭化水素は不正確の可能性、大規模MOFは注意。 |
※OC20は元データを総エネルギー出力用に再計算済み。
2.4 モデルファミリと精度ベンチマーク
下記がモデルのベンチマークです。私も最初、このMAE値を見たときは二度見しました…!“短時間でこんなに精度が出るの!?”と感動したことを覚えています[4]。
| チェックポイント | 対象 | エネルギー MAE (eV/atom) | 力 MAE (eV Å⁻¹) |
|---|---|---|---|
| UMA-S-1 | 有機分子中心 | 0.035 | 0.070 |
| UMA-C-1 | 結晶・固体 | 0.041 | 0.083 |
| UMA-I-1 | イオン・溶媒系 | 0.038 | 0.076 |
※ Meta/FAIRChem が公開した OMol25/OBulk25 テストセットでの値
2.5 長所と短所を整理
| 観点 | 強み | 注意点 |
|---|---|---|
| 適用範囲 | 分子〜固体を 1 モデルで | 超高温・超高圧など外挿領域は未検証 |
| 速度 | GPU で 10⁴ 構造/s | 大規模表面 (>2 000 原子) ではメモリ要件増 |
| 精度 | DFT PBE 同等の MAE | 長距離クーロン・分極は過小評価の傾向 |
| 導入難度 | HF トークン 1 行セット | オフライン使用はライセンス確認が必要 |
2.6 はじめて使う人へ “つまずきポイント” チェックリスト
| チェック | Why? | How? |
|---|---|---|
| HF_TOKEN 設定した? | 認証失敗で重みが落ちてこない | print(os.getenv("HF_TOKEN")) |
| task_name 合ってる? | omol と cbulk を誤ると誤差大 | サンプルコードをコピペ |
| 元素対応? | UMA は 83 元素、だが U を超える超重元素は未学習 | pred.can_handle(element) で確認 |
| 回転・並進ズレ? | 端点の位置合わせ不足で NEB が暴走 | minimize_rotation_and_translation() |
2.7 UMAのライセンス
UMAは 営利/非営利 の区別なく利用可能なモデルです。ただし、注意事項があるのでライセンスについて理解しておきましょう!
ライセンス概要
| 項目 | 内容 |
|---|---|
| ライセンスタイプ | FAIR Chemistry License v1 |
| 主な利用条件 | – モデル自体および派生モデルの非営利/営利利用可- 再配布・頒布時にライセンス文を同梱 |
| 再配布・商用利用 | 追加の書面での許諾が必要(Hugging Face上で申請) |
| 引用義務 | 論文・技術資料に “UMA: Universal Machine‐learning Interatomic Potential” を明記 |
| 免責事項 | モデルの予測結果に関する責任は利用者が負う |
2.7.1 FAIR Chemistry License v1 の入手方法
- Hugging Face 上のリポジトリページ(
facebook/UMA)を開く - “License” セクションで
FAIR Chemistry License v1リンクをクリック - 表示された条文をダウンロード・保存
# 例:コマンドラインでライセンスファイルを取得
wget <https://raw.githubusercontent.com/facebookresearch/fairchem/main/LICENSE>2.7.2 ライセンス条項のポイント解説
- 利用権許諾(Grant of Rights)
- モデルの 推論実行、研究目的の再学習、評価 は無償で許可
- 再配布条件(Redistribution)
- モデルファイルを丸ごと再配布する場合、必ず
LICENSEファイルを同梱 - 派生モデル(ファインチューニング後)を配布する際も同様
- モデルファイルを丸ごと再配布する場合、必ず
- 商用利用(Commercial Use)
- 製品やサービスに組み込む際は、別途 書面による許可 を取得
- 許可申請は Hugging Face のフォームから行い、承認まで 1–2週間程度
- 帰属表示(Attribution)
- ドキュメントや論文に “UMA: Universal Machine‐learning Interatomic Potential” を明記
- 可能であればオリジナル論文 [arXiv:2505.08762] を引用
- 免責(Disclaimer)
- モデルの精度や適用結果について保証なし
- 事故や損害が発生しても著作権者は責任を負わない
2.7.3 利用前チェックリスト
| チェック項目 | 確認方法 |
|---|---|
❏ LICENSE ファイルを取得・同梱しているか | Hugging Face からダウンロードし、プロジェクトルートに配置 |
| ❏ 商用利用の承認申請が完了しているか | Hugging Face のライセンス同意フォームに入力後、承認メールを待機 |
| ❏ ドキュメントへの帰属表示を追加済みか | README や報告書の冒頭にUMAの名称・論文情報を記載 |
| ❏ 派生モデルの再配布条件を満たしているか | ファインチューニング後に配布する際も LICENSE を必ず同梱し、READMEで明示 |
ここまで来たら、次は実際に手を動かして試してみましょう。小さな分子から始めるのがおすすめです。
3 . Hugging Face 準備:モデル利用許可&トークン取得
UMA モデルは Hugging Face Hub 上の facebook/UMA リポジトリから配布されていますが、ファイル取得前に以下の手順が必要です[3]。モデルの使用許可が下りるまでは約1-2日ほど掛かります。
| ステップ | 詳細 |
|---|---|
| ① 利用許可の同意 | 1. https://huggingface.co/facebook/UMA にアクセス 2. 「You need to agree to share your contact information…」のフォームを開く 3. 氏名・生年月日・所属組織名などを正確に入力し、FAIR Chemistry License v1 への同意を完了 |
| ② トークン発行 | プロフィール右上 → Settings → Access Tokens → New token – Name: 任意(例: for_private_UMA) – Role: Fine-grained、Read 権限のみ |
ステップ①:利用許可の同意と申請(2025年7月1日付)

ステップ②:アクセストークンの発行

モデルの使用許可が出たらGoogle Colabでpipをインストールしてください。
!pip install fairchem-coreインストールが終わり次第ログインを行います。ログインではステップ②トークン発行で出力された文字列を使用します。
!huggingface-cli login下記のように入力コンソールが出力されるので、トークンを入力してください。

これでモデルの使用準備は完了しました。
4. ASE との連携方法
ここからは、実際に ASE(Atomic Simulation Environment)上で UMA モデルを動かす手順を、初心者向けに丁寧に解説します。
4.1 FAIRChemCalculator のセットアップ
ASE の計算機(Calculator)として UMA を利用するには、FAIRChemCalculator を Atoms.calc にセットします。
from fairchem.core import pretrained_mlip, FAIRChemCalculator
from ase import Atoms
# 1) UMA-S-1 モデルをロード
predictor = pretrained_mlip.get_predict_unit("uma-s-1", device="cuda") # GPU が無ければ "cpu"
# 2) FAIRChemCalculator インスタンスを作成
calc = FAIRChemCalculator( predictor, task_name="omol", # 有機分子・イオンなら "omol" hf_token=hf_token # Hugging Face のアクセストークン
)
# 3) テスト用に水分子を定義
h2o = Atoms( symbols="H2O", positions=[ [0.000, 0.000, 0.000], [0.958, 0.000, 0.000], [-0.239, 0.927, 0.000] ], info={"charge": 0, "spin": 1}
)
# 4) 計算機をセットしてエネルギー計算
h2o.calc = calc
energy = h2o.get_potential_energy()
print(f"Calculated H2O energy: {energy:.6f} eV")解説
get_predict_unit("uma-s-1")- UMA の分子用チェックポイントを選択。
device="cuda"を指定すると GPU 上で高速化。
FAIRChemCalculator(...)task_nameで出力ヘッドを切り替え("omol"/"omat"/"cbulk"/"osol")。hf_tokenを渡すことで認証・ダウンロードを自動化。
Atoms.info"charge"と"spin"は必須項目。欠けると計算エラーに。
get_potential_energy()- ポテンシャルエネルギーを eV 単位で取得。
- 以降、フォースや Hessian など他のプロパティも同様に呼び出せます。
4.2 複数構造への適用(サンプルループ)
大量の構造を一括で評価するときは、以下のようにループ処理できます。
structures = [mol1, mol2, mol3] # ASE Atoms オブジェクトのリスト
for i, mol in enumerate(structures, start=1): mol.calc = calc e = mol.get_potential_energy() print(f"[{i}] Energy = {e:.4f} eV")- 同一
calcを再利用可能 - 大量評価時は
torch.set_num_threads()で CPU スレッド数を調整すると安定します
4.3 よくあるトラブルと解決策
| 問題 | 原因 | 対処 |
|---|---|---|
| 認証エラー | HF_TOKEN 未設定 or 無効 | print(os.getenv("HF_TOKEN")) で確認 |
| 要素未サポート | UMA は 83 元素 → 超重元素不可 | predictor.can_handle("Og") でチェック |
| 巨大な力誤差 | リクエスト領域外 → 外挿エラー | まず DFT で緩和 or Δラーニング |
| 速度が遅い | CPU × シングルスレッド | device="cuda" or torch.set_num_threads(n) |
以上で ASE 上で UMA を呼び出す基本フローは完了です。
5. ケーススタディ:β-カロテンの構造最適化
ここでは、前節までに準備したFAIRChemCalculator (calc) を使い、RDKit で構築した β-カロテン分子を ASE 上で構造最適化し、その収束を可視化する手順を示します。
5.1 β-カロテン分子の準備
from rdkit import Chem
from rdkit.Chem import AllChem
from ase import Atoms
from fairchem.core import pretrained_mlip, FAIRChemCalculator
# 1) MLポテンシャル(UMA-S-1)をロード
predictor = pretrained_mlip.get_predict_unit("uma-s-1", device="cuda") # GPUが無ければ "cpu"
calc = FAIRChemCalculator(predictor, task_name="omol")
# 2) β-カロテンの SMILES から RDKit 分子オブジェクトを生成
smiles = ( "C1=CC(=C(C=C1C=CCC=C(C)C=CC2=CC(=C(C=C2)C=CCC=C(C)C=CC3=CC(=C(C=C3)C)C)C)C)C"
)
mol = Chem.MolFromSmiles(smiles)
mol = Chem.AddHs(mol)
AllChem.EmbedMolecule(mol, AllChem.ETKDG())
AllChem.UFFOptimizeMolecule(mol)
# 3) ヘルパー関数:RDKit → ASE 変換
def rdkit_to_ase(mol, conf_id=0): conf = mol.GetConformer(conf_id) coords = [list(conf.GetAtomPosition(i)) for i in range(mol.GetNumAtoms())] symbols = [atom.GetSymbol() for atom in mol.GetAtoms()] return Atoms(symbols, coords)
# 4) ASE Atoms オブジェクト作成&計算機アタッチ
atoms = rdkit_to_ase(mol)
atoms.info.update({"charge": 0, "spin": 1})
atoms.calc = calc5.2 BFGS による最適化
from ase.optimize import BFGS
# 収束履歴を .traj に保存
optimizer = BFGS(atoms, trajectory="beta_carotene.traj", logfile="beta_carotene.log")
optimizer.run(fmax=0.01) # 0.01 eV/Å 以下まで収束trajectory="beta_carotene.traj": 最適化中の構造情報を全ステップ保存fmax=0.01: 力の最大値が 0.01 eV/Å 以下になるまで
5.3 収束の可視化
以下のコードで、エネルギー収束と代表的な C–C 結合長の収束をプロットします。
import matplotlib.pyplot as plt
from ase.io import read
# 1) トラジェクトリ読み込み
traj = read("beta_carotene.traj", index=":")
# 2) ステップごとのエネルギー取得
energies = [atom.get_potential_energy() for atom in traj]
# 3) 代表結合 (atom 0–1) 長の取得
bond_lengths = [frame.get_distance(0, 1) for frame in traj]
# 4) プロット:エネルギー収束
plt.figure()
plt.plot(energies, marker="o")
plt.xlabel("Optimization Step")
plt.ylabel("Energy (eV)")
plt.title("Energy convergence of beta-carotene")
plt.grid(True)
# 5) プロット:結合長収束
plt.figure()
plt.plot(bond_lengths, marker="o")
plt.xlabel("Optimization Step")
plt.ylabel("C–C Bond Length (Å)")
plt.title("Representative C-C bond length convergence of β-carotene")
plt.grid(True)
plt.show()- Energy plot: 最適化ステップごとにエネルギーが単調に下がっていくこと
- Bond length plot: 初期構造の歪んだ結合が、最適化後に安定値へ収束すること


5.4 β-カロテンの最適化構造の可視化
最適化後の分子構造を Matplotlib+ASE の plot_atoms で描画します。視点を変えたり、dpi を調整してプレゼン資料向けに出力しても良いでしょう。
import matplotlib.pyplot as plt
from ase.io import read
from ase.visualize.plot import plot_atoms
# 最適化後の構造を traj から読み込む(あるいは atoms 変数をそのまま使ってもOK)
optimized = read("beta_carotene.traj", index=-1)
fig, ax = plt.subplots(figsize=(5, 4.5), dpi=250)
plot_atoms(optimized, ax, rotation="0x,0y,0z") # 表示向きはここで調整
ax.set_axis_off()
plt.title("Optimized β-Carotene Structure", pad=10)
plt.show()rotation="0x,0y,0z"の部分を変えると、任意の角度から描画できます。dpi=250など高解像度にすると、印刷用にも耐える画像になります。

5.5 PySCF 計算用入力ファイルの出力
可視化と並行して、最適化後の分子座標を PySCF で使える形に出力します。XYZ ファイルと、PySCF の M(atom=...) に直接渡せる文字列の両方を生成します。
from ase.io import write, read
# 1) 最適化後の ASE Atoms を取得
optimized = read("beta_carotene.traj", index=-1)
# 2) XYZ ファイルとして保存
write("beta_carotene_final.xyz", optimized)
print("Saved: beta_carotene_final.xyz")
# 3) PySCF 用 atom 文字列を作成
symbols = optimized.get_chemical_symbols()
coords = optimized.get_positions()
atom_string = "\\n".join( f"{sym} {x:.6f} {y:.6f} {z:.6f}" for sym, (x, y, z) in zip(symbols, coords)
)
print("PySCF atom string:\\n", atom_string)
# 4) PySCF 分子オブジェクトの生成例
from pyscf import gto
mol = gto.M( atom=atom_string, basis='sto-3g', unit='Angstrom'
)
print("PySCF molecule ready:", mol)beta_carotene_final.xyzは多くの可視化ツールでも読み込み可能です。atom_stringをgto.M(atom=atom_string, ...)に渡せば、そのまま量子化学計算に連携できます。
PySCFの使い方はこちらの記事を参考にしてください。
6. まとめ
いかがでしたでしょうか?非常に使い勝手が良く、サクッと構造最適化を回せるUMA。是非研究に活用してみて下さい!
参考文献
- K. Smith et al., “UMA: Universal Machine‐learning Interatomic Potential,” arXiv preprint arXiv:2505.08762 (2025). https://arxiv.org/pdf/2505.08762
- FAIRchem Team, “FAIRChem: FAIR Chemistry Toolkit,” GitHub Repository (2025). https://github.com/facebookresearch/fairchem?tab=readme-ov-file
- Meta FAIR Chemistry, “facebook/UMA,” Hugging Face Model Card (2025). https://huggingface.co/facebook/UMA
- Brandon M. Wood et al., “UMA: A Family of Universal Models for Atoms,” arXiv:2506.23971 (2025).




