I/O Problemas en la Carga de Varios de los Grandes H5PY Archivos (Pytorch)

0

Pregunta

Me encontré con un problema!

Recientemente me encuentro con un problema de I/O problema. El destino y los datos de entrada se almacenan con h5py archivos. Cada archivo de destino es de 2.6 GB , mientras que cada archivo de entrada es de 10.2 GB. Tengo 5 datasets de entrada y 5 de destino de los conjuntos de datos en total.

He creado un conjunto de datos personalizado de la función para cada h5py archivo y, a continuación, utilizar los datos.ConcatDataset clase para vincular todos los conjuntos de datos. El conjunto de datos personalizado de la función es:

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])

Entonces yo uso dataset_train = data.ConcatDataset([MydataSet(indx=index, train=True) for index in range(1, 6)]) para la formación. Cuando sólo 2-3 h5py se utilizan los archivos, la velocidad de e/S es normal y se va todo a la derecha. Sin embargo, cuando el 5 de archivos se utilizan, el entrenamiento de la velocidad está disminuyendo gradualmente (5 iteraciones/s a 1 iteraciones/s). Puedo cambiar el num_worker y el problema persiste.

Podría alguien darme una solución? Debo combinar varios h5py archivos en uno más grande? O de otros métodos? Gracias de antemano!

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

Mejor respuesta

1

La mejora del rendimiento requiere una sincronización puntos de referencia. Para hacer que usted necesita para identificar los posibles cuellos de botella y asociados escenarios. Usted dijo "con 2-3 archivos de la velocidad de e/S es normal" y "5 cuando se usan los archivos, la velocidad de entrenamiento disminuye gradualmente". Así que, es su problema de rendimiento de e/S de velocidad, o velocidad de entrenamiento? O ¿sabes? Si usted no sabe, usted necesita para aislar y comparar el rendimiento de e/S y el funcionamiento de la formación por separado para los 2 escenarios.
En otras palabras, para medir el rendimiento de e/S (sólo) deberá ejecutar las siguientes pruebas:

  1. Tiempo para leer y concatenar 2-3 archivos,
  2. Tiempo para leer y concatenar los 5 archivos,
  3. Copia los 5 archivos en 1, y el tiempo de la lectura del archivo combinado,
  4. O, el enlace de los 5 archivos en 1 archivo y la hora.

Y para medir la velocidad de entrenamiento (sólo) lo que usted necesita para comparar los resultados de los siguientes exámenes:

  • Combinación de 2-3 archivos, a continuación, leer y tren desde el archivo combinado.
  • Combinar todos los 5 archivos, a continuación, leer y tren de archivo combinado.
  • O, el enlace de los 5 archivos en 1 archivo, leer y tren de archivo vinculado.

Como señalé en mi comentario, la fusión (o vinculación) de múltiples HDF5 archivos en uno, es fácil si todos los conjuntos de datos son a nivel de la raíz y todo el conjunto de datos de nombres son únicos. He añadido el enlace externo método porque puede ofrecer el mismo rendimiento, sin duplicar los grandes archivos de datos.

A continuación se muestra el código que se muestra ambos métodos. Sustituir los nombres de archivo en la fnames lista, y debería estar listo para ejecutar. Si el conjunto de datos de nombres no son únicos, usted tendrá que crear nombres únicos, y asignar en h5fr.copy() - como esta: h5fr.copy(h5fr[ds],h5fw,'unique_dataset_name')

Código de combinación -o - link de los archivos :
(comentar/descomentar las líneas según corresponda)

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

Después de enviar el código que las copias de todos los conjuntos de datos 1 archivo, me di cuenta de que los enlaces externos podría ser una mejor solución. Que eliminar la duplicación de copias de los datos. La única pregunta es el rendimiento. El código de enlace es casi idéntico. He modificado mi respuesta y el código para mostrar ambos métodos.
kcw78

En otros idiomas

Esta página está en otros idiomas

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