Problèmes d'e/S dans le Chargement de Plusieurs Grandes H5PY Fichiers (Pytorch)

0

La question

J'ai rencontré un problème!

Récemment, j'ai rencontrer un problème d'I/O question. La cible et les données d'entrée sont stockés avec h5py fichiers. Chaque fichier cible est de 2,6 GO tandis que chaque fichier d'entrée est de 10,2 GB. J'ai 5 jeux de données en entrée et 5 ensembles de données au total.

J'ai créé un dataset personnalisé fonction pour chaque h5py le fichier et utiliser les données.ConcatDataset classe de faire le lien entre tous les ensembles de données. Le dataset personnalisé fonction est:

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

Puis-je utiliser dataset_train = data.ConcatDataset([MydataSet(indx=index, train=True) for index in range(1, 6)]) pour la formation. Lorsque seulement 2-3 h5py fichiers sont utilisés, les e/S de vitesse est normale et tout va bien. Toutefois, lorsque les 5 fichiers sont utilisés, la vitesse d'entraînement est en train de diminuer progressivement (5 itérations/s à 1 itérations/s). - Je changer la num_worker et le problème existe toujours.

Quelqu'un pourrait-il me donner une solution? Devrais-je fusionner plusieurs h5py fichiers dans un plus gros? Ou d'autres méthodes? Merci à l'avance!

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

La meilleure réponse

1

L'amélioration de la performance nécessite la synchronisation de repères. Pour faire que vous avez besoin pour identifier les goulots d'étranglement potentiels et associé à des scénarios. Vous avez dit "avec 2-3 fichiers les e/S de vitesse est normale" et "quand 5 fichiers sont utilisés, la formation de la vitesse diminue progressivement". Donc, c'est votre problème de performances I/O de la vitesse ou de la vitesse de formation? Ou connaissez-vous? Si vous ne savez pas, vous avez besoin d'isoler et de comparer les performances d'e/S et de la formation de la performance séparément pour les 2 scénarios.
En d'autres termes, pour mesurer les performances d'e/S (uniquement), vous devez exécuter les tests suivants:

  1. Temps de les lire et de les enchaîner 2-3 fichiers,
  2. Temps de les lire et de les enchaîner 5 fichiers,
  3. Copiez le 5 fichiers sur 1, et le temps de la lire à partir du fichier fusionné,
  4. Ou de, le lien la 5 fichiers sur 1 fichier, et dans le temps.

Et de formation sur mesure de la vitesse (seulement), vous devez comparer les performances pour les tests suivants:

  • Fusion 2-3 fichiers, puis de lire et de former à partir du fichier fusionné.
  • Fusionner toutes les 5 fichiers, puis lisez et train de fichier fusionné.
  • Ou de, le lien la 5 fichiers sur 1 fichier, puis de le lire et le train de fichier lié.

Comme indiqué dans mon commentaire, la fusion (ou de liaison) plusieurs HDF5 fichiers en un seul est facile si tous les ensembles de données sont au niveau de la racine et tous les noms de jeux de données sont uniques. J'ai ajouté le lien externe méthode, car il peut fournir les mêmes performances, sans dupliquer les fichiers de données volumineux.

Ci-dessous est le code qui montre que les deux méthodes. Remplacer les noms de vos fichiers dans le fnames liste, et il devrait être prêt à fonctionner. Si votre jeu de données les noms ne sont pas uniques, vous devrez créer un nom unique, et attribuer en h5fr.copy() -- comme ceci: h5fr.copy(h5fr[ds],h5fw,'unique_dataset_name')

Code de fusionner ou de lier des fichiers :
(commenter/décommenter des lignes au besoin)

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

Après la publication du code que des copies de tous les ensembles de données à 1 fichier, j'ai réalisé que les liens externes pourrait être une meilleure solution. Ils éliminer le dédoublement des copies de données. La seule question est la performance. Le code de lien est presque identique. J'ai modifié ma réponse et le code de montrer les deux méthodes.
kcw78

Dans d'autres langues

Cette page est dans d'autres langues

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