[PYTHON] Eine Sammlung von Tipps zur Beschleunigung des Lernens und Denkens mit PyTorch

In diesem Artikel werde ich eine Sammlung von Tipps zur Beschleunigung des Deep Learning mit PyTorch vorstellen, die von NVIDIA angekündigt wurden.

Über diesen Artikel

Dieser Artikel wurde von Arun Mallya von NVIDIA angekündigt, 「PyTorch Performance Tuning Guide - Szymon Migacz, NVIDIA」 Ich werde erklären, indem ich Erklärungen und Programme hinzufüge.

d1.JPG

Der Punkt dieses Artikels ist genau das, was Andrew Karpathy auf Twitter murmelt.

Ich werde dies auf leicht verständliche Weise erklären.

※Andrej Karpathy Promotion bei Dr. Fay Fay Lee, die ImageNet vorbereitet hat Derzeit der Direktor der KI-Abteilung von Tesla Die menschliche Leistung mit ImageNet hat eine Fehlerrate von 5%, aber um dieses Ergebnis zu erzielen, die Person, die ImageNet herausgefordert hat, was vom menschlichen Vertreter durchgeführt wurde

Inhalt dieses Artikels

  1. Vorsichtsmaßnahmen für den Inhalt
  2. Über DataLoader (num_workers, pin_memory)
  3. Über torch.backends.cudnn.benchmark = True
  4. Erhöhen Sie die Mini-Batch-Größe (AMP, LARS und LAMB).
  5. Multi-GPU-Einstellungen
  6. Tensolumwandlungsfunktion in JIT
  7. Andere Tipps  7. non_blocking=True

0. Vorsichtsmaßnahmen für den Inhalt

Der in diesem Artikel beschriebene Inhalt hängt von der von Ihnen verwendeten GPU-Umgebung ab.

Versuchen Sie herauszufinden, welches für Ihre Umgebung geeignet ist.

Alle Programme in diesem Artikel https://github.com/YutaroOgawa/Qiita/tree/master/pytorch_performance Es ist für die Öffentlichkeit zugänglich.

Es ist im Jupyter Notebook-Format.

In diesem Artikel können Sie [Leistungsänderung] in der Zeit von "MNIST Training 1 Epoche" leicht überprüfen.

1. Über DataLoader

Der DataLoader von PyTorch bietet zwei Funktionen: Die Standardeinstellungen sind nicht sehr gut. https://pytorch.org/docs/stable/data.html

1.1 num_workers

Erstens ist das Argument standardmäßig "num_workers = 0". Infolgedessen ist der Mini-Batch-Abruf ein einzelner Prozess.

Durch Setzen von "num_workers = 2" usw. werden Daten mit mehreren Prozessen geladen und die Verarbeitung beschleunigt.

Sie können die Anzahl der CPU-Kerne unten überprüfen.

#Überprüfen Sie die Anzahl der CPU-Kerne
import os
os.cpu_count()  #Zahl der Kerne

Für die Anzahl der Kerne reicht 2 für 1 GPU.

Erstellen Sie einen DataLoader wie folgt.

#Für Data Loader mit Standardeinstellungen
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)

#Datenlader: 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)


#Datenlader: voll
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())

[Leistungsänderung] Überprüfen Sie die Leistungsänderung in der MNIST-Trainingsphase 1.

#Überprüfen Sie die GPU
!nvidia-smi

Sie können die GPU der Nutzungsumgebung mit überprüfen.

Diesmal, ● Fall 1: p3.2xlarge (NVIDIA® VOLTA V100 Tensor Core-GPU) ● Fall 2: Google Colaboratory (Tesla Turing T4 Tensor Core-GPU)

Es wird sein. Bitte beachten Sie, dass Google Colaboratory jedes Mal einen anderen GPU-Typ hat.

[Standard] ● Fall 1: p3.2xlarge: 14,73 Sekunden ● Fall 2: Google Colaboratory: 10,01 Sekunden

[Im Fall von num_workers = os.cpu_count ()] ● Fall 1: p3.2xlarge: 3,47 Sekunden ● Fall 2: Google Colaboratory: 9,43 Sekunden

Beide sind schneller, aber Fall 1 ist sehr schnell, bis zu etwa 1/3.

