Best Practices: Cloud Run-Worker-Pools mit GPUs

Auf dieser Seite finden Sie Best Practices zur Leistungsoptimierung bei der Verwendung eines Cloud Run-Worker-Pools mit KI-Arbeitslasten, z. B. zum Trainieren großer Sprachmodelle (Large Language Models, LLMs) mit Ihren bevorzugten Frameworks, zum Feinabstimmen und zum Ausführen von Batch- oder Offline-Inferenz für LLMs. So erstellen Sie einen Cloud Run-Worker-Pool, mit dem rechenintensive Aufgaben oder die Batchverarbeitung in Echtzeit ausgeführt werden können:
  • Verwenden Sie Modelle, die schnell geladen werden und nur minimale Transformationen in GPU-fähige Strukturen erfordern, und optimieren Sie das Laden.
  • Verwenden Sie Konfigurationen, die eine maximale, effiziente, gleichzeitige Ausführung ermöglichen, um die Anzahl der GPUs zu reduzieren, die zum Ausführen einer Zielanfrage pro Sekunde erforderlich sind, und gleichzeitig die Kosten niedrig zu halten.

Empfohlene Methoden zum Laden großer ML-Modelle in Cloud Run

Google empfiehlt, ML-Modelle aus Cloud Storage herunterzuladen und über die Google Cloud CLI darauf zuzugreifen. Alternativ können Sie Modelle in Container-Images speichern. Diese Methode eignet sich jedoch am besten für kleinere Modelle mit weniger als 10 GB.

Vor- und Nachteile beim Speichern und Laden von ML-Modellen

Hier ein Vergleich der Optionen:

Modellstandort Bereitstellungszeit Entwicklungserfahrung Container-Startzeit Speicherkosten
Cloud Storage, gleichzeitig heruntergeladen mit dem Google Cloud CLI-Befehl gcloud storage cp oder der Cloud Storage API, wie im Codebeispiel für den gleichzeitigen Download des Transfer Managers gezeigt. Am schnellsten. Modell wird beim Starten des Containers heruntergeladen. Achten Sie darauf, dass der Cloud Run-Instanz genügend RAM zugewiesen ist, um die Modelldateien zu speichern. Etwas schwieriger einzurichten, da Sie entweder die Google Cloud CLI auf dem Image installieren oder Ihren Code aktualisieren müssen, um die Cloud Storage API zu verwenden. Weitere Informationen zum Abrufen von Anmeldedaten vom Metadatenserver finden Sie unter Einführung in die Dienstidentität. Schnell bei Netzwerkoptimierungen. Die Google Cloud CLI lädt die Modelldatei parallel herunter, was schneller ist als die FUSE-Bereitstellung. Eine Kopie in Cloud Storage.
Cloud Storage über das Cloud Storage FUSE-Volume bereitgestellt Höheres Tempo. Modell wird beim Starten des Containers heruntergeladen. Einfach einzurichten, keine Änderungen am Docker-Image erforderlich. Schnell bei Netzwerkoptimierungen. Download wird nicht parallelisiert. Eine Kopie in Cloud Storage.
Container-Image Antworten finden Das Importieren eines Images mit einem großen Modell in Cloud Run dauert länger. Sie müssen jedes Mal ein neues Image erstellen, wenn Sie ein anderes Modell verwenden möchten. Änderungen am Container-Image erfordern eine erneute Bereitstellung, was bei großen Images langsam sein kann. Abhängig von der Größe des Modells. Verwenden Sie für sehr große Modelle Cloud Storage, um eine vorhersehbarere, aber langsamere Leistung zu erzielen. Möglicherweise mehrere Kopien in Artifact Registry.
Internet Langsam. Modell wird beim Starten des Containers heruntergeladen. In der Regel einfacher (viele Frameworks laden Modelle aus zentralen Repositories herunter). In der Regel schlecht und unvorhersehbar:
  • Frameworks können während der Initialisierung Modelltransformationen anwenden. (Sie sollten dies während der Erstellung tun).
  • Modellhost und Bibliotheken zum Herunterladen des Modells sind möglicherweise nicht effizient.
  • Das Herunterladen aus dem Internet birgt Zuverlässigkeitsrisiken. Ihre Worker-Pools können möglicherweise nicht gestartet werden, wenn das Downloadziel nicht erreichbar ist. Außerdem kann sich das heruntergeladene zugrunde liegende Modell ändern, was die Qualität verringert. Wir empfehlen, das Modell in Ihrem eigenen Cloud Storage-Bucket zu hosten.
Abhängig vom Anbieter des Modell-Hostings.

Modelle in Cloud Storage speichern

