4 Punkte von GN⁺ 2024-10-04 | 1 Kommentare | Auf WhatsApp teilen
  • Docker-basierte Inferenz-Engine zum Ausführen großer Sprachmodelle auf AMD GPUs, ausgerichtet auf Hugging-Face-Modelle und mit Fokus auf die LLaMA-Familie
  • Die Laufzeitumgebung erfordert eine ROCm-fähige AMD GPU, Docker sowie auf dem Host installierte ROCm-Treiber in Version 5.4.2 oder einer kompatiblen Version
  • run-docker-amd.sh baut das Docker-Image automatisch und startet den Container mit den für den AMD-GPU-Zugriff nötigen Einstellungen: /dev/kfd, /dev/dri, Gruppe video, SYS_PTRACE und seccomp=unconfined
  • Nutzer können das Modell wechseln, indem sie den Namen eines Hugging-Face-Repositorys und einen Prompt als Argumente übergeben; als Beispiele werden meta-llama/Llama-2-7b-chat-hf und facebook/opt-1.3b genannt
  • Um das Inferenzverhalten zu ändern, muss run_inference.py angepasst und anschließend das Docker-Image neu gebaut werden; bei Speichermangel sollte ein kleineres Modell oder eine kürzere Ein-/Ausgabelänge verwendet werden

Projektziel und Zielmodelle

  • Dieses Projekt ist eine Docker-basierte Inferenz-Engine zum Ausführen von LLMs auf AMD GPUs
  • Es ist für die Nutzung von Hugging-Face-Modellen ausgelegt und fokussiert insbesondere die LLaMA-Modellfamilie
  • Es verwendet die Hugging Face Transformers Library

Anforderungen an die Umgebung

  • Vor der Ausführung müssen folgende Voraussetzungen erfüllt sein
    • Eine AMD GPU mit ROCm-Unterstützung
    • Auf dem System installiertes Docker
    • Auf dem Host-System installierte ROCm-Treiber
      • Erforderlich ist Version 5.4.2 oder eine kompatible Version

Projektstruktur

  • Die Repository-Struktur besteht aus dem Verzeichnis src/ sowie Ausführungs- und Build-Dateien
    • src/engine.py
    • src/model.py
    • src/utils.py
    • src/amd_setup.py
    • Dockerfile
    • requirements.txt
    • run_inference.py
    • run-docker-amd.sh
    • README.md

Schneller Ablauf zum Starten

  • Nach dem Klonen des Repositorys in das Projektverzeichnis wechseln
git clone https://github.com/slashml/amd-gpu-inference.git
cd amd-gpu-inference
  • Dem Ausführungsskript Ausführungsrechte geben
chmod +x run-docker-amd.sh
  • Die Inferenz-Engine mit Modellnamen und Prompt starten
./run-docker-amd.sh "meta-llama/Llama-2-7b-chat-hf" "Translate the following English text to French: 'Hello, how are you?'"
  • "meta-llama/Llama-2-7b-chat-hf" kann durch das gewünschte Hugging-Face-Modell ersetzt werden, und auch der Prompt kann frei angegeben werden

Ausführung mit Docker und ROCm

  • Aptfile listet die ROCm-Pakete auf, die im Docker-Container installiert werden sollen
    • Diese Konfiguration soll die benötigten ROCm-Treiber und -Bibliotheken im Container verfügbar machen
  • run-docker-amd.sh baut das Docker-Image automatisch
  • Ein manueller Build ist mit folgendem Befehl möglich
docker build -t amd-gpu-inference .
  • Beim manuellen Start des Containers werden Geräte- und Berechtigungsoptionen für den Zugriff auf die AMD GPU angegeben
docker run --rm -it \
    --device=/dev/kfd \
    --device=/dev/dri \
    --group-add=video \
    --cap-add=SYS_PTRACE \
    --security-opt seccomp=unconfined \
    amd-gpu-inference "model_name" "your prompt here"
  • In "model_name" wird der Name des Hugging-Face-Modells eingetragen, in "your prompt here" der Eingabetext

Anpassung und Fehlerbehebung

  • Ein Modellwechsel erfolgt, indem beim Start der Name des Hugging-Face-Repositorys angegeben wird