Beachten Sie, dass p3.2xlarge 8 CPU-Kerne und Goole Colaboratory 2 CPU-Kerne hat.

Die Anzahl der Kerne beträgt jedoch 2 und num_workers = 2 vermittelt einen ausreichenden Eindruck.

Selbst in der ursprünglichen Ankündigung scheint es keinen großen Unterschied zwischen 2 und mehr zu geben.

d2.JPG

1.2 pin_memory

Der DataLoader von PyTorch verwendet standardmäßig das Argument "pin_memory = False".

** Automatisches Speichern des Speichers ** kann durch Setzen von pin_memory = True verwendet werden.

Der Speicherbereich der CPU wird nicht ausgelagert, was sich voraussichtlich beschleunigen wird.

pinned-1024x541.jpg

(Referenz) 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/

(Erklärung des Speicher-Paging) https://wa3.i-3-i.info/word13352.html

Die Implementierung ist wie folgt.

#Für Data Loader mit Standardeinstellungen
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)

#Pin-Speicher des Datenladers
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)

Überprüfen Sie nach wie vor die Leistungsänderung in der MNIST-Trainingsphase 1.

[Standard] ● Fall 1: p3.2xlarge: 14,73 Sekunden ● Fall 2: Google Colaboratory: 10,01 Sekunden

[Wenn pin_memory = True] ● Fall 1: p3.2xlarge: 13,65 Sekunden ● Fall 2: Google Colaboratory: 9,82 Sekunden

[Im Fall von num_workers = os.cpu_count ()] ● Fall 1: p3.2xlarge: 3,47 Sekunden ● Fall 2: Google Colaboratory: 9,43 Sekunden

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

Im Vergleich zu den Standardeinstellungen können Sie feststellen, dass es schneller ist.

Wenn num_workers festgelegt ist, ist der Maßstab dieses MNIST zu klein oder der Effekt von pin_memory ist nicht sichtbar.

1.3 Fazit zur Erstellung von DataLoader

[1] Wenn Sie einen DataLoader mit PyTorch erstellen, ändern Sie die Argumente num_workers und pin_memory und implementieren Sie sie wie folgt.

#Standardkonfiguration
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)

#Datenlader empfohlen
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)

#Oder Datenlader-Nummer_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. Über torch.backends.cudnn.benchmark = True

2.1 Erklärung

Stellen Sie sicher, dass Sie "torch.backends.cudnn.benchmark = True" ausführen, wenn Sie das Training durchführen.

Dies optimiert und beschleunigt Netzwerkberechnungen auf der GPU-Seite, wenn die Netzwerkform festgelegt ist.

Auf True setzen, wenn sich die Dateneingabegröße am Anfang oder in der Mitte nicht wie bei einem normalen CNN ändert.

Bitte beachten Sie jedoch, dass die Reproduzierbarkeit der Berechnung verloren geht.

(Über die Berechnungsreproduzierbarkeit von PyTorch) https://pytorch.org/docs/stable/notes/randomness.html

Die Implementierung ist beispielsweise wie folgt.

def MNIST_train_cudnn_benchmark_True(optimizer, model, device, train_loader, test_loader):
    #Standardmäßig Training
    epochs = 1

    #hinzufügen
    torch.backends.cudnn.benchmark = True

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

Hier hat die Funktion train () die folgende Form.

def train(model, device, train_loader, optimizer, epoch):
    model.train()  #Im Trainingsmodus
    for batch_idx, (data, target) in enumerate(train_loader):
        #Datenabruf
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad()

        #Vermehrung
        output = model(data)

        #Verlustberechnung und Rückausbreitung
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()

Geschwindigkeiten vergleichen. Belassen Sie den Datenlader bei der Standardeinstellung.

[Standard] ● Fall 1: p3.2xlarge: 14,73 Sekunden ● Fall 2: Google Colaboratory: 10,01 Sekunden

[Wenn torch.backends.cudnn.benchmark = True] ● Fall 1: p3.2xlarge: 14,47 Sekunden ● Fall 2: Google Colaboratory: 9,66 Sekunden

Dieses Mal löse ich nur MNIST, daher ist das Netzwerk klein, daher ist dieser Effekt schwach, aber etwas schneller.

