如何在内存中加载较大的h5文件?

问题描述

我在HDFS中有一个带有5维numpy数组的h5大文件文件大小为〜130Gb。即使计算机具有256Gb RAM,使用进程加载文件时,我也遇到内存问题,并因OOM错误而被杀死。如何将文件分块写入并分块加载?我环顾四周,发现h5py提供了像这样对数据集进行分块的方法,但如何将数据分块加载?如果文件驻留在HDFS中,也可以使用吗?

dset = f.create_dataset("Images2",(100,480,640),'f',chunks=True)

想法是分批加载文件,以减少I / O时间和内存问题。任何帮助将不胜感激。

解决方法

上面的答案和评论中提到了两个相似(但不同)的h5py I / O概念:

  • HDF5 Chunking 用于启用分块I / O,以提高性能。如果尝试读取内存不足的大型数据集时遇到OOM错误,则分块可能无济于事
  • NumPy样式 Slicing 用于将数据片段从驱动器读取到内存(或将数据片段写入驱动器)。切片是读取超大文件时避免OOM错误的关键。
  • 此外,在创建非常大的数据集时,通常需要 它可调整大小。您可以分配一个初始大小,然后使用“ .resize()”方法增加磁盘上的大小。

我写了一个简单的示例,展示了如何同时使用切片和分块。它将一次加载100张图像到可调整大小的数据集中。然后,它关闭文件并重新打开(只读),一次将100张图像读取到NumPy数组中。

有效分块需要适当的大小/形状,并且取决于您的阵列形状和I / O需求。我在示例中将块大小/形状设置为与正在写入/读取的100个图像数组的大小匹配。

该示例将帮助您入门。您将需要修改以使用5维数组/数据集。

import numpy as np
import h5py

with h5py.File('SO_64645940.h5','w') as h5w:
    img_ds = h5w.create_dataset('Images',shape=(100,480,640),dtype='f',maxshape=(None,chunks=(10,640))

    next_img_row = 0    
    arr = np.random.random(100*480*640).reshape(100,640)
    for cnt in range(1,10):
#        print(cnt,img_ds.len(),next_img_row)
        if img_ds.len() == next_img_row :
            img_ds.resize(100*cnt,axis=0)
            print('new ds size=',img_ds.len())
        h5w['Images'][next_img_row:next_img_row+100] = arr
        next_img_row += 100
    
    
with h5py.File('SO_64645940.h5','r') as h5r:
     for cnt in range(10):
         print('get slice#',str(cnt))
         img_arr = h5r['Images'][cnt*100:(cnt+1)*100] 
,

HDF5中的块化意味着数据不是连续存储,而是成块存储。 在此处查看信息:https://docs.h5py.org/en/stable/high/dataset.html#chunked-storage ->这样对您的问题没有帮助。

解决方案可能是您自己构建一个函数以分块加载数据。 例如,我以这种方式获取数据块:

def get_chunked(data,chunk_size=100):
    for i in give_chunk(len(data),chunk_size):
        chunked_array = data[i]
        yield chunked_array

def give_chunk(length,chunk_size):
    it = iter(range(length))
    while True:
        chunk = list(itertools.islice(it,chunk_size))
        if not chunk:
            break
        yield chunk

要向HDF5写入数据,您可以先创建数据集,然后再通过切片将数据块明智地写入,请参见h5py文档:https://docs.h5py.org/en/stable/high/dataset.html#reading-writing-data

我真的可以推荐这本书以获取有关HDF5的基础知识:https://www.oreilly.com/library/view/python-and-hdf5/9781491944981/