Rückblick: Nvidias Rapids bringt Python-Analysen auf die GPU

Das Erstellen von Modellen für maschinelles Lernen ist ein sich wiederholender Prozess. Oft rot und routinemäßig, ist dies ein Spiel mit „schnellsten Siegen durch den Zyklus“. Je schneller Sie iterieren können, desto einfacher ist es, neue Theorien zu erforschen und gute Antworten zu erhalten. Dies ist einer der Gründe, warum der praktische Einsatz von KI in Unternehmen heute von den größten Unternehmen dominiert wird, die enorme Ressourcen auf das Problem werfen können.

Rapids ist ein Dach für mehrere von Nvidia gegründete Open-Source-Projekte, das die gesamte Verarbeitungspipeline auf die GPU überträgt, die E / A-gebundenen Datenübertragungen eliminiert und gleichzeitig die Geschwindigkeit jedes einzelnen Schritts erheblich erhöht. Es bietet auch ein gemeinsames Format für die Daten, wodurch der Datenaustausch zwischen unterschiedlichen Systemen erleichtert wird. Auf Benutzerebene ahmt Rapids die Python-API nach, um den Übergang für diese Benutzerbasis zu erleichtern.

Das Tidyverse Kochbuch

Stromschnellen-Ökosystemarchitektur

Das Rapids-Projekt zielt darauf ab, die APIs für maschinelles Lernen und Datenanalyse von Python größtenteils zu replizieren, jedoch eher für GPUs als für CPUs. Dies bedeutet, dass Python-Entwickler bereits über alles verfügen, was sie zum Ausführen auf der GPU benötigen, ohne die Details der CUDA-Programmierung und der parallelen Operationen auf niedriger Ebene kennen zu müssen. Pythonistas kann Code auf einem nicht GPU-fähigen Computer entwickeln und ihn dann mit ein paar Änderungen auf allen verfügbaren GPUs ausführen.

Das Nvidia CUDA-Toolkit bietet Grundelemente auf niedrigerer Ebene für Mathematikbibliotheken, parallele Algorithmen und Diagrammanalysen. Das Herzstück der Architektur ist der auf Apache Arrow basierende GPU-Datenrahmen, der eine spaltenweise speicherinterne Datenstruktur bereitstellt, die programmiersprachenunabhängig ist. Der Benutzer interagiert mit dem GPU-Datenrahmen über cuDF und eine Pandas-ähnliche API. Dask, eine Python-Bibliothek für paralleles Rechnen, ahmt die vorgelagerten Python-APIs nach und arbeitet mit CUDA-Bibliotheken für parallele Berechnungen zusammen. Stellen Sie sich Dask als Funken für Python vor.

SCHNELLE

Die drei Hauptprojekte cuDF, cuML und cuGraph werden unabhängig voneinander entwickelt, arbeiten jedoch nahtlos zusammen. Im Rahmen des Projekts werden auch Brücken zum breiteren Python-Ökosystem entwickelt.

Stromschnelleninstallation

Die Installation über Anaconda auf einem Linux-Computer in AWS war größtenteils unkompliziert, abgesehen von einigen Problemen aufgrund einer Änderung der Abhängigkeiten in Version 0.11. Die Installation der C / C ++ - Bibliotheken zur Verwendung von libcudf war nicht so einfach, und ich würde empfehlen, sich an die Python-APIs und den Conda-Installationsprozess zu halten. Rapids enthält ein Jupyter-Notizbuch, das auch in Googles kostenlosem Colab verfügbar ist und den Einstieg erleichtert. Ich habe das Jupyter-Notebook Version 0.10 verwendet, um den Code auf Google Colab auszuführen, das eine Nvidia Tesla T4-GPU enthält.

GPU-Datenrahmen von Rapids

Das Herzstück eines jeden Data Science-Workflows ist der Datenrahmen. Hier findet das Feature-Engineering statt und die meiste Zeit wird damit verbracht, dass Datenwissenschaftler mit schmutzigen Daten streiten. cuDF ist das Rapids-Projekt für einen GPU-basierten, Pandas-ähnlichen Datenrahmen. CuDF basiert auf libcudf, einer C ++ - Bibliothek, die Grundelemente auf niedriger Ebene zum Importieren von Apache Arrow-Daten, zum Ausführen elementweiser Mathematik für Arrays und zum Ausführen von Sortier-, Verknüpfungs-, Gruppierungs-, Reduktions- und anderen Operationen für GPU-Speichermatrizen implementiert. Die grundlegende Datenstruktur von libcudf ist der GPU DataFrame (GDF), der wiederum dem spaltenweisen Datenspeicher von Apache Arrow nachempfunden ist.