2.2 Fazit

** Geben Sie beim Ausführen des Programms torch.backends.cudnn.benchmark = True ein **

3. Erhöhen Sie die Mini-Chargengröße

Je größer die Mini-Batch-Größe ist, desto stabiler ist das Lernen. Erhöhen wir daher die Mini-Stapelgröße.

Mit der ** AMP-Funktion (Automatic Mixed Precision) ** von PyTorch ** gibt es Fälle, in denen eine Mini-Batch-Größe, die größer als die erwartete Berechnung ist, tatsächlich möglich ist.

3.1 Informationen zur AMP-Funktion (Automatic Mixed Precision)

AMP (Automatic Mixed Precision) bedeutet Mischgenauigkeit.

Normalerweise wird es mit FP32 (32-Bit-Gleitkomma) berechnet, aber die Hälfte von FP16 (16-Bit-Gleitkomma) ist eine Funktion, die Speicherplatz spart und die Berechnungsgeschwindigkeit verbessert, ohne die Genauigkeit zu beeinträchtigen.

Wenn die GPU über einen Tensorkern verfügt, ist diese 8- bis 16-mal schneller als zweimal. (Bis zu 12 Mal für das Training, bis zu 6 Mal für die Argumentation)

Volta-Tensor-Core_30fps_FINAL_994x559.gif

(Referenz) https://www.nvidia.com/ja-jp/data-center/tensor-cores/

Der V100 Volta ist mit dem TENSOR-Kern der 1. Generation ausgestattet. Die T-Serie ist mit dem TURING TENSOR Core 2. Generation ausgestattet. Die 2. Generation des TURING TENSOR-Kerns soll etwa doppelt so schnell sein wie die 1. Generation.

Turing-Tensor-Core_30fps_FINAL_736x414.gif

3.2 AMP (Automatic Mixed Precision) verwenden

Klicken Sie hier, um Erklärungen zur Verwendung zu erhalten.

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

Implementieren Sie gemäß den obigen Beispielen.

Schreiben Sie den vorherigen Funktionstest () neu.

def train_PyTorchAMP(model, device, train_loader, optimizer, epoch):
    model.train()  #Im Trainingsmodus

    scaler = torch.cuda.amp.GradScaler()

    for batch_idx, (data, target) in enumerate(train_loader):
        #Datenabruf
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad()

        #Vermehrung
        # 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()

Erstellen Sie einen Skalierer mit "scaler = torch.cuda.amp.GradScaler ()" und schließen Sie Vorwärts-, Verlust-, Rückausbreitungs- und Parameteraktualisierungen mit dem Skalierer ab.

Legen Sie DataLoader als Standardeinstellung fest und vergleichen Sie die Geschwindigkeit mit AMP.

[Standard] ● Fall 1: p3.2xlarge: 14,73 Sekunden ● Fall 2: Google Colaboratory: 10,01 Sekunden

[Für AMP] ● Fall 1: p3.2xlarge: 14,21 Sekunden ● Fall 2: Google Colaboratory: 11,97 Sekunden

In diesem MNIST ist der Betrag einer Berechnung gering, sodass ich keinen großen Effekt verspürte.

Mit diesem AMP ist es jedoch möglich, die Mini-Batch-Größe stärker als erwartet zu erhöhen Bitte beachten Sie die folgenden Punkte, wenn Sie die Größe des Mini-Batches erhöhen.

[1] Anpassung des Lernratenwerts [2] Anpassung des Gewichtsabfalls: Die Höhe der Strafen des Optimierers [3] Aufwärmen in das Lernen einbeziehen: In den frühen Lernphasen wird die Lernrate schrittweise linear von 0 auf ein bestimmtes Niveau erhöht. [4] Lernratenverfall in das Lernen einbeziehen: Die Lernrate am Ende des Lernens schrittweise reduzieren

3.3 Über LARS und LAMB

Bei großen Mini-Batchs sollten Sie auch LARS, LAMB, NVIDIAs LAMB NVLAMB usw. für den Optimierer verwenden.

Für große Mini-Chargen

