Zum Hauptinhalt springen

Hardware-Beschleunigtes Maschinelles Lernen

Diese Funktion ermöglicht es Ihnen, eine GPU zu verwenden, um maschinelle Lernaufgaben wie Smart Search und Gesichtserkennung zu beschleunigen und gleichzeitig die CPU-Belastung zu reduzieren. Da dies eine neue Funktion ist, befindet sie sich noch im experimentellen Stadium und funktioniert möglicherweise nicht auf allen Systemen.

Info

Sie müssen keine maschinellen Lernaufgaben erneut ausführen, nachdem Sie die Hardware-Beschleunigung aktiviert haben. Das Beschleunigungsgerät wird für alle Aufgaben verwendet, die nach der Aktivierung ausgeführt werden.

Unterstützte Backends

  • ARM NN (Mali)
  • CUDA (NVIDIA GPUs mit Compute-Fähigkeit 5.2 oder höher)
  • ROCm (AMD GPUs)
  • OpenVINO (Intel GPUs wie Iris Xe und Arc)
  • RKNN (Rockchip)

Einschränkungen

  • Die hier aufgeführten Anweisungen und Konfigurationen gelten spezifisch für Docker Compose. Andere Container-Engines erfordern möglicherweise eine andere Konfiguration.
  • Nur Linux- und Windows-Server (über WSL2) werden unterstützt.
  • ARM NN wird nur auf Geräten mit Mali-GPUs unterstützt. Andere Arm-Geräte werden nicht unterstützt.
  • Einige Modelle sind möglicherweise mit bestimmten Backends nicht kompatibel. CUDA ist das zuverlässigste.
  • Die Suchlatenz wird durch ARM NN aufgrund von Modellkompatibilitätsproblemen, die dessen Verwendung verhindern, nicht verbessert. Smart-Search-Aufträge nutzen jedoch ARM NN.

Voraussetzungen

ARM NN

  • Stellen Sie sicher, dass der passende Linux-Kernel-Treiber installiert ist.
    • Dieser ist auf den Linux-Images des Geräteanbieters normalerweise vorinstalliert.
  • /dev/mali0 muss auf dem Host-Server verfügbar sein.
    • Dies können Sie bestätigen, indem Sie ls /dev ausführen, um zu überprüfen, ob es existiert.
  • Sie benötigen die geschlossene Firmware libmali.so (möglicherweise mit einer zusätzlichen Firmwaredatei).
    • Wo und wie Sie diese Datei erhalten können, hängt vom Gerät und Anbieter ab. Typischerweise stellt der Geräteanbieter diese ebenfalls bereit.
    • Die Datei hwaccel.ml.yml nimmt an, dass sich diese unter /usr/lib/libmali.so befindet. Aktualisieren Sie dies entsprechend, falls sie woanders liegt.
    • Die Datei hwaccel.ml.yml geht von einer zusätzlichen Datei /lib/firmware/mali_csffw.bin aus. Aktualisieren Sie entsprechend, wenn der Treiber Ihres Geräts diese Datei nicht benötigt.
  • Optional: Konfigurieren Sie Ihre .env-Datei, siehe Umgebungsvariablen für ARM NN-spezifische Einstellungen.
    • Insbesondere die Variable MACHINE_LEARNING_ANN_FP16_TURBO kann die Leistung erheblich verbessern, allerdings auf Kosten einer etwas geringeren Genauigkeit.

CUDA

  • Die GPU muss Compute-Fähigkeit 5.2 oder höher haben.
  • Der Server muss den offiziellen NVIDIA-Treiber installiert haben.
  • Der installierte Treiber muss >= 545 sein (er muss CUDA 12.3 unterstützen).
  • Unter Linux (außer WSL2) müssen Sie außerdem das NVIDIA Container Toolkit installiert haben.

