NVIDIA hat kürzlich die Version 6.0 von Deepstream veröffentlicht, dem Streaming-Analytics-Toolkit für KI-basierte Multisensor-Verarbeitung, Video-, Audio- und Bildverständnis. Zu den neuen Funktionen gehören verbesserte Python-Bindungen (die Versionshinweise finden Sie hier). Warum ist das wichtig, werden Sie sich fragen?
Wenn Sie eine Standardpipeline für die Objekterkennung und -verfolgung erstellen möchten, können Sie mit der Deepstream-Referenzanwendung beginnen. Mein Kollege Victor hat einen NVIDIA Deepstream Quickstart geschrieben, in dem er erklärt, wie man die Anwendung einrichtet. Wie er am Ende seines Blogposts erwähnt, stößt man an eine Wand, sobald man etwas Eigenes machen möchte. Sie denken vielleicht: "Kein Problem! Ich werde in den Code eintauchen und meine Programmierkenntnisse nutzen, um eine benutzerdefinierte Logik hinzuzufügen". Leider sind die Deepstream-Anwendungen ursprünglich in C++ geschrieben. Python ist immer noch die beliebteste Programmiersprache im ML-Bereich und auch die Sprache meiner Wahl. Glücklicherweise bietet NVIDIA Python-Bindings an. Mit der Veröffentlichung von Deepstream 6.0 hat NVIDIA die Python-Bindings in seinem Python-Apps-Repository zur Verfügung gestellt. In diesem Repository sind auch einige Python-Beispielanwendungen enthalten.
Wenn es Ihnen wie mir geht, haben Sie sich beim Betrachten der Deepstream-Python-Beispiele wahrscheinlich ein wenig verwirrt. Es ist schwierig, den Beispielen zu folgen und die logischen Komponenten der Anwendung zu verstehen. Jede Anwendung ist im Grunde ein monolithisches Skript mit verschiedenen Codeteilen, die alle miteinander vermischt sind. Hinzu kommt, dass alle diese Beispielanwendungen viele Funktionen gemeinsam haben und daher viel redundanten Code enthalten.
Als großer Fan von OOP (Object Oriented Programming) und DRY (Don't Repeat Yourself) habe ich es auf mich genommen, einige der Deepstream-Beispielanwendungen neu zu schreiben, zu verbessern und zu kombinieren. Das Ergebnis ist eine Deepstream 6.0 Python Boilerplate.
Das Boilerplate-Repository ist wie folgt aufgebaut:
Das Verzeichnis app/ enthält die Deepstream-Pipeline-Implementierungen. Deepstream-Konfigurationsdateien werden im Verzeichnis configs/ gespeichert. Modellgewichte, Bibliotheken und Beispielvideos sind im Verzeichnis data/ zu finden.
Im Verzeichnis app/ finden Sie ein Skript pipeline.py und ein Verzeichnis pipelines. Ersteres enthält eine Pipeline-Basisklasse, die übliche Pipeline zur Objekterkennung und -verfolgung (z. B. YOLOv4 mit DeepSORT). Als Eingabe akzeptiert sie jedes von Gstreamer unterstützte Format (z.B. RTSP-Stream, mp4-Datei...) unter Verwendung eines URI-Decodierers. Die resultierenden Bounding Boxes und Tracker-IDs werden auf das Video gezeichnet und als mp4-Datei oder neuer RTSP-Stream zurückgegeben. Auch wenn dies eine Vielzahl von Anwendungen ermöglicht, möchten Sie in der Regel eine eigene Logik hinzufügen. Der nächste Abschnitt beschreibt eine Möglichkeit, dies zu tun.
Neben der Basis-Pipeline gibt es einige Beispiele für benutzerdefinierte Pipelines:
Die Pipelines überschreiben einen Teil der Logik der Basis-Pipeline und fügen mithilfe von Gstreamer-Sonden benutzerdefinierte Logik ein. Sie können sowohl Metadaten (z. B. Bounding Boxes) als auch Daten (z. B. Videoframes) prüfen.
Die AnonymizationPipeline ist ein Beispiel für eine benutzerdefinierte Pipeline, die sowohl die zugrunde liegenden Metadaten als auch die Bilddaten verwendet. Der unten stehende Codeausschnitt ist alles, was Sie für die Erstellung Ihrer Pipeline schreiben müssen. Die Magie von Deepstream findet in der Funktion _add_probes statt. Sie wählen zunächst eine Komponente Ihrer Pipeline aus, in diesem Fall den Tiler. Dann holen Sie das statische Pad und fügen eine Probe hinzu. Die Funktion _wrap_probe dient als Zwischenglied, um die zugrunde liegende C-Speicherverwaltung zu abstrahieren. So können Sie einfach eine Funktion (z. B. _anonymize ) schreiben, die Numpy-Frames und Listen von Metadaten-Wörterbüchern als Eingabe erhält.
Da das gesamte Deepstream- und Python-Bindungs-Setup sehr umständlich sein kann, habe ich die meisten Anforderungen in eine Dockerdatei gepackt. Sie müssen nur Docker, das NVIDIA Container-Toolkit und den NVIDIA-Treiber installieren. Die kompilierten Python-Bindungen und alle übrigen Abhängigkeiten sind Teil des Docker-Images.
Installieren Sie auf einem NVIDIA-fähigen Rechner die NVIDIA-Treiberversion 470.63.01:
Überprüfen Sie die Installation mit:
nvidia-smi
Richten Sie Docker und das NVIDIA Container Toolkit gemäß der NVIDIA Container Toolkit Installationsanleitungein .
Klonen Sie das Repository in ein lokales Verzeichnis, z. B. ~/deepstream-python:
git clone https://github.com/ml6team/deepstream-python.git
Führen Sie danach unbedingt git lfs pull aus, um die Dateien aus dem LFS-Speicher herunterzuladen:
Erstellen Sie das Container-Image, indem Sie den folgenden Befehl im Verzeichnis deepstream/ (in dem sich die Dockerdatei befindet) ausführen:
docker build -t deepstream .
Als nächstes starten Sie den Container mit:
docker run -it --gpus all -v ~/deepstream-python/output:/app/output
deepstream python3 run.py <URI>
Dabei ist URI ein Dateipfad (file://...) oder eine RTSP-URL (rtsp://...) zu einem Videostream.
Zum Beispiel:
Mit der Option -v wird das Ausgabeverzeichnis in den Container eingebunden. Nachdem die Pipeline ausgeführt wurde, enthält deepstream-python/output die Ergebnisse. Für die Basis-Pipeline ist dies ein Video (out.mp4) mit gezeichneten Begrenzungsrahmen.
All diese Anleitungen und mehr finden Sie in der README des Repositorys finden. Viel Spaß beim Kodieren!
Dieser Blogpost wurde ermöglicht durch die Unterstützung von Flandern Innovation & Unternehmertum - VLAIO