元鉴
返回中文阅读流

NVIDIA Developer Blog

使用 NVIDIA ALCHEMI 工具包为化学和材料科学构建自定义原子模拟工作流

几十年来,计算化学一直面临精度与速度之间的博弈。像密度泛函理论(DFT)这样的从头计算方法提供了高...

中文内容

已翻译official company source英文原文2026-05-26

几十年来,计算化学一直面临准确性与速度之间的拉锯。密度泛函理论(DFT)等从头算方法具有高保真度,但计算成本高昂,使研究人员只能处理数百个原子的体系。相反,经典力场速度很快,但往往缺乏复杂断键或过渡态分析所需的化学准确性。

机器学习原子间势(MLIPs)已成为连接两者的桥梁,以经典速度提供量子级准确性。然而,软件生态系统成为新的瓶颈。尽管 MLIP 模型本身在 GPU 上运行,其周边的模拟基础设施却往往依赖以 CPU 为中心的遗留代码。

NVIDIA ALCHEMI(AI Lab for Chemistry and Materials Innovation)通过 AI 加速化学品和材料发现,帮助应对这些挑战。我们此前已宣布 ALCHEMI 产品组合的两个组件:

  • ALCHEMI NIM 微服务:用于化学和材料科学中 AI 加速批量原子级模拟的可扩展、云就绪微服务
  • ALCHEMI Toolkit-Ops:一组基础 GPU 内核,旨在加速模拟背后的计算,例如邻居列表、色散校正和静电计算。

今天,我们推出 NVIDIA ALCHEMI Toolkit,这是一组 GPU 加速的模拟构建模块,整合并扩展了 ALCHEMI Toolkit-Ops。ALCHEMI Toolkit 旨在管理加速化学和材料领域专用内核与深度学习模型之间的数据流。ALCHEMI Toolkit 超越了单个模型和内核,提供了一种模块化、PyTorch 原生的结构,供研究人员和开发人员组合自定义模拟工作流。

图 1 展示了 ALCHEMI 的架构栈以及 ALCHEMI Toolkit 初始版本中支持的产品功能,包括 Toolkit-Ops 中扩展的功能。此版本包含几何弛豫和分子动力学能力,以及用于组合多个模拟工作流的配套流水线基础设施。

Graphic of ALCHEMI architectural stack (left) with list of product features supported in the initial release of ALCHEMI Toolkit (right).Graphic of ALCHEMI architectural stack (left) with list of product features supported in the initial release of ALCHEMI Toolkit (right).
图 1. NVIDIA ALCHEMI Toolkit 是一组 GPU 加速的模拟构建模块,可支持利用 AI 进行大规模批量模拟。

ALCHEMI Toolkit 如何推进数字化学?

ALCHEMI Toolkit 不仅仅是一组脚本。它旨在让研究人员和开发人员能够轻松构建自定义的高性能原子级模拟工作流。

扩展 ALCHEMI Toolkit-Ops

ALCHEMI Toolkit 利用 Toolkit-Ops 的能力来处理模拟的底层计算。此前的版本包含了几项关键操作:

  • 邻居列表构建
  • DFT-D3 色散校正
  • 长程静电相互作用

此版本扩大了所涵盖常见操作的范围,包括:

  • 批处理动力学内核
  • JAX 支持(适用于 v0.2.0 版本发布功能)

与原子级模拟生态系统集成

ALCHEMI Toolkit 旨在与更广泛的原子级模拟生态系统无缝集成。我们很高兴宣布与化学和材料科学领域领先平台的以下集成。

正文:Orbital

Orbital 开发先进的 AI 基础模型,用于加速数据中心新型冷却系统和可持续材料的发现。Orbital 已将 ALCHEMI Toolkit 集成到其新的 OrbMolv2 模型中,以大幅缩短推理所需时间。新模型将利用 ALCHEMI Toolkit 组件,例如用于周期性库仑相互作用的 PME 静电学,以及用于批量恒压分子动力学的 MTK 积分器。现有的 Orb 模型已利用 Toolkit-Ops 进行 GPU 加速的图构建,在 TorchSim 支持下,可为大型系统提供约 1.7 倍加速,并为批量较小系统提供约 33 倍加速。

正文:Materials Graph Library (MatGL)

