Une collection de conseils pour accélérer l'apprentissage et le raisonnement avec PyTorch

Dans cet article, je présenterai une collection de conseils pour accélérer l'apprentissage profond avec PyTorch annoncé par NVIDIA.

À propos de cet article

Cet article a été annoncé par Arun Mallya de NVIDIA, 「PyTorch Performance Tuning Guide - Szymon Migacz, NVIDIA」 J'expliquerai en ajoutant des explications et des programmes à.

d1.JPG

Le but de cet article est exactement ce qu'Andrew Karpathy marmonne sur Twitter.

Je vais expliquer cela d'une manière facile à comprendre.

※Andrej Karpathy A obtenu un doctorat du Dr Fay Fay Lee qui a préparé ImageNet Actuellement directeur du département IA de Tesla La performance humaine avec ImageNet a un taux d'erreur de 5%, mais pour obtenir ce résultat, la personne qui a contesté ImageNet, ce qui a été fait par le représentant humain

Contenu de cet article

  1. Précautions concernant le contenu
  2. À propos de DataLoader (num_workers, pin_memory)
  3. À propos de torch.backends.cudnn.benchmark = True
  4. Augmentez la taille du mini-lot (AMP, LARS et LAMB)
  5. Paramètres multi-GPU
  6. Fonction de conversion Tensol en JIT
  7. Autres conseils  7. non_blocking=True

0. Précautions concernant le contenu

Le contenu décrit dans cet article dépend de l'environnement GPU que vous utilisez.

Essayez de voir lequel fonctionne pour votre environnement.

Tous les programmes de cet article https://github.com/YutaroOgawa/Qiita/tree/master/pytorch_performance Il est ouvert au public au.

Il est au format Jupyter Notebook.

Dans cet article, vous pouvez facilement vérifier [Performance change] au moment de "MNIST training 1 epoch".

1. À propos de DataLoader

Le DataLoader de PyTorch a deux choses, les paramètres par défaut ne sont pas très bons. https://pytorch.org/docs/stable/data.html

1.1 num_workers

Tout d'abord, l'argument est par défaut num_workers = 0. En conséquence, la récupération du mini-lot est un processus unique.

En définissant num_workers = 2 etc., cela devient un chargement de données multi-processus et le traitement s'accélère.

Vous pouvez vérifier le nombre de cœurs de processeur ci-dessous.

#Vérifiez le nombre de cœurs de processeur
import os
os.cpu_count()  #Nombres de coeurs

Quant au nombre de cœurs, 2 suffisent pour 1 GPU.

Créez un DataLoader comme suit.

#Pour Data Loader avec les paramètres par défaut
train_loader_default = torch.utils.data.DataLoader(dataset1,batch_size=mini_batch_size)
test_loader_default = torch.utils.data.DataLoader(dataset2,batch_size=mini_batch_size)

#Chargeur de données: 2
train_loader_nworker = torch.utils.data.DataLoader(
    dataset1, batch_size=mini_batch_size, num_workers=2)
test_loader_nworker = torch.utils.data.DataLoader(
    dataset2, batch_size=mini_batch_size, num_workers=2)


#Chargeur de données: plein
train_loader_nworker = torch.utils.data.DataLoader(
    dataset1, batch_size=mini_batch_size, num_workers=os.cpu_count())
test_loader_nworker = torch.utils.data.DataLoader(
    dataset2, batch_size=mini_batch_size, num_workers=os.cpu_count())

[Changement de performance] Vérifiez le changement de performance à l'époque de la formation MNIST 1.

#Vérifier le GPU
!nvidia-smi

Vous pouvez vérifier le GPU de l'environnement d'utilisation avec.

Cette fois, ● Cas 1: p3.2xlarge (NVIDIA® VOLTA V100 Tensor Core GPU) ● Cas 2: Google Colaboratory (Tesla Turing T4 Tensor Core GPU)

Ce sera. Veuillez noter que Google Colaboratory a un type de GPU différent à chaque fois.

