Problemas de e/S em Carga de Vários Grandes H5PY Arquivos (Pytorch)

0

Pergunta

Eu conheci um problema!

Recentemente eu encontro um problema de e/S do problema. O destino e os dados de entrada são armazenados com h5py arquivos. Cada arquivo de destino é de 2,6 GB , enquanto cada arquivo de entrada é de 10.2 GB. Eu tenho 5 conjuntos de dados de entrada e 5 conjuntos de dados de destino no total.

Eu criei um dataset personalizada função para cada h5py arquivo e, em seguida, usar de dados.ConcatDataset classe para ligação de todos os conjuntos de dados. O dataset personalizada função é:

class MydataSet(Dataset):
def __init__(self, indx=1, root_path='./xxx', tar_size=128, data_aug=True, train=True):
    self.train = train
    if self.train:
        self.in_file = pth.join(root_path, 'train', 'train_noisy_%d.h5' % indx)
        self.tar_file = pth.join(root_path, 'train', 'train_clean_%d.h5' % indx)
    else:
        self.in_file = pth.join(root_path, 'test', 'test_noisy.h5')
        self.tar_file = pth.join(root_path, 'test', 'test_clean.h5')
    self.h5f_n = h5py.File(self.in_file, 'r', driver='core')
    self.h5f_c = h5py.File(self.tar_file, 'r')
    self.keys_n = list(self.h5f_n.keys())
    self.keys_c = list(self.h5f_c.keys())
    # h5f_n.close()
    # h5f_c.close()

    self.tar_size = tar_size
    self.data_aug = data_aug

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

def __del__(self):
    self.h5f_n.close()
    self.h5f_c.close()

def __getitem__(self, index):
    keyn = self.keys_n[index]
    keyc = self.keys_c[index]
    datan = np.array(self.h5f_n[keyn])
    datac = np.array(self.h5f_c[keyc])
    datan_tensor = torch.from_numpy(datan).unsqueeze(0)
    datac_tensor = torch.from_numpy(datac)
    if self.data_aug and np.random.randint(2, size=1)[0] == 1: # horizontal flip
        datan_tensor = torch.flip(datan_tensor,dims=[2]) # c h w
        datac_tensor = torch.flip(datac_tensor,dims=[2])

Então eu uso dataset_train = data.ConcatDataset([MydataSet(indx=index, train=True) for index in range(1, 6)]) para a formação. Quando apenas 2-3 h5py arquivos são utilizados, a velocidade de e/S é normal e tudo vai dá certo. No entanto, quando 5 arquivos são usados, o treinamento de velocidade vai diminuindo gradualmente (5 iterações/s para 1 iterações/s). Eu alterar o num_worker e o problema ainda existe.

Alguém poderia me dar uma solução? Eu deveria mesclar vários h5py arquivos em um maior? Ou outros métodos? Obrigado antecipadamente!

h5py python pytorch pytorch-dataloader
2021-11-24 02:02:17
1

Melhor resposta

1

Melhoria do desempenho requer sincronismo valores de referência. Para fazer isso você precisa identificar possíveis gargalos e associados cenários. Você disse:"com 2-3 arquivos de velocidade de e/S é normal" e "quando 5 arquivos são usados, a formação velocidade diminui gradualmente". Então, é o problema de desempenho de e/S de velocidade ou a velocidade de treinamento? Ou você sabe? Se você não conhece, você precisa isolar e comparar o desempenho de I/O e desempenho de treino e separadamente para os 2 cenários.
Em outras palavras, para medir o desempenho de e/S (apenas) você precisa executar os seguintes testes:

  1. Tempo para ler e concatenar ficheiros 2-3,
  2. Tempo para ler e concatenar 5 arquivos,
  3. Copie os 5 arquivos em 1, e o tempo a ler a partir do arquivo mesclado,
  4. Ou, ligar os 5 arquivos para 1 ficheiro e o tempo.

E para medir a velocidade de treinamento (apenas) o que você precisa para comparar o desempenho para os seguintes testes:

  • Série 2-3 arquivos e, em seguida, ler e treinar a partir da fusão de arquivo.
  • Mesclar todos os 5 arquivos e, em seguida, ler e trem de arquivo mesclado.
  • Ou, ligar os 5 arquivos para 1 ficheiro e, em seguida, ler e de trem do arquivo vinculado.

Como observado no meu comentário, a fusão (ou ligar) vários HDF5 arquivos em um, é fácil se todos os conjuntos de dados no nível raiz, e de todo o conjunto de nomes são únicos. Eu adicionei o link externo de um método porque ele pode oferecer o mesmo desempenho, sem duplicação de grandes arquivos de dados.

Abaixo está o código que mostra ambos os métodos. Substitua os nomes de arquivo no fnames lista, e ele deve estar pronto para executar. Se o seu conjunto de dados de nomes não são exclusivos, o que você vai precisar para criar nomes exclusivos, e atribuir, em h5fr.copy() -- como esta: h5fr.copy(h5fr[ds],h5fw,'unique_dataset_name')

Código de mesclagem ou arquivos de link :
(comentar/descomentar as linhas conforme apropriado)

import h5py
fnames = ['file_1.h5','file_2.h5','file_3.h5']
# consider changing filename to 'linked_' when using links:
with h5py.File(f'merge_{len(fnames)}.h5','w') as h5fw:      
    for fname in fnames:
        with h5py.File(fname,'r') as h5fr:
            for ds in h5fr.keys():
                # To copy datasets into 1 file use:
                h5fr.copy(h5fr[ds],h5fw)
                # to link datasets to 1 file use:
                # h5fw[ds] = h5py.ExternalLink(fname,ds)
2021-11-25 15:23:04

Após a postagem o código que copia todos os conjuntos de dados para 1 arquivo, percebi que as ligações externas podem ser uma solução melhor. Eles eliminam cópias duplicadas de dados. A única questão é o desempenho. O código para ligar é quase idêntico. Eu modifiquei a minha resposta e o código para mostrar que ambos os métodos.
kcw78

Em outros idiomas

Esta página está em outros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................