Connect with us

Artificiell intelligens

Optimering av LLM-distribution: vLLM PagedAttention och framtiden för effektiv AI-service

mm
Deploy the vLLM Inference Engine to Run Large Language Models

Stora språkmodeller (LLM) som distribueras i realvärldens applikationer presenterar unika utmaningar, särskilt i termer av beräkningsresurser, latency och kostnadseffektivitet. I den här omfattande guiden kommer vi att utforska landskapet för LLM-service, med särskild fokus på vLLM (vektor språkmodell), en lösning som omformar hur vi distribuerar och interagerar med dessa kraftfulla modeller.

Utmaningarna med att serva stora språkmodeller

Innan vi dyker in i specifika lösningar, låt oss undersöka de viktigaste utmaningarna som gör LLM-service till en komplex uppgift:

Beräkningsresurser

LLM är ökända för sina enorma parameterantal, som sträcker sig från miljarder till hundratals miljarder. Till exempel har GPT-3 175 miljarder parametrar, medan mer nyliga modeller som GPT-4 beräknas ha ännu fler. Denna enorma storlek översätts till betydande beräkningskrav för inferens.

Exempel:
Tänk på en relativt blygsam LLM med 13 miljarder parametrar, som LLaMA-13B. Även denna modell kräver:

– Cirka 26 GB minne bara för att lagra modellparametrarna (antagande 16-bitars precision)
– Ytterligare minne för aktiveringar, uppmärksamhetsmekanismer och intermediärberäkningar
– Avsevärd GPU-beräkningskraft för realtidsinferens

Latens

I många applikationer, som chatbots eller realtidsinnehållsgenerering, är låg latens avgörande för en bra användarupplevelse. Men komplexiteten i LLM kan leda till betydande bearbetningstider, särskilt för längre sekvenser.

Exempel:
Tänk dig en kundtjänstchatbot som drivs av en LLM. Om varje svar tar flera sekunder att generera, kommer samtalet att kännas onaturligt och frustrerande för användarna.

Kostnad

Hårdvaran som krävs för att köra LLM på stor skala kan vara extremt dyrt. Högkvalitativa GPU:er eller TPU:er är ofta nödvändiga, och energiförbrukningen av dessa system är betydande.

Exempel:
Att köra en kluster av NVIDIA A100 GPU:er (ofta används för LLM-inferens) kan kosta tusentals dollar per dag i molntjänster.

Traditionella metoder för LLM-service

Innan vi utforskar mer avancerade lösningar, låt oss kortfattat granska några traditionella metoder för att serva LLM:

Enkel distribution med Hugging Face Transformers

Hugging Face Transformers-biblioteket erbjuder ett enkelt sätt att distribuera LLM, men det är inte optimerat för högpresterande service.

Exempelkod:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

model_name = "meta-llama/Llama-2-13b-hf"
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)

def generate_text(prompt, max_length=100):
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_length=max_length)
return tokenizer.decode(outputs[0], skip_special_tokens=True)

print(generate_text("The future of AI is"))

Medan denna metod fungerar, är den inte lämplig för högtrafikapplikationer på grund av dess ineffektiva användning av resurser och brist på optimeringar för service.

Användning av TorchServe eller liknande ramverk

Ramverk som TorchServe erbjuder mer robusta serviefunktioner, inklusive lastbalansering och modellversionering. Men de adresserar fortfarande inte de specifika utmaningarna med LLM-service, som effektiv minneshantering för stora modeller.

Förstå minneshantering i LLM-service

Effektiv minneshantering är avgörande för att serva stora språkmodeller (LLM) på grund av de omfattande beräkningsresurser som krävs. Följande bilder illustrerar olika aspekter av minneshantering, som är integrerade i optimering av LLM-prestanda.

Segmenterad vs. sidminne