[Par défaut] ● Cas 1: p3.2xlarge: 14,73 secondes ● Cas 2: Google Colaboratory: 10,01 secondes

[Dans le cas de num_workers = os.cpu_count ()] ● Cas 1: p3.2xlarge: 3,47 secondes ● Cas 2: Google Colaboratory: 9,43 secondes

Les deux sont plus rapides, mais le cas 1 est très rapide, jusqu'à environ 1/3.

Notez que p3.2xlarge a 8 cœurs de processeur et Goole Colaboratory a 2 cœurs de processeur.

Cependant, le nombre de cœurs est de 2 et num_workers = 2 donne une impression suffisante.

Même dans l'annonce originale, il semble qu'il n'y ait pas beaucoup de différence entre 2 et plus.

d2.JPG

1.2 pin_memory

Le DataLoader de PyTorch utilise par défaut l'argument pin_memory = False.

** L'épinglage automatique de la mémoire ** peut être utilisé en définissant pin_memory = True.

La zone de mémoire du processeur ne sera pas paginée, ce qui devrait s'accélérer.

pinned-1024x541.jpg

(référence) https://pytorch.org/docs/stable/data.html#memory-pinning https://zukaaax.com/archives/301 https://developer.nvidia.com/blog/how-optimize-data-transfers-cuda-cc/

(Explication de la pagination de la mémoire) https://wa3.i-3-i.info/word13352.html

La mise en œuvre est la suivante.

#Pour Data Loader avec les paramètres par défaut
train_loader_default = torch.utils.data.DataLoader(dataset1,batch_size=mini_batch_size)
test_loader_default = torch.utils.data.DataLoader(dataset2,batch_size=mini_batch_size)

#Mémoire des broches du chargeur de données
train_loader_pin_memory = torch.utils.data.DataLoader(
    dataset1, batch_size=mini_batch_size, pin_memory=True)
test_loader_pin_memory = torch.utils.data.DataLoader(
    dataset2, batch_size=mini_batch_size, pin_memory=True)

Comme précédemment, vérifiez le changement de performance à l'époque de la formation MNIST 1.

[Par défaut] ● Cas 1: p3.2xlarge: 14,73 secondes ● Cas 2: Google Colaboratory: 10,01 secondes

[Lorsque pin_memory = True] ● Cas 1: p3.2xlarge: 13,65 secondes ● Cas 2: Google Colaboratory: 9,82 secondes

[Dans le cas de num_workers = os.cpu_count ()] ● Cas 1: p3.2xlarge: 3,47 secondes ● Cas 2: Google Colaboratory: 9,43 secondes

[Lorsque num_workers = os.cpu_count () & pin_memory = True] ● Cas 1: p3.2xlarge: 3,50 secondes ● Cas 2: Google Colaboratory: 9,35 secondes

Par rapport aux paramètres par défaut, vous pouvez voir que c'est plus rapide.

Si num_workers est défini, l'échelle de ce MNIST est trop petite ou l'effet de pin_memory ne peut pas être vu.

1.3 Conclusion sur la création de DataLoader

[1] Lors de la création d'un DataLoader avec PyTorch, modifiez les arguments num_workers et pin_memory et implémentez comme suit.

#Configuration par défaut
train_loader_default = torch.utils.data.DataLoader(dataset1,batch_size=mini_batch_size)
test_loader_default = torch.utils.data.DataLoader(dataset2,batch_size=mini_batch_size)

#Chargeur de données recommandé
train_loader_pin_memory = torch.utils.data.DataLoader(
    dataset1, batch_size=mini_batch_size, num_workers=os.cpu_count(), pin_memory=True)
test_loader_pin_memory = torch.utils.data.DataLoader(
    dataset2, batch_size=mini_batch_size, num_workers=os.cpu_count(), pin_memory=True)

#Ou chargeur de données num_workers=2
train_loader_pin_memory = torch.utils.data.DataLoader(
    dataset1, batch_size=mini_batch_size, num_workers=2, pin_memory=True)
test_loader_pin_memory = torch.utils.data.DataLoader(
    dataset2, batch_size=mini_batch_size, num_workers=2, pin_memory=True)

