【问题标题】:HDF5 dataloading very slow. Causes zero % volatility in GPUsHDF5 数据加载非常慢。导致 GPU 的波动性为零
【发布时间】:2020-05-17 22:46:40
【问题描述】:

我正在使用自定义 PyTorch 数据类从我创建的 H5 数据集中加载实例。但是,加载样本时似乎非常慢。我遵循了一些关于处理大型 HDF5 数据集的建议,但我想知道我是否在做一些明显错误的事情。如果这有所作为,我将在 Linux 上部署我的代码。我在 4 个 GPU 上运行代码,并为我的模型设置了 nn.dataparallel。由于数据加载非常缓慢,GPU 波动性为 0%。这是我的数据类加载器:

import h5py
from torch.utils import data

class Features_Dataset(data.Dataset):
    def __init__(self, archive, phase):
        self.archive = archive
        self.phase = phase

    def __getitem__(self, index):
        with h5py.File(self.archive, 'r', libver='latest', swmr=True) as archive:
            datum = archive[str(self.phase) + '_all_arrays'][index]
            label = archive[str(self.phase) + '_labels'][index]
            path = archive[str(self.phase) +  '_img_paths'][index]
            return datum, label, path

    def __len__(self):
        with h5py.File(self.archive, 'r', libver='latest', swmr=True) as archive:
            datum = archive[str(self.phase) + '_all_arrays']
            return len(datum)


if __name__ == '__main__':
    train_dataset = Features_Dataset(archive= "featuresdata/train.hdf5", phase= 'train')
    trainloader = data.DataLoader(train_dataset, num_workers=8, batch_size=128)
    print(len(trainloader))
    for i, (data, label, path) in enumerate(trainloader):
        print(path)


我是否遗漏了一些明显的东西?有没有更好的快速加载实例的方法?

编辑:

这里是更新后的数据类,但是当我尝试使用多处理时,我现在得到一个 picling 错误。


import h5py
from torch.utils import data
import torch.multiprocessing as mp
mp.set_start_method('spawn')

class Features_Dataset(data.Dataset):
    def __init__(self, archive, phase):
        self.archive = h5py.File(archive, 'r')
        self.labels = self.archive[str(phase) + '_labels']
        self.data = self.archive[str(phase) + '_all_arrays']
        self.img_paths = self.archive[str(phase) + '_img_paths']

    def __getitem__(self, index):
        datum = self.data[index]
        label = self.labels[index]
        path = self.img_paths[index]
        return datum, label, path

    def __len__(self):
        return len(self.data)

    def close(self):
        self.archive.close()

if __name__ == '__main__':
    train_dataset = Features_Dataset(archive= "featuresdata/train.hdf5", phase= 'train')
    trainloader = data.DataLoader(train_dataset, num_workers=2, batch_size=4)
    print(len(trainloader))
    for i, (data, label, path) in enumerate(trainloader):
        print(path)

【问题讨论】:

    标签: python linux pytorch gpu hdf5


    【解决方案1】:

    你不能在 init 中打开一次文件并存储文件处理程序吗?目前,当您调用 get item 或 len 时,您将始终在每次调用时打开文件。

    【讨论】:

    • 嗨,我已经尝试在 init 中打开它。当我尝试使用超过 1 个工人时,我最终会遇到错误。有人告诉我应该使用import torch.multiprocessing as mp mp.set_start_method('spawn')。但是,我收到一个酸洗错误:TypeError: h5py objects cannot be pickle。我已将新课程添加到我原来的帖子中。
    • 嗨,是的,所以我已经尝试为 init 中的数组放置 [()]self.labels = self.archive[str(phase) + '_labels'][()]。这适用于小型数据集,但是我假设我在使用大型数据集时遇到内存错误:MemoryError: Unable to allocate array with shape (2140063, 1, 6144, 1, 1) and data type float32。当我将[()] 放在getitem 中时,我认为这是正确的位置,例如datum = self.data[index][()],我会收到标签和路径错误; TypeError: string indices must be integers 。有可行的解决方法吗?
    • 另外,仅将数据放入 numpy 数组示例中,我仍然得到TypeError: h5py objects cannot be pickled
    • 希望您能解决。一个想法是在单独的进程中读取 h5 并将数据添加到多处理队列中。 4 个 gpu 进程使用队列中的数据。本质上是创建自己的数据加载器,而不是使用 pytorch 数据加载器。我最近才为 pytorch 推理创建了数据加载部分,并设法增加了系统的吞吐量。
    猜你喜欢
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 2013-06-26
    相关资源
    最近更新 更多