In diesem Artikel werde ich eine Sammlung von Tipps zur Beschleunigung des Deep Learning mit PyTorch vorstellen, die von NVIDIA angekündigt wurden.
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.
Der Punkt dieses Artikels ist genau das, was Andrew Karpathy auf Twitter murmelt.
good quick tutorial on optimizing your PyTorch code ⏲️: https://t.co/7CIDWfrI0J
— Andrej Karpathy (@karpathy) August 30, 2020
quick summary: pic.twitter.com/6J1SJcWJsl
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
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.
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.
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.
(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] 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)
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.
** Geben Sie beim Ausführen des Programms torch.backends.cudnn.benchmark = True
ein **
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.
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)
(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.
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
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
(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
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.
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.
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
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.
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.
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.
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.
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/
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.
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 ♪
** [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)
** [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