ROCm

  • Die GPU muss von ROCm unterstützt werden. Wenn sie nicht offiziell unterstützt wird, können Sie versuchen, die Umgebungsvariable HSA_OVERRIDE_GFX_VERSION zu verwenden: HSA_OVERRIDE_GFX_VERSION=<eine unterstützte Version, z. B. 10.3.0>. Wenn dies nicht funktioniert, müssen Sie möglicherweise auch HSA_USE_SVM=0 setzen.
  • Das ROCm-Image ist ziemlich groß und erfordert mindestens 35 GiB freien Speicherplatz. Das Abrufen späterer Service-Updates über Docker wird im Allgemeinen jedoch nur wenige hundert Megabyte umfassen, da der Rest zwischengespeichert wird.
  • Dieses Backend ist neu und kann einige Probleme aufweisen. Beispielsweise kann der Stromverbrauch der GPU nach der Durchführung von Inferenzläufen höher als gewöhnlich sein, selbst wenn der maschinelle Lernservice inaktiv ist. In solch einem Fall wird der normale Zustand erst nach 5 Minuten Inaktivität (konfigurierbar mit der MACHINE_LEARNING_MODEL_TTL-Einstellung) wiederhergestellt.

OpenVINO

  • Integrierte GPUs sind anfälliger für Probleme als diskrete GPUs, insbesondere bei älteren Prozessoren oder Servern mit wenig RAM.
  • Stellen Sie sicher, dass die Kernel-Version des Servers neu genug ist, um das Gerät für die Hardware-Beschleunigung verwenden zu können.
  • Erwarten Sie einen höheren RAM-Verbrauch bei Verwendung von OpenVINO im Vergleich zur CPU-Verarbeitung.

RKNN

  • Sie benötigen einen unterstützten Rockchip-SoC: Derzeit werden nur RK3566, RK3568, RK3576 und RK3588 unterstützt.
  • Stellen Sie sicher, dass der passende Linux-Kernel-Treiber installiert ist.
    • Dieser ist auf den Linux-Images des Geräteanbieters normalerweise vorinstalliert.
  • RKNPU-Treiber V0.9.8 oder höher muss auf dem Host-Server verfügbar sein.
    • Dies können Sie bestätigen, indem Sie cat /sys/kernel/debug/rknpu/version ausführen, um die Version zu überprüfen.
  • Optional: Konfigurieren Sie Ihre .env-Datei, siehe Umgebungsvariablen für RKNN-spezifische Einstellungen.
    • Insbesondere das Setzen von MACHINE_LEARNING_RKNN_THREADS auf 2 oder 3 kann die Leistung für RK3576 und RK3588 dramatisch im Vergleich zum Standardwert von 1 verbessern, allerdings auf Kosten eines erheblich höheren RAM-Verbrauchs pro Modell.

Einrichtung

  1. Laden Sie, falls noch nicht vorhanden, die neueste hwaccel.ml.yml-Datei herunter und stellen Sie sicher, dass sie sich im selben Ordner wie die docker-compose.yml befindet.
  2. Kommentieren Sie den extends-Abschnitt in der docker-compose.yml unter immich-machine-learning aus und ändern Sie cpu auf das entsprechende Backend.
  3. Fügen Sie immer noch unter immich-machine-learning eines der folgenden Backends hinzu: [-armnn, cuda, rocm, openvino, rknn] am Ende des Abschnitts image in der Zeile.
  4. Stellen Sie den immich-machine-learning-Container mit diesen aktualisierten Einstellungen erneut bereit.

Überprüfung der Geräteverwendung

Sie können überprüfen, ob das Gerät erkannt und verwendet wird, indem Sie dessen Auslastung prüfen. Es gibt viele Tools zur Anzeige, wie nvtop für NVIDIA oder Intel, intel_gpu_top für Intel und radeontop für AMD.

Sie können auch die Protokolle des immich-machine-learning-Containers überprüfen. Wenn ein Smart-Search- oder Gesichtserkennungsauftrag beginnt oder wenn Sie in Immich mit Text suchen, sollten Sie entweder ein Protokoll für Available ORT providers mit dem entsprechenden Anbieter (z. B. CUDAExecutionProvider im Fall von CUDA) sehen oder einen Protokolleintrag Loaded ANN model ohne Fehler im Fall von ARM NN.

Einzelne Compose-Datei

Einige Plattformen, einschließlich Unraid und Portainer, unterstützen zum Zeitpunkt des Schreibens keine mehreren Compose-Dateien. Alternativ können Sie die relevanten Inhalte der Datei hwaccel.ml.yml direkt in den Service immich-machine-learning einfügen.

Zum Beispiel ist der Abschnitt cuda in dieser Datei wie folgt:

deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities:
- gpu

Sie können diesen Abschnitt dem Service immich-machine-learning hinzufügen, anstatt von hwaccel.ml.yml zu erweitern:

immich-machine-learning:
container_name: immich_machine_learning
# Beachten Sie das `-cuda` am Ende
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
# Beachten Sie das Fehlen eines `extends`-Abschnitts
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities:
- gpu
volumes:
- model-cache:/cache
env_file:
- .env
restart: always

Sobald dies erledigt ist, können Sie den immich-machine-learning-Container erneut bereitstellen.

Multi-GPU

Wenn Sie mehrere NVIDIA- oder Intel-GPUs nutzen möchten, können Sie die Umgebungsvariable MACHINE_LEARNING_DEVICE_IDS auf eine durch Kommas getrennte Liste von Geräte-IDs setzen und MACHINE_LEARNING_WORKERS auf die Anzahl der aufgelisteten Geräte setzen. Sie können beispielsweise nvidia-smi -L oder glxinfo -B ausführen, um die aktuell verfügbaren Geräte und deren entsprechende IDs anzuzeigen.

Zum Beispiel, wenn Sie die Geräte 0 und 1 haben, setzen Sie die Werte wie folgt:

MACHINE_LEARNING_DEVICE_IDS=0,1
MACHINE_LEARNING_WORKERS=2

In diesem Beispiel wird der maschinelle Lernservice zwei Worker erzeugen, von denen einer die Modelle Gerät 0 und der andere Gerät 1 zuweist. Unterschiedliche Anfragen werden von einem der beiden Worker verarbeitet.

Dieser Ansatz kann auch verwendet werden, um einfach ein bestimmtes Gerät auszuwählen. Zum Beispiel sorgt MACHINE_LEARNING_DEVICE_IDS=1 dafür, dass immer Gerät 1 verwendet wird, anstatt Gerät 0.

Beachten Sie, dass Sie die Auftragskonkurrenzen erhöhen sollten, um die Gesamtauslastung zu erhöhen und die Arbeit effektiver auf mehrere GPUs zu verteilen. Außerdem muss jede GPU alle Modelle laden können. Es ist nicht möglich, ein einzelnes Modell auf mehrere GPUs zu verteilen, die individuell nicht über genügend VRAM verfügen, oder ein bestimmtes Modell einer GPU zuzuweisen.

Tipps

  • Wenn ein Fehler auftritt, während ein Modell ausgeführt wird, versuchen Sie ein anderes Modell, um zu prüfen, ob das Problem modell-spezifisch ist.
  • Sie können die Parallelität über den Standardwert hinaus erhöhen, um eine höhere Auslastung zu erreichen. Beachten Sie jedoch, dass dadurch auch der VRAM-Verbrauch steigt.
  • Größere Modelle profitieren mehr von der Hardware-Beschleunigung, sofern Sie über ausreichend VRAM verfügen.
  • Im Vergleich zu ARM NN hat RKNPU:
    • Breitere Modellunterstützung (einschließlich für Suchen, die ARM NN nicht beschleunigt)
    • Geringere Wärmeentwicklung
    • Sehr leicht geringere Genauigkeit (RKNPU verwendet immer FP16, während ARM NN standardmäßig höhere Präzision FP32 verwendet, es sei denn, MACHINE_LEARNING_ANN_FP16_TURBO ist aktiviert)
    • Unterschiedliche Geschwindigkeit (getestet auf RK3588):
      • Wenn MACHINE_LEARNING_RKNN_THREADS den Standardwert 1 hat, weist RKNPU in den meisten Fällen eine erheblich niedrigere Durchsatzrate für ML-Aufgaben als ARM NN auf, jedoch eine ähnliche Latenz (z. B. bei Suchen)
      • Wenn MACHINE_LEARNING_RKNN_THREADS auf 3 gesetzt ist, wird es etwas schneller als ARM NN bei FP32 sein, aber etwas langsamer als ARM NN, wenn MACHINE_LEARNING_ANN_FP16_TURBO aktiviert ist
      • Wenn andere Aufgaben auch die GPU nutzen (wie Transkodierung), hat RKNPU einen signifikanten Vorteil gegenüber ARM NN, da es die ansonsten inaktive NPU verwendet, anstatt um die Nutzung der GPU zu konkurrieren
    • Niedrigeren RAM-Verbrauch, wenn MACHINE_LEARNING_RKNN_THREADS den Standardwert 1 hat, aber erheblich höheren, wenn höher als 1 (was jedoch notwendig ist, damit es die NPU vollständig ausnutzen kann und somit in Geschwindigkeit mit ARM NN vergleichbar ist)