2. À propos de torch.backends.cudnn.benchmark = True

2.1 Explication

Assurez-vous d'exécuter torch.backends.cudnn.benchmark = True lors de la formation.

Cela optimise et accélère les calculs de réseau côté GPU lorsque la forme du réseau est fixe.

Définissez sur True si la taille d'entrée des données ne change pas au début ou au milieu comme un CNN normal.

Cependant, veuillez noter que la reproductibilité du calcul sera perdue.

(À propos de la reproductibilité des calculs de PyTorch) https://pytorch.org/docs/stable/notes/randomness.html

La mise en œuvre est la suivante, par exemple.

def MNIST_train_cudnn_benchmark_True(optimizer, model, device, train_loader, test_loader):
    #Formation par défaut
    epochs = 1

    #ajouter à
    torch.backends.cudnn.benchmark = True

    #En traitement
    for epoch in range(1, epochs+1):
        train(model, device, train_loader, optimizer, epoch)
        test(model, device, test_loader)

Ici, la fonction train () a la forme suivante.

def train(model, device, train_loader, optimizer, epoch):
    model.train()  #En mode entraînement
    for batch_idx, (data, target) in enumerate(train_loader):
        #Récupération de données
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad()

        #propagation
        output = model(data)

        #Calcul des pertes et rétro-propagation
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()

Comparez les vitesses. Laissez le chargeur de données sur le paramètre par défaut.

[Par défaut] ● Cas 1: p3.2xlarge: 14,73 secondes ● Cas 2: Google Colaboratory: 10,01 secondes

[Lorsque torch.backends.cudnn.benchmark = True] ● Cas 1: p3.2xlarge: 14,47 secondes ● Cas 2: Google Colaboratory: 9,66 secondes

Cette fois, je résous uniquement MNIST, donc le réseau est petit, donc cet effet est faible, mais c'est un peu plus rapide.

2.2 Conclusion

** Entrez torch.backends.cudnn.benchmark = True lors de l'exécution du programme **

3. Augmentez la taille du mini lot

Plus la taille du mini-lot est grande, plus l'apprentissage est stable. Par conséquent, augmentons la taille du mini lot.

Avec la fonction ** AMP (Automatic Mixed Precision) ** de PyTorch, il existe des cas où une taille de mini-lot plus grande que le calcul attendu est réellement possible.

3.1 À propos de la fonction AMP (Automatic Mixed Precision)

AMP (Automatic Mixed Precision) signifie la précision du mélange.

Normalement, il est calculé avec FP32 (virgule flottante 32 bits), mais la moitié de FP16 (virgule flottante 16 bits) est une fonction qui économise l'utilisation de la mémoire et améliore la vitesse de calcul sans compromettre la précision.