./run-docker-amd.sh "facebook/opt-1.3b" "Your prompt here"
  • Um die Inferenzlogik zu ändern, wird die Datei run_inference.py angepasst
    • Nach Änderungen muss das Docker-Image neu gebaut werden
  • Punkte zur Fehlerbehebung sind
    • Prüfen, ob AMD-GPU-Treiber und ROCm auf dem Host-System korrekt installiert und konfiguriert sind
    • Wenn ein "out of memory"-Fehler auftritt, ein kleineres Modell verwenden oder die Eingabe- und Ausgabelänge reduzieren
    • Bei modellspezifischen Problemen die Dokumentation des jeweiligen Modells auf Hugging Face heranziehen

Lizenz und Hinweise

  • Das Projekt kann Beiträge per Pull Request annehmen
  • ROCm wurde von AMD entwickelt und wird unter der MIT License bereitgestellt
  • Fragen oder Issues können im GitHub-Repository als Issue eröffnet werden

1 Kommentare

 
GN⁺ 2024-10-04
Meinungen auf Hacker News
  • Für Inferenz lässt sich, wenn es sich um eine unterstützte Karte handelt oder um eine Architektur, bei der man unter Linux HSA_OVERRIDE_GFX_VERSION verwenden kann, fast alles mit Upstream-PyTorch und transformers ausführen.
    Auch llama.cpp lässt sich seit mindestens etwa einem Jahr ziemlich problemlos kompilieren, und unter Windows enthalten die Releases meist ein win-hip-Binary; falls nicht, kann man mit geringerer Performance auf einen Vulkan-Build ausweichen.
    Allerdings ist ROCm 5.4.2 in diesem Artikel fast zwei Jahre alt, und seitdem hat sich viel geändert; ich frage mich, warum er im Oktober 2024 neu veröffentlicht wurde.
    Ich habe kürzlich die auf RDNA3 fokussierte Kompatibilitätsdokumentation auf Basis von ROCm 6.2 aktualisiert, und selbst in wenigen Monaten hat sich viel getan: Upstream-bitsandbytes, Upstream-xformers, Triton-basierte Flash Attention usw.: https://llm-tracker.info/howto/AMD-GPUs

  • Die Flut an grob generativ zusammengebauten Machine-Learning-Bibliotheken ist erstaunlich.
    Diese Bibliothek besteht zur Hälfte aus print-Anweisungen, und die Stellen mit Branching müssten eigentlich gar nicht verzweigen.
    Im Grunde werden zwei Umgebungsvariablen definiert und zwei torch-Flags gesetzt.

    • Ich musste sogar eine Therapie machen, um mir abzugewöhnen, Data Scientists und Machine-Learning-Leute für Software Engineers zu halten und von ihnen denselben Output zu erwarten; das treibt nur den Blutdruck hoch.
      In Teams oder Organisationen ist Erwartungsmanagement meiner Meinung nach wirklich ein großer Teil.
    • Ich dachte erst, das sei zu harsh, aber nach einem Blick ins Repository war es das nicht.
      Tatsächlich ist da fast nichts drin.
    • Ich verstehe, was gemeint ist, aber Kommentare wie dieser bringen Leute dazu, sich davor zu scheuen, Code zu teilen, Open-Source-Beiträge zu leisten oder überhaupt weiter zu programmieren.
  • Es scheint ein altes ROCm 5.4.2 zu verwenden; das ist eine Version von vor zwei Jahren, daher bezweifle ich, dass sie meine RX 7900 XTX unterstützt.
    Persönlich fand ich es am einfachsten, das aktuelle rocm/pytorch-Image zu verwenden und darin auszuführen, was ich brauche.

    • Die RX 7900 XTX (gfx1100) wurde in ROCm 5.4 erstmals für Mathematikbibliotheken wie rocBLAS aktiviert, aber AI-Bibliotheken wie MIOpen waren meines Wissens erst ab ROCm 5.5 aktiviert.
      Ich denke, die Performance hat sich in späteren Releases ebenfalls ziemlich deutlich verbessert.
  • Unter Ubuntu 24.04 und Debian Unstable kann man llama.cpp mit ROCm auf fast allen diskreten AMD-GPUs seit Vega allein mit den vom Betriebssystem bereitgestellten Paketen ausführen.
    Docker oder HSA_OVERRIDE_GFX_VERSION sind nicht nötig; man installiert hipcc, libhipblas-dev, librocblas-dev, cmake usw., gibt Berechtigungen für die Gruppen video und render und baut mit GGML_HIPBLAS=ON.
    Für Nutzer von RDNA 3, MI200 und MI300 sind wegen der Performance die von AMD bereitgestellten ROCm-Pakete besser, und wenn PyTorch benötigt wird, ist es ebenfalls sinnvoller, die AMD-Pakete zu verwenden, weil es Abhängigkeiten gibt, die in den Systempaketen fehlen.
    Trotzdem sind die Betriebssystempakete bei Installationskomfort und Kompatibilität mit älterer Hardware schwer zu schlagen; der Referenzlink ist https://lists.debian.org/debian-ai/2024/07/msg00002.html.

    • Unter Ubuntu 22.04.5 habe ich auf einer RX 7900 XTX das von AMD bereitgestellte ROCm und Ollama ohne größere Probleme installiert, und ROCm-basierte LLMs laufen mit Ollama ebenfalls gut.
    • Gibt es derzeit am Markt eine AMD-Karte mit mehr als 24 GB VRAM zu einem verbraucherfreundlichen Preis?
  • Ich habe mir vor etwa 8 Monaten einen Ryzen 8700G gekauft, um neuronale Netze über die NPU auszuführen, aber bisher bekomme ich Beschleunigung nur über Vulkan auf der iGPU, nicht über die NPU.
    Ich nutze ausschließlich Linux, und der Vorteil ist, dass ich dank 64 GB RAM auch Modelle mit mehr als 32 GB problemlos ausprobieren konnte.
    llama.cpp verdient Lob für seinen Vulkan-Backend-Support.

    • Man sollte auch ROCm/HIP-Unterstützung auf der iGPU bekommen können; beim Kompilieren von llama.cpp kann man den Flag LLAMA_HIP_UMA=1 ausprobieren.
      Wenn man sich https://github.com/amd/RyzenAI-SW ansieht, gibt es einiges an Software, mit der man mit der NPU herumspielen kann, aber Phoenix hat 16 TOPS, daher hatte ich keine Lust, es selbst zu testen.
  • Auf meiner NixOS-Workstation musste ich nur ungefähr Folgendes hinzufügen:
    hardware.graphics.enable = true; aktivieren und in services.ollama acceleration = "rocm";, ROC_ENABLE_PRE_VEGA = "1"; sowie HSA_OVERRIDE_GFX_VERSION = "11.0.0"; setzen.

  • Früher hätte mich die Einfachheit von llamafile fast dazu gebracht, AMD ROCm zu installieren.
    Aber sudo apt install rocm ergab 203 zu installierende Pakete, rund 2,37 GB Download und 35,7 GB benötigten Speicherplatz.
    Ich verstehe nicht, wie sich 36 GB für etwas rechtfertigen lassen, das im Grunde einem GPU-Treiber nahekommt.

    • Es stimmt zwar, dass Software heutzutage absurd aufgebläht ist, aber ROCm ist kein einfacher GPU-Treiber.
      Es enthält mehrere Tools und Bibliotheken.
      Auch das CUDA Toolkit ist, wenn man es als einzelne Datei herunterlädt, schon über 4 GB groß; in beiden Fällen wirkt das Ergebnis lächerlich groß.
    • https://github.com/zml/zml arbeitet daran, dieses Problem zu lösen.
    • Ein CPU-Treiber, der auf der GPU läuft, ist inzwischen fast ein vollständiges Betriebssystem.
    • AMD verschmutzt den Linux-Kernel mit seinen Treibern regelrecht: https://www.phoronix.com/news/AMD-5-Million-Lines
  • Das sieht aus wie ein von KI erzeugter Wrapper auf einem Wrapper auf einem Wrapper.
    Da stehen Kommentare wie # Other AMD-specific optimizations can be added here und # For example, you might want to set specific flags or use AMD-optimized libraries, und dann weiß ich nicht, was hier eigentlich gemacht wird.

    • Im Grunde ist es eine große requirements-Datei plus Dockerfile, und der Rest sind größtenteils Helper-Skripte.
  • Welche AMD-GPUs haben heutzutage ein gutes Preis-Leistungs-Verhältnis?
    Ich habe gerade zwei gebrauchte 3090 als eBay-Refurbs für jeweils etwa 750 Dollar gekauft, frage mich aber, was andere für lokale LLMs verwenden.

    • Ich habe mir kürzlich eine MI100 für 650 Dollar gekauft.
      Sie hat 32 GB HBM2 und ist in grundlegenden Flash-Attention-2-Benchmarks etwa 0–5 % schneller als eine 3090, aber die Performance in realen Anwendungen ist sehr uneinheitlich.
      Viele Projekte sind nicht auf die Matrix-Cores von CDNA optimiert, und selbst wenn es Arbeit für RDNA gibt, überträgt sich das oft nicht direkt auf CDNA.
      Frustrierend ist auch, dass llama.cpp den Flash-Attention-PR für AMD geschlossen hat, weil eine Header-only-Bibliothek eine unnötige Abhängigkeit hinzufügen würde: https://github.com/ggerganov/llama.cpp/pull/7011
      Mit xformers bei den SDXL-Defaults komme ich auf etwa 4,5–5 it/s, also ungefähr zwischen 3090 und 4090; in exllamav2 läuft Qwen 72B 3bpw mit rund 7 t/s und damit langsamer als auf einer 3090, allerdings müsste man bei der 3090 eine niedrigere Präzision verwenden, damit es passt.
      Ich bin mir nicht sicher, was dieses Projekt AMD-Nutzern gegenüber bestehenden Optionen wie llama.cpp, exllamav2 oder mlc-ai zusätzlich bringt; heutzutage laufen die meisten Projekte relativ problemlos.
    • Persönlich waren AMD-iGPU/GPU für mich nicht besonders wertvoll, weil bei jedem Update von PyTorch, ROCm, xformers oder Ollama wieder etwas kaputtging.
      Mit Nvidia schläft man nachts ruhiger.
    • Ich habe eine Radeon Pro VII neu für 300 Euro gekauft, das war kein schlechter Deal.
      Sie hat HBM2 und eine Speicherbandbreite von 1 TB/s, also wie eine 4090.
      Allerdings hat sie nur 16 GB VRAM.
    • Vermutlich ist die 7900 XTX die Antwort.
      24 GB RAM für 1.000 Dollar.
  • Leute sagen oft „Docker-basiert“, aber eigentlich meinen sie, dass $SOFTWARE als Docker-Image ausgeliefert wird.
    „Docker-basiert“ liest sich so, als würde Docker die Inferenz auf AMD-Karten ausführen, und das wirkt wie eine unsinnige Formulierung.

    • Man kann Inferenz innerhalb eines Docker-Containers ausführen, so wie bei Nvidia.
      OpenAI betreibt seine K8s-Cluster ebenfalls so, und AMD hat dazu auch Dokumentation.
      Bei AMD AI braucht man allerdings die richtige Karte, die richtige ROCm-Version und reines Glück.
      AMD stellt Docker-Images mit ROCm-Unterstützung bereit; wenn man die als Basis-Layer nimmt, mit der App kombiniert und die GPU an den Container durchreicht, kann es funktionieren.
      Am Ende reduziert das eine Variable, um die man sich bei der Bereitstellung kümmern muss, also macht man im Wortsinn Inferenz auf AMD mit Docker.
    • Docker ist deshalb zum Standardwerkzeug im Machine Learning geworden, weil Python-Distributionen, die gegen Systembibliotheken gelinkt sind, sonst ein Chaos verursachen, wenn man diese Ebene nicht mittransportiert.
    • Man kann bestimmte Geräte in Docker mounten.
      Wenn man sich das Skript ansieht, wird dort die GPU gemountet: https://github.com/slashml/amd_inference/blob/main/run-docke...
    • ZML arbeitet daran, dieses Problem zu lösen: https://github.com/zml/zml
    • Warum sollte das unsinnig sein? Auch Docker-Container können mit Geräten kommunizieren; man muss sie nur durchreichen.