paint-brush
Ein Überblick über die Data-Loader-Landschaft: Experimenteller Aufbauvon@serialization
155 Lesungen

Ein Überblick über die Data-Loader-Landschaft: Experimenteller Aufbau

Zu lang; Lesen

In diesem Artikel heben Forscher Dataloader als Schlüssel zur Verbesserung des ML-Trainings hervor und vergleichen Bibliotheken hinsichtlich Funktionalität, Benutzerfreundlichkeit und Leistung.
featured image - Ein Überblick über die Data-Loader-Landschaft: Experimenteller Aufbau
The Serialization Publication HackerNoon profile picture
0-item

Autoren:

(1) Iason Ofeidis, Department of Electrical Engineering und Yale Institute for Network Science, Yale University, New Haven {Gleicher Beitrag};

(2) Diego Kiedanski, Department of Electrical Engineering und Yale Institute for Network Science, Yale University, New Haven {Gleicher Beitrag};

(3) Leandros TassiulasLevon Ghukasyan, Activeloop, Mountain View, CA, USA, Fakultät für Elektrotechnik und Yale Institute for Network Science, Yale University, New Haven.

Linktabelle

3. Versuchsaufbau

Es wurden mehrere Bibliotheken und Datensätze ausgewählt, um ihre Funktionen und Leistung zu vergleichen. Obwohl wir uns bemüht haben, so verständlich wie möglich zu sein, entwickelt sich der Bereich des Datenladens ständig weiter und jeden Tag kommen neue Bibliotheken und Versionen hinzu. In dieser Hinsicht erwarten wir, dass die folgende Liste einen guten Überblick über die aktuellen Fähigkeiten von Datenladern bietet, ohne unbedingt den Anspruch zu erheben oder zu finden, dass es sich um das insgesamt Beste handelt (was sich wahrscheinlich vom Zeitpunkt des Schreibens bis zum Zeitpunkt der Veröffentlichung ändern würde). Wir stellen den gesamten Quellcode der Experimente der Öffentlichkeit zur Verfügung und erwarten, dass die Ergebnisse vollständig reproduzierbar sind.


Wir haben sieben Bibliotheken für unsere Experimente ausgewählt: PyTorch (Paszke et al., 2019), Torchdata (TorchData, 2021), Hub (Team, 2022a), FFCV (Leclerc et al., 2022), Webdatasets (Webdataset, 2013), Squirrel (Team, 2022b) und Deep Lake (Hambardzumyan et al., 2022). Eine interessante Erkenntnis, die wir dabei gewonnen haben, ist, dass nicht alle Bibliotheken dieselben Funktionen unterstützen. Beispielsweise konnten wir FFCV nicht mit einem in einem S3-Bucket gehosteten Dataset ausführen, um unsere Remote-Experimente durchzuführen. Wie in Abschnitt 1 erwähnt, führen wir alle unsere Experimente in PyTorch durch. Wir haben überlegt, die Experimente in anderen gängigen Frameworks für maschinelles Lernen zu reproduzieren, haben uns jedoch dagegen entschieden, da der zweite Kandidat Tensorflow gewesen wäre, aber es gibt Gerüchte, dass Google davon Abstand nimmt und stattdessen JAX verwendet. Abbildung 1 zeigt die Popularität verschiedener ML-Frameworks in den letzten 12 Monaten.

3.1 Datensätze

In Bezug auf die Datensätze haben wir uns zunächst für zwei klassische Datensätze entschieden, um zwei verschiedene Lernaufgaben zu unterstützen: CIFAR-10 (Krizhevsky et al., 2009) für die Bildklassifizierung und CoCo (Lin et al., 2014) für die Objekterkennung. Bei der Durchführung einiger Experimente haben wir ein seltsames Verhalten beobachtet (Bibliotheken schnitten besser ab als erwartet), das wie folgt erklärt werden könnte:


Abbildung 1. Popularität verschiedener ML-Frameworks in den letzten 12 Monaten


CIFAR-10 passt in den Speicher[2]. Aus diesem Grund haben wir einen dritten Datensatz mit dem Namen RANDOM erstellt, der aus zufällig generierten Farbbildern der Größe 256 mal 256 Pixel und einer zufälligen Klasse aus 20 besteht. Dieser dritte Datensatz enthält 45.000 Bilder zum Training, 5.000 zur Validierung und 500 zum Testen und ist erheblich größer als CIFAR-10.