SCHNELLE

Die Rapids Python-Bibliothek bietet dem Benutzer eine übergeordnete Oberfläche, die Datenrahmen ähnelt, wie sie in Pandas verwendet werden. In vielen Fällen wird Pandas-Code auf cuDF unverändert ausgeführt. Ist dies nicht der Fall, sind in der Regel nur geringfügige Änderungen erforderlich.

Benutzerdefinierte Funktionen in cuDF

Sobald Sie die grundlegende Datenmanipulation hinter sich haben, müssen Sie manchmal Zeilen und Spalten mit benutzerdefinierten Funktionen (UDFs) verarbeiten. cuDF bietet eine API im PyData-Stil zum Schreiben von Code, um kurskörnigere Datenstrukturen wie Arrays, Serien und sich bewegende Fenster zu verarbeiten. Derzeit werden nur numerische und boolesche Typen unterstützt. UDFs werden mit dem Numba JIT-Compiler kompiliert, der eine Teilmenge von LLVM verwendet, um numerische Funktionen in CUDA-Maschinencode zu kompilieren. Dies führt zu wesentlich kürzeren Laufzeiten auf der GPU.

Strings in cuDF

Obwohl GPUs für die schnelle Verarbeitung von Float-Vektoren fantastisch sind, wurden sie normalerweise nicht für die Verarbeitung von String-Daten verwendet, und die Realität ist, dass die meisten Daten in Form von Strings zu uns kommen. cuStrings ist eine GPU-String-Manipulationsbibliothek zum Teilen, Anwenden von regulären Ausdrücken, Verketten, Ersetzen von Token usw. in Arrays von Strings. Wie andere Funktionen von cuDF wird es als C / C ++ - Bibliothek (libnvStrings) implementiert und von einer Python-Ebene umschlossen, die Pandas imitieren soll. Obwohl der String-Datentyp nicht für die Ausführung auf GPUs optimiert ist, sollte die parallele Ausführung des Codes eine Beschleunigung gegenüber der CPU-basierten String-Manipulation bewirken.

Daten in oder aus cuDF holen

Dataframe-E / A wird von einer dedizierten Bibliothek, cuIO, verwaltet. Alle am häufigsten vorkommenden Formate werden unterstützt, einschließlich Arrow, ORC, Parkett, HDF5 und CSV. Wenn Sie das Glück haben, auf DGX-2-Hardware ausgeführt zu werden, können Sie die GPU Direct Storage-Integration verwenden, um Daten direkt vom Hochgeschwindigkeitsspeicher auf die GPU zu übertragen, ohne die CPU einzubeziehen. Sterbliche Benutzer werden die Beschleunigung der GPU beim Dekomprimieren großer Datenmengen und die enge Integration in das Python-Ökosystem immer noch zu schätzen wissen.

GPU Direct Storage ist derzeit in Alpha verfügbar und wird bei Veröffentlichung auf den meisten Tesla-GPUs verfügbar sein. Sie können einen GPU-Datenrahmen aus NumPy-Arrays, Pandas DataFrames und PyArrow-Tabellen mit nur einer einzigen Codezeile erstellen. Andere Projekte können Daten über __cuda_array_interface__Bibliotheken austauschen , die in das Numba-Ökosystem fallen. DLPack für neuronale Netzwerkbibliotheken ist ebenfalls eine unterstützte Schnittstelle.

Der wahrscheinlich größte Nachteil bei der Verwendung von cuDF ist die mangelnde Interoperabilität außerhalb von Python. Ich denke, ein Fokus auf eine starke Basis von C / C ++ - APIs, wie es Arrow getan hat, würde ein breiteres Ökosystem ermöglichen und dem gesamten Projekt zugute kommen.

Stromschnellen cuML

Die erklärten Ziele von cuML sind "Pythons Scikit-Lernen mit GPUs". Theoretisch bedeutet dies, dass Sie nur Ihre Importanweisung ändern und möglicherweise einige der Parameter optimieren müssen, um die Unterschiede bei der Ausführung auf einer CPU zu berücksichtigen, bei der manchmal ein Brute-Force-Ansatz besser ist. Der Vorteil eines GPU-basierten Scikit-Lernens ist schwer zu unterschätzen. Die Beschleunigungen sind erheblich und Datenanalysten können um ein Vielfaches produktiver sein. Die C ++ - API ist außerhalb ihrer Python-Bindungen noch nicht für den breiten Verbrauch bereit, dies wird sich jedoch voraussichtlich verbessern.