Dessa två diagram jämför segmenterad minne och sidminne-hanteringsmetoder, som vanligtvis används i operativsystem (OS).

  • Segmenterad minne: Denna teknik delar minnet i olika segment, var och en motsvarar ett annat program eller process. I en LLM-servicekontext kan olika segment tilldelas olika komponenter i modellen, som tokenisering, inbäddning och uppmärksamhetsmekanismer. Varje segment kan växa eller minska oberoende, vilket ger flexibilitet men potentiellt leder till fragmentering om segmenten inte hanteras korrekt.
  • Sidminne: Här delas minnet i fasta sidstorlekar, som mappas till fysiskt minne. Sidor kan bytas in och ut som behövs, vilket möjliggör en effektiv användning av minnesresurser. I LLM-service kan detta vara avgörande för att hantera de stora mängder minne som krävs för att lagra modellvikter och intermediärberäkningar.

Minneshantering i OS vs. vLLM

Denna bild kontrasterar traditionell OS-minneshantering med minneshanteringsmetoden som används i vLLM.

  • OS-minneshantering: I traditionella operativsystem tilldelas processer (t.ex. Process A och Process B) sidor av minne (Sida 0, Sida 1, etc.) i fysiskt minne. Denna tilldelning kan leda till fragmentering över tiden när processer begär och släpper minne.
  • vLLM-minneshantering: vLLM-ramverket använder en Key-Value (KV)-cacheminneshantering för att hantera minnet mer effektivt. Begäranden (t.ex. Begäran A och Begäran B) tilldelas block av KV-cachen (KV-block 0, KV-block 1, etc.). Denna metod hjälper till att minimera fragmentering och optimerar minnesanvändning, vilket möjliggör snabbare och mer effektiv modellservice.

Uppmärksamhetsmekanism i LLM

Uppmärksamhetsmekanism i LLM

Uppmärksamhetsmekanism i LLM

Uppmärksamhetsmekanismen är en grundläggande komponent i transformermodeller, som vanligtvis används för LLM. Denna bild illustrerar uppmärksamhetsformeln och dess komponenter:

  • Förfrågan (Q): En ny token i dekodarsteget eller den sista token som modellen har sett.
  • Nyckel (K): Tidigare kontext som modellen ska uppmärksamma.
  • Värde (V): Vägt summa över tidigare kontext.

Formeln beräknar uppmärksamhetsscoren genom att ta dotprodukten av förfrågan med nycklarna, skalera med kvadratrotten av nyckelstorleken, applicera en softmax-funktion och slutligen ta dotprodukten med värdena. Denna process tillåter modellen att fokusera på relevanta delar av inmatningssekvensen när den genererar varje token.

Servicegenomströmning jämförelse

vLLM: Enkel, snabb och billig LLM-service med PagedAttention

vLLM: Enkel, snabb och billig LLM-service med PagedAttention

Denna bild presenterar en jämförelse av servicegenomströmning mellan olika ramverk (HF, TGI och vLLM) som använder LLaMA-modeller på olika hårdvarukonfigurationer.

  • LLaMA-13B, A100-40GB: vLLM uppnår 14 gånger – 24 gånger högre genomströmning än Hugging Face Transformers (HF) och 2,2 gånger – 2,5 gånger högre genomströmning än Hugging Face Text Generation Inference (TGI).
  • LLaMA-7B, A10G: Liknande trender observeras, med vLLM som signifikant överträffar både HF och TGI.

vLLM: En ny LLM-servicearkitektur

vLLM, utvecklad av forskare vid UC Berkeley, representerar ett betydande steg framåt i LLM-service-teknik. Låt oss utforska dess nyckelfunktioner och innovationer:

PagedAttention

I hjärtat av vLLM ligger PagedAttention, en ny uppmärksamhetsalgoritm inspirerad av virtuell minneshantering i operativsystem. Här är hur det fungerar:

Nyckel-Värde (KV)-cachdelning: Istället för att lagra hela KV-cachen kontinuerligt i minne, delar PagedAttention den i fasta block.
Icke-kontinuerlig lagring: Dessa block kan lagras icke-kontinuerligt i minne, vilket möjliggör mer flexibel minneshantering.
Allokeringsbegäran: Block allokeras endast när de behövs, vilket minskar minnesavfall.
Effektiv delning: Flera sekvenser kan dela block, vilket möjliggör optimeringar för tekniker som parallell sampling och strålsökning.

Illustration:

