VASP 内存溢出:先算清要多少,再决定降参数还是换机器
「内存不够」有两种完全不同的样子:一种是进程被 Killed、OUTCAR 里一行报错都没有;另一种是没被杀,但慢得像死机——那是在 swap。两种解法完全不同,而多数人第一反应(加核)对这两种都没用,只会更糟。
先确认:你是溢出,还是在交换
dmesg -T | grep -iE "killed process|out of memory" # 被 OOM killer 杀
free -g # available 是不是贴着 0
vmstat 1 5 # si/so 长期不为 0 = 在 swap
| 现象 | 本质 | 方向 |
|---|---|---|
| 被 Killed,退出码 137,无报错 | 物理内存 + swap 都不够 | 降需求或换内存规格 |
| 没被杀,但一步要几十分钟 | 在 swap 上换页 | 同样要降需求,加 swap 是饮鸩止渴 |
报 ZBRENT: fatal error 之类 | 不是内存问题 | 去看结构/算法,见 报错手册 |
| 被平台回收、机器消失几分钟 | 实例层面的事故 | 见 中断排查 |
VASP 到底把内存花在哪
VASP 的内存需求不是一个数,而是几块加起来,其中两块最容易被低估:
- 波函数:
NBANDS × NPW × 16 字节 × k 点数(ISPIN=2再翻一倍)。这是主体,也是最难压的一块。 - 投影算符与 PAW 数据:按原子种类与
LORBIT决定,几百 MB 到几 GB。 - FFT 工作区:正比于网格点数,
PREC=Accurate或ADDGRID=.TRUE.会明显变大。 - 每个 MPI 进程的副本:小数组是按进程各存一份的,所以进程数越多,这部分固定开销越大。
把它算成具体数字:内存与 WAVECAR 估算器可以直接输入原子数、ENCUT、k 点与 ISPIN 给出建议规格;只有一两分钟也可以直接用经验值——每原子 0.5 GB 起步、0.75 GB 留余量,128 原子对应 64–96 GB。
五个把内存吃掉的参数
1. NBANDS 被调大
有人为了"看得更准"把 NBANDS 设成默认值的两三倍。NBANDS 直接乘在波函数上,等于内存乘两三倍,而大多数计算并不需要那么多空带。先看 OUTCAR 里的默认 NBANDS 是多少,再决定要不要加。
2. k 点太密
每个 k 点的波函数是独立存储的。4×4×4 换到 8×8×8,不只是计算量涨 8 倍,内存里驻留的波函数也涨约 8 倍。k 点收敛测试是省内存最有效的一件事,而且往往发现少一半 k 点结果几乎不变。
3. ISPIN = 2
自旋极化会让波函数数量翻倍,内存也近似翻倍。如果体系本来是非磁性的(比如大多数半导体、简单氧化物),ISPIN=2 只是白花一倍内存与时间。
4. LORBIT 与投影
LORBIT=11 要把波函数投影到原子轨道上,额外占用与波函数同量级的内存。只在真的需要 PDOS/投影能带时开。
5. ALGO 的档次
ALGO=Exact(或等价的 Normal)保存的中间量最多,Fast/VeryFast 明显省内存,收敛步数通常只多一点。内存吃紧时先降这一档,比加机器便宜得多。
真正有效的三个动作
动作一:用 KPAR 把 k 点摊开
这是最容易被忽略的一招。VASP 的两层并行里,NCORE 负责把平面波系数分给同一 k 点内的进程,KPAR 负责把不同 k 点分给不同进程组。每个进程组只持有自己那部分 k 点的波函数,所以 KPAR 增大时单进程内存近似按 1/KPAR 下降。
KPAR = 4 # 内存吃紧时的常用起点;不超过 k 点总数
NCORE = 4 # 每组内进程数,经验值 2~8
代价:k 点太少时并行效率会下降。判定方法很简单——同样输入跑 20 个电子步,比较 KPAR=1 与 KPAR=k 的墙钟。如果 KPAR 让速度掉了 20% 以上而内存还够用,就别开。
动作二:降低精度试探,定稿再提高
粗结构用 EDIFF=1E-4、PREC=Normal、ALGO=Fast 先把结构放松,最后一步再上高精度。总内存峰值往往出现在最终静态计算,前面几步不需要那么高的配置。
动作三:换内存型规格
上面两招加起来通常能省 1.5–3 倍内存。如果算完还需要 200 GB 以上,或者你要跑的是 500 原子以上的体系,那就不是参数问题了,该换规格。云上对应的做法是选内存配比更高的实例族(每核 8 GB 一档),而不是把计算型实例的核数堆上去——实例族怎么选里有对照表。
对照表:不同体系该买多大内存
| 体系规模 | 典型推荐 | 核数 | 说明 |
|---|---|---|---|
| 32 原子以内 | 16 GB | 8–16 | 常规优化,笔记本也能跑 |
| 64 原子 | 32 GB | 16–32 | 开始需要注意 k 点数 |
| 128 原子 | 64–96 GB | 32–64 | 分水岭:k 点与 NBANDS 在这里最容易失控 |
| 256 原子 | 128–192 GB | 64–96 | 建议 KPAR≥2,WAVECAR 也要几十 GB 磁盘 |
| 500 原子以上 | 256 GB 起,可能要多节点 | 96–128/节点 | 跨节点并行看 多节点指南 |
注意这是下限:如果 ISPIN=2、k 点密集或加了 LORBIT,按 1.5–2 倍往上取。买的时候留余量比事后迁移便宜。
swap 到底该不该开
很多教程说"开大 swap 就不怕内存溢出了"。这话只对了一半:swap 能让进程不被杀,但 VASP 一旦开始交换,速度会掉一个数量级,你付出的机时费并没有减少,只是把崩溃变成了慢性浪费。
合理的用法是:swap 开到物理内存的 10%–25%,作为"别被杀掉"的最后保险,同时用监控确认它没被真的用上。判断方法就是 vmstat 的 si/so 两列。
预防:开跑之前花两分钟
- 按原子数与 k 点数估一次内存,留 1.5 倍余量再选规格。
- 跑长任务前
df -h确认磁盘够——WAVECAR体积可能和内存同量级。 - 用
nohup/systemd-run起任务,别挂在 SSH 上。 - 满核长跑用计算型或内存型实例,不要用突发性能(共享)实例。
- 任务跑起来后
top看一眼RES实际占用,与估算值对一下,差太多说明有参数没设对。
如果你的结论是"确实需要更大的内存",下一步是算钱:按量与包月的成本对比,以及不同预算能跑多少核时。
先估内存,再选规格
输入原子数、ENCUT、k 点与自旋,直接得到建议内存与 WAVECAR 体积;再顺手算出这段计算要多少核时、多少钱。
打开内存估算器 core-hour 机时估算器 查看内存型实例要买的话:先点上面的推广链接登录或注册,再回到本页点一次同一条链接——阿里云按「两次点击」建立推广关联(关联期 90 天),你的价格不受任何影响。
top 实测为准。