cuML enthält auch APIs zur Unterstützung der Optimierung von Hyperparametern über Dask, eine Bibliothek zum Skalieren von Python über mehrere Knoten hinweg. Viele Algorithmen für maschinelles Lernen können effektiv parallel geschaltet werden, und cuML entwickelt aktiv sowohl Multi-GPU- als auch Multi-Node-Multi-GPU-Algorithmen.

SCHNELLE

Stromschnellen-CuGraph

cuGraph ist das dritte Mitglied des Rapids-Ökosystems und wie die anderen ist cuGraph vollständig in cuDF und cuML integriert. Es bietet eine gute Auswahl an Diagrammalgorithmen, Grundelementen und Dienstprogrammen mit GPU-beschleunigter Leistung. Die Auswahl an APIs in cuGraph ist etwas umfangreicher als in anderen Teilen von Rapids, wobei NetworkX, Pregel, GraphBLAS und GQL (Graph Query Language) verfügbar sind.

SCHNELLE

cuGraph ist im Geiste eher ein Toolkit als cuML. Die Graphentechnologie ist sowohl in der Wissenschaft als auch in der Industrie ein sich schnell bewegender Raum. CuGraph bietet Entwicklern daher Zugriff auf die C ++ - Layer- und Graph-Grundelemente und ermutigt Dritte, Produkte mit cuGraph zu entwickeln. Mehrere Universitäten haben dazu beigetragen, und Projekte von Texas A & M (GraphBLAS), Georgia Tech (Hornet) und UC Davis (Gunrock) wurden „produziert“ und unter das Dach von cuGraph aufgenommen. Jedes Projekt bietet unterschiedliche Funktionen, die alle GPU-beschleunigt sind und von demselben cuDF-Datenrahmen unterstützt werden.

NetworkX ist die Python-API, auf die das Rapids-Team für seine native Schnittstelle abzielt. Über diese Schnittstelle stehen eine Reihe von Algorithmen zur Verfügung. Während nur der Seitenrang Multi-GPU ist, arbeitet das Team gegebenenfalls aktiv an Multi-GPU-Versionen der anderen.

SCHNELLE

Eines der cuGraph-Unterprojekte, die ich interessant fand, ist cugraphBLAS, ein Versuch, Bausteine ​​für Graphalgorithmen in der Sprache der linearen Algebra zu standardisieren. Basierend auf GraphBLAS (graphblas.org), einer benutzerdefinierten Datenstruktur für die Verarbeitung spärlicher dynamischer Diagramme.

Hornet, ein weiteres cuGraph-Unterprojekt, bietet ein systemunabhängiges Format für die Aufnahme von Grafikdaten, analog zu der Art und Weise, wie der Apache-Pfeil eine systemunabhängige Möglichkeit zur Verarbeitung von Datenrahmen bietet. Hornet unterstützt die meisten gängigen Diagrammformate, einschließlich SNAP, mtx, metis und Kanten.

In Übereinstimmung mit dem Geist, der Python-Community nahe zu sein, kann das native NetworkX-Paket von Python zum Studium komplexer Netzwerke verwendet werden. Dies umfasst Datenstrukturen für Diagramme und Multi-Diagramme, die mithilfe von CUDA-Grundelementen neu implementiert wurden. So können Sie viele der Standard-Diagrammalgorithmen wiederverwenden und Netzwerkstruktur- und Analysemaßnahmen durchführen. Die meisten Algorithmen sind Single-GPUs wie NetworkX. Die alleinige Ausführung auf der GPU bietet jedoch eine erhebliche Beschleunigung, während die Arbeit weiterhin auf Implementierungen mit mehreren GPUs verlagert wird.

Auf der Rapids Roadmap 

Angesichts der enormen Geschwindigkeit, die GPU-basierte Analysen bieten, kommen in zukünftigen Versionen einige neue Projekte hinzu.

DLPack und array_interface für tiefes Lernen

Mehrschichtige neuronale Netze waren eine der ersten Workloads, die auf GPUs verlagert wurden, und für diesen Anwendungsfall des maschinellen Lernens gibt es eine beträchtliche Menge an Code. Zuvor war DLPack der De-facto-Standard für den Datenaustausch zwischen Deep-Learning-Bibliotheken. Heutzutage wird die array_interface häufig unterstützt. Stromschnellen unterstützen beide.