Wenn Sie das Laden von ML-Modellen aus Cloud Storage optimieren möchten, entweder über Cloud Storage-Volumen-Bereitstellungen oder direkt über die Cloud Storage API oder die Befehlszeile, müssen Sie Direct VPC mit der Einstellung für ausgehenden Traffic auf all-traffic und Private Google Access verwenden.

Gegen Aufpreis können Sie mit Anywhere Cache die Latenz beim Laden von Modellen reduzieren, indem Daten effizient auf SSDs zwischengespeichert werden, um schnellere Lesevorgänge zu ermöglichen.

Um die Lesezeiten für Modelle zu verkürzen, versuchen Sie die folgenden Bereitstellungsoptionen, um Cloud Storage FUSE-Funktionen zu aktivieren:

  • cache-dir: Aktivieren Sie die Funktion für das Datei-Caching mit einer In-Memory-Volumen-Bereitstellung, die als zugrunde liegendes Verzeichnis zum Speichern von Dateien verwendet werden soll. Legen Sie den Wert der Bereitstellungsoption cache-dir auf den Namen des In-Memory-Volumes im Format cr-volume:{volume name} fest. Wenn Sie beispielsweise ein In-Memory-Volume mit dem Namen in-memory-1 als Cache-Verzeichnis verwenden möchten, geben Sie cr-volume:in-memory-1 an. Wenn dieser Wert festgelegt ist, können Sie auch andere file-cache Flags festlegen, die für den Cache konfiguriert werden können.
  • enable-buffered-read: Legen Sie das enable-buffered-read-Feld auf true fest, um das asynchrone Prefetching von Teilen eines Cloud Storage-Objekts in einen Arbeitsspeicher-Puffer zu aktivieren. Dadurch können nachfolgende Lesevorgänge aus dem Puffer bedient werden, ohne dass Netzwerkaufrufe erforderlich sind. Wenn Sie dieses Feld konfigurieren, können Sie auch das read-global-max-blocks Feld festlegen, um die maximale Anzahl an Blöcken zu konfigurieren, die für gepufferte Lesevorgänge für alle Datei-Handles verfügbar sind.

Wenn sowohl cache-dir als auch enable-buffered-read verwendet werden, hat cache-dir Vorrang. Wenn Sie eine dieser Funktionen aktivieren, wird die Ressourcenabrechnung des Cloud Storage FUSE-Prozesses so geändert, dass sie unter den Arbeitsspeicherlimits für Container gezählt wird. Sie können das Arbeitsspeicherlimit für Container erhöhen. Folgen Sie dazu der Anleitung zum Konfigurieren von Arbeitsspeicherlimits.

Modelle in Container-Images speichern

Wenn Sie das ML-Modell im Container-Image speichern, profitiert das Laden des Modells von der optimierten Container-Streaming-Infrastruktur von Cloud Run. Das Erstellen von Container-Images, die ML-Modelle enthalten, ist jedoch ein ressourcenintensiver Prozess, insbesondere bei großen Modellen. Insbesondere der Build-Prozess kann durch den Netzwerkdurchsatz eingeschränkt werden. Wenn Sie Cloud Build verwenden, empfehlen wir eine leistungsstärkere Build-Maschine mit erhöhter Rechen- und Netzwerkleistung. Erstellen Sie dazu ein Image mit einer Build-Konfigurationsdatei, die die folgenden Schritte enthält:

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'IMAGE', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'IMAGE']
images:
- IMAGE
options:
 machineType: 'E2_HIGHCPU_32'
 diskSizeGb: '500'
 

Sie können eine Modellkopie pro Image erstellen, wenn sich die Ebene mit dem Modell zwischen den Images unterscheidet (unterschiedlicher Hash). Es können zusätzliche Kosten für Artifact Registry anfallen, da es eine Kopie des Modells pro Image geben kann, wenn Ihre Modellebene für jedes Image eindeutig ist.

Modelle aus dem Internet laden

Um das Laden von ML-Modellen aus dem Internet zu optimieren, leiten Sie den gesamten Traffic über das VPC-Netzwerk und legen Sie für die Einstellung für ausgehenden Traffic den Wert all-traffic fest. Richten Sie Cloud NAT ein, um das öffentliche Internet mit hoher Bandbreite zu erreichen.

Erwägungen zu Build, Bereitstellung, Laufzeit und Systemdesign

In den folgenden Abschnitten werden Erwägungen zu Build, Bereitstellung, Laufzeit und Systemdesign beschrieben.

Während der Erstellung