MatGL 是一个面向先进图神经网络机器学习原子间势(MLIP)的开源框架。ALCHEMI Toolkit 正在与 MatGL TensorNet 模型集成,以显著加速材料模拟和性质预测工作流。通过利用 ALCHEMI Toolkit 的 GPU 原生内核和批处理基础设施,MatGL 用户可以在大规模模拟中实现更高的计算效率和更低的内存消耗。

正文:Matlantis

Matlantis 通过将通用 MLIPs 与高性能云计算相结合,实现快速材料发现。Matlantis 正在积极探索 ALCHEMI Toolkit,并确定其可组合动力学在哪些方面能够为工业材料模拟客户带来最大价值。这建立在其对 ALCHEMI Toolkit-Ops 的成熟集成之上——包括经过 Warp 优化的邻居列表构建和 DFT-D3 色散校正——显著降低了原子级相互作用的计算开销,最高可实现 10 倍加速。

此外,通过评估 ALCHEMI Toolkit 中的特定组件,此次合作有望使 Matlantis 从单结构优化迈向对数百万个分子构型进行高通量、并行弛豫。最终,该集成旨在进一步赋能小规模研究和工业级材料设计,以无与伦比的 GPU 效率加速化学评估。

如何开始使用 ALCHEMI Toolkit

本节将引导您了解如何开始使用 ALCHEMI Toolkit,该工具包上手简单,并以易用性为设计目标。

系统和软件包要求

  • 正文:Python ≥3.11,<3.14
  • 正文:PyTorch ≥2.8
  • CUDA Toolkit 12+,NVIDIA 驱动 470.57.02+
  • 操作系统:Linux(主要)、macOS
  • NVIDIA GPU(RTX 20xx 或更新版本),CUDA 计算能力 ≥ 7.0
  • 最低 4 GB RAM(大型系统推荐 16 GB)

安装

使用以下代码安装 ALCHEMI Toolkit:

# Install Atomic Simulation Environment (ASE, used in the examples below)
uv pip install ase

# Using pip
pip install nvalchemi-toolkit

# Using uv
uv venv --seed --python 3.12
uv pip install nvalchemi-toolkit

# Install from source
git clone https://github.com/NVIDIA/nvalchemi-toolkit.git 
cd nvalchemi-toolkit
uv sync --all-extras

# Add nvalchemi as a project dependency
uv add nvalchemi-toolkit

更多信息请参考 NVIDIA/nvalchemi-toolkit GitHub 仓库和 ALCHEMI Toolkit 文档。

ALCHEMI Toolkit 用于构建端到端工作流的关键功能

本节深入介绍 ALCHEMI Toolkit 的四项核心功能:可自定义的批量仿真工作流、自行构建的动力学类、模型封装器以及高级数据管理。这些功能为研究人员和开发者提供了所需的工具和灵活性,以创建定制化的端到端工作流,在 NVIDIA GPU 上最大限度提高效率和性能。

可自定义的批量仿真工作流

NVIDIA ALCHEMI Toolkit 的独特功能是 GPU 原生的批量动力学引擎。没有任何单一 MLIP 模型能够完美适用于每一种化学环境,尤其是在处理非局域、长程相互作用时。

ALCHEMI Toolkit 使研究人员能够将模块化的化学和材料科学领域专用内核与模型组合成自定义仿真工作流。该架构支持开发专用计算工作流,并运行包含数百万个并发原子相互作用的虚拟实验室,而不会产生传统软件栈的延迟。

能力

  • 将 MLIPs 与基于物理的修正相结合的可组合计算器
  • 高性能封装器(MACE、TensorNet、AIMNet2)

API 示例

以下示例构建数据、设置 MLIP,并配置 FIRE2 几何优化,随后将其用作 velocity Verlet(微正则系综)动力学的起点:

from ase import Atoms
from nvalchemi.data import AtomicData, Batch
from nvalchemi.dynamics import ConvergenceHook
from nvalchemi.dynamics.optimizers import FIRE2
from nvalchemi.dynamics.integrator import VelocityVerlet

# setup some batch of atomic structures
atomic_data = [AtomicData.from_atoms(Atoms(...), device="cuda") for _ in range(16)]
batch = Batch.from_data_list(atomic_data)