cuSignal

Wie die meisten anderen Projekte bei Rapids ist cuSignal eine GPU-beschleunigte Version einer vorhandenen Python-Bibliothek, in diesem Fall der SciPy-Signal-Bibliothek. Die ursprüngliche SciPy-Signalbibliothek basiert auf NumPy, das durch sein GPU-beschleunigtes Äquivalent CuPy in cuSignal ersetzt wird. Dies ist ein gutes Beispiel für die Rapids-Designphilosophie bei der Arbeit. Mit Ausnahme einiger benutzerdefinierter CUDA-Kernel umfasst der Port zur GPU hauptsächlich das Ersetzen der Importanweisung und das Optimieren einiger Funktionsparameter. 

Die Signalverarbeitung in die Rapids-Falte zu bringen, ist ein kluger Schachzug. Die Signalverarbeitung ist überall und hat viele sofort nützliche kommerzielle Anwendungen in Industrie und Verteidigung.

cuSpatial

Räumliche und räumlich-zeitliche Operationen sind hervorragende Kandidaten für die GPU-Beschleunigung und lösen viele reale Probleme, mit denen wir im Alltag konfrontiert sind, wie z. B. die Analyse von Verkehrsmustern, Bodengesundheit / -qualität und Hochwasserrisiko. Ein Großteil der von Mobilgeräten, einschließlich Drohnen, gesammelten Daten hat eine räumliche Komponente, und die räumliche Analyse ist das Herzstück der Smart City. 

CuSpatial ist wie die anderen Komponenten aufgebaut und eine C ++ - Bibliothek, die auf CUDA-Grundelementen und der Thrust-Vektor-Verarbeitungsbibliothek basiert und cuDF für den Datenaustausch verwendet. Verbraucher der C ++ - Bibliothek können Punkt-, Polylinien- und Polygondaten mit einem C ++ - Reader lesen. Python-Benutzer sollten vorhandene Python-Pakete wie Shapely oder Fiona verwenden, um ein NumPy-Array zu füllen, dann die cuSpatial Python-API verwenden oder in cuDF-Datenrahmen konvertieren. 

Cuxfilter zur Datenvisualisierung

Die Visualisierung von Daten ist sowohl innerhalb des Analyse-Workflows als auch für die Darstellung oder Berichterstellung von Ergebnissen von grundlegender Bedeutung. Bei aller Magie, mit der GPUs an den Daten selbst arbeiten können, ist es keine triviale Aufgabe, diese Daten in einen Browser zu übertragen. cuxfilter, inspiriert von der Crossfilter-JavaScript-Bibliothek, soll diese Lücke schließen, indem ein Stapel bereitgestellt wird, mit dem Visualisierungsbibliotheken von Drittanbietern Daten in cuDF-Datenrahmen anzeigen können.

Es gab einige Iterationen von Cuxfilter, als das Team die besten Architektur- und Verbindungsmuster heraussuchte. Die neueste Iteration nutzt Jupyter-Notebooks, Bokeh-Server und PyViz-Panels, während Integrationsexperimente Projekte von Uber, Falcon und PyDeck umfassen. Diese Komponente ist noch nicht für die Hauptsendezeit bereit, soll jedoch in Rapids 0.13 veröffentlicht werden. Es gibt viele bewegliche Teile, und ich konnte nicht aus erster Hand damit experimentieren, aber wenn es sein Versprechen erfüllt, ist dies eine großartige Ergänzung des Rapids-Toolkits.

Mit Dask hoch und raus skalieren

Dask ist ein verteilter Taskplaner für Python, der für Python eine ähnliche Rolle spielt wie Apache Spark für Scala. Dask-cuDF ist eine Bibliothek, die partitionierte, GPU-gestützte Datenrahmen bereitstellt. Dask-cuDF funktioniert gut, wenn Sie cuML verwenden möchten oder wenn Sie einen Datensatz laden, der größer als der GPU-Speicher ist oder auf mehrere Dateien verteilt ist.

Wie ein Spark-RDD (Resilient Distributed Dataset) verhält sich der verteilte Dask-cuDF-Datenrahmen meist wie ein lokaler, sodass Sie mit Ihrem lokalen Computer experimentieren und bei Bedarf zu einem verteilten Modell wechseln können. Dask-cuML bietet cuML-Funktionen für mehrere Knoten und ist daher eine gute Option, wenn Sie nicht über das Budget für eine DGX-Workstation verfügen.