Um die Benchmarks vergleichbar zu machen, haben wir für alle Bibliotheken die gleichen Transformationen verwendet. Die einzige Ausnahme war FFCV, das über eine eigene Implementierung der verschiedenen Transformationen verfügt. Für die Bildklassifizierung bestand der Transformationsstapel aus Folgendem: Zufällige horizontale Spiegelung, Normalisierung, Ausschnitt, Transformation in Tensor.


Zur Objekterkennung haben wir uns hauptsächlich auf die Transformationsimplementierung von Albumentations (Buslaev et al., 2020) verlassen. Der Stapel sah wie folgt aus: Zufälliger Zuschnitt, zufällige horizontale Spiegelung, Normalisierung, Transformation in Tensor. Diese Transformationen gelten sowohl für Bilder als auch für Begrenzungsrahmen.

3.2 Versuchsvarianten

Wenn möglich, hosteten wir den Datensatz lokal und in einem S3-äquivalenten Bucket. Dadurch konnten wir die Verlangsamung beurteilen, die durch das Training mit einem Datenstrom über das Netzwerk entsteht. Eine detaillierte Beschreibung der Trainingseinstellung finden Sie in Abschnitt 4.


Da die intensivsten Trainingsaufgaben die Verwendung von mehr als einer GPU erfordern, haben wir dieselben Experimente, wann immer möglich, auch in einer Umgebung mit mehreren GPU-Einheiten durchgeführt. Da zum Zeitpunkt der Durchführung der Experimente nicht alle Bibliotheken PyTorch Lightning vollständig unterstützten, entschieden wir uns, die Multi-GPU mithilfe der Bibliothek Distributed Data Parallel (DDP) (Li et al., 2020) von PyTorch zu implementieren.


Für einige Projekte zum maschinellen Lernen benötigen wir möglicherweise nur Zugriff auf eine Teilmenge eines größeren Datensatzes. In diesen Fällen kann die Fähigkeit, die erforderlichen Datenpunkte schnell zu filtern, ohne den gesamten Datensatz durchlaufen zu müssen, die gesamte Trainingszeit drastisch reduzieren. Einige Bibliotheken ermöglichen das Filtern basierend auf bestimmten Merkmalen, wie z. B. der Klasse (für Aufgaben zur Bildklassifizierung). Wir haben den Geschwindigkeitsgewinn (oder -verlust) untersucht, der sich ergibt, wenn wir die von der Bibliothek bereitgestellte Filtermethode (falls sie eine anbot) im Vergleich zu gar keiner Filterung verwenden. Wenn die Bibliothek keine Filtermethode anbot, haben wir sie naiv implementiert, d. h. wir haben den gesamten Datensatz gescannt und nur die Elemente behalten, die die angegebene Bedingung erfüllen. Eine schnelle Filterung ist nicht unbedingt einfach zu implementieren, da sie eine indexähnliche zusätzliche Struktur erfordert, die beibehalten werden muss, um eine Iteration über alle Beispiele zu vermeiden.


Schließlich gibt Tabelle 1 die Kompatibilität der verschiedenen Bibliotheken mit den verschiedenen Experimenten und Datensätzen an, die wir in diesem Artikel untersucht haben.

3.3 Metriken

Unsere oberste Priorität beim Aufbau der Experimente bestand darin, eine objektive Messgröße zu finden, die uns einen fundierten Vergleich aller unterschiedlichen Bibliotheken ermöglicht.