** Im gleichen Zeitraum ist die Gesamtzahl der Epochen geringer als bei einer kleinen Chargengröße. Wenn Sie einfach die Lernrate erhöhen, um dies auszugleichen, ist die Lernrate diesmal zu hoch und es ist schwierig, das Training zu stabilisieren **

Wird passieren.

Daher ist LARS (Layerwise Adaptive Rate Scaling) eine Methode zum Multiplizieren der Lernrate mit einem Koeffizienten, der als "Vertrauensverhältnis" bezeichnet wird, gemäß dem Gradienten.

Darüber hinaus ist LAMB (Layer-Wise Adaptive Moments Optimizer für Batch-Training) eine Optimierungsmethode, die die Änderungsrate jedes Gewichtsparameters für jede Epoche in LARS berücksichtigt.

Durch die Verwendung von LAMB kann das BERT-Lernen, das normalerweise 81 Stunden dauert, auf 76 Minuten beschleunigt werden, was etwa 100-mal schneller ist.

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

0_4adbYyMXvYW4E3LN.png (Aus NVIDIAs A Guide to Optimizer Implementation für BERT at Scale)

(Referenz) 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 Verwendung von LAMB usw. mit NVIDIA

Installieren Sie zunächst Apex, indem Sie auf die folgende Seite NVIDIA APEX (A PyTorch Extension) verweisen.

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" ./

Die Implementierung ist wie folgt. Schreiben Sie zuerst train () neu.

from apex import amp


def trainAMP(model, device, train_loader, optimizer, epoch):
    model.train()  #Im Trainingsmodus

    for batch_idx, (data, target) in enumerate(train_loader):
        #Datenabruf
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad()

        #Vermehrung
        output = model(data)

        #Verlustberechnung und Rückausbreitung
        loss = F.nll_loss(output, target)

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

        optimizer.step()

Schreiben Sie dann eine Trainingsfunktion mit trainAMP ().

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

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

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

    #Zeit genommen
    print("=======Zeit genommen========")
    print(time.time() - start)

Setzen Sie den Optimierer auf apex.optimizers.FusedLAMB. NVIDIAs LAMBA heißt NVLAMB.

import apex


#Modell, Lernrate und Optimierer einstellen
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)

Initialisieren Sie das Modell und den Optimierer mit AMP.

Schließlich werden wir Schulungen durchführen.

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

So verwenden Sie den LAMB-Optimierer von NVIDIA für große Mini-Batches.

4. Multi-GPU-Einstellungen

Beim Training mit Multi-GPU Nicht die torch.nn.DataParallel von DATAPARALLEL DISTRIBUTED DATA PARALLEL torch.nn.parallel.DistributedDataParallel Verwenden Sie die.

Dies ist wie auf der Folie unten Dies liegt daran, dass DATA PARALLEL nur einen Kern der CPU verwendet. Wenn es DISTRIBUTEDDATAPARALLEL ist, wird 1 CPU-Kern 1 CPU-Kern zugewiesen.

d3.JPG

Außerdem kann NVIDIAs APEX apex.parallel.DistributedDataParallel auf die gleiche Weise wie torch.nn.parallel.DistributedDataParallel verwendet werden, jedoch mit seinen Vorteilen.

Das heißt, NVIDIAs "apex.parallel.DistributedDataParallel" ist jetzt ** Synchronized Batch Normalization **.

Im Fall einer Multi-GPU führt die Chargennormalisierungsschicht von PyTorch eine Chargennormalisierung innerhalb eines jeder GPU zugewiesenen Minibatches durch, berechnet den Durchschnitt und die Standardabweichung für jede GPU und mittelt sie, um die Chargennormalisierung zu mitteln. Lernen wir die Standardabweichung.

Dies wird als ** Asynchronisierte Stapelnormalisierung ** bezeichnet, da für jede GPU eine Stapelnormalisierung durchgeführt wird.

Die Ergebnisse der Chargennormalisierung und -berechnung für alle auf der Multi-GPU verteilten Daten ändern sich.

Im Fall von PyToch gibt es eine Strategie zur Verwendung von "torch.nn.SyncBatchNorm", deren Implementierung jedoch recht mühsam ist.

Verwenden von NVIDIAs APEX apex.parallel.DistributedDataParallel