# setup your MLIP and dynamics classes
mlip = ...
# optimizer convergence depends on the force norm and max values
conv_criteria = ConvergenceHook(
    criteria=[
        {"key": "forces", "threshold": 0.05, "reduce_op": "norm"},
        {"key": "forces", "threshold": 0.1, "reduce_op": "max"}
    ]
)
optimizer = FIRE2(
    mlip,
    convergence_hook=conv_criteria,
    n_steps=200
)
velverlet = VelocityVerlet(mlip, n_steps=1000)

你可以通过两种方式之一运行并扩展仿真流水线:在单个 GPU 上,或跨多个 CPU 和 GPU。

在单个 GPU 上运行并扩展流水线:FusedStage 类通过将两个或多个动力学对象“相加”而形成。这使得可以将端到端工作流封装在 torch.compile 中,并共享 CUDA 流上下文。

fused = optimizer + velverlet
# context manager handles compilation and CUDA stream
with fused:
    # runs 200 steps of optimization and 1000 steps of MD
    fused.run(batch)

通过这种方法,你可以轻松构建仿真工作流,使其在批次中的样本立即收敛时按顺序运行各个步骤,并充分利用你的 GPU。

在多个 CPU 和 GPU 上运行并扩展流水线:第二种方法是将流水线分布到多个 CPU/GPU 上。随后,在两个 dynamics 类上使用管道运算符,会将 FIRE2 优化分配到一个 GPU 上,并将速度 Verlet 积分分配到另一个 GPU 上。

pipeline = optimizer | velverlet
# equivalent to manual allocation with explicit producer/consumer
# optimizer.next_rank = 1, velverlet.prior_rank = 0
# DistributedPipeline({0: optimizer, 1: velverlet})
with pipeline:
    pipeline.run(batch)

虽然这个示例为了说明目的而有意简化,但这种抽象允许用户将其流水线扩展到一个节点上的多个 GPU,并进一步扩展到多个节点,以处理任意大的数据集和任意数量的 ranks。

以下示例配置八个 GPU 来运行几何优化,并将结果通过流水线传递给另外八个 GPU 运行 Langevin 动力学:

from torch import distributed as dist
from torch.utils.data.distributed import DistributedSampler
from nvalchemi.data.datapipes import Dataset, DataLoader

# set up distributed; torchrun --nproc-per-node 8 --nnodes 2 ...
dist.initialize_process_group()
# set up data and distributed sampler
dataset = Dataset(...)
data_sampler = DistributedSampler(
   dataset,
   num_replicas=dist.get_world_size(),
   rank=dist.get_rank()
)
loader = DataLoader(
   dataset,
   batch_size=128,
   sampler=sampler,
   use_stream=True
)
# configure your pipeline; 8 ranks do optimization, 8 do langevin dynamics
optimizers = [FIRE2(mlip, ..., next_rank=index + 8) for index in range(8)]
dynamics = [Langevin(mlip, ..., prior_rank=index) for index in range(8)]
pipeline = DistributedPipeline(
    {index: stage for index, stage in enumerate(optimizers + dynamics)}
)
with pipeline:
    for batch in loader:
        pipeline.run(batch)

构建你自己的 dynamics 类

ALCHEMI Toolkit 提供模块化架构,可从零开始构建和自定义动力学类。这种方法使社区能够将新的采样方法或热力学系综集成到 ALCHEMI 环境中,同时保持对底层内核的直接访问。这将动力学转变为一个完全可自定义的环境,用户可以从头构建专用的动力学类。

功能

  • 专用的 GPU 优先轨迹分析工具
  • 集成且可自定义的动力学内核(Velocity Verlet、NPT、Langevin thermostats)
  • FIRE 和 FIRE2 优化器

API 示例

from enum import Enum

import torch

from nvalchemi.data import Batch
from nvalchemi.dynamics.base import BaseDynamics, DynamicsStage
from nvalchemi.hooks import Hook, HookContext


class MySimulatedAnnealer(Hook):
       def __init__(
           self,
           t_start: float,
           t_end: float,
           cooldown_steps: int,
           frequency: int,
           stage: DynamicsStage
       ) -> None:
           # this hook will fire off every `frequency` MD steps,
           # bringing the temperature from `t_start` to `t_end`
           self.frequency = frequency
           self.t_start = t_start
           self.t_end = t_end
           self.cooldown_steps = cooldown_steps
           self.stage = DynamicsStage.BEFORE_STEP
           self.decay = (t_end / t_start) ** (1.0 / cooldown_steps)
           self._current_temp = t_start

       def __call__(self, ctx: HookContext, stage: Enum) -> None:
           # access the calling dynamics class through `HookContext`
           dynamics = ctx.workflow
           dynamics.target_temperature = max(
               dynamics.target_temperature * self.decay,
               self.t_end
           )