“`
Traditionell KV-cache:
[Token 1 KV][Token 2 KV][Token 3 KV]…[Token N KV]
(Kontinuerlig minnesallokering)

PagedAttention KV-cache:
[Block 1] -> Fysisk adress A
[Block 2] -> Fysisk adress C
[Block 3] -> Fysisk adress B

(Icke-kontinuerlig minnesallokering)
“`

Denna metod minskar signifikant minnesfragmentering och möjliggör en mycket mer effektiv användning av GPU-minne.

Kontinuerlig batchning

vLLM implementerar kontinuerlig batchning, som dynamiskt bearbetar begäranden när de anländer, snarare än att vänta på att bilda fasta batchstorlekar. Detta leder till lägre latens och högre genomströmning.

Exempel:
Tänk dig en ström av inkommande begäranden:

“`
Tid 0ms: Begäran A anländer
Tid 10ms: Starta bearbetning av Begäran A
Tid 15ms: Begäran B anländer
Tid 20ms: Starta bearbetning av Begäran B (i parallell med A)
Tid 25ms: Begäran C anländer

“`

Med kontinuerlig batchning kan vLLM starta bearbetning av varje begäran omedelbart, snarare än att vänta på att gruppera dem i fördefinierade batchar.

Effektiv parallell sampling

För applikationer som kräver flera utdataexempel per prompt (t.ex. kreativa skrivhjälpare), lyser vLLM:s minneshanteringsegenskaper. Det kan generera flera utdata samtidigt som det återanvänder KV-cachen för delade prefix.

Exempelkod med vLLM:


from vllm import LLM, SamplingParams

llm = LLM(model="meta-llama/Llama-2-13b-hf")
prompts = ["The future of AI is"]

# Generera 3 exempel per prompt
sampling_params = SamplingParams(n=3, temperature=0.8, max_tokens=100)
outputs = llm.generate(prompts, sampling_params)

for output in outputs:
print(f"Prompt: {output.prompt}")
for i, out in enumerate(output.outputs):
print(f"Exempel {i + 1}: {out.text}")

Denna kod genererar effektivt flera exempel för den angivna prompten, med vLLM:s optimeringar.

Prestandajämförelse av vLLM

För att verkligen uppskatta vLLM:s påverkan, låt oss titta på några prestandajämförelser:

Genomströmningjämförelse

Baserat på den tillgängliga informationen överträffar vLLM signifikant andra servelösningar:

– Upp till 24 gånger högre genomströmning jämfört med Hugging Face Transformers
– 2,2 gånger – 3,5 gånger högre genomströmning än Hugging Face Text Generation Inference (TGI)

Illustration:

“`
Genomströmning (Token/sekund)
|
| ****
| ****
| ****
| **** ****
| **** **** ****
| **** **** ****
|————————
HF TGI vLLM
“`

Minneseffektivitet

vLLM:s PagedAttention resulterar i nästan optimal minnesanvändning:

– Endast cirka 4% minnesavfall, jämfört med 60-80% i traditionella system
– Denna effektivitet möjliggör service av större modeller eller hantering av fler samtidiga begäranden med samma hårdvara

Komma igång med vLLM

Nu när vi har utforskat vLLM:s fördelar, låt oss gå igenom processen för att ställa in och använda det i dina projekt.

6.1 Installation

Att installera vLLM är enkelt med pip:


!pip install vllm

6.2 Grundläggande användning för offline-inferens

Här är ett enkelt exempel på att använda vLLM för offline-textgenerering:

from vllm import LLM, SamplingParams

# Initiera modellen
llm = LLM(model="meta-llama/Llama-2-13b-hf")

# Förbered prompts
prompts = [
"Skriv en kort dikt om artificiell intelligens:",
" Förklara kvantberäkning på ett enkelt sätt:"
]

# Ställ in samplingparametrar
sampling_params = SamplingParams(temperature=0.8, max_tokens=100)

# Generera svar
outputs = llm.generate(prompts, sampling_params)

# Skriv ut resultaten
for output in outputs:
print(f"Prompt: {output.prompt}")
print(f"Genererad text: {output.outputs[0].text}\n")

Denna skript demonstrerar hur du kan ladda en modell, ställa in samplingparametrar och generera text för flera prompts.

6.3 Konfigurera en vLLM-server

