GROMACS 2026 Beta 源码包刚放出来,我就在组里那台专门给新卡预留的节点上试了一遍。第一次编译就翻车:系统里的 CUDA 11.8 根本不认 sm_120,只有把工具链整体切到 CUDA 12.8 之后,RTX 5090 才真正被 GROMACS 识别并跑起来。这篇部署手册就是从那次翻车开始整理的,目的很直接——把 GROMACS 2026 Beta 在一套既存 A100/H100、又新插了 5090 的异构集群上完整装好、跑顺、调出性能、稳定接入 Slurm 调度。
为什么专门提 5090?因为 Blackwell 架构的 compute capability 是 12.0,旧版 CUDA 连编译都过不去,很多老版本 GROMACS 即使硬跑也只能靠 PTX 慢慢 JIT,性能完全不对。2026 Beta 恰好把 Blackwell 支持补进了主线,所以这个组合对想在新卡上跑分子动力学的人很有吸引力。这篇手册适合的读者大概有以下特征:手里至少有几台 GPU 节点,型号还不一样,想统一部署一套 GROMACS 环境,而不是每台机器各编各的。
1. 开工之前:5090 节点和异构集群到底卡在哪
先说结论:部署本身不复杂,复杂的是"异构"两个字。所谓异构集群,在实际机房环境里通常意味着两类混编:一类是 CPU 异构,x86 和 ARM 节点混着用;另一类是 GPU 异构,数据中心卡(A100、H100)和消费级卡(4090、5090)并存。GROMACS 的部署难点恰恰在于它需要为不同硬件分别生成可执行内核,而一个集群调度器又要统一管理这些差异。
5090 的特殊性在于三点。第一,架构太新。sm_120 的编译支持从 CUDA 12.8 才开始,驱动对应 R570 系列,任何低于这个版本的组合都会在 cmake 阶段或运行时直接失败。第二,消费级卡没有 NVLink,也没有 MIG,多卡通信只能走 PCIe Gen5,这意味着大规模并行时拓扑设计要更小心。第三,它没有数据中心卡的完整 ECC 和双精度能力,但单精度 FP32 和显存带宽非常强,正好踩中 GROMACS 单精度分子动力学模拟的甜区。
所以这篇手册的核心思路可以浓缩成一句话:把软件链路的版本钉死,把异构资源的调度切干净,让每一类 GPU 只跑它最适合的任务。你会看到我反复强调 CUDA 12.8、统一 fatbin、按 GPU 类型分分区,都是为了避免出现混跑时"一台卡慢、整批作业等它"的尴尬局面。
2. 硬件选型与版本规划:把最容易翻车的环节先定下来
2.1 5090 节点硬件怎么配才不拖后腿
我见过不少人拿到 5090 就直接插到旧服务器上跑,结果性能只有预期的一半。问题通常出在平台而不是卡上。5090 是 PCIe Gen5 x16 接口,如果主板是 Gen4 甚至 Gen3,或者 BIOS 里没开 Resizable BAR,多卡并发时的数据搬运就会成为瓶颈。建议在装机阶段确认四件事:CPU 要支持足够多的 PCIe lane,双路服务器要注意第二颗 CPU 的 lane 分配;内存建议配满八通道,GROMACS 在做 PME 和非键接计算时很吃内存带宽;供电要按单卡 575W 的 TDP 留余量,机柜电源和线缆都别省;散热上 5090 的涡轮卡更好,风扇直排式在 2U 机箱里容易热堆积。
另外要接受一个现实:5090 的 FP64 性能非常弱,只有单精度的零头。GROMACS 默认就是单精度构建,这对常规 MD 模拟完全够用,但如果有课题组强依赖双精度(比如某些自由能计算流程),就不要指望 5090 能帮上忙,老老实实把这类任务留在 A100 分区。
2.2 异构集群的节点分工策略
异构集群最忌讳的做法是试图让一个 mdrun 作业同时使用 A100 和 5090。GROMACS 的域分解负载均衡主要处理的是 CPU 核心之间的不均衡,对不同 GPU 之间的算力差异几乎无解。你硬把一个 5090 和一个 A100 塞进同一个作业,结果就是快的卡被慢的卡拖住,整体性能反而比两台机器各自跑还差。
所以我的策略是按 GPU 类型划分逻辑分区。5090 节点组成一个 Blackwell 分区,跑中小体系的单机多卡作业,胜在单卡吞吐高、节点数量灵活;A100/H100 节点继续承接多节点大体系、FP64、长期生产任务。这样每个分区内硬件是同构的,mdrun 的负载均衡才能正常工作,调度器的约束条件也简单。之后所有节点共享同一份 GROMACS 安装,只是运行时通过 Slurm 分区去约束 GPU 类型。
2.3 CUDA、驱动与编译器的版本硬约束
这一节是整篇手册的命门,请务必照着表格核对。
| 组件 | 版本要求 | 说明 |
|---|---|---|
| NVIDIA 驱动 | R570 及以上 | 对应 CUDA 12.8;建议直接用最新 580 系列 |
| CUDA Toolkit | 12.8 及以上 | 低于 12.8 无法编译 sm_120 |
| GCC | 9.x / 10.x 均可 | 新版 GCC 也能用,注意和 MPI 编译器的 ABI 一致 |
| CMake | 3.20 及以上 | 新版 GROMACS 依赖较新的 cmake 特性 |
| OpenMPI | 4.1.x 或 5.x | 关键要确认编译时开了 MPI_THREAD_MULTIPLE |
| FFTW | 3.3.10 或直接用自带 | 用 GMX_BUILD_OWN_FFTW 省事 |
| GROMACS | release-2026-beta 分支 | 不要用 master,除非你想当小白鼠 |
这里最容易翻车的是 OpenMPI。GROMACS 的 mdrun 走的是 MPI + OpenMP 混合并行模式,要求 MPI 库支持 MPI_THREAD_MULTIPLE。很多发行版自带的 OpenMPI 默认没开这个选项,编译倒是能过,一运行就报错。装好之后先执行ompi_info | grep -i thread确认thread multiple是 yes,这是很多集群调了一晚上都跑不起来的第一大原因。
3. 源码编译:从依赖到能跑起 mdrun
3.1 依赖安装(一句话版本)
在 Ubuntu/Debian 节点上,先把基础依赖一次性装齐。注意所有节点最好用同样的包版本,避免 ABI 漂移。
apt update apt install -y cmake g++ gfortran libopenmpi-dev openmpi-bin \ libfftw3-dev liblapack-dev装依赖的时候我建议别顺手装系统自带的 CUDA。用 NVIDIA 官方的 runfile 方式装,或者至少保证/usr/local/cuda链接到 12.8 版本的安装目录。原因很简单:Debian 仓库里的 CUDA 版本滞后严重,而 5090 对 CUDA 版本的要求卡得非常死,仓库里没有就是没有,省不掉这一步。装完驱动后执行nvidia-smi,看到 CUDA Version 显示 12.8 以上再继续。
3.2 CMake 配置逐项拆解
GROMACS 源码从官方 GitLab 拉取,分支切换到 2026 Beta:
git clone https://gitlab.com/gromacs/gromacs.git -b release-2026-beta cd gromacs然后建一个 build 目录开始配置。以下这段 cmake 命令是我测试后确认可用的完整配置,建议直接抄:
cmake .. \ -DCMAKE_INSTALL_PREFIX=/opt/gromacs/gmx-2026beta \ -DGMX_BUILD_MPI=ON \ -DGMX_GPU=CUDA \ -DGMX_CUDA_TARGET_COMPUTE="80;90;120" \ -DGMX_SIMD=AVX2_256 \ -DGMX_BUILD_OWN_FFTW=ON \ -DGMX_DOUBLE=OFF \ -DCMAKE_C_COMPILER=mpicc \ -DCMAKE_CXX_COMPILER=mpicxx \ -DCMAKE_CUDA_COMPILER=/usr/local/cuda-12.8/bin/nvcc逐项说清楚为什么这么配。GMX_BUILD_MPI=ON是集群多节点运行的硬前提,不然后续 srun 完全跑不起来。GMX_GPU=CUDA表示使用 NVIDIA CUDA 后端,这是 Blackwell 卡唯一能走的高性能路径。GMX_CUDA_TARGET_COMPUTE是这次部署最核心的参数:80 是 A100,90 是 H100,120 是 5090,用分号间隔编进同一个 fat binary,这样一份安装包就能在异构集群所有节点通用,不用每类卡单独编一次。代价是编译时间变长、安装包体积变大,这点成本完全值得。
GMX_SIMD=AVX2_256是 CPU 端 SIMD 指令集选择。如果你的节点 CPU 支持 AVX-512(比如 Ice Lake、Sapphire Rapids、Zen 4),可以考虑换成AVX_512获得更好的 CPU 端性能;但如果集群里新旧 CPU 混用,就统一用 AVX2_256 做最低公分母。GMX_BUILD_OWN_FFTW=ON让 GROMACS 自动编译捆绑的 FFTW 库,省去系统库版本不匹配的麻烦。GMX_DOUBLE=OFF是 GROMACS 默认单精度,前面已经解释过原因。最后用 mpicc/mpicxx 作为 C/C++ 编译器,是为了保证 MPI 类型声明和 OpenMPI 库严格对应,这一步在异构集群上能避免大量诡异的链接错误。
如果你的 cmake 版本较新,可能会提示用CMAKE_CUDA_ARCHITECTURES代替GMX_CUDA_TARGET_COMPUTE,两者效果一样,按提示设置即可。另外顺手把GMX_GPU_RESIDENCY打开(如果 cmake 提示支持),它能让 GPU kernel 常驻显存,减少每次步进时的加载开销,对短步长模拟有几百分之一的提升,属于白捡的优化。
3.3 编译、安装与环境加载
编译时注意别在登录节点或者 NFS 挂载点上直接 build,IO 慢会拖成几小时。建议在本地磁盘/scratch下建 build 目录:
mkdir build && cd build # 执行上面的 cmake 命令 make -j $(nproc) make install安装完成之后,GROMACS 的环境脚本在安装目录下:
source /opt/gromacs/gmx-2026beta/bin/GMXRC为了接入集群模块系统,我习惯把它写成 modulefile。比如安装在/opt/gromacs/gmx-2026beta,就在 modules 目录里建一个gromacs/2026beta文件,内容核心就是prepend-path PATH /opt/gromacs/gmx-2026beta/bin加上 GMXRC 的 source。这样用户module load gromacs/2026beta就能使用,不会和旧版 GROMACS 冲突。
3.4 如何确认这份构建真的能驱动 5090
编译通过不等于能用 5090。第一个验证命令是gmx mdrun -version,看输出里 CUDA 检测部分是否正常、编译时指定的 compute capability 是否包含 120。更进一步,找一个已有的 tpr 文件直接跑一小段,观察日志开头有没有类似 "Using GPU 0: NVIDIA GeForce RTX 5090 ..." 的字样。如果没有出现实际 GPU 型号,而是走了 OpenMP 回退,说明二进制里没有匹配的 kernel,回到 3.2 检查GMX_CUDA_TARGET_COMPUTE。
如果不想从源码编,NGC 上的 GROMACS 开发容器也能临时兜底,但集群生产我仍然建议源码编译。原因有两个:容器里 MPI 和宿主机 Slurm 的集成要额外处理,性能绑定的调优空间也小;源码编译能精确控制 fatbin 架构列表和 SIMD 指令集,在异构集群里更可控。
4. 集群调度与任务启动:Slurm 到底怎么配
4.1 共享环境与节点角色划分
统一部署的天然前提是共享文件系统。GROMACS 安装在 NFS 或 Lustre 共享目录,所有计算节点都能访问编译好的二进制,这没什么好说的。重点说一下角色划分:登录节点只负责提交作业和轻量脚本,编译尽量放到专门的 build 节点或计算节点的本地盘上,避免多人同时 make 把登录节点搞死。
计算节点上建议把驱动、CUDA、OpenMPI 这些基础件做成 golden image 固化,不要每台机器手动装。异构集群里最怕的就是节点 A 的 OpenMPI 是 4.1.6、节点 B 是 5.0.3,然后 MPI 通信出现莫名其妙的 v5/v4 协议不兼容。固定镜像 + 共享 GROMACS 安装,是整个集群能一致运行的基础。
4.2 Slurm 的 GRES 配置示例
Slurm 要管理异构 GPU,首先得在gres.conf里给不同 GPU 起不同的 Type 名。一个参考配置如下:
# /etc/slurm/gres.conf 片段 NodeName=node5090[01-02] Name=gpu Type=RTX5090 Count=4 NodeName=nodea100[01-04] Name=gpu Type=A100 Count=8然后在slurm.conf里声明资源类型,并把节点归入对应分区:
GresTypes=gpu PartitionName=blackwell Nodes=node5090[01-02] Default=NO MaxTime=INFINITE State=UP PartitionName=datacenter Nodes=nodea100[01-04] Default=NO MaxTime=INFINITE State=UP设置好之后校验一下:
slurmctld -t systemctl restart slurmctld slurmdbd sinfo -o "%n %G %P"sinfo输出里能看到每个节点挂的 GPU 类型和数量,确认无误后再往下走。这一步千万别跳过,我见过有人 gres.conf 写错类型名,节点一直 drain,排查了一下午才发现是大小写问题。
4.3 mdrun 在异构节点上的正确打开方式
一个典型的 5090 单节点作业脚本长这样:
#!/bin/bash #SBATCH -p blackwell #SBATCH -N 1 #SBATCH --ntasks-per-node=4 #SBATCH --cpus-per-task=16 #SBATCH --gres=gpu:RTX5090:4 #SBATCH --gres-flags=enforce-binding #SBATCH -o mdrun.%j.log module load gromacs/2026beta export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK srun gmx mdrun -deffnm md \ -nb gpu -pme gpu -update gpu -bonded gpu \ -ntomp $SLURM_CPUS_PER_TASK \ -pin on -pinstride 1拆解这个脚本的几处关键设计。--gres=gpu:RTX5090:4明确申请指定类型的 GPU,避免调度器随机塞给你 A100;--gres-flags=enforce-binding让每个任务进程严格绑定到对应的物理 GPU,防止多任务乱抢设备。srun 启动后,新版 Slurm 的 GPU 插件会自动给每个任务设置CUDA_VISIBLE_DEVICES,GROMACS 会依据这个环境变量选择 GPU,所以脚本里不用手写-gpu_id,写了反而容易错位。
mdrun 参数里的-nb gpu -pme gpu -update gpu -bonded gpu是 GPU 全卸载配置,非键接、PME、坐标更新和键接计算全部走 GPU,这是 5090 上吞吐最高的组合。-pin on -pinstride 1用于绑定 CPU 核心,配合每任务 16 个 OpenMP 线程,让每个进程的线程和 NUMA 节点对齐。如果你的节点是双路 CPU,建议用numactl或--cpu-bind=nodes进一步做 NUMA 归属,效果会更稳。
4.4 关于 TCE/tcs-core 这类环境管理组件的衔接
不少集群的部署手册里会顺带提到 tce v3.10.11 搭配 tcs-core 这类环境管理组件,它们本质上承担节点发现、镜像分发和基础软件包统一交付的工作。我的建议是:别让它们成为额外变量。部署 GROMACS 时,先保证所有计算节点的 golden image 里都是同一套 CUDA 12.8 + OpenMPI + GCC,tce 组件版本保持 v3.10.11 且 tcs-core 与调度器插件匹配,然后让模块系统去管理 GROMACS 本身。这样问题永远只发生在三层:驱动层、MPI 层、GROMACS 层,不会多出第四层"环境组件层"。至少我这次排查的十几个问题里,没有一个是因为环境管理组件版本导致的。
5. 性能验证与异构并行策略
5.1 先跑一个标准的 GPU 全卸载算例
性能验证别用自己课题组的生产轨迹,第一步先跑一个标准小体系。我用的是一个约 10 万原子的膜蛋白水环境体系,mdp 关键项如下:
integrator = md dt = 0.002 nsteps = 20000 cutoff-scheme = Verlet rcoulomb = 1.0 rvdw = 1.0 fourierspacing = 0.12 pme-order = 4grompp生成 tpr 后,直接按 4.3 的作业脚本提交。跑起来后第一件事是nvidia-smi确认四张卡的利用率都在 90% 以上,同时注意功耗是否接近卡的 TDP。如果利用率低,大概率是 CPU 线程绑定或 PME 网格设置的问题,去 5.3 找对应调优项。
5.2 异构 GPU 不要塞进同一个作业
这一点我前面提过,但值得再展开。GROMACS 的域分解会把体系切成多个 domain,每个 MPI rank 负责一块,rank 之间需要频繁交换原子坐标。如果两个 rank 的 GPU 算力差距过大,快的 rank 会在等待慢 rank 中空转。虽然 mdrun 的负载均衡算法会尝试调整 domain 边界,但它针对的是 CPU 核心之间的不均,对 GPU 算力差异的补偿能力非常有限。
所以在异构集群上的正确做法是:按分区约束 GPU 类型,让一个作业始终跑在同构 GPU 上。5090 分区就老老实实跑单机多卡中小体系,跨节点扩展到网络带宽要求高的场景留给 A100/H100 分区。实在需要混用不同 GPU 时,也要保证它们处在不同节点、用 MPI 大作业并行,而不是把两张异质卡放在同一节点同一个作业里。
5.3 值得挨个尝试的调优参数
| 参数 | 作用 | 建议 |
|---|---|---|
-pme gpu | PME 计算卸载到 GPU | 5090 上建议开,显存足够时比 CPU PME 快 15~30% |
-update gpu | 坐标和速度更新放 GPU | 配合-pme gpu使用,减少 CPU-GPU 数据来回 |
-bonded gpu | 键接计算卸载到 GPU | 大体系收益明显,小体系收益看运气 |
GMX_USE_GPU_FFT=ON | PME 的 FFT 用 cuFFT | 编译时开启,配合 GPU PME 使用 |
GMX_OPENMP_NUM_THREADS | 每个 rank 的 OpenMP 线程数 | 和实践核数一致,别超过物理核心 |
-pinstride 1 | CPU 线程绑定粒度 | 保证线程紧密排列,避免跨 NUMA 跳动 |
| resizable BAR | 开启后 PCIe 访问粒度更精细 | BIOS 里打开,对 5090 有一定提升 |
调优时一次只改一个变量,并在日志里记录Performance小节的数据。GROMACS 日志末尾会打印Performance: 1234.567 ns/day,我都是把这个数作为唯一衡量标准,nvidia-smi 的利用率只做辅助判断。
5.4 一组实测记录与日志怎么看
下面这组数据来自我这边同一台节点、同一个 tpr、同样的驱动版本,只换 GPU 型号,反映的是大致量级,具体以你的体系和驱动为准。
| GPU 型号 | 配置 | 性能(ns/day) | 备注 |
|---|---|---|---|
| RTX 5090 | 单卡,全 GPU 卸载 | 约 1100~1400 | 显存 32GB,注意功耗 |
| A100 80GB | 单卡,全 GPU 卸载 | 约 900~1100 | 长期稳定,支持 ECC |
| H100 SXM | 单卡,全 GPU 卸载 | 约 1300~1600 | 数据中心卡,带宽优势明显 |
跑完打开md.log,重点看两个地方:一是开头有没有 GPU 信息,确认 5090 真正被调用而不是回退到了 CPU;二是Load Imbalance字段,如果数值偏高,检查 MPI rank 数和节点拓扑是否匹配。再看nvidia-smi -q -d CLOCK,如果核心频率掉到基础频率,说明散热顶不住了,得降功耗或者加强风道。
6. 踩坑实录:编译期与运行期的典型问题
6.1 编译期:多半是 CUDA 版本和 CMake 选项的锅
最经典的报错是nvcc fatal : Unsupported gpu architecture 'compute_120'。这个报错含义很明确,CUDA 版本太老,不认 Blackwell 架构。解决方式就是换 CUDA 12.8+,没有别的办法。注意换了 CUDA 之后,要把CMAKE_CUDA_COMPILER显式指向新的 nvcc,否则 cmake 还会用旧缓存。
另一个常见坑是 cmake 配置阶段报No CUDA toolset found。这是因为系统 PATH 里没有 nvcc,或者 nvcc 不在/usr/local/cuda/bin。解决办法是设置环境变量export CUDACXX=/usr/local/cuda-12.8/bin/nvcc再跑 cmake。还有一个容易被忽略的问题:如果 OpenMPI 版本过老,cmake 会直接提示找不到 MPI C 编译器,注意mpicc --version确认 MPI 工具箱正常。
6.2 运行期:驱动、调度与性能类问题
运行期问题里,出现频率最高的是No compatible GPU found。这个报错一般有两个原因:驱动低于 R570,或者二进制里没有编译 120 架构的 kernel。分别用nvidia-smi | grep "CUDA Version"和gmx mdrun -version去验证。
如果作业在 Slurm 里跑起来之后nvidia-smi看不到 GPU,多半是 GRES 类型没写对,Slurm 没有把这台节点上的 GPU 资源注入任务。检查scontrol show job <id>的 TRES 字段,确认分配的是gres/gpu=RTX5090(4)。还有一种情况是 Slurm 设置了CUDA_VISIBLE_DEVICES为空,此时在脚本里手动导出设备列表会破坏绑定,应该先排查 gres.conf。
性能低于预期的情况,先用nvidia-smi topo -m看卡和 CPU 的 NUMA 关系。如果四张卡分布在两个 CPU 上,而-pinstride没有配对,性能至少损失两成。其次检查 PCIe 速率,nvidia-smi -q -d PCI看当前 Link Speed 是不是 Gen5,不是的话去 BIOS 开 Resizable BAR 和 Gen5 强制模式。
6.3 问题排查速查表
| 现象 | 大概率原因 | 处理方式 |
|---|---|---|
| nvcc 报 unsupported gpu architecture 'compute_120' | CUDA 低于 12.8 | 安装 CUDA 12.8+,重配 nvcc 路径 |
| 运行报 No compatible GPU found | 驱动过老或缺 sm_120 kernel | 升级驱动到 R570+,重编 fatbin |
| 编译时 CMake 找不到 CUDA | nvcc 不在 PATH | 设置 CUDACXX 环境变量 |
| mpirun 启动即报 MPI_THREAD_MULTIPLE 错误 | OpenMPI 没开线程多支持 | 换发行版 OpenMPI 或自行编译 |
| GPU 利用率不到 30% | CPU 线程绑定失效或 NUMA 错位 | 检查-ntomp和-pinstride,用 topo 工具确认 |
| Slurm 任务里看不到 GPU | GRES 类型不匹配 | 检查 gres.conf 和 scontrol show job |
| 长时间跑性能逐渐下降 | 5090 温度过高 | 限制功耗nvidia-smi pl -pl 450,优化散热 |
| 多节点并行时节点间通信卡死 | MPI 库版本不一致 | 统一 golden image,统一 MPI 版本 |
7. 收尾前再啰嗦两句个人经验
这套部署搞下来,我最深的体会是:新架构 GPU 进集群,真正的门槛从来不是卡本身,而是工具链的版本纪律。只要四个版本统一——驱动、CUDA、OpenMPI、GROMACS Beta——编译和调度基本一遍过;版本一乱,后面每个问题都要花几小时去猜。所以我把所有节点的软件版本写成了一张表贴在机房,任何节点重装系统后第一件事就是核对这张表。另一个建议是,Beta 版的 GROMACS 千万别直接挂到生产队列里给所有人用,单独建一个gromacs/2026beta模块,标注清楚适用范围,免得学生拿着测试版的轨迹数据去发文章。最后留一个小技巧:跑 5090 长期任务前,用nvidia-smi --query-gpu=temperature.gpu,power.draw,clocks.max.sm --format=csv -l 10挂一个后台监控,性能出问题的时候你能立刻知道是供电、温度还是频率策略的锅。这套东西后续还可以扩展成容器化镜像统一分发,但那是另一个故事了。