De plus, si le GPU a un cœur Tensor, il sera 8 à 16 fois plus rapide que deux fois. (Jusqu'à 12 fois pour l'entraînement, jusqu'à 6 fois pour le raisonnement)

Volta-Tensor-Core_30fps_FINAL_994x559.gif

(référence) https://www.nvidia.com/ja-jp/data-center/tensor-cores/

Le V100 Volta est équipé du noyau TENSOR 1ère génération. La série T est équipée du noyau TURING TENSOR 2ème génération. On dit que la 2ème génération de noyau TURING TENSOR est environ deux fois plus rapide que la 1ère génération.

Turing-Tensor-Core_30fps_FINAL_736x414.gif

3.2 Utiliser AMP (Automatic Mixed Precision)

Cliquez ici pour des explications sur son utilisation.

(référence) https://pytorch.org/blog/accelerating-training-on-nvidia-gpus-with-pytorch-automatic-mixed-precision/ https://pytorch.org/docs/stable/notes/amp_examples.html

Mettre en œuvre selon les exemples ci-dessus.

Réécrivez le test de fonction précédent ().

def train_PyTorchAMP(model, device, train_loader, optimizer, epoch):
    model.train()  #En mode entraînement

    scaler = torch.cuda.amp.GradScaler()

    for batch_idx, (data, target) in enumerate(train_loader):
        #Récupération de données
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad()

        #propagation
        # Runs the forward pass with autocasting.
        with torch.cuda.amp.autocast():
            output = model(data)
            loss = F.nll_loss(output, target)

        # Scales loss.  Calls backward() on scaled loss to create scaled gradients.
        scaler.scale(loss).backward()

        # scaler.step() first unscales the gradients of the optimizer's assigned params.
        scaler.step(optimizer)

        # Updates the scale for next iteration.
        scaler.update()

Créez un scaler avec scaler = torch.cuda.amp.GradScaler () et encapsulez les mises à jour avant, perte, rétropropagation et paramètres avec scaler.

Définissez DataLoader comme paramètre par défaut et utilisez AMP pour comparer les vitesses.

[Par défaut] ● Cas 1: p3.2xlarge: 14,73 secondes ● Cas 2: Google Colaboratory: 10,01 secondes

[Pour AMP] ● Cas 1: p3.2xlarge: 14,21 secondes ● Cas 2: Google Colaboratory: 11,97 secondes

Dans ce MNIST, le montant d'un calcul est petit, donc je n'ai pas ressenti beaucoup d'effet.

En utilisant cet AMP, il est possible d'augmenter la taille du mini-lot plus que prévu, mais Veuillez tenir compte des points suivants à noter lors de l'augmentation de la taille du mini-lot.

[1] Ajustement de la valeur du taux d'apprentissage [2] Ajustement de la décroissance du poids: L'ampleur des pénalités de l'optimiseur [3] Incorporer l'échauffement dans l'apprentissage: Dans les premiers stades de l'apprentissage, le taux d'apprentissage est progressivement augmenté linéairement de 0 à un certain niveau. [4] Incorporer la dégradation du taux d'apprentissage dans l'apprentissage: réduire progressivement le taux d'apprentissage à la fin de l'apprentissage

3.3 À propos de LARS et LAMB

De plus, pour les gros mini-lots, envisagez d'utiliser LARS, LAMB, LAMB NVLAMB de NVIDIA, etc. pour l'optimiseur.

Pour les grands mini-lots

** Sur le même laps de temps, le nombre total d'époques sera inférieur à celui lorsque la taille du mini-lot est petite. Si vous augmentez simplement le taux d'apprentissage pour le compenser, cette fois le taux d'apprentissage sera trop élevé et il sera difficile de stabiliser l'entraînement **

Arrivera.

Par conséquent, LARS (Layerwise Adaptive Rate Scaling) est une méthode de multiplication du taux d'apprentissage par un coefficient appelé «rapport de confiance» en fonction du gradient.

De plus, LAMB (Layer -wise Adaptive Moments optimizer for Batch training) est une méthode d'optimisation qui prend en compte le taux de changement de chaque paramètre de poids pour chaque époque dans LARS.

En utilisant LAMB, l'apprentissage BERT, qui prend normalement 81 heures, peut être accéléré à 76 minutes, ce qui est environ 100 fois plus rapide.

Large Batch Optimization for Deep Learning: Training BERT in 76 minutes https://arxiv.org/abs/1904.00962

0_4adbYyMXvYW4E3LN.png (Tiré du guide NVIDIA sur l'implémentation de l'optimiseur pour BERT à grande échelle)

(référence) https://medium.com/nvidia-ai/a-guide-to-optimizer-implementation-for-bert-at-scale-8338cc7f45fd https://developer.nvidia.com/blog/pretraining-bert-with-layer-wise-adaptive-learning-rates/ https://postd.cc/optimizing-gradient-descent/ https://towardsdatascience.com/an-intuitive-understanding-of-the-lamb-optimizer-46f8c0ae4866

3.4 Comment utiliser LAMB etc. avec NVIDIA

Tout d'abord, installez apex en vous référant à la page NVIDIA APEX (A PyTorch Extension).

https://github.com/NVIDIA/apex https://nvidia.github.io/apex/

$ git clone https://github.com/NVIDIA/apex
$ cd apex
$ pip install -v --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" ./

La mise en œuvre est la suivante. Tout d'abord, réécrivez train ().

from apex import amp


def trainAMP(model, device, train_loader, optimizer, epoch):
    model.train()  #En mode entraînement

    for batch_idx, (data, target) in enumerate(train_loader):
        #Récupération de données
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad()

        #propagation
        output = model(data)

        #Calcul des pertes et rétro-propagation
        loss = F.nll_loss(output, target)

        # AMP Train your model
        with amp.scale_loss(loss, optimizer) as scaled_loss:
            scaled_loss.backward()

        optimizer.step()

Ensuite, écrivez une fonction d'apprentissage en utilisant trainAMP ().

def MNIST_trainAMP(optimizer, model, device, train_loader, test_loader): 
    epochs = 1

    start = time.time()
    torch.backends.cudnn.benchmark = True

    #En traitement
    for epoch in range(1, epochs+1):
        trainAMP(model, device, train_loader, optimizer, epoch)
        test(model, device, test_loader)

    #Temps pris
    print("=======Temps pris========")
    print(time.time() - start)

Définissez l'optimiseur sur apex.optimizers.FusedLAMB. Le LAMBA de NVIDIA s'appelle NVLAMB.

import apex


#Définir le modèle, le taux d'apprentissage et l'optimiseur
model = Net().to(device)
lr_rate = 0.1
optimizer = apex.optimizers.FusedLAMB(model.parameters(), lr=lr_rate)
# Initialization
opt_level = 'O1'
model, optimizer = amp.initialize(model, optimizer, opt_level=opt_level)

Initialisez le modèle et l'optimiseur avec AMP.

Enfin, nous effectuerons des formations.

MNIST_trainAMP(optimizer, model, device,
               train_loader_pin_memory, test_loader_pin_memory)

Voilà comment utiliser l'optimiseur LAMB de NVIDIA pour les gros mini-lots.

4. Paramètres multi-GPU

Lors de l'entraînement avec Multi-GPU Pas le torch.nn.DataParallel de DATAPARALLEL DISTRIBUTEDDATAPARALLEL torch.nn.parallel.DistributedDataParallel Utilisez le.

C'est comme la diapositive de la conférence ci-dessous En effet, DATA PARALLEL n'utilise qu'un seul cœur du processeur. S'il s'agit de DISTRIBUTEDDATAPARALLEL, 1 cœur de processeur est alloué à 1 GPU.

d3.JPG

En outre, APEX ʻapex.parallel.DistributedDataParallel de NVIDIA peut être utilisé de la même manière que torch.nn.parallel.DistributedDataParallel`, mais avec ses avantages.

Autrement dit, ʻapex.parallel.DistributedDataParallel` de NVIDIA est maintenant ** Normalisation de lots synchronisés **.

Dans le cas du multi-GPU, la couche de normalisation par lots de PyTorch effectue une normalisation par lots dans un mini-lot attribué à chaque GPU, calcule la moyenne et l'écart type pour chaque GPU, et les moyenne pour faire la moyenne de la normalisation du lot. Apprenons l'écart type.

Cela s'appelle ** Normalisation de lots asynchronisée ** car elle effectue une normalisation par lots pour chaque GPU.

La normalisation par lots et les résultats des calculs pour toutes les données distribuées sur le multi-GPU changeront.

Dans le cas de PyToch, il existe une stratégie pour utiliser torch.nn.SyncBatchNorm, mais c'est assez compliqué à mettre en œuvre.

Utilisation de l'APEX de NVIDIA ʻapex.parallel.DistributedDataParallel`

sync_bn_model = apex.parallel.convert_syncbn_model(model) Convertissez simplement le modèle avec pour obtenir la * normalisation synchronisée des lots **.

(référence) https://nvidia.github.io/apex/parallel.html https://github.com/NVIDIA/apex/tree/master/apex/parallel https://github.com/NVIDIA/apex/tree/master/examples/simple/distributed

5. Fonction de conversion Tensol en JIT

Attachez le [email protected] à la fonction de l'opération individuelle au tenseur et faites-le PyToch JIT (format d'exécution C ++) Accélérez.