Die ideale Metrik wäre die Gesamtlaufzeit des Trainingsjobs gewesen, da wir darauf warten und dafür bezahlen müssen. Leider hätte dies die Anzahl der Experimente, die wir durchführen konnten, stark eingeschränkt. Nach sorgfältiger Überlegung entschieden wir uns für die Anzahl der verarbeiteten Datenpunkte (Bilder) pro Sekunde, ein Ergebnis, das durch unsere numerischen Experimente gestützt wird. Wir ziehen zwei Varianten dieser Metrik in Betracht: eine, bei der wir das ML-Modell zum Trainieren verwenden und Backpropagation durchführen, und eine, bei der wir das ML-Modell nicht verwenden und nur über die Samples iterieren und sie auf die GPU kopieren. Der Unterschied zwischen den beiden Metriken lässt sich aus dem Pseudocode der Trainingsschleife in Algorithmus 1 erkennen, wobei m die Geschwindigkeitsvariable bezeichnet. Wir haben auch die Gesamtlaufzeit[3] und die Zeit erfasst, die zum Initialisieren der Datenlader benötigt wurde. Letztere war dadurch motiviert, dass einige der Bibliotheken möglicherweise im Voraus teure Berechnungen durchführen, um ihre Geschwindigkeit während des Trainings zu erhöhen. Wir führten am Ende auch ein Aufwärmen zur Berechnung der Geschwindigkeit durch. Dies wird in Unterabschnitt 3.5 weiter erläutert.


3.4 Zusammenhang zwischen Geschwindigkeit und Laufzeit


Tabelle 1. Vergleich der verschiedenen Bibliotheken und ihrer Unterstützung für die getesteten Funktionen. (J)as, unterstützt und implementiert. (N)icht unterstützt. (X) nicht implementiert. (W)orkaround gefunden, standardmäßig nicht unterstützt.


Abbildung 2. Zusammenhang zwischen Durchschnittsgeschwindigkeit und Gesamttrainingszeit,

3.5 Ein genauerer Blick auf die Laufzeiten

Um unser Verständnis der inneren Mechanismen in jeder Bibliothek zu verbessern, haben wir uns entschlossen, in einem einzigen Durchlauf zu untersuchen, wie lange es dauerte, jeden Batch auszuführen und den Datenlader zu initialisieren. Abbildung 3 zeigt für eine einzelne Parameterkombination [4] die Zeit, die jede Bibliothek für die im Algorithmus 1 beschriebenen Schritte benötigte. Alle diese Experimente beinhalteten einen Cutoff nach 10 Batches.


Interessanterweise dauert der erste Batch erheblich länger als die anderen. Dies lässt sich wie folgt erklären: Da die meisten Datenlader an dieser Stelle auf verzögertes Laden von Daten angewiesen sind, profitieren zukünftige Aufrufe vom Vorabruf, bereits im Speicher vorhandenen Daten und von Parallelisierung (Dinge ausführen, während die GPU mit Berechnungen beschäftigt ist).


Die Größe der Bänder 1 bis 9 bietet den besten Hinweis darauf, wie gut jede Bibliothek skaliert, da die Zeit, die für eine


Abbildung 3. Überprüfung der Zeit, die jede Bibliothek für eine einzelne Simulation benötigt.


Der große Datensatz wächst linear mit dieser Breite. Wir können beobachten, dass die meisten Bibliotheken eine einheitliche Breite haben, wobei Deep Lake die kürzeste (die schnellste) ist. Andererseits ist FFCV die einzige Bibliothek, die nicht homogene Breiten aufweist, wobei die Bänder 1 bis 3 so dünn sind, dass sie im Bild nicht zu sehen sind.


Die Fertigstellung dauert für alle Bibliotheken ungefähr gleich lang, mit Ausnahme von FFCV und Deep Lake, die erheblich länger dauern. Die Fertigstellungszeit hängt hauptsächlich vom Modell ab und ist nicht unbedingt ein Hinweis darauf, wie gut jede Bibliothek skaliert.


Auf Grundlage dieser Zahl haben wir uns entschieden, bei der Berechnung der Geschwindigkeit ein Aufwärmen durchzuführen. Das bedeutet, dass wir bei allen Geschwindigkeitsberechnungen die Zeit, die der erste Batch benötigt, ignorieren.


Abbildung 4. Geschwindigkeit als Funktion der Batchgröße für CIFAR10 auf einer einzelnen GPU.



[2] Dies ist oft wünschenswert und wird in einigen Übersichtsartikeln auch erwartet. Wir stellten jedoch fest, dass dies in mehreren praktischen Anwendungen mit kleinen Teams und In-House-Arbeitsplätzen nicht der Fall ist.


[3] Dies ist die Zeit vom Start der Simulation bis zum Cut-off, die in der Praxis oft nur 10 Batches betrug.


[4] RANDOM-Datensatz, einzelne GPU, 0 Arbeiter, Batchgröße 64