sync_bn_model = apex.parallel.convert_syncbn_model(model) Konvertieren Sie einfach das Modell mit, um * Synchronized Batch Normalization ** zu erhalten.

(Referenz) 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. Tensolumwandlungsfunktion in JIT

Hängen Sie den Befehl [email protected] an die Funktion der einzelnen Operation an den Tensor an und machen Sie ihn zu PyToch JIT (C ++ - Ausführungsformat). Beschleunigen Sie.

JIT (Just-In-Time-Compiler) ist ein Compiler, der Code kompiliert, wenn Software ausgeführt wird, um die Ausführungsgeschwindigkeit zu verbessern.

Tensorflow und Keras werden definiert und ausgeführt, kompiliert und dann ausgeführt (der Code war umständlich zu schreiben).

PyTorch wird durch Ausführen definiert, wodurch Berechnungen erstellt werden, während Daten fließen. Es ist jedoch besser, zuerst die festen Berechnungsfunktionen zu kompilieren. Verwenden Sie daher JIT, um ein C ++ - Ausführungsformat zu erstellen (arbeiten Sie mit Python).

Wenn Sie beispielsweise die Aktivierungsfunktion gelu definieren möchten, lauten die normale Definition und die Definition in JIT wie folgt.

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

Um es zu PyTorch JIT zu machen, hängen Sie den Dekorator @ torch.jit.script an die Funktion an.

Vergleich der Ausführungsgeschwindigkeit davon,

import time

x = torch.randn(2000, 3000)

start = time.time()

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

#Zeit genommen
print("=======Zeit genommen========")
print(time.time() - start)

Wann

import time

x = torch.randn(2000, 3000)

start = time.time()

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

#Zeit genommen
print("=======Zeit genommen========")
print(time.time() - start)

Dann

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

Also 9,8 Sekunden → 6,6 Sekunden

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

Dann 13,94 Sekunden → 13,91 Sekunden

war.

In Google Colaboratory gibt es fast keine Änderungen, aber in AWS p3.2xlarge wird die Zeit auf etwa 60% reduziert.

6. Andere Tipps

6.1 Einrichten eines Modells, für das keine Rückübertragung erforderlich ist

Wenn Sie ein Modell verwenden, für das für einen Teil des Ganzen keine Rückausbreitung erforderlich ist, z. B. für die GAN-Berechnung,

model.zero_grad()

nicht,

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

Setzen Sie die Gradientenberechnung auf Keine mit. Dies liegt daran, dass model.zero_grad () tatsächlich einen Speicherbereich belegt.

d4.JPG

6.2 Schicht vor der Chargennormalisierung Setzen Sie den Bias-Parameter auf False

Wenn Sie mit Batch-Normalisierung standardisieren und auf 0 mitteln, lernt die Batch-Normalisierung bei einem Bias-Parameter in der vorherigen Ebene auch einen konstanten Term, um ihn abzubrechen.

Da dies eine Verschwendung von Berechnungszeit und Rechenaufwand ist, sollte der Bias-Parameter für die Schicht vor der Chargennormalisierung auf False gesetzt werden, und der Bias-Term sollte nicht verwendet werden.

  1. non_blocking=True

7.1 Führen Sie asynchrone GPU-Kopien durch

  1. Über DataLoader (num_workers, pin_memory) Also erklärte ich, wie man pin_memory benutzt.

Der DataLoader von PyTorch verwendet standardmäßig das Argument "pin_memory = False". Sie können jedoch ** automatische Speicheranbindung ** verwenden, indem Sie "pin_memory = True" setzen.

Der Speicherbereich der CPU wird nicht ausgelagert, was sich voraussichtlich beschleunigen wird.

pinnedv3-1024x541.jpg

Die Implementierung war zu diesem Zeitpunkt wie folgt.

#Datenlader empfohlen
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)

Aktivieren Sie jetzt für noch schnellere Geschwindigkeiten asynchrone GPU-Kopien.

Weil, wie es ist ** Die CPU kann nicht arbeiten, während Daten vom angehefteten Speicher der CPU zur GPU übertragen werden **.

Verwenden Sie daher die Einstellung non_blocking = True.

Dann kann die CPU auch während der Übertragung vom fixierten Speicher zur GPU arbeiten, und es wird eine Beschleunigung erwartet.