JIT (Just-In-Time Compiler) est un compilateur qui compile le code lorsque le logiciel est exécuté pour améliorer la vitesse d'exécution.

Tensorflow et Keras sont définis et exécutés, compilés puis exécutés (le code était difficile à écrire)

PyTorch est défini par exécution, qui construit des calculs tout en faisant circuler les données. Cependant, il est préférable de compiler d'abord les fonctions de calcul fixes, utilisez donc JIT pour en faire un format d'exécution C ++ (fonctionne à partir de Python).

Par exemple, lorsque vous souhaitez définir la fonction d'activation gelu, la définition normale et la définition dans JIT sont les suivantes.

def gelu(x):
    return x * 0.5 * (1.0 + torch.erf(x / 1.41421))

@torch.jit.script
def fused_gelu(x):
    return x * 0.5 * (1.0 + torch.erf(x / 1.41421))

Pour créer PyTorch JIT, attachez le décorateur @ torch.jit.script à la fonction.

En comparant la vitesse d'exécution de ceci,

import time

x = torch.randn(2000, 3000)

start = time.time()

for i in range(200):
    gelu(x)

#Temps pris
print("=======Temps pris========")
print(time.time() - start)

Quand

import time

x = torch.randn(2000, 3000)

start = time.time()

for i in range(200):
    fused_gelu(x)