För online-service tillhandahåller vLLM en OpenAI-kompatibel API-server. Här är hur du ställer in den:

1. Starta servern:

python -m vllm.entrypoints.openai.api_server --model meta-llama/Llama-2-13b-hf

2. Fråga servern med curl:

curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{"model": "meta-llama/Llama-2-13b-hf", "prompt": "The benefits of artificial intelligence include:", "max_tokens": 100, "temperature": 0.7}'

Denna konfiguration möjliggör service av din LLM med ett gränssnitt som är kompatibelt med OpenAI:s API, vilket gör det enkelt att integrera i befintliga applikationer.

Avancerade ämnen om vLLM

Medan vLLM erbjuder signifikanta förbättringar i LLM-service, finns det ytterligare överväganden och avancerade ämnen att utforska:

7.1 Modellkvantifiering

För ännu mer effektiv service, särskilt på hårdvara med begränsat minne, kan kvantifieringstekniker användas. Medan vLLM inte stöder kvantifiering, kan det användas i kombination med kvantifierade modeller:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# Ladda en kvantifierad modell
model_name = "meta-llama/Llama-2-13b-hf"
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", load_in_8bit=True)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# Använd den kvantifierade modellen med vLLM
from vllm import LLM

llm = LLM(model=model, tokenizer=tokenizer)

7.2 Distribuerad inferens

För extremt stora modeller eller högtrafikapplikationer kan distribuerad inferens över flera GPU:er eller maskiner vara nödvändig. Medan vLLM inte stöder detta naturligt, kan det integreras i distribuerade system med ramverk som Ray:

import ray
from vllm import LLM

@ray.remote(num_gpus=1)
class DistributedLLM:
def __init__(self, model_name):
self.llm = LLM(model=model_name)

def generate(self, prompt, params):
return self.llm.generate(prompt, params)

# Initiera distribuerade LLM
llm1 = DistributedLLM.remote("meta-llama/Llama-2-13b-hf")
llm2 = DistributedLLM.remote("meta-llama/Llama-2-13b-hf")

# Använd dem i parallellt
result1 = llm1.generate.remote("Prompt 1", sampling_params)
result2 = llm2.generate.remote("Prompt 2", sampling_params)

# Hämta resultaten
print(ray.get([result1, result2]))

7.3 Övervakning och observerbarhet

När du servar LLM i produktion är övervakning avgörande. Medan vLLM inte tillhandahåller inbyggd övervakning, kan du integrera det med verktyg som Prometheus och Grafana:

from prometheus_client import start_http_server, Summary
from vllm import LLM

# Definiera mått
REQUEST_TIME = Summary('request_processing_seconds', 'Tid som spenderats på att bearbeta begäran')

# Initiera vLLM
llm = LLM(model="meta-llama/Llama-2-13b-hf")

# Exponera mått
start_http_server(8000)

# Använd modellen med övervakning
@REQUEST_TIME.time()
def process_request(prompt):
return llm.generate(prompt)

# Din serveloop här

Denna konfiguration möjliggör spårning av mått som begäranbearbetningstid, som kan visualiseras i Grafana- instrumentpaneler.

Slutsats

Att serva stora språkmodeller effektivt är en komplex men avgörande uppgift i AI-eran. vLLM, med sin innovativa PagedAttention-algoritm och optimerad implementering, representerar ett betydande steg framåt i att göra LLM-distribution mer tillgänglig och kostnadseffektiv.

Genom att dramatiskt förbättra genomströmning, minska minnesavfall och möjliggöra mer flexibla servelösningar, öppnar vLLM upp nya möjligheter för att integrera kraftfulla språkmodeller i en mängd olika applikationer. Oavsett om du bygger en chatbot, en innehållsgenereringsystem eller någon annan NLP-baserad applikation, kommer förståelse och användning av verktyg som vLLM att vara avgörande för framgång.

Jag har under de senaste fem åren dykt ner i den fascinerande världen av Machine Learning och Deep Learning. Min passion och expertis har lett mig till att bidra till över 50 olika mjukvaruutvecklingsprojekt, med särskild fokus på AI/ML. Min pågående nyfikenhet har också dragit mig mot Natural Language Processing, ett område som jag är angelägen om att utforska vidare.