Die folgende Liste enthält Erwägungen, die Sie bei der Planung Ihres Builds berücksichtigen müssen:

  • Wählen Sie ein gutes Basis-Image aus. Beginnen Sie mit einem Image aus den Deep Learning Containern oder der NVIDIA-Container Registry für das verwendete ML-Framework. Bei diesen Images sind die neuesten leistungsrelevanten Pakete bereits installiert. Wir raten davon ab, ein benutzerdefiniertes Image zu erstellen.
  • Wählen Sie 4-Bit-quantisierte Modelle aus, um die Nebenläufigkeit zu maximieren, es sei denn, Sie können nachweisen, dass sie die Ergebnisqualität beeinträchtigen. Durch Quantisierung entstehen kleinere und schnellere Modelle, was zu weniger GPU-Arbeitsspeicherverbrauch für die Bereitstellung des Modells führt und gleichzeitig die Parallelität zur Laufzeit erhöhen kann. Idealerweise sollten die Modelle mit der Zielbittiefe trainiert werden, anstatt auf diese herunterquantisiert zu werden.
  • Wählen Sie ein Modellformat mit schnellen Ladezeiten aus, um die Startzeit des Containers zu minimieren, z. B. GGUF. Diese Formate spiegeln den Zielquantisierungstyp genauer wider und erfordern weniger Transformationen, wenn sie in die GPU geladen werden. Verwenden Sie aus Sicherheitsgründen keine Prüfpunkte im Pickle-Format.
  • LLM-Caches beim Build erstellen und vorwärmen Starten Sie das LLM auf der Build-Maschine, während Sie das Docker-Image erstellen. Aktivieren Sie das Prompt-Caching und geben Sie allgemeine oder Beispiel-Prompts ein, um den Cache für die reale Verwendung vorzuwärmen. Speichern Sie die generierten Ausgaben, damit sie zur Laufzeit geladen werden können.
  • Speichern Sie Ihr eigenes Inferenzmodell, das Sie während der Erstellung generieren. Dadurch sparen Sie viel Zeit im Vergleich zum Laden weniger effizient gespeicherter Modelle und zum Anwenden von Transformationen wie der Quantisierung beim Starten des Containers.

Bei der Bereitstellung

Die folgende Liste enthält Erwägungen, die Sie bei der Planung Ihrer Bereitstellung berücksichtigen müssen:

  • GPU-Worker-Pools können nicht automatisch skaliert werden. Die GPU wird Ihnen auch dann in Rechnung gestellt, wenn darauf keine Prozesse ausgeführt werden.
  • CPU und Arbeitsspeicher für Worker-Pools werden anders berechnet als für Dienste und Jobs. Die GPU-SKU wird jedoch genauso berechnet wie für Dienste und Jobs.

Während der Laufzeit

  • Verwalten Sie aktiv die unterstützte Kontextlänge. Je kleiner das unterstützte Kontextfenster, desto mehr Abfragen können parallel ausgeführt werden. Die Details dazu hängen vom Framework ab.
  • Verwenden Sie die LLM-Caches, die Sie während der Erstellung generiert haben. Geben Sie dieselben Flags an, die Sie während der Erstellung verwendet haben, als Sie den Prompt- und Präfix-Cache generiert haben.
  • Laden Sie das gerade gespeicherte Modell. Unter Vor- und Nachteile beim Speichern und Laden von Modellen finden Sie einen Vergleich der Möglichkeiten zum Laden des Modells.
  • Verwenden Sie einen quantisierten Schlüssel/Wert-Paar-Cache, wenn Ihr Framework ihn unterstützt. Dadurch können die Arbeitsspeicheranforderungen pro Abfrage reduziert und mehr Parallelität konfiguriert werden. Dies kann sich jedoch auch auf die Qualität auswirken.
  • Legen Sie die GPU-Arbeitsspeichermenge fest, die für die Modellgewichtungen, die Aktivierung und den Schlüssel/Wert-Paar-Cache reserviert werden soll. Legen Sie sie so hoch wie möglich fest, ohne einen Fehler aufgrund von zu wenig Arbeitsspeicher zu erhalten.
  • Prüfen Sie, ob Ihr Framework Optionen zur Verbesserung der Startleistung von Containern bietet (z. B. durch Parallelisierung des Ladens von Modellen).

Auf Systemdesignebene

  • Fügen Sie gegebenenfalls semantische Caches hinzu. In einigen Fällen kann das Caching ganzer Abfragen und Antworten eine gute Möglichkeit sein, die Kosten für häufige Abfragen zu begrenzen.
  • Kontrollieren Sie die Varianz in Ihren Präambeln. Prompt-Caches sind nur nützlich, wenn sie die Prompts in der richtigen Reihenfolge enthalten. Caches werden effektiv als Präfix-Cache verwendet. Einfügungen oder Änderungen in der Sequenz führen dazu, dass sie entweder nicht im Cache gespeichert oder nur teilweise vorhanden sind.