#Temps pris
print("=======Temps pris========")
print(time.time() - start)

Puis

● Cas 1: p3.2xlarge (NVIDIA® VOLTA V100 Tensor Core GPU)

Donc, 9,8 secondes → 6,6 secondes

● Cas 2: Google Colaboratory (Tesla Turing T4 Tensor Core GPU)

Puis 13,94 secondes → 13,91 secondes

était.

Il n'y a pratiquement aucun changement dans Google Colaboratory, mais dans AWS p3.2xlarge, le temps est réduit à environ 60%.

6. Autres conseils

6.1 Configuration d'un modèle qui ne nécessite pas de rétro-propagation

Lors de l'utilisation d'un modèle ne nécessitant pas de rétropropagation pour une partie de l'ensemble, comme pour le calcul du GAN,

model.zero_grad()

ne pas,

for param in model.parameters():
    param.grad = None

Définissez le calcul du dégradé sur Aucun avec. En effet, model.zero_grad () consomme en fait une zone mémoire.

d4.JPG

6.2 Couche avant la normalisation du lot, définissez le paramètre de biais sur False

Si vous standardisez avec la normalisation par lots et que vous la moyennez à 0, alors s'il y a un paramètre de biais dans la couche précédente, la normalisation par lots apprendra également un terme constant pour l'annuler.

Puisqu'il s'agit d'une perte de temps de calcul et de quantité de calcul, le paramètre de biais doit être défini sur Faux pour la couche avant la normalisation du lot, et le terme de biais ne doit pas être utilisé.

  1. non_blocking=True

7.1 Effectuer des copies GPU asynchrones

  1. À propos de DataLoader (num_workers, pin_memory) Alors, j'ai expliqué comment utiliser pin_memory.

Le DataLoader de PyTorch utilise par défaut l'argument pin_memory = False, mais vous pouvez utiliser ** l'épinglage de mémoire automatique ** en définissant pin_memory = True.

La zone de mémoire du processeur ne sera pas paginée, ce qui devrait s'accélérer.

pinnedv3-1024x541.jpg

La mise en œuvre à ce moment était la suivante.

#Chargeur de données recommandé
train_loader_pin_memory = torch.utils.data.DataLoader(
    dataset1, batch_size=mini_batch_size, num_workers=os.cpu_count(), pin_memory=True)
test_loader_pin_memory = torch.utils.data.DataLoader(
    dataset2, batch_size=mini_batch_size, num_workers=os.cpu_count(), pin_memory=True)

Désormais, pour des vitesses encore plus rapides, activez les copies GPU asynchrones.

