Slurm内存分配异常:申请120GB仍出现92.3GiB内存不足错误
Slurm申请120GB内存仍触发MemoryError的原因及解决方案
问题背景
我是Slurm新手,需运行一个需要92.3GiB内存的Python文件,已编写submit_venv.sh脚本:
#!/bin/bash #SBATCH --account=melchua #SBATCH --mem=120GB #SBATCH --time=2:00:00 module load python/3.8.2 python3 1.methylation_data_processing.py
执行脚本后仍返回内存错误,报错回溯信息如下:
File "1.methylation_data_processing.py", line 49, in <module> meth_clin = pd.concat([gene_symbol, meth_clin]) # add gene_symbol to dataframe File "/scg/apps/software/python/3.8.2/lib/python3.8/site-packages/pandas/util/_decorators.py", line 311, in wrapper return func(*args, **kwargs) File "/scg/apps/software/python/3.8.2/lib/python3.8/site-packages/pandas/core/reshape/concat.py", line 307, in concat return op.get_result() File "/scg/apps/software/python/3.8.2/lib/python3.8/site-packages/pandas/core/reshape/concat.py", line 532, in get_result new_data = concatenate_managers( File "/scg/apps/software/python/3.8.2/lib/python3.8/site-packages/pandas/core/internals/concat.py", line 222, in concatenate_managers values = _concatenate_join_units(join_units, concat_axis, copy=copy) File "/scg/apps/software/python/3.8.2/lib/python3.8/site-packages/pandas/core/internals/concat.py", line 486, in _concatenate_join_units to_concat = [ File "/scg/apps/software/python/3.8.2/lib/python3.8/site-packages/pandas/core/internals/concat.py", line 487, in <listcomp> ju.get_reindexed_values(empty_dtype=empty_dtype, upcasted_na=upcasted_na) File "/scg/apps/software/python/3.8.2/lib/python3.8/site-packages/pandas/core/internals/concat.py", line 441, in get_reindexed_values missing_arr = np.empty(self.shape, dtype=empty_dtype) numpy.core._exceptions.MemoryError: Unable to allocate 92.3 GiB for an array with shape (111331, 111332) and data type object
一、为何120GB内存仍报错?
- 内存需求被低估:报错中提到的92.3GiB只是单个数组的申请量,
pd.concat操作还会保留原有的两个DataFrame内存占用,同时生成临时中间变量,总内存开销会远大于92.3GiB。加上系统进程、Python解释器本身的内存占用,120GB的预留量不足以覆盖峰值需求。 - 单位混淆:Slurm中
--mem=120GB的GB是十进制单位(1GB=109字节),而报错中的GiB是二进制单位(1GiB=230字节),120GB≈111.76GiB,实际可用的二进制内存比预期少。 - 低效数据类型放大内存占用:报错数组的
dtype=object,这类数组每个元素都是指针,内存效率远低于数值类型或category类型,进一步推高了内存需求。 - 节点内存共享:如果作业没有独占节点,节点上的其他作业会分摊内存,导致实际可用内存不足120GB。
二、正确在Slurm中分配内存的方法
- 预留足够冗余内存:基于实际需求增加内存申请量,建议至少申请180-200GiB,同时用
GiB单位避免混淆:#SBATCH --mem=180GiB - 申请独占节点:如果集群允许,添加
--exclusive参数独占整个节点,确保内存不被其他作业抢占:#SBATCH --exclusive - 优化代码降低内存开销:从根源减少内存需求是更有效的方案:
- 将
object类型列转换为category类型(适用于重复值多的字符串列),或匹配的数值类型:gene_symbol['column_name'] = gene_symbol['column_name'].astype('category') - 用
join替代concat实现列合并,避免生成大尺寸临时数组:meth_clin = meth_clin.join(gene_symbol) - 分块读取和处理数据,避免一次性加载全量数据到内存。
- 将
- 监控实际内存使用:在脚本中添加内存监控命令,比如每隔10秒输出内存状态,帮助精准调整申请量:
sar -r 10 &
内容的提问来源于stack exchange,提问作者melolilili
相关产品推荐
相关产品推荐

