Vernetzen Sie sich mit uns

Künstliche Intelligenz

Optimierung des Speichers für die Inferenz und Feinabstimmung großer Sprachmodelle

mm
Speicher für die Inferenz großer Sprachmodelle

Große Sprachmodelle (LLMs) wie GPT-4, Bloom und LLaMA haben durch die Skalierung auf Milliarden von Parametern bemerkenswerte Fähigkeiten erreicht. Der Einsatz dieser umfangreichen Modelle zur Inferenz oder Feinabstimmung ist jedoch aufgrund ihres enormen Speicherbedarfs eine Herausforderung. In diesem technischen Blog werden wir Techniken zur Schätzung und Optimierung des Speicherverbrauchs während der LLM-Inferenz und Feinabstimmung über verschiedene Hardware-Setups hinweg untersuchen.

Speicheranforderungen verstehen

Der zum Laden eines LLM erforderliche Speicher 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 von VRAM in 32-bit Float-Präzision
  • Das Laden eines Modells mit X Milliarden Parametern erfordert ungefähr 2X GB von VRAM in 16-bit bfloat16/float16 Präzision

Das Laden des GPT-175-Modells mit 3B-Parametern würde beispielsweise etwa 350 GB VRAM in bfloat16-Genauigkeit erfordern. Derzeit bieten die größten kommerziell erhältlichen GPUs wie NVIDIA A100 und H100 nur 80 GB VRAM, was Tensorparallelitäts- und Modellparallelitätstechniken erfordert.

Während der Inferenz wird der Speicherbedarf von den Modellparametern und den erzeugten temporären Aktivierungstensoren dominiert. Eine grobe Schätzung für die maximale Speichernutzung während der Inferenz ist die Summe des zum Laden der Modellparameter erforderlichen Speichers und des Speichers für Aktivierungen.

Quantifizierung des Inferenzgedächtnisses

Quantifizieren wir den Speicherbedarf für die Inferenz mit dem OctoCode-Modell, das rund 15 Milliarden Parameter im bfloat16-Format (~ 31 GB) hat. Wir verwenden die Transformers-Bibliothek So laden Sie das Modell und generieren Text:

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
import torch

model = AutoModelForCausalLM.from_pretrained("bigcode/octocoder",
torch_dtype=torch.bfloat16,
device_map="auto",
pad_token_id=0)
tokenizer = AutoTokenizer.from_pretrained("bigcode/octocoder")
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)

prompt = "Question: Please write a Python function to convert bytes to gigabytes.\n\nAnswer:"
result = pipe(prompt, max_new_tokens=60)[0]["generated_text"][len(prompt):]

def bytes_to_gigabytes(bytes):
return bytes / 1024 / 1024 / 1024

bytes_to_gigabytes(torch.cuda.max_memory_allocated())

Ausgang:

29.0260648727417

Die maximale GPU-Speichernutzung liegt bei etwa 29 GB, was unserer Schätzung von 31 GB für das Laden der Modellparameter im bfloat16-Format entspricht.

Optimierung des Inferenzgedächtnisses durch Quantisierung

Während bfloat16 die übliche Präzision ist, die für das Training von LLMs verwendet wird, haben Forscher herausgefunden, dass die Quantisierung der Modellgewichte auf Datentypen mit geringerer Präzision wie 8-Bit-Ganzzahlen (int8) oder 4-Bit-Ganzzahlen die Speichernutzung bei minimalem Genauigkeitsverlust für Inferenzaufgaben wie erheblich reduzieren kann Textgenerierung.

Sehen wir uns die Speichereinsparungen durch die 8-Bit- und 4-Bit-Quantisierung des OctoCode-Modells an:

</div>
# 8-bit quantization
model = AutoModelForCausalLM.from_pretrained("bigcode/octocoder", load_in_8bit=True, 
pad_token_id=0)
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=60)[0]["generated_text"][len(prompt):]
bytes_to_gigabytes(torch.cuda.max_memory_allocated())</pre>
Ausgang:
15.219234466552734
# 4-bit quantization
model = AutoModelForCausalLM.from_pretrained("bigcode/octocoder", load_in_4bit=True,
low_cpu_mem_usage=True, pad_token_id=0)
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=60)[0]["generated_text"][len(prompt):]
bytes_to_gigabytes(torch.cuda.max_memory_allocated())

Ausgang:

9.543574333190918

Mit der 8-Bit-Quantisierung sinkt der Speicherbedarf von 31 GB auf 15 GB, während er mit der 4-Bit-Quantisierung weiter auf nur 9.5 GB reduziert wird! Dies ermöglicht die Ausführung des 15B-Parameter-OctoCode-Modells auf Consumer-GPUs wie der RTX 3090 (24 GB VRAM).

Beachten Sie jedoch, dass eine aggressivere Quantisierung wie 4-Bit manchmal zu einer Verschlechterung der Genauigkeit im Vergleich zu 8-Bit- oder Bfloat16-Präzision führen kann. Es gibt einen Kompromiss zwischen Speichereinsparungen und Genauigkeit, den Benutzer für ihren Anwendungsfall abwägen sollten.

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

Schätzen des Speichers zur Feinabstimmung

Während die Quantisierung hauptsächlich für eine effiziente Inferenz verwendet wird, sind Techniken wie Tensorparallelität und Modellparallelität von entscheidender Bedeutung für die Verwaltung des Speicherbedarfs während des Trainings oder Feintuning großer Sprachmodelle.

Der Spitzenspeicherverbrauch während der Feinabstimmung ist in der Regel drei- bis viermal höher als bei der Inferenz aufgrund zusätzlicher Speicheranforderungen für:

  • Farbverläufe
  • Optimiererzustände
  • Aktivierungen aus dem Vorwärtsdurchlauf werden für die Rückausbreitung gespeichert

Eine konservative Schätzung geht davon aus, dass die Feinabstimmung eines LLM mit X Milliarden Parametern etwa erfordert 4 * (2X) = 8X GB von VRAM in bfloat16-Präzision.

Beispielsweise würde die Feinabstimmung des 7B-Parameter-LLaMA-Modells ungefähr erforderlich sein 7 * 8 = 56 GB VRAM pro GPU in bfloat16-Präzision. Dies übersteigt die Speicherkapazität aktueller GPUs und erfordert verteilte Feinabstimmungstechniken.

Verteilte Feinabstimmungstechniken

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

  1. Datenparallelität: Der klassische Datenparallelitätsansatz repliziert das gesamte Modell auf mehreren GPUs und teilt dabei die Trainingsdatenstapel auf und verteilt sie. Dies reduziert die Trainingszeit linear mit der Anzahl der GPUs, verringert jedoch nicht den Spitzenspeicherbedarf auf jeder GPU.
  2. ZeRO Stufe 3: Eine erweiterte Form der Datenparallelität, die die Modellparameter, Verläufe und Optimiererzustände auf GPUs verteilt. Es reduziert den Speicher im Vergleich zur klassischen Datenparallelität, indem während verschiedener Trainingsphasen nur die erforderlichen partitionierten Daten auf jeder GPU gespeichert werden.
  3. Tensorparallelität: Anstatt das Modell zu replizieren, unterteilt die Tensorparallelität die Modellparameter in Zeilen oder Spalten und verteilt sie auf GPUs. Jede GPU arbeitet mit einem partitionierten Satz von Parametern, Verläufen und Optimierungszuständen, was zu erheblichen Speichereinsparungen führt.
  4. Pipeline-Parallelität: Bei dieser Technik werden die Modellschichten auf verschiedene GPUs/Worker aufgeteilt, wobei jedes Gerät eine Teilmenge der Schichten ausführt. Aktivierungen werden zwischen Arbeitern weitergegeben, was die Speicherauslastung reduziert, aber den Kommunikationsaufwand erhöht.

Die Schätzung der Speichernutzung für diese verteilten Methoden ist nicht trivial, da die Verteilung von Parametern, Verläufen, Aktivierungen und Optimiererzuständen je nach Technik unterschiedlich ist. Darüber hinaus können verschiedene Komponenten wie der Transformatorkörper und der Sprachmodellierungskopf ein unterschiedliches Speicherzuweisungsverhalten aufweisen.

Die LLMem-Lösung

Forscher haben kürzlich vorgeschlagen LLMem, eine Lösung, die den GPU-Speicherverbrauch genau schätzt, wenn verteilte Feinabstimmungsmethoden auf LLMs über mehrere GPUs hinweg angewendet werden.

Schätzung der GPU-Speichernutzung zur Feinabstimmung von vorab trainiertem LLM

Schätzung der GPU-Speichernutzung zur Feinabstimmung von vorab trainiertem LLM

LLMem berücksichtigt Faktoren wie die Neukombination von Parametern vor der Berechnung (ZeRO Stufe 3), die Ausgabesammlung im Rückwärtsdurchlauf (Tensorparallelität) und die unterschiedlichen Speicherzuweisungsstrategien für den Transformatorkörper und den Sprachmodellierungskopf.

Experimentelle Ergebnisse zeigen, dass LLMem die maximale GPU-Speicherauslastung für die Feinabstimmung von LLMs auf einer einzelnen GPU mit Fehlerraten von bis zu 1.6 % schätzen kann und damit die durchschnittliche Fehlerrate des hochmodernen DNNMem von 42.6%. Bei der Anwendung verteilter Feinabstimmungsmethoden auf LLMs mit über einer Milliarde Parametern auf mehreren GPUs erreicht LLMem eine beeindruckende durchschnittliche Fehlerrate von 3.0%.

Durch die genaue Schätzung des Speicherbedarfs im Voraus kann LLMem Benutzern dabei helfen, die effizienteste verteilte Feinabstimmungsmethode auszuwählen, die Probleme aufgrund von Speichermangel vermeidet und gleichzeitig die Trainingszeit minimiert.

Aufkommende Techniken

Während Quantisierung, Tensorparallelität und Modellparallelität etablierte Techniken sind, erforschen Forscher weiterhin neue Methoden, um die Grenzen eines effizienten LLM-Trainings und -Einsatzes zu erweitern.

  1. LoRA und QLoRA: Bei diesen Techniken wird ein kleineres Residualadaptermodul trainiert, um das vortrainierte LLM mit neuem Wissen zu aktualisieren, anstatt die enorme Anzahl an Parametern direkt zu optimieren. Dies kann zu erheblichen Speichereinsparungen führen, während die Leistung des Modells weitgehend erhalten bleibt.
  2. BlitzAchtung: Der Selbstaufmerksamkeitsmechanismus ist ein Speicher- und Rechenengpass in Transformatormodellen. FlashAttention nähert sich der Standardaufmerksamkeit mit linearer Komplexität an und reduziert den Speicherbedarf in der Länge der Eingabesequenz von quadratisch auf linear.
  3. Mischung aus Experten: Dieser Ansatz leitet jede Eingabedatenprobe bedingt an ein spezialisiertes Expertenmodell weiter, anstatt sie im gesamten Modell zu verarbeiten. Diese dynamische Sparsity kann Speicher sparen, indem für jede Probe nur eine Teilmenge von Experten aktiviert wird.
  4. Umgekehrte Modellchirurgie: Forscher haben die Komprimierung chirurgischer Modelle untersucht, indem sie iterativ weniger wichtige Komponenten wie Aufmerksamkeitspunkte entfernt haben, um Speicher/Geschwindigkeit zugunsten der Genauigkeit zu kompensieren.
  5. Entladen: Schließlich können Techniken, die Parameter, Optimierungszustände oder Aktivierungen in den CPU-RAM oder die Festplatte verlagern, den begrenzten GPU-Speicher für große Modelle ergänzen.

Diese hochmodernen Methoden veranschaulichen das lebendige Forschungsökosystem, das sich auf die Demokratisierung effizienter LLM-Schulung und -Bereitstellung in verschiedenen Hardwareumgebungen konzentriert.

Fazit

Der Speicherbedarf großer Sprachmodelle stellt ihre weitverbreitete Einführung in reale Anwendungen vor große Herausforderungen. Durch das Verständnis von Speicherschätzungstechniken und die Nutzung von Quantisierung, verteilten Trainingsstrategien und neuen Innovationen können wir LLM-Bereitstellungen auf Geräten mit eingeschränkten Ressourcen optimieren.

Tools wie LLMem ebnen den Weg zu einer genauen Speicherschätzung und ermöglichen es Benutzern, die am besten geeignete Feinabstimmungskonfiguration auszuwählen. Da sich die Hardware weiterentwickelt und die Forschung voranschreitet, können wir mit einem effizienteren LLM-Training und Inferenz rechnen, was den Fortschritt in der Verarbeitung natürlicher Sprache und der künstlichen Intelligenz vorantreiben wird.

Um das volle Potenzial großer Sprachmodelle über verschiedene Domänen und Anwendungsfälle hinweg auszuschöpfen, wird es entscheidend sein, das richtige Gleichgewicht zwischen Modellkapazität, Genauigkeit und Ressourcennutzung zu finden. Durch den Einsatz von Speicheroptimierungstechniken kommen wir einer Zukunft näher, in der modernste Sprach-KI zugänglich, skalierbar und nachhaltig ist.

Ich habe die letzten fünf Jahre damit verbracht, in die faszinierende Welt des maschinellen Lernens und des Deep Learning einzutauchen. Meine Leidenschaft und mein Fachwissen haben dazu geführt, dass ich an über 50 verschiedenen Software-Engineering-Projekten mitgewirkt habe, mit besonderem Schwerpunkt auf KI/ML. Meine anhaltende Neugier hat mich auch zur Verarbeitung natürlicher Sprache geführt, einem Bereich, den ich gerne weiter erforschen möchte.