Parce que, comme c'est ** Le CPU ne peut pas fonctionner pendant le transfert de données de la mémoire épinglée du CPU vers le GPU **.

Utilisez donc le paramètre non_blocking = True.

Ensuite, le processeur peut fonctionner même lors du transfert de la mémoire épinglée vers le GPU, et une accélération est attendue.

La mise en œuvre est simple, réécrivant la partie qui envoie les données à cuda.

for batch_idx, (data, target) in enumerate(train_loader):
        #Récupération de données
        data, target = data.to(device), target.to(device)

À

# non_blocking=True
for batch_idx, (data, target) in enumerate(train_loader):
        #Récupération de données
        data, target = data.to(device, non_blocking=True), target.to(device, non_blocking=True)

Et donnez l'argument non_blocking = True dans à ().

référence https://stackoverflow.com/questions/55563376/pytorch-how-does-pin-memory-works-in-dataloader https://pytorch.org/docs/stable/notes/cuda.html#use-pinned-memory-buffers https://discuss.pytorch.org/t/should-we-set-non-blocking-to-true/38234 https://developer.nvidia.com/blog/how-optimize-data-transfers-cuda-cc/

7.2 Comparaison de la différence de vitesse

Comparez quand non_blocking = True et quand ce n'est pas le cas (pin_memory = True uniquement).

● Cas 1: p3.2xlarge (NVIDIA® VOLTA V100 Tensor Core GPU)

Donc, 13,126 secondes → 13,125 secondes

● Cas 2: Google Colaboratory (Tesla P100-PCIE Tensor Core GPU) Cela a changé. C'est la même Tesla.

Donc, 8,370 secondes → 8,298 secondes

C'est devenu un peu plus rapide.

Ce qui précède a été exécuté avec num_workers = 0 de DataLoader, donc s'il est exécuté avec num_workers = 2,

● Cas 1: p3.2xlarge Donc, 6,843 secondes → 6,77 6 secondes

● Cas 2: Google Colaboratory Puis 8,059 secondes → 7,935 secondes

C'est aussi un peu plus rapide.

Étant donné que l'échelle est petite avec MNIST, il est difficile de voir les avantages, mais cela peut être significativement efficace pour le traitement compliqué et les données volumineuses qui sont lourdes pour le processeur.

Résumé

Jusqu'à présent, nous avons présenté les conseils pour accélérer l'apprentissage et le raisonnement avec PyTorch.

Certaines techniques, dans le cas de Google Colaboratory, J'ai eu le sentiment: "Est-ce que quelque chose se passe dans les coulisses, est-ce que cela ne fonctionne pas ou est-ce que cela fonctionne automatiquement?"

D'un autre côté, je pense que cet article peut être utilisé de nombreuses manières lorsque vous configurez normalement une instance GPU dans le cloud et effectuez un apprentissage en profondeur avec PyTorch.

J'espère que vous en profiterez ♪


Remarques

** [Auteur] ** Dentsu International Information Service (ISID) AI Transformation Center Development Gr Yutaro Ogawa (Livre principal "Apprendre en créant! Apprentissage en profondeur par PyTorch", etc. /github.com/YutaroOgawa/about_me))

【Twitter】 En me concentrant sur l'IT / IA et le business / management, j'envoie des articles que je trouve intéressants et des impressions de nouveaux livres que j'ai récemment lus. Si vous souhaitez collecter des informations sur ces champs, veuillez nous suivre ♪ (Il y a beaucoup d'informations à l'étranger)

Yutaro Ogawa @ISID_AI_team

** [Autre] ** L '«équipe de développement AI Transformation Center» que je dirige recherche des membres. Si vous êtes intéressé, veuillez visiter cette page pour postuler.

** [Sokumen-kun] ** Si vous souhaitez postuler soudainement, nous aurons un entretien informel avec "Sokumen-kun". Veuillez également l'utiliser ♪ https://sokumenkun.com/2020/08/17/yutaro-ogawa/