class VelocityVerlet(BaseDynamics)
	__needs_keys__: {"energies", "forces", "masses", "velocities"}
	__provides_keys__: {"positions"}

       def __init__(
           self,
           model: BaseModelMixin,
           n_steps: int,
           dt: float = 1.0,  # timestep
           target_temperature: float = 300.0,  # initial temperature
           tau: float = 10.0,  # coupling constant
           hooks: list[Hook] | None = None,
           convergence_hook: ConvergenceHook | dict | None = None,
           **kwargs,
       ):
           super().__init__(model=model, n_steps=n_steps, hooks=hooks, convergence_hook=convergence_hook)
           self.dt = dt
           self.target_temperature = target_temperature
           self.tau = tau
           self._prev_accelerations = None
       
       def pre_update(self, batch: Batch) -> None:
           # perform the first half of velocity Verlet
           with torch.no_grad():
                accelerations = batch.forces / batch.masses
                self._prev_accelerations = accelerations.clone()
                batch.positions.add_(
                    batch.velocities * dt + 0.5 * accelerations * dt**2.0
                )

       def post_update(self, batch: Batch) -> None:
           # perform second half of velocity Verlet, with thermostat
           # temperature update
           with torch.no_grad():
               new_accelerations = batch.forces / batch.masses
               batch.velocities.add_(0.5 * (self._prev_accelerations + new_accelerations) * self.dt)
               ke_per_atom = 0.5 * batch.masses * (batch.velocities**2).sum(dim=-1, keepdim=True)
               # get the total kinetic energy per system
               total_ke = scatter_add_(...)
               current_temp = 2.0 * total_ke / (batch.num_atoms * 3.0)
               ratio = self.target_temperature / current_temp
               lam = torch.sqrt(
                  torch.tensor(1.0 + (self.dt / self.tau) * (ratio - 1.0))
               ).clamp(min=0.8, max=1.2)  # clamp for stability
               batch.velocities.mul_(lam)

# configure the new dynamics class
my_velverlet = VelocityVerlet(
    ...,
    hooks=[
        MySimulatedAnnealer(t_start=900.0, t_end=300.0, cooldown_steps=10, frequency=100, stage=DynamicsStage.BEFORE_STEP)
    ],
)

模型封装器

借助 ALCHEMI Toolkit,您可以将自己的预训练模型与加速物理组件结合使用。它提供了将您自己的模型导入流水线所需的基础设施,确保专有或特定领域的架构能够利用 GPU 原生编排。这抽象了不同模型类型的复杂性,提供了一条标准化路径,可将独立模型转化为生产就绪的高吞吐量仿真。

功能

  • MLIP 支持(MACE、TensorNet、AIMNet2)
  • 可组合的计算器
  • 标准化模型配置

API 示例

from beartype import beartype
from super_mlip import BestMLIPModel

from nvalchemi._typing import ModelOutputs
from nvalchemi.models.base import BaseModelMixin, ModelConfig, NeighborConfig


class BestMLIPWrapper(nn.Module, BaseModelMixin):
    def __init__(self, model: BestMLIPModel, **kwargs):
          super().__init__(**kwargs)
          # ModelConfig declares model capabilities (which are frozen)
          # and runtime control (mutable) for the rest of the framework
          self.model_config = ModelConfig(
	                 outputs=frozenset({"energy", "forces", "hessians"}),
	                 # this is actually the default value
	                 required_inputs=frozenset({"positions", "atomic_numbers"})
	                 autograd_outputs=frozenset({"forces"}),
	                 neighbor_config=NeighborConfig(cutoff=5.0, format="coo")
)

    def adapt_input(self, data: Batch, **kwargs) -> dict[str, Any]:
        # adapts the nvalchemi data structure to what is
        # expected by the model
        model_inputs = super().adapt_input(data, **kwargs)
        # dict structure expected by BestMLIPModel
        model_inputs["atom_numbers"] = data.atomic_numbers
        model_inputs["coords"] = data.positions
        return model_inputs

   def adapt_output(self, model_output: any, data: Batch) -> ModelOutputs:
       # adapt the model outputs from the model's forward pass to
       # format expected by nvalchemi
       output = super().adapt_output(model_output, data)
       energies = model_output["energies"]
       output["energies"] = energies
       # check model config for expected outputs
       if "forces" in self.model_config.active_outputs:
           output["forces"] = model_output["forces"]
       return output

    # beartype decorator is optional, but will runtime type check arguments
    @beartype
    def forward(self, data: Batch, **kwargs) -> ModelOutputs:
        model_inputs = self.adapt_input(data, **kwargs)
        # calls BestMLIPModel's forward definition based on MRO
        model_outputs = super().forward(**model_inputs)
        return self.adapt_output(model_outputs, data)

