- Verwenden Sie Modelle, die schnell geladen werden und nur minimal in GPU-fähige Strukturen transformiert werden müssen. Optimieren Sie außerdem das Laden der Modelle.
- 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 finden Sie einen 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 gleichzeitigen Download des Transfer Manager gezeigt.
|
Schnell. Das Modell wird beim Start des Containers heruntergeladen. Achten Sie darauf, dass der Cloud Run-Instanz genügend RAM zugewiesen ist, um die Modelldateien zu speichern. | Die Einrichtung ist etwas schwieriger, 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. Das Modell wird beim Start des Containers heruntergeladen. | Die Einrichtung ist einfach und es sind keine Änderungen am Docker-Image erforderlich. | Schnell bei Netzwerkoptimierungen. Der Download wird nicht parallelisiert. | Eine Kopie in Cloud Storage. |
| Container-Image | Antworten finden Das Importieren eines Bildes 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. Bei sehr großen Modellen sollten Sie Cloud Storage verwenden, um eine vorhersehbarere, aber langsamere Leistung zu erzielen. | Möglicherweise mehrere Kopien in Artifact Registry. |
| Internet | Langsam. Das Modell wird beim Start des Containers heruntergeladen. | In der Regel einfacher (viele Frameworks laden Modelle aus zentralen Repositories herunter). | In der Regel schlecht und unvorhersehbar:
|
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 privaten Google-Zugriff verwenden.
Gegen Aufpreis kann die Latenz beim Laden von Modellen mit Anywhere Cache reduziert werden, indem Daten effizient auf SSDs zwischengespeichert werden, um das Lesen zu beschleunigen.
Um die Lesezeiten für Modelle zu verkürzen, können Sie die folgenden Bereitstellungsoptionen verwenden, um Cloud Storage FUSE-Funktionen zu aktivieren:
cache-dir: Aktivieren Sie die Funktion für das Datei-Caching mit einer Bereitstellung eines In-Memory-Volumes, das als zugrunde liegendes Verzeichnis zum Speichern von Dateien verwendet werden soll. Legen Sie den Wert der Mount-Optioncache-dirauf den Namen des In-Memory-Volumes im Formatcr-volume:{volume name}fest. Wenn Sie beispielsweise ein In-Memory-Volume mit dem Namenin-memory-1haben, das Sie als Cacheverzeichnis verwenden möchten, geben Siecr-volume:in-memory-1an. Wenn dieser Wert festgelegt ist, können Sie auch anderefile-cache-Flags für die Cachekonfiguration festlegen.enable-buffered-read: Setzen Sie das Feldenable-buffered-readauftrue, 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 Feldread-global-max-blocksfestlegen, 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 auf die Container-Speicherlimits angerechnet. Erhöhen Sie das Speicherlimit des Containers. Eine Anleitung dazu finden Sie hier.
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 der Arbeit mit großen Modellen. Insbesondere der Build-Prozess kann durch den Netzwerkdurchsatz beeinträchtigt werden. Wenn Sie Cloud Build verwenden, empfehlen wir, eine leistungsstärkere Build-Maschine mit erhöhter Rechen- und Netzwerkleistung zu verwenden. Dazu erstellen Sie 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 Bild erstellen, wenn sich die Ebene mit dem Modell zwischen den Bildern unterscheidet (unterschiedlicher Hash). Es können zusätzliche Artifact Registry-Kosten anfallen, da es möglicherweise eine Kopie des Modells pro Image gibt, wenn die 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 weiter, wobei der Wert der Egress-Einstellung auf all-traffic festgelegt ist, und 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 Überlegungen zu Build, Bereitstellung, Laufzeit und Systemdesign beschrieben.
Zur Build-Zeit
In der folgenden Liste finden Sie einige Aspekte, die Sie bei der Planung Ihres Builds berücksichtigen sollten:
- 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 installiert. Wir raten davon ab, ein benutzerdefiniertes Image zu erstellen.
- Wählen Sie 4-Bit-quantisierte Modelle aus, um die Nebenläufigkeit zu maximieren, sofern Sie nicht nachweisen können, dass sie sich auf die Ergebnisqualität auswirken. Durch die Quantisierung entstehen kleinere und schnellere Modelle, wodurch der für die Modellbereitstellung benötigte GPU-Speicher reduziert und die Parallelität zur Laufzeit erhöht wird. 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 entsprechen genauer dem Zielquantisierungstyp und erfordern weniger Transformationen für das Laden in die GPU. Aus Sicherheitsgründen sollten Sie keine Checkpoints im Pickle-Format verwenden.
- LLM-Caches beim Build erstellen und vorwärmen Starten Sie das LLM auf dem Build-Computer, während Sie das Docker-Image erstellen. Aktivieren Sie das Prompt-Caching und geben Sie gängige oder Beispiel-Prompts ein, um den Cache für die Verwendung in der Praxis vorzubereiten. Speichern Sie die Ausgaben, die es generiert, damit sie zur Laufzeit geladen werden können.
- Speichern Sie Ihr eigenes Inferenzmodell, das Sie während der Erstellung generieren. Das spart im Vergleich zum Laden weniger effizient gespeicherter Modelle und zum Anwenden von Transformationen wie der Quantisierung beim Starten des Containers viel Zeit.
Bei der Bereitstellung
Die folgende Liste enthält Aspekte, die Sie bei der Planung der Bereitstellung berücksichtigen müssen:
- Achten Sie darauf, dass Sie die Nebenläufigkeit des Dienstes in Cloud Run richtig festlegen.
- Passen Sie die Startprüfungen entsprechend Ihrer Konfiguration an.
Startprüfungen ermitteln, ob der Container gestartet wurde und bereit ist, Traffic entgegenzunehmen. Beachten Sie beim Konfigurieren von Startprüfungen die folgenden wichtigen Punkte:
- Angemessene Startzeit: Planen Sie genügend Zeit für die vollständige Initialisierung und das Laden Ihres Containers, einschließlich der Modelle, ein.
- Prüfung der Modellbereitschaft: Konfigurieren Sie Ihre Probe so, dass sie nur bestanden wird, wenn Ihre Anwendung bereit ist, Anfragen zu bearbeiten. Viele Bereitstellungs-Engines erreichen dies automatisch, wenn das Modell in den GPU-Arbeitsspeicher geladen wird, wodurch vorzeitige Anfragen verhindert werden.
Ollama kann einen TCP-Port öffnen, bevor ein Modell geladen wird. Um dies zu beheben können Sie
Modelle vorab laden: Informationen zum Vorabladen Ihres Modells beim Start finden Sie in der Ollama-Dokumentation.
Während der Laufzeit
- Passen Sie die unterstützte Kontextlänge an. Je kleiner das Kontextfenster, desto mehr Anfragen 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 Build-Phase verwendet haben, als Sie den Prompt- und Präfix-Cache generiert haben.
- Laden Sie das gespeicherte Modell, das Sie gerade erstellt haben. Einen Vergleich dazu, wie das Modell geladen wird, finden Sie unter Vor- und Nachteile beim Speichern und Laden von Modellen.
- Verwenden Sie einen quantisierten Schlüssel/Wert-Paar-Cache, sofern Ihr Framework dies unterstützt. Dadurch kann der Speicherbedarf pro Anfrage gesenkt 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 Aktivierungen und den Schlüssel/Wert-Paar-Cache reserviert werden soll. Stellen Sie den Wert so hoch wie möglich ein, ohne dass ein Fehler aufgrund von zu wenig Arbeitsspeicher auftritt.
- Prüfen Sie, ob Ihr Framework Optionen zur Verbesserung der Container-Startleistung bietet, z. B. durch Parallelisierung des Modellladens.
- Konfigurieren Sie die Nebenläufigkeit in Ihrem Dienstcode richtig. Achten Sie darauf, dass Ihr Dienstcode für die Nebenläufigkeitseinstellungen Ihres Cloud Run-Dienstes konfiguriert ist.
Auf Systemdesignebene
- Fügen Sie gegebenenfalls semantische Caches hinzu. In einigen Fällen kann das Zwischenspeichern ganzer Anfragen und Antworten eine gute Möglichkeit sein, die Kosten für häufige Anfragen zu begrenzen.
- Varianz in Ihren Präambeln kontrollieren Prompt-Caches sind nur nützlich, wenn sie die Prompts in der richtigen Reihenfolge enthalten. Caches werden effektiv als Präfix-Cache gespeichert. Einfügungen oder Änderungen in der Sequenz bedeuten, dass sie entweder nicht im Cache gespeichert oder nur teilweise vorhanden sind.
Autoscaling und GPUs
Wenn Sie das standardmäßige Cloud Run-Autoscaling verwenden, skaliert Cloud Run die Anzahl der Instanzen jeder Revision automatisch basierend auf Faktoren wie CPU-Auslastung und Anfrage-Nebenläufigkeit. Cloud Run skaliert die Anzahl der Instanzen jedoch nicht automatisch basierend auf der GPU-Auslastung.
Wenn eine Version mit einer GPU keine erhebliche CPU-Auslastung aufweist, wird Cloud Run für die Anfrageparallelität hochskaliert. Um eine optimale Skalierung für die Nebenläufigkeit von Anfragen zu erreichen, müssen Sie eine optimale maximale Anzahl gleichzeitiger Anfragen pro Instanz festlegen, wie im nächsten Abschnitt beschrieben.
Maximale Anzahl gleichzeitiger Anfragen pro Instanz
Mit der Einstellung Maximale Anzahl gleichzeitiger Anfragen pro Instanz wird die maximale Anzahl von Anfragen gesteuert, die Cloud Run gleichzeitig an eine einzelne Instanz sendet. Sie müssen die Nebenläufigkeit anpassen, damit sie der maximalen Parallelität entspricht, die der Code in jeder Instanz mit guter Leistung verarbeiten kann.
Maximale Nebenläufigkeit und KI-Arbeitslasten
Wenn Sie eine KI-Inferenzarbeitslast auf einer GPU in jeder Instanz ausführen, hängt die maximale Nebenläufigkeit, die der Code mit guter Leistung verarbeiten kann, von den spezifischen Details des Frameworks und der Implementierung ab. Die folgenden Faktoren wirken sich darauf aus, wie Sie die optimale Einstellung für die maximale Anzahl gleichzeitiger Anfragen festlegen:
- Anzahl der auf die GPU geladenen Modellinstanzen
- Anzahl der parallelen Anfragen pro Modell
- Batching verwenden
- Spezifische Batchkonfigurationsparameter
- Anteil der Arbeit ohne GPU
Wenn die maximale Anzahl gleichzeitiger Anfragen zu hoch eingestellt ist, kann es passieren, dass Anfragen innerhalb der Instanz auf den Zugriff auf die GPU warten müssen, was zu einer erhöhten Latenz führt. Wenn die maximale Anzahl gleichzeitiger Anfragen zu niedrig eingestellt ist, kann es zu einer Unterauslastung der GPU kommen, was dazu führt, dass Cloud Run mehr Instanzen horizontal skaliert als nötig.
Als Faustregel für die Konfiguration der maximalen Anzahl gleichzeitiger Anfragen für KI-Arbeitslasten gilt:
(Number of model instances * parallel queries per model) + (number of model instances * ideal batch size)
Angenommen, eine Instanz lädt 3 Modellinstanzen auf die GPU und jede Modellinstanz kann 4 parallele Anfragen verarbeiten. Die ideale Batchgröße ist ebenfalls 4, da dies die Anzahl der parallelen Anfragen ist, die jede Modellinstanz verarbeiten kann. Nach der Faustregel würden Sie die maximale Anzahl gleichzeitiger Anfragen auf 24 festlegen: (3 * 4) + (3 * 4).
Diese Formel ist nur eine Faustregel. Die optimale Einstellung für die maximale Anzahl gleichzeitiger Anfragen hängt von den spezifischen Details Ihrer Implementierung ab. Um die tatsächlich optimale Leistung zu erzielen, empfehlen wir Ihnen, Ihren Dienst mit verschiedenen Einstellungen für die maximale Anzahl gleichzeitiger Anfragen einen Lasttest durchzuführen, um zu ermitteln, welche Option die beste Leistung erzielt.
Kompromisse zwischen Durchsatz, Latenz und Kosten
Unter Kompromisse zwischen Durchsatz, Latenz und Kosten finden Sie Informationen dazu, wie sich die maximale Anzahl gleichzeitiger Anfragen auf Durchsatz, Latenz und Kosten auswirkt. Beachten Sie, dass für alle Cloud Run-Dienste, die GPUs verwenden, die instanzbasierte Abrechnung konfiguriert sein muss.