[Clause de non-responsabilité] Le contenu de cet article lui-même est l'opinion / la transmission de l'auteur, et non l'opinion officielle de la société à laquelle l'auteur appartient.


Recommended Posts

Une collection de conseils pour accélérer l'apprentissage et le raisonnement avec PyTorch
Découvrez la puissance de l'accélération avec NumPy / SciPy
J'ai recherché une carte similaire de Hearthstone avec Deep Learning
Raisonnement causal et recherche causale par Python (pour les débutants)
Un mémorandum d'étude et de mise en œuvre du Deep Learning
Une collection de ressources qui peuvent être utiles pour créer et développer des fichiers dotfiles
Créer un ensemble de données d'images à utiliser pour la formation
[PyTorch] Un peu de compréhension de CrossEntropyLoss avec des formules mathématiques
Vue d'ensemble et astuces de Seaborn avec visualisation de données statistiques
Créez un lot d'images et gonflez avec ImageDataGenerator
Remarques sur l'accélération du code Python avec Numba
L'apprentissage automatique pratique avec Scikit-Learn et TensorFlow-TensorFlow a abandonné -
Chargement / affichage et accélération de gif avec python [OpenCV]
Conseils pour ouvrir une scène avec une référence brisée dans un script
Collecte et automatisation d'images érotiques à l'aide du deep learning
Peut être utilisé avec AtCoder! Une collection de techniques pour dessiner du code court en Python!
Essayez l'analyse morphologique et la chaîne de Markov avec Django (Ari avec beaucoup de marge d'amélioration)
Obtenez une liste des métriques CloudWatch et une table de correspondance des unités unitaires avec Python boto
Convertissez RVB et HSV sous une forme divisible avec PyTorch
Créez un environnement d'apprentissage automatique scikit-learn avec VirtualBox et Ubuntu
Une collection de techniques professionnelles compétitives à résoudre avec Python
Procédure d'installation pour Python et Ansible avec une version spécifique
Détecter les objets d'une couleur et d'une taille spécifiques avec Python
Essayez d'ouvrir une sous-fenêtre avec PyQt5 et Python
[Django] Une collection de scripts pratiques pour le développement
Une collection de méthodes utilisées lors de l'agrégation de données avec des pandas
Bibliothèque pour spécifier un serveur de noms en python et dig
Tourner un tableau de chaînes avec une instruction for (Python3)
Prédiction de la moyenne Nikkei avec Pytorch 2
Démineur d'apprentissage automatique avec PyTorch
Prédiction de la moyenne Nikkei avec Pytorch
Création, apprentissage et raisonnement de modèles d'apprentissage
Introduction et astuces de mlflow.
Une histoire coincée avec l'installation de la bibliothèque de machine learning JAX
Créer et tester un environnement CI pour plusieurs versions de Python
Création d'un environnement Windows 7 pour une introduction à l'apprentissage automatique avec Python
Créez une illusion rayée avec correction gamma pour Python3 et openCV3
J'ai créé beaucoup de fichiers pour la connexion RDP avec Python
L'histoire de la création d'un pilote standard pour db avec python.
Apprentissage automatique avec docker (42) Programmation PyTorch pour l'apprentissage en profondeur par Ian Pointer
Résumé des API recommandées pour l'intelligence artificielle, l'apprentissage automatique et l'IA
Conseils d'utilisation de Selenium et Headless Chrome dans un environnement CUI
Créer et renvoyer un fichier CSV CP932 pour Excel avec Chalice
[DynamoDB] [Docker] Créer un environnement de développement pour DynamoDB et Django avec docker-compose
Les débutants veulent créer quelque chose comme un cube rubic avec UE4 et en faire une bibliothèque pour un apprentissage amélioré # 4
Introduction et utilisation de la bouteille Python ・ Essayez de configurer un serveur Web simple avec une fonction de connexion
Les débutants veulent créer quelque chose comme un cube rubic avec UE4 et en faire une bibliothèque pour un apprentissage amélioré # 5
Les débutants veulent créer quelque chose comme un cube rubic avec UE4 et en faire une bibliothèque pour un apprentissage amélioré # 6