KI-Modelle und Plattformen

Optimierung des Speicherbedarfs für Large Language Model-Inferenz und Feinabstimmung

mm
Unite.AI zu deinen bevorzugten Quellen auf Google hinzufügen

Große Sprachmodelle (LLMs) wie GPT-4, Bloom und LLaMA haben durch die Skalierung auf Milliarden von Parametern bemerkenswerte Fähigkeiten erlangt. Die Bereitstellung dieser riesigen Modelle für Inferenz oder Feinabstimmung ist jedoch aufgrund ihrer enormen Speicheranforderungen herausfordernd. In diesem technischen Blog werden wir Techniken für die Schätzung und Optimierung des Speicherbedarfs während der LLM-Inferenz und Feinabstimmung auf verschiedenen Hardware-Konfigurationen untersuchen.

Verständnis der Speicheranforderungen

Der Speicher, der zum Laden eines LLM benötigt wird, wird hauptsächlich durch die Anzahl der Parameter und die numerische Genauigkeit bestimmt, die zum Speichern der Parameter verwendet wird. Eine einfache Faustregel lautet:

  • Das Laden eines Modells mit X Milliarden Parametern erfordert ungefähr 4X GB VRAM in 32-Bit-Float-Genauigkeit
  • Das Laden eines Modells mit X Milliarden Parametern erfordert ungefähr 2X GB VRAM in 16-Bit-bfloat16/Float16-Genauigkeit

Beispielsweise würde das Laden des 175-Milliarden-Parameter-GPT-3-Modells etwa 350 GB VRAM in bfloat16-Genauigkeit erfordern. Derzeit bieten die größten kommerziell verfügbaren GPUs wie die NVIDIA A100 und H100 nur 80 GB VRAM, was die Notwendigkeit von Techniken wie Tensor-Parallelismus und Modell-Parallelismus erfordert.

Während der Inferenz wird der Speicherbedarf von den Modellparametern und den temporären Aktivierungstensoren dominiert, die erzeugt werden. Eine hochrangige Schätzung für den Spitzen-Speicherbedarf während der Inferenz ist die Summe des Speichers, der zum Laden der Modellparameter und des Speichers für Aktivierungen erforderlich ist.

Quantifizierung des Inferenzspeichers

Lassen Sie uns die Speicheranforderungen für die Inferenz mithilfe des OctoCode-Modells quantifizieren, das etwa 15 Milliarden Parameter in bfloat16-Format (~ 31 GB) hat. Wir werden die Transformers-Bibliothek verwenden, um das Modell zu laden und Text zu generieren:

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
import torch

<p>model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;,
torch_dtype=torch.bfloat16,
device_map=&quot;auto&quot;,
pad_token_id=0)
tokenizer = AutoTokenizer.from_pretrained(&quot;bigcode/octocoder&quot;)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)</p>

<p>prompt = &quot;Frage: Bitte schreiben Sie eine Python-Funktion, um Bytes in Gigabyte umzuwandeln.\n\nAntwort:&quot;
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]</p>

<p>def bytes_to_gigabytes(bytes):
return bytes / 1024 / 1024 / 1024</p>

<p>bytes_to_gigabytes(torch.cuda.max_memory_allocated())

Ausgabe:

29.0260648727417

Der Spitzen-GPU-Speicherbedarf beträgt etwa 29 GB, was unserer Schätzung von 31 GB für das Laden der Modellparameter in bfloat16-Format entspricht.

Optimierung des Inferenzspeichers mit Quantisierung

Während bfloat16 die übliche Genauigkeit für das Training von LLMs ist, haben Forscher festgestellt, dass die Quantisierung der Modellgewichte auf niedrigere Genauigkeitsdatentypen wie 8-Bit-Ganzzahlen (int8) oder 4-Bit-Ganzzahlen den Speicherbedarf erheblich reduzieren kann, während der Verlust an Genauigkeit für Inferenzaufgaben wie Textgenerierung minimiert wird.

Lassen Sie uns die Speichereinsparungen durch 8-Bit- und 4-Bit-Quantisierung des OctoCode-Modells sehen:

&amp;lt;/div&amp;gt;
# 8-Bit-Quantisierung
model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;, load_in_8bit=True,
pad_token_id=0)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]
bytes_to_gigabytes(torch.cuda.max_memory_allocated())&lt;/pre&gt;
Ausgabe:
15.219234466552734
# 4-Bit-Quantisierung
model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;, load_in_4bit=True,
low_cpu_mem_usage=True, pad_token_id=0)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]
bytes_to_gigabytes(torch.cuda.max_memory_allocated())

Ausgabe:

9.543574333190918

Mit 8-Bit-Quantisierung reduziert sich der Speicherbedarf von 31 GB auf 15 GB, während die 4-Bit-Quantisierung ihn weiter auf 9,5 GB reduziert! Dies ermöglicht es, das 15-Milliarden-Parameter-OctoCode-Modell auf Consumer-GPUs wie der RTX 3090 (24 GB VRAM) auszuführen.

Es ist jedoch zu beachten, dass eine aggressivere Quantisierung wie 4-Bit manchmal zu einer Verschlechterung der Genauigkeit im Vergleich zu 8-Bit oder bfloat16-Genauigkeit führen kann. Es gibt einen Kompromiss zwischen Speichereinsparungen und Genauigkeit, den die Benutzer für ihren Anwendungsfall bewerten sollten.

Quantisierung ist eine leistungsstarke Technik, die die Bereitstellung von LLMs in ressourcenbeschränkten Umgebungen wie Cloud-Instanzen, Edge-Geräten oder sogar Mobiltelefonen ermöglichen kann, indem der Speicherbedarf drastisch reduziert wird.

Schätzung des Speicherbedarfs für Feinabstimmung

Während Quantisierung hauptsächlich für effiziente Inferenz verwendet wird, sind Techniken wie Tensor-Parallelismus und Modell-Parallelismus entscheidend für die Verwaltung des Speicherbedarfs während des Trainings oder der Feinabstimmung von großen Sprachmodellen.

Der Spitzen-Speicherbedarf während der Feinabstimmung ist typischerweise 3-4 Mal höher als bei der Inferenz aufgrund zusätzlicher Speicheranforderungen für:

  • Gradienten
  • Optimizer-Zustände
  • Aktivierungen aus dem Vorwärtsdurchlauf, die für die Rückwärtsverbreitung gespeichert werden

Eine konservative Schätzung ist, dass die Feinabstimmung eines LLM mit X Milliarden Parametern etwa 4 * (2X) = 8X GB VRAM in bfloat16-Genauigkeit erfordert.

Beispielsweise würde die Feinabstimmung des 7-Milliarden-Parameter-LLaMA-Modells etwa 7 * 8 = 56 GB VRAM pro GPU in bfloat16-Genauigkeit erfordern. Dies übersteigt die Speicherkapazität aktueller GPUs, was die Notwendigkeit verteilter Feinabstimmungstechniken erfordert.

Verteilte Feinabstimmungstechniken

Es wurden mehrere verteilte Feinabstimmungsmethoden vorgeschlagen, um die GPU-Speicherbeschränkungen für große Modelle zu überwinden:

  1. Daten-Parallelismus: Der klassische Daten-Parallelismus-Ansatz repliziert das gesamte Modell auf mehrere GPUs, während die Trainingsdaten-Batches aufgeteilt und verteilt werden. Dies reduziert die Trainingszeit linear mit der Anzahl der GPUs, reduziert jedoch nicht den Spitzen-Speicherbedarf auf jeder GPU.
  2. ZeRO Stage 3: Eine fortgeschrittene Form des Daten-Parallelismus, die die Modellparameter, Gradienten und Optimizer-Zustände auf GPUs aufteilt. Dies reduziert den Speicherbedarf im Vergleich zum klassischen Daten-Parallelismus, indem nur die erforderlichen partitionierten Daten auf jeder GPU während verschiedenen Phasen des Trainings gespeichert werden.
  3. Tensor-Parallelismus: Anstelle der Replikation des Modells teilt der Tensor-Parallelismus die Modellparameter in Zeilen oder Spalten auf und verteilt sie auf GPUs. Jede GPU arbeitet mit einer partitionierten Menge von Parametern, Gradienten und Optimizer-Zuständen, was zu erheblichen Speichereinsparungen führt.
  4. Pipeline-Parallelismus: Diese Technik teilt die Modellschichten auf verschiedene GPUs/Arbeiter auf, wobei jeder Gerät eine Teilmenge der Schichten ausführt. Aktivierungen werden zwischen den Arbeitern übertragen, was den Spitzen-Speicherbedarf reduziert, aber die Kommunikationsüberlastung erhöht.

Die Schätzung des Speicherbedarfs für diese verteilten Methoden ist nicht trivial, da die Verteilung von Parametern, Gradienten, Aktivierungen und Optimizer-Zuständen je nach Technik variiert. Darüber hinaus können verschiedene Komponenten wie der Transformer-Körper und der Sprachmodell-Kopf unterschiedliche Speicherzuweisungsverhaltensweisen aufweisen.

Die LLMem-Lösung

Forscher haben kürzlich LLMem vorgeschlagen, eine Lösung, die den GPU-Speicherbedarf bei der Anwendung verteilter Feinabstimmungsmethoden auf LLMs auf mehrere GPUs genau schätzt.

Schätzung des GPU-Speicherbedarfs für die Feinabstimmung vorgefertigter LLM

Schätzung des GPU-Speicherbedarfs für die Feinabstimmung vorgefertigter LLM

LLMem berücksichtigt Faktoren wie die Rekombination von Parametern vor der Berechnung (ZeRO Stage 3), die Ausgabe-Sammlung im Rückwärtsdurchlauf (Tensor-Parallelismus) und die verschiedenen Speicherzuweisungsstrategien für den Transformer-Körper und den Sprachmodell-Kopf.

Experimentelle Ergebnisse zeigen, dass LLMem den Spitzen-GPU-Speicherbedarf für die Feinabstimmung von LLMs auf einer einzelnen GPU mit einem Fehler von bis zu 1,6 % schätzen kann, was den durchschnittlichen Fehler von 42,6 % des aktuellen Standes der Technik DNNMem übertrifft. Wenn verteilte Feinabstimmungsmethoden auf LLMs mit über einer Milliarde Parametern auf mehrere GPUs angewendet werden, erreicht LLMem einen beeindruckenden durchschnittlichen Fehler von 3,0 %.

Durch die genaue Schätzung der Speicheranforderungen im Voraus kann LLMem den Benutzern helfen, die effizienteste verteilte Feinabstimmungsmethode auszuwählen, die Out-of-Memory-Probleme vermeidet und die Trainingszeit minimiert.

Aufkommende Techniken

Während Quantisierung, Tensor-Parallelismus und Modell-Parallelismus etablierte Techniken sind, erforschen Forscher weiterhin neue Methoden, um die Effizienz des LLM-Trainings und der Bereitstellung zu verbessern.

  1. LoRA und QLoRA: Diese Techniken beinhalten das Training eines kleineren Residual-Adapter-Moduls, um das vorgefertigte LLM mit neuen Kenntnissen zu aktualisieren, anstatt direkt die riesige Anzahl von Parametern fein abzustimmen. Dies kann zu erheblichen Speichereinsparungen führen, während die Leistung des Modells größtenteils erhalten bleibt.
  2. FlashAttention: Der Selbst-Aufmerksamkeitsmechanismus ist ein Speicher- und Rechenbottleneck in Transformer-Modellen. FlashAttention approximiert die Standard-Aufmerksamkeit mit linearer Komplexität, wodurch der Speicherbedarf von quadratisch auf linear im Eingabesequenzlänge reduziert wird.
  3. Mixture-of-Experts: Dieser Ansatz leitet jeden Eingabedatensatz bedingt an ein spezialisiertes Expertenmodell weiter, anstatt ihn durch das gesamte Modell zu verarbeiten. Diese dynamische Sparsity kann Speicher sparen, indem nur eine Teilmenge von Experten für jeden Datensatz aktiviert wird.
  4. Reversed Model Surgery: Forscher haben die chirurgische Modellkomprimierung durch iterative Entfernung weniger wichtiger Komponenten wie Aufmerksamkeitsköpfe erforscht, um Speicher/Geschwindigkeit gegen Genauigkeit einzutauschen.
  5. Offloading: Schließlich können Techniken, die Parameter, Optimizer-Zustände oder Aktivierungen auf den CPU-Speicher oder die Festplatte auslagern, den begrenzten GPU-Speicher für große Modelle ergänzen.

Diese bahnbrechenden Methoden veranschaulichen die lebendige Forschungsumgebung, die sich auf die Demokratisierung effizienten LLM-Trainings und der Bereitstellung auf verschiedene Hardware-Umgebungen konzentriert.

Schlussfolgerung

Die Speicheranforderungen großer Sprachmodelle stellen eine erhebliche Herausforderung für ihre weitverbreitete Anwendung in realen Anwendungen dar. Durch das Verständnis von Speicherschätzungstechniken und die Nutzung von Quantisierung, verteilten Trainingsstrategien und aufkommenden Innovationen können wir LLM-Bereitstellungen auf ressourcenbeschränkten Geräten optimieren.

Werkzeuge wie LLMem ebnen den Weg für eine genaue Speicherschätzung, die es Benutzern ermöglicht, die effizienteste Feinabstimmungskonfiguration auszuwählen. Wenn die Hardware evolviert und die Forschung voranschreitet, können wir effizienteres LLM-Training und -Inferenz erwarten, was den Fortschritt in der natürlichen Sprachverarbeitung und künstlichen Intelligenz vorantreibt.

Das Finden des richtigen Gleichgewichts zwischen Modellkapazität, Genauigkeit und Ressourcenausnutzung wird entscheidend sein, um das volle Potenzial großer Sprachmodelle in verschiedenen Bereichen und Anwendungsfällen zu entfalten. Durch die Nutzung von Speicheroptimierungstechniken kommen wir einem Zukunft näher, in der state-of-the-art-Sprachkünstliche Intelligenz zugänglich, skalierbar und nachhaltig ist.

Ich habe die letzten fünf Jahre damit verbracht, mich in die faszinierende Welt des Machine Learning und Deep Learning zu vertiefen. Mein Engagement und meine Expertise haben mich dazu geführt, an über 50 verschiedenen Software-Entwicklungsprojekten mit einem besonderen Fokus auf AI/ML beizutragen. Meine anhaltende Neugier hat mich auch zum Bereich der Natural Language Processing hingezogen, einem Feld, das ich weiter erforschen möchte.