高级数据管理

传统上,在 CPU 与 GPU 之间移动数据所产生的“内存税”是 AI 驱动发现中的一个重要瓶颈。ALCHEMI Toolkit 充当科学数据的专用编排器,提供构建自定义摄取管道所需的基础设施,以便将信息从标准研究文件转移到优化的 GPU 张量中。

这支持发现流程实现规模化,使工业规模模拟能够通过熟悉的接口进行访问。通过标准化原子信息的表示和加载方式,ALCHEMI Toolkit 确保数据常驻在设备上,也就是说整个模拟都保留在 GPU 上,从而支持批量模拟,以优化 GPU 利用率并消除通信开销。

功能

  • 高性能数据加载器
  • ASE 和 Pymatgen 接口
  • AtomicData 和批处理对象

API 示例

from nvalchemi import AtomicData, Batch
from nvalchemi import data
from ase.build import slab
atoms = slab(...)

# Create AtomicData object from ase.Atoms object
data = AtomicData.from_atoms(atoms, device="cuda")
>>> data ...

data.node_properties
data.system_properties

# Create a Batch object from a list of AtomicData
batch = Batch.from_data_list([data, data, data])
batch.num_graphs
batch.get_data(0)
# get first three samples
batch[:2]
batch[mask]
batch["energies"] -> ...

batch.from_atoms([ase.Atoms,...])

# Create a dataset from ase.Atoms
writer = data.AtomicDataZarrWriter("atom_dataset.zarr")
# writer will amortize overhead by writing batches of data;
# this is equivalent to writing individual samples but efficiently
writer.write(batch)

# Read the data from zarr
reader = data.AtomicDataZarrReader("atom_dataset.zarr")
# Dataset treats device natively; individual samples # are placed on GPU and it accelerates preprocessing transforms;
# num_workers sets the number of threads used for async prefetching
dataset = data.Dataset(reader, device = "cuda", num_workers=4)
dataloader = data.DataLoader(dataset, batch_size=16)
for batch in dataloader:
	# do something with batch

开始使用 ALCHEMI Toolkit 构建分子工作流

ALCHEMI Toolkit 为研究人员和开发者提供了构建端到端、GPU 原生分子工作流所需的低级原语和高级抽象。将关键瓶颈——例如邻居列表构建、结构弛豫和积分步骤——迁移到 PyTorch 生态系统中,消除了主机到设备的内存传输开销;这种开销传统上一直限制着 MLIP 驱动的模拟。

无论你是在组合混合 ML 势或物理势,还是在扩展批量分子动力学,ALCHEMI Toolkit 都会公开必要的 API 钩子,以管理复杂的张量化状态,同时不牺牲性能。

要加速您的化学和材料科学模拟,并探索构建您自己的自定义工作流,请访问 NVIDIA/nvalchemi-toolkit GitHub 仓库和 ALCHEMI Toolkit 文档。随着我们持续扩展受支持操作和架构的库,我们鼓励您克隆该仓库,探索提供的 Jupyter notebooks,并开始将这些 GPU 加速工作流集成到您自己的发现流水线中。

致谢

我们要感谢 Orbital 的 James Gin、Tim Duignan、Vaidas Šimkus;MatGL 的 Shyue Ping Ong 教授;Matlantis 的 Susumu Ohno、Ryuhei Okuno、Jethro Tan,感谢他们与我们合作,将 NVIDIA ALCHEMI Toolkit 采用到他们的平台中。我们还要感谢 Nikita Fedik、Roman Zubatyuk、Atul Thakur 和 Logan Ward 对本文的贡献。

Like

标签

原文标题

Building Custom Atomistic Simulation Workflows for Chemistry and Materials Science with NVIDIA ALCHEMI Toolkit