Ich verwende Tensorflow, schreibe jedoch eine Dokumentation für Benutzer, die in der Regel je nach Deep-Learning-Framework variiert .
Wenn ich mit Datensätzen arbeite, die nicht in das lokale Dateisystem (TB +) passen, probiere ich Daten aus einem entfernten Datenspeicher und schreibe Proben lokal in ein Tensorflow-Standardformat tfrecords
.
Während der ersten Trainingsepoche habe ich nur einige Werte abgetastet, daher ist eine Epoche lokaler Daten sehr klein, ich trainiere darauf. In Epoche 2 überprüfe ich erneut, welche Datendateien von meinen Stichproben-Teilprozessen erzeugt wurden (jetzt mehr), und trainiere den erweiterten Satz lokaler Datendateien für die nächste Epoche. Wiederholen Sie den Vorgang in jeder Epoche. Auf diese Weise baue ich einen lokalen Cache mit Samples auf und kann ältere Samples entfernen, wenn ich den lokalen Speicher auffülle. Der lokale Stichproben-Cache wächst ungefähr zu dem Zeitpunkt, an dem das Modell die Varianz am meisten benötigt (in Richtung des letzten Teils des Trainings).
In Python / Tensorflow ist es entscheidend, dass ich die Daten im Python-Trainingsschleifenprozess nicht deserialisiere, da die Python-GIL die Datenübertragungsraten (300-600 MB / s, die Daten sind wissenschaftlich unkomprimierbar) und damit die GPU-Leistung nicht unterstützen kann leidet, wenn die Python GIL die Trainingsschleife nicht schnell bedienen kann.
Durch das Schreiben der Samples in eine tfrecords
Datei aus Unterprozessen (Python-Multiprocessing) kann der native Tensorflow eine TFRecordsDataset
Deserialisierung außerhalb von Python durchführen. Daher umgehen wir die Python-GIL-Probleme und können eine GPU mit hohen E / A-Datenraten sättigen.
Ich würde gerne wissen, wie ich dieses Problem in Pytorch angehen würde. Ich schreibe über die verwendete Stichprobenstrategie und möchte Benutzern von Tensorflow und PyTorch spezifische Empfehlungen geben, aber ich kenne das PyTorch-Vorverarbeitungs-Ökosystem nicht gut genug, um mit ausreichenden Details zu schreiben.
Randnotiz: Die einzige rein Python-basierte Lösung zur Unterstützung dieser Datenübertragungsraten ist möglicherweise Python 3.8 mit gemeinsam genutztem System V-Speicher und Multiprocessing. Ich habe dies jedoch noch nicht versucht, da die Unterstützung dafür nicht ausreicht (bald wird es so sein) ). Bestehende Multiprozessor-Lösungen reichen nicht aus, da sie eine Deserialisierung im Trainingsschleifenprozess erfordern und somit die GIL während der Deserialisierung mit hohen E / A-Raten sperren.
DataLoader
wie in meiner Antwort geladen werden .Antworten:
Tatsächlich können Sie Daten in einem Unterprozess mithilfe von einfach deserialisieren
torch.utils.data.DataLoader
. Wenn Sie dasnum_workers
Argument auf 1 oder einen höheren Wert setzen, können Sie Unterprozesse mit ihren eigenen Python-Interpreten und GILs erzeugen.A
Dataloader
benötigt atorch.utils.data.Dataset
, um Daten von zu erhalten. Es ist möglicherweise keine triviale Aufgabe, in Ihrem Fall eine geeignete Unterklasse zu implementieren. Falls SieDataset
für jede Epoche eine Instanz neu erstellen müssen , können Sie so etwas tun.oder noch besser
Als Randnotiz beachten Sie bitte, dass es sich in den meisten Fällen um einen CPU-gebundenen Betrieb handelt, der von GIL betroffen ist, und nicht um einen E / A-gebundenen Betrieb, dh
threading
für einen rein E / A-schweren Betrieb, den Sie nicht einmal benötigensubprocess
. Weitere Informationen finden Sie in dieser Frage und in diesem Wikipedia- Artikel .quelle
torch.utils.data.DataLoader
Platzieren Sie zur Bestätigung Daten aus den Unterprozessen auf der GPU oder versuchen Sie, die Multiprozession von Python zu verwenden, um sie in den Trainingsschleifenprozess zu verschieben? Ich habe festgestellt, dass nur die Deserialisierung von einem Prozess zum anderen bei Datenraten nahe 1 GB / s> 1 Kern der Arbeit ist, daher die GIL-Probleme, auf die ich gestoßen bin, als ich diesen Ansatz in TF ausprobiert habe. Wenntorch.utils.data.DataLoader
Daten jedoch so auf die GPU verschoben werden, dass keine Python-Deserialisierung erforderlich ist, ist alles in Ordnung. Ich möchte dieses Verständnis nur bestätigen.torch.utils.data.DataLoader
kann leicht 600% CPU oder mehr ausnutzen, und der Hauptprozess benötigt in den meisten Fällen nicht viel CPU-Leistung, wenn das Training hauptsächlich aus GPU-Berechnungen besteht (wenn das Training hauptsächlich aus CPU-Berechnungen besteht, ist dies immer noch kein Problem, da die Matrixoperation von pytorch problemlos mehrere verwenden kann CPUs).