Die Implementierung ist einfach und schreibt den Teil neu, der Daten an cuda sendet.

for batch_idx, (data, target) in enumerate(train_loader):
        #Datenabruf
        data, target = data.to(device), target.to(device)

Zu

# non_blocking=True
for batch_idx, (data, target) in enumerate(train_loader):
        #Datenabruf
        data, target = data.to(device, non_blocking=True), target.to(device, non_blocking=True)

Und geben Sie das Argument non_blocking = True in () ein.

Referenz 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 Vergleich der Geschwindigkeitsdifferenz

Vergleichen Sie, wenn non_blocking = True ist und wenn dies nicht der Fall ist (pin_memory = True nur).

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

Also 13,126 Sekunden → 13,125 Sekunden

● Fall 2: Google Colaboratory (Tesla P100-PCIE Tensor Core-GPU) * Die GPU ist ein wenig, weil sie im Postscript überarbeitet wurde. Es hat sich geändert. Es ist das gleiche Tesla.

Also 8,370 Sekunden → 8,298 Sekunden

Es wurde etwas schneller.

Das obige wurde mit num_workers = 0 von DataLoader ausgeführt. Wenn es also mit num_workers = 2 ausgeführt wird,

● Fall 1: p3.2xlarge Also 6,843 Sekunden → 6,77 6 Sekunden

● Fall 2: Google Colaboratory Dann 8,059 Sekunden → 7,935 Sekunden

Das geht auch etwas schneller.

Da der Maßstab bei MNIST klein ist, ist es schwierig, die Vorteile zu erkennen, aber er kann bei komplizierter Verarbeitung und großen Datenmengen, die die CPU belasten, erheblich effektiv sein.

Zusammenfassung

Bisher haben wir die Tipps zur Beschleunigung des Lernens und Denkens mit PyTorch vorgestellt.

Einige Techniken, im Fall von Google Colaboratory, Ich hatte das Gefühl: "Passiert etwas hinter den Kulissen, funktioniert es nicht oder funktioniert es automatisch?"

Andererseits denke ich, dass dieser Artikel auf viele Arten verwendet werden kann, wenn Sie normalerweise eine GPU-Instanz in der Cloud einrichten und mit PyTorch vertiefen.

Ich hoffe, Sie werden es ausnutzen ♪


Bemerkungen

** [Autor] ** Dentsu Internationaler Informationsdienst (ISID) AI Transformation Center Entwicklung Gr Yutaro Ogawa (Hauptbuch "Lernen beim Bilden! Tiefes Lernen von PyTorch" usw. ["Details zur Selbsteinführung"](https: / /github.com/YutaroOgawa/about_me))

【Twitter】 Ich konzentriere mich auf IT / KI und Business / Management und versende Artikel, die ich interessant finde, und Eindrücke von neuen Büchern, die ich kürzlich gelesen habe. Wenn Sie Informationen zu diesen Feldern sammeln möchten, folgen Sie uns bitte ♪ (Es gibt viele Informationen aus Übersee)

Yutaro Ogawa @ISID_AI_team

** [Andere] ** Das von mir geleitete "AI Transformation Center Development Team" sucht Mitglieder. Wenn Sie interessiert sind, besuchen Sie bitte diese Seite, um sich zu bewerben.

** [Sokumen-Kun] ** Wenn Sie sich plötzlich bewerben möchten, haben wir ein ungezwungenes Interview mit "Sokumen-kun". Bitte benutzen Sie dies auch ♪ https://sokumenkun.com/2020/08/17/yutaro-ogawa/

[Haftungsausschluss] Der Inhalt dieses Artikels selbst ist die Meinung / Übermittlung des Autors, nicht die offizielle Meinung des Unternehmens, zu dem der Autor gehört.


Recommended Posts

Eine Sammlung von Tipps zur Beschleunigung des Lernens und Denkens mit PyTorch
Sehen Sie, wie schnell Sie mit NumPy / SciPy beschleunigen können
Ich suchte mit Deep Learning nach einer ähnlichen Karte von Hearthstone
Kausales Denken und kausale Suche von Python (für Anfänger)
Ein Memorandum zum Studieren und Implementieren von Deep Learning
Eine Sammlung von Ressourcen, die zum Erstellen und Erweitern von Punktedateien hilfreich sein können
Erstellen Sie einen Datensatz mit Bildern, die für das Training verwendet werden sollen
[PyTorch] Ein wenig Verständnis von CrossEntropyLoss mit mathematischen Formeln
Übersicht und Tipps von Seaborn mit statistischer Datenvisualisierung
Erstellen Sie einen Stapel von Bildern und blasen Sie sie mit ImageDataGenerator auf
Hinweise zur Beschleunigung des Python-Codes mit Numba
Praktisches maschinelles Lernen mit Scikit-Learn und TensorFlow-TensorFlow gab auf-
Laden / Anzeigen und Beschleunigen von GIF mit Python [OpenCV]
Tipps zum Öffnen einer Szene mit einer fehlerhaften Referenz in einem Skript
Sammlung und Automatisierung erotischer Bilder durch Deep Learning
Kann mit AtCoder verwendet werden! Eine Sammlung von Techniken zum Zeichnen von Kurzcode in Python!
Versuchen Sie es mit morphologischer Analyse und Markov-Kette mit Django (Ari mit viel Raum für Verbesserungen)
Holen Sie sich eine Liste der CloudWatch-Metriken und eine Entsprechungstabelle der Einheiteneinheiten mit Python boto
Konvertieren Sie RGB und HSV mit PyTorch in teilbare Form
Erstellen Sie mit VirtualBox und Ubuntu eine Scikit-Lernumgebung für maschinelles Lernen
Eine Sammlung wettbewerbsfähiger Pro-Techniken, die mit Python gelöst werden können
Installationsverfahren für Python und Ansible mit einer bestimmten Version
Erkennen Sie mit Python Objekte einer bestimmten Farbe und Größe
Versuchen Sie, ein Unterfenster mit PyQt5 und Python zu öffnen
[Django] Eine Sammlung von Skripten, die für die Entwicklung geeignet sind
Eine Sammlung von Methoden, die beim Aggregieren von Daten mit Pandas verwendet werden
Bibliothek zur Angabe eines Nameservers in Python und Dig
Drehen Sie ein Array von Zeichenfolgen mit einer for-Anweisung (Python3).
Vorhersage des Nikkei-Durchschnitts mit Pytorch 2
Maschinelles Lernen Minesweeper mit PyTorch
Vorhersage des Nikkei-Durchschnitts mit Pytorch
Modellbildung, Lernen und Denken lernen
Einführung und Tipps von mlflow.Tracking
Eine Geschichte, die mit der Installation der maschinellen Lernbibliothek JAX zusammenhängt
Erstellen und testen Sie eine CI-Umgebung für mehrere Versionen von Python
Erstellen einer Windows 7-Umgebung für eine Einführung in das maschinelle Lernen mit Python
Erstellen Sie eine gestreifte Illusion mit Gammakorrektur für Python3 und openCV3
Ich habe viele Dateien für die RDP-Verbindung mit Python erstellt
Die Geschichte, einen Standardtreiber für db mit Python zu erstellen.
Maschinelles Lernen mit Docker (42) Programmieren von PyTorch für Deep Learning Von Ian Pointer
Zusammenfassung der empfohlenen APIs für künstliche Intelligenz, maschinelles Lernen und KI
Tipps zur Verwendung von Selen und Headless Chrome in einer CUI-Umgebung
Erstellen Sie eine CP932-CSV-Datei für Excel mit Chalice und geben Sie sie zurück
[DynamoDB] [Docker] Erstellen Sie mit Docker-Compose eine Entwicklungsumgebung für DynamoDB und Django
Anfänger möchten mit UE4 so etwas wie einen Rubic Cube erstellen und daraus eine Bibliothek für verbessertes Lernen # 4 machen
Einführung und Verwendung der Python-Flasche ・ Versuchen Sie, einen einfachen Webserver mit Anmeldefunktion einzurichten
Anfänger möchten mit UE4 so etwas wie einen Rubic Cube erstellen und daraus eine Bibliothek für erweitertes Lernen # 5 machen
Anfänger möchten mit UE4 so etwas wie einen Rubic Cube erstellen und daraus eine Bibliothek für verbessertes Lernen # 6 machen