AI-modeller og platforme
Optimering af hukommelse til stor sprogmodelinference og finjustering
Store sprogmodeller (LLMâer) som GPT-4, Bloom og LLaMA har opnÃĨet bemÃĶrkelsesvÃĶrdige evner ved at skala op til milliarder af parametre. however, at deployere disse massive modeller til inference eller finjustering er udfordrende pÃĨ grund af deres enorme hukommelseskrav. I denne tekniske blog vil vi udforske teknikker til at estimere og optimere hukommelsesforbrug under LLM-inference og finjustering pÃĨ tvÃĶrs af forskellige hardware-konfigurationer.
ForstÃĨelse af hukommelseskrav
Hukommelsen, der krÃĶves for at indlÃĶse en LLM, bestemmes primÃĶrt af antallet af parametre og den numeriske prÃĶcision, der bruges til at gemme parametrene. En simpel regel er:
- At indlÃĶse en model med X milliarder parametre krÃĶver omtrent 4X GB VRAM i 32-bit float-prÃĶcision
- At indlÃĶse en model med X milliarder parametre krÃĶver omtrent 2X GB VRAM i 16-bit bfloat16/float16-prÃĶcision
For eksempel ville indlÃĶsning af 175B parameter GPT-3 model krÃĶve omtrent 350GB VRAM i bfloat16-prÃĶcision. Som det er i dag, tilbyder de stÃļrste kommercielt tilgÃĶngelige GPUâer som NVIDIA A100 og H100 kun 80GB VRAM, hvilket nÃļdvendiggÃļr tensor-parallellisme og model-parallellisme-teknikker.
Under inference domineres hukommelsesaftrykket af modelparametrene og de midlertidige aktiverings-tensorer, der produceres. En hÃļjniveau-estimation for peak-hukommelsesforbrug under inference er summen af hukommelsen, der krÃĶves for at indlÃĶse modelparametrene, og hukommelsen for aktiveringer.
Kvantificering af inference-hukommelse
Lad os kvantificere hukommelseskravene for inference ved hjÃĶlp af OctoCode-modellen, der har omkring 15 milliarder parametre i bfloat16-format (~ 31GB). Vi vil bruge Transformers-biblioteket til at indlÃĶse modellen og generere tekst:
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline import torch <p>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)</p> <p>prompt = "SpÃļrgsmÃĨl: Skriv en Python-funktion til at konvertere bytes til gigabyte.\n\nSvar:" result = pipe(prompt, max_new_tokens=60)[0]["generated_text"][len(prompt):]</p> <p>def bytes_to_gigabytes(bytes): return bytes / 1024 / 1024 / 1024</p> <p>bytes_to_gigabytes(torch.cuda.max_memory_allocated())
Output:
29.0260648727417Peak-GPU-hukommelsesforbrug er omkring 29GB, hvilket stemmer overens med vores estimation pÃĨ 31GB for at indlÃĶse modelparametrene i bfloat16-format.
Optimering af inference-hukommelse med kvantificering
Selvom bfloat16 er den almindelige prÃĶcision, der bruges til at trÃĶne LLMâer, har forskere fundet, at kvantificering af modelvÃĶgte til lavere prÃĶcisionsdata typer som 8-bit integers (int8) eller 4-bit integers kan betydeligt reducere hukommelsesforbrug med minimal tab af nÃļjagtighed for inference-opgaver som tekstgenerering.
Lad os se hukommelsesbesparelsen fra 8-bit og 4-bit kvantificering af OctoCode-modellen:
&lt;/div&gt; # 8-bit kvantificering 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>
Output:
15.219234466552734# 4-bit kvantificering 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())
Output:
9.543574333190918Med 8-bit kvantificering falder hukommelseskravet fra 31GB til 15GB, mens 4-bit kvantificering reducerer det yderligere til kun 9,5GB! Dette tillader kÃļrsel af 15B parameter OctoCode-modellen pÃĨ forbruger-GPUâer som RTX 3090 (24GB VRAM).
Men bemÃĶrk, at mere aggressive kvantificering som 4-bit kan nogle gange fÃļre til en nedgang i nÃļjagtighed sammenlignet med 8-bit eller bfloat16-prÃĶcision. Der er en balance mellem hukommelsesbesparelse og nÃļjagtighed, som brugere skal evaluere for deres brugstilfÃĶlde.
Kvantificering er en kraftfuld teknik, der kan aktivere LLM-deployment pÃĨ ressource-begrÃĶnsede miljÃļer som skyen, edge-enheder eller endda mobiltelefoner ved at drastisk reducere hukommelsesaftrykket.
Estimering af hukommelse til finjustering
Selvom kvantificering primÃĶrt bruges til effektiv inference, er teknikker som tensor-parallellisme og model-parallellisme afgÃļrende for at hÃĨndtere hukommelseskrav under trÃĶning eller finjustering af store sprogmodeller.
Peak-hukommelsesforbrug under finjustering er typisk 3-4 gange hÃļjere end under inference pÃĨ grund af ekstra hukommelseskrav til:
- Gradients
- Optimizer-tilstande
- Aktiveringer fra forward-passen gemt til backpropagation
En konservativ estimation er, at finjustering af en LLM med X milliarder parametre krÃĶver omtrent 4 * (2X) = 8X GB VRAM i bfloat16-prÃĶcision.
For eksempel ville finjustering af 7B parameter LLaMA-modellen krÃĶve omtrent 7 * 8 = 56GB VRAM per GPU i bfloat16-prÃĶcision. Dette overstiger hukommelseskapaciteten af nuvÃĶrende GPUâer, hvilket nÃļdvendiggÃļr distribueret finjusteringsteknikker.
Distribuerede finjusteringsteknikker
Forskere har foreslÃĨet flere distribuerede finjusteringmetoder for at overvinde GPU-hukommelsesbegrÃĶnsninger for store modeller:
- Data-parallellisme: Den klassiske data-parallellisme-tilgang replikerer hele modellen pÃĨ tvÃĶrs af flere GPUâer, mens trÃĶningsdata-batchene deles og distribueres. Dette reducerer trÃĶningstiden lineÃĶrt med antallet af GPUâer, men reducerer ikke peak-hukommelseskravet pÃĨ hver GPU.
- ZeRO Stage 3: En avanceret form for data-parallellisme, der partitionerer modelparametre, grader og optimizer-tilstande pÃĨ tvÃĶrs af GPUâer. Det reducerer hukommelse sammenlignet med klassisk data-parallellisme ved at holde kun den nÃļdvendige partitionerede data pÃĨ hver GPU under forskellige faser af trÃĶning.
- Tensor-parallellisme: I stedet for at replikere modellen, partitionerer tensor-parallellisme modelparametre i rÃĶkker eller kolonner og distribuerer dem pÃĨ tvÃĶrs af GPUâer. Hver GPU opererer pÃĨ en partitioneret samling af parametre, grader og optimizer-tilstande, hvilket fÃļrer til betydelige hukommelsesbesparelser.
- RÃļrlednings-parallellisme: Denne teknik partitionerer model-lag pÃĨ tvÃĶrs af forskellige GPUâer/arbejdere, hvor hver enhed udfÃļrer en undermÃĶngde af lagene. Aktiveringer overfÃļres mellem arbejdere, hvilket reducerer peak-hukommelse, men Ãļger kommunikations-overhead.
At estimere hukommelsesforbrug for disse distribuerede metoder er ikke-trivialt, da distributionen af parametre, grader, aktiveringer og optimizer-tilstande varierer pÃĨ tvÃĶrs af teknikker. Desuden kan forskellige komponenter som transformer-kroppen og sprogmodel-hovedet vise forskellige hukommelses-allokering-adfÃĶrd.
LLMem-lÃļsningen
Forskere har foreslÃĨet LLMem, en lÃļsning, der nÃļjagtigt estimerer GPU-hukommelsesforbrug, nÃĨr distribuerede finjusteringsteknikker anvendes pÃĨ store sprogmodeller pÃĨ tvÃĶrs af flere GPUâer.
LLMem tager hensyn til faktorer som gensammensÃĶtning af parametre fÃļr beregning (ZeRO Stage 3), output-samling i backward-passet (tensor-parallellisme) og forskellige hukommelses-allokering-strategier for transformer-kroppen og sprogmodel-hovedet.
Eksperimentelle resultater viser, at LLMem kan estimere peak-GPU-hukommelsesforbrug for finjustering af LLMâer pÃĨ en enkelt GPU med fejl-rater pÃĨ op til 1,6%, hvilket overgÃĨr den gennemsnitlige fejl-rate pÃĨ 42,6% for den hidtidige DNNMem. NÃĨr distribuerede finjusteringsteknikker anvendes pÃĨ LLMâer med over en milliard parametre pÃĨ flere GPUâer, opnÃĨr LLMem en imponerende gennemsnitlig fejl-rate pÃĨ 3,0%.













