Ubuntu运行Speaker Diarization项目时numpy数组存读触发Killed错误
Numpy保存/加载500MB大小npz文件时进程被系统Killed问题排查
问题背景
- 正在学习深度学习,重点研究Speaker Diarization实现,在Ubuntu系统上搭建对应开源说话人分色项目的运行环境
- 生成说话人embedding过程中遇到进程被
Killed报错,执行dmesg -e排查结果如下:
报错触发场景
- 首次报错出现在执行以下代码时:
np.savez('training_data', train_sequence=train_sequence, train_cluster_id=train_cluster_id)
- 调低epoch数量后生成的
training_data.npz仅500MB,远小于设备标称RAM容量,生成流程可正常完成,但后续加载该文件时再次触发相同报错,触发代码如下:
train_data = np.load('./ghostvlad/training_data.npz')
核心疑问
为什么系统无法正常保存、加载这个远小于内存容量的numpy文件?
原因分析
这是Numpy处理npz压缩文件时的内存峰值溢出问题,和文件本身的磁盘占用大小没有直接关系:
- npz是压缩归档格式,你看到的500MB是压缩后的磁盘占用值,实际加载时Numpy需要先将所有数组完整解压到内存中,解压后的真实内存占用通常是压缩后体积的3~10倍,很容易超出设备实际可用内存阈值,触发系统OOM Killer杀掉进程。
- 保存阶段的内存溢出同理:调用
np.savez时,Numpy需要先在内存中完成所有数组的压缩计算,这个过程会产生额外的内存开销,哪怕最终输出的文件体积很小,计算过程中的内存峰值也可能超过可用内存上限。 - 注意你对比的是设备总RAM容量,而实际可用内存是总容量扣除系统自身占用、其他后台进程占用、显存共享占用(如果是集成显卡/共享显存的GPU)后的剩余值,同时如果没有配置Swap分区,可用内存阈值会更低,OOM触发会更敏感。
解决方案
- 加载时新增
mmap_mode参数:train_data = np.load('./ghostvlad/training_data.npz', mmap_mode='r'),通过内存映射的方式按需加载数组,不会一次性将所有内容解压到内存中。 - 拆分数据集:将大数组拆分成多个小的npz文件分批保存和加载,避免单次操作的内存峰值过高。
- 新增或扩容Swap分区,给系统留出内存溢出的缓冲空间。
内容的提问来源于stack exchange,提问作者CHO
相关产品推荐
相关产品推荐

