Modele Či platforme AI
Optimizarea implementÄrii LLM: vLLM PagedAttention Či viitorul servirii eficiente a IA
Modelele de limbaj mari (LLM) care ruleazÄ aplicaČii din lumea realÄ prezintÄ provocÄri unice, ÃŪn special ÃŪn ceea ce priveČte resursele de calcul, latenČa Či eficienČa costurilor. Ãn acest ghid cuprinzÄtor, vom explora peisajul servirii LLM, cu un accent deosebit pe vLLM (model de limbaj vectorial), o soluČie care reconfigureazÄ modul ÃŪn care implementÄm Či interacČionÄm cu aceste modele puternice.
ProvocÄrile servirii Modelelor de Limbaj Mari
Ãnainte de a explora soluČii specifice, sÄ examinÄm principalele provocÄri care fac servirea LLM o sarcinÄ complexÄ:
Resurse de Calcul
LLM-urile sunt notorii pentru numÄrul lor enorm de parametri, care variazÄ de la miliarde la sute de miliarde. De exemplu, GPT-3 are 175 de miliarde de parametri, ÃŪn timp ce modelele mai recente, cum ar fi GPT-4, se estimeazÄ cÄ au Či mai mulČi. AceastÄ dimensiune uriaČÄ se traduce ÃŪn cerinČe semnificative de calcul pentru inferenČÄ.
Exemplu:
ConsideraČi un LLM relativ modest, cu 13 miliarde de parametri, cum ar fi LLaMA-13B. Chiar Či acest model necesitÄ:
â Aproximativ 26 GB de memorie doar pentru a stoca parametrii modelului (presupunÃĒnd precizie de 16 biČi)
â Memorare suplimentarÄ pentru activÄri, mecanisme de atenČie Či calcule intermediare
â Putere de calcul substanČialÄ pentru inferenČÄ ÃŪn timp real
LatenČÄ
Ãn multe aplicaČii, cum ar fi chatbot-urile sau generarea de conČinut ÃŪn timp real, latenČa scÄzutÄ este crucialÄ pentru o experienČÄ bunÄ a utilizatorului. Cu toate acestea, complexitatea LLM-urilor poate duce la timpi de procesare semnificativi, ÃŪn special pentru secvenČe mai lungi.
Exemplu:
ImaginaČi-vÄ un chatbot de asistenČÄ pentru clienČi alimentat de un LLM. DacÄ fiecare rÄspuns necesitÄ cÃĒteva secunde pentru a fi generat, conversaČia va pÄrea nefireascÄ Či frustrantÄ pentru utilizatori.
Cost
Hardware-ul necesar pentru a rula LLM-uri la scarÄ poate fi extrem de scump. GPU-urile de ÃŪnaltÄ performanČÄ sau TPU-urile sunt adesea necesare, iar consumul de energie al acestor sisteme este substanČial.
Exemplu:
Rularea unui cluster de GPU-uri NVIDIA A100 (adesea utilizate pentru inferenČa LLM) poate costa mii de dolari pe zi ÃŪn taxe de calcul cloud.
AbordÄri TradiČionale pentru Servirea LLM
Ãnainte de a explora soluČii mai avansate, sÄ trecem ÃŪn revistÄ unele abordÄri tradiČionale pentru servirea LLM-urilor:
Implementare SimplÄ cu Hugging Transformers
Biblioteca Hugging Face Transformers oferÄ o modalitate simplÄ de a implementa LLM-urile, dar nu este optimizatÄ pentru servire de ÃŪnaltÄ performanČÄ.
Exemplu de cod:
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
<p>nume_model = "meta-llama/Llama-2-13b-hf"
model = AutoModelForCausalLM.from_pretrained(nume_model, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(nume_model)</p>
<p>def genereazÄ_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)</p>
<p>print(genereazÄ_text("Viitorul inteligenČei artificiale este"))
DeČi aceastÄ abordare funcČioneazÄ, nu este potrivitÄ pentru aplicaČii cu trafic ridicat din cauza utilizÄrii ineficiente a resurselor Či a lipsei de optimizÄri pentru servire.
Folosirea TorchServe sau a unor cadre similare
Cadrele precum TorchServe oferÄ capacitÄČi de servire mai robuste, inclusiv echilibrare a ÃŪncÄrcÄrii Či gestionare a versiunilor modelului. Cu toate acestea, ele nu abordeazÄ ÃŪncÄ provocÄrile specifice ale servirii LLM, cum ar fi gestionarea eficientÄ a memoriei pentru modele mari.
ÃnČelegerea GestionÄrii Memoriei ÃŪn Servirea LLM
Gestionarea eficientÄ a memoriei este criticÄ pentru servirea modelelor de limbaj mari (LLM) din cauza resurselor de calcul extinse necesare. UrmÄtoarele imagini ilustreazÄ diverse aspecte ale gestionÄrii memoriei, care sunt integrale pentru optimizarea performanČei LLM.
Memorie SegmentatÄ vs. PaginatÄ
Aceste douÄ diagrame comparÄ tehnici de gestionare a memoriei segmentate Či paginate, utilizate ÃŪn mod obiČnuit ÃŪn sisteme de operare (OS).
- Memorie SegmentatÄ: AceastÄ tehnicÄ ÃŪmparte memoria ÃŪn segmente diferite, fiecare corespunzÃĒnd unui program sau proces diferit. De exemplu, ÃŪntr-un context de servire LLM, segmente diferite ar putea fi alocate pentru diverse componente ale modelului, cum ar fi tokenizare, ÃŪncorporare Či mecanisme de atenČie. Fiecare segment poate creČte sau scÄdea independent, oferind flexibilitate, dar potenČial conducÃĒnd la fragmentare dacÄ segmentele nu sunt gestionate corespunzÄtor.
- Memorie PaginatÄ: Aici, memoria este ÃŪmpÄrČitÄ ÃŪn pagini de dimensiune fixÄ, care sunt mapate pe memoria fizicÄ. Paginile pot fi schimbate ÃŪn Či ieČit ÃŪn funcČie de nevoi, permiČÃĒnd o utilizare eficientÄ a resurselor de memorie. Ãn servirea LLM, acest lucru poate fi crucial pentru gestionarea cantitÄČilor mari de memorie necesare pentru stocarea parametrilor modelului Či calculelor intermediare.
Gestionarea Memoriei ÃŪn OS vs. vLLM
AceastÄ imagine prezintÄ o comparaČie ÃŪntre gestionarea tradiČionalÄ a memoriei ÃŪn sisteme de operare Či abordarea de gestionare a memoriei utilizatÄ ÃŪn vLLM.
- Gestionarea Memoriei ÃŪn OS: Ãn sistemele de operare tradiČionale, procesele (de exemplu, Proces A Či Proces B) sunt alocate pagini de memorie (PaginÄ 0, PaginÄ 1, etc.) ÃŪn memoria fizicÄ. Alocarea aceasta poate duce la fragmentare ÃŪn timp, pe mÄsurÄ ce procesele solicitÄ Či elibereazÄ memorie.
- Gestionarea Memoriei vLLM: Cadru vLLM utilizeazÄ o cache KV (cheie-valoare) pentru a gestiona memoria mai eficient. SolicitÄrile (de exemplu, Solicitare A Či Solicitare B) sunt alocate blocuri ale cache-ului KV (Bloc KV 0, Bloc KV 1, etc.). AceastÄ abordare ajutÄ la minimizarea fragmentÄrii Či optimizeazÄ utilizarea memoriei, permiČÃĒnd o servire mai rapidÄ Či mai eficientÄ a modelului.
Mecanismul de AtenČie ÃŪn LLM
Mecanismul de atenČie este o componentÄ fundamentalÄ a modelelor de transformare, care sunt utilizate ÃŪn mod obiČnuit pentru LLM. AceastÄ diagramÄ ilustreazÄ formula de atenČie Či componentele sale:
- Cerere (Q): Un token nou ÃŪn pasul decodificÄrii sau ultimul token pe care modelul l-a vÄzut.
- Cheie (K): Contextul anterior la care modelul ar trebui sÄ se concentreze.
- Valoare (V): Suma ponderatÄ a contextului anterior.
Formula calculeazÄ scorurile de atenČie prin produsul punctului dintre cerere Či chei, scalat cu rÄdÄcina pÄtratÄ a dimensiunii cheii, aplicÃĒnd o funcČie softmax Či, ÃŪn final, prin produsul punctului cu valorile. Acest proces permite modelului sÄ se concentreze pe pÄrČi relevante ale secvenČei de intrare la generarea fiecÄrui token.
ComparaČie a Debitului de Servire
AceastÄ imagine prezintÄ o comparaČie a debitului de servire ÃŪntre diferite cadre (HF, TGI Či vLLM) utilizÃĒnd modele LLaMA pe diverse configuraČii de hardware.
- LLaMA-13B, A100-40GB: vLLM atinge un debit de 14x â 24x mai mare decÃĒt Hugging Face Transformers (HF) Či 2,2x â 2,5x mai mare decÃĒt Hugging Face Text Generation Inference (TGI).
- LLaMA-7B, A10G: Se observÄ tendinČe similare, cu vLLM depÄČindu-le pe ambele, HF Či TGI.
vLLM: O NouÄ ArhitecturÄ de Servire LLM
vLLM, dezvoltat de cercetÄtori de la UC Berkeley, reprezintÄ un salt semnificativ ÃŪnainte ÃŪn tehnologia de servire LLM. SÄ explorÄm caracteristicile sale cheie Či inovaČiile:
PagedAttention
Ãn inima vLLM se aflÄ PagedAttention, un algoritm de atenČie inovator inspirat de gestionarea memoriei virtuale ÃŪn sisteme de operare. IatÄ cum funcČioneazÄ:
â ÃmpÄrČirea Cache-ului KV: Ãn loc de a stoca ÃŪntregul cache KV ÃŪn mod contiguu ÃŪn memorie, PagedAttention ÃŪl ÃŪmparte ÃŪn blocuri de dimensiune fixÄ.
â Stocare NecontiguÄ: Aceste blocuri pot fi stocate ÃŪn mod necontiguu ÃŪn memorie, permiČÃĒnd o gestionare mai flexibilÄ a memoriei.
â Alocare la Cerere: Blocurile sunt alocate doar atunci cÃĒnd sunt necesare, reducÃĒnd risipa de memorie.
â Partajare EficientÄ: Mai multe secvenČe pot partaja blocuri, permiČÃĒnd optimizÄri pentru tehnici precum eÅantionarea paralelÄ Či cÄutarea cu fascicul.
IlustraČie:
â`
Cache KV Traditional:
[Token 1 KV][Token 2 KV][Token 3 KV]âĶ[Token N KV]
(Alocare contiguÄ de memorie)
â`
PagedAttention Cache KV:
[Block 1] -> AdresÄ FizicÄ A
[Block 2] -> AdresÄ FizicÄ C
[Block 3] -> AdresÄ FizicÄ B
âĶ
(Alocare necontiguÄ de memorie)
â`
AceastÄ abordare reduce semnificativ fragmentarea memoriei Či permite o utilizare mult mai eficientÄ a memoriei GPU.
Loturi Continue
vLLM implementeazÄ loturi continue, care proceseazÄ dinamic solicitÄrile pe mÄsurÄ ce acestea sosesc, ÃŪn loc de a aČtepta sÄ formeze loturi de dimensiune fixÄ. Acest lucru conduce la o latenČÄ mai scÄzutÄ Či un debit mai mare.
Exemplu:
ImaginaČi-vÄ un flux de solicitÄri care sosesc:
â`
Timp 0ms: Solicitare A soseČte
Timp 10ms: Ãncepe procesarea SolicitÄrii A
Timp 15ms: Solicitare B soseČte
Timp 20ms: Ãncepe procesarea SolicitÄrii B (ÃŪn paralel cu A)
Timp 25ms: Solicitare C soseČte
âĶ
â`
Cu loturi continue, vLLM poate ÃŪncepe procesarea fiecÄrei solicitÄri imediat, ÃŪn loc de a aČtepta sÄ le grupeze ÃŪn loturi predefinite.
EČantionare ParalelÄ EficientÄ
Pentru aplicaČii care necesitÄ mai multe exemple de ieČire pe prompt (de exemplu, asistenČi de scriere creativÄ), capacitÄČile de partajare a memoriei vLLM strÄlucesc. Poate genera mai multe ieČiri ÃŪn timp ce reutilizeazÄ cache-ul KV pentru prefixe comune.
Exemplu de cod utilizÃĒnd vLLM:
from vllm import LLM, SamplingParams
<p>llm = LLM(model="meta-llama/Llama-2-13b-hf")
prompturi = ["Viitorul inteligenČei artificiale este"]</p>
<p># GenereazÄ 3 exemple pe prompt
sampling_params = SamplingParams(n=3, temperatura=0.8, max_tokens=100)
ieČiri = llm.generate(prompturi, sampling_params)</p>
<p>pentru ieČire ÃŪn ieČiri:
print(f"Prompt: {ieČire.prompt}")
pentru i, iesire in enumerate(ieČire.ieČiri):
print(f"Exemplu {i + 1}: {iesire.text}")
Acest cod genereazÄ eficient mai multe exemple pentru promptul dat, valorificÃĒnd optimizÄrile vLLM.
Testarea PerformanČei vLLM
Pentru a aprecia cu adevÄrat impactul vLLM, sÄ examinÄm cÃĒteva comparaČii de performanČÄ:
ComparaČie a Debitului
Pe baza informaČiilor furnizate, vLLM depÄČeČte semnificativ alte soluČii de servire:
â PÃĒnÄ la 24x debit mai mare ÃŪn comparaČie cu Hugging Face Transformers
â 2,2x â 3,5x debit mai mare decÃĒt Hugging Face Text Generation Inference (TGI)
IlustraČie:
â`
Debit (Tokeni pe secundÄ)
|
| ****
| ****
| ****
| **** ****
| **** **** ****
| **** **** ****
|ââââââââ
HF TGI vLLM
â`
EficienČÄ a Memoriei
PagedAttention din vLLM conduce la o utilizare aproape optimÄ a memoriei:
â Doar aproximativ 4% pierdere de memorie, comparativ cu 60-80% ÃŪn sistemele tradiČionale
â AceastÄ eficienČÄ permite servirea unor modele mai mari sau gestionarea unui numÄr mai mare de solicitÄri concurente cu acelaČi hardware
Ãnceperea cu vLLM
Acum cÄ am explorat beneficiile vLLM, sÄ trecem la procesul de configurare Či utilizare a acestuia ÃŪn proiectele dvs.
6.1 Instalare
Instalarea vLLM este simplÄ utilizÃĒnd pip:
!pip install vllm
6.2 Utilizare de BazÄ pentru InferenČÄ Offline
IatÄ un exemplu simplu de utilizare a vLLM pentru generarea de text offline:
from vllm import LLM, SamplingParams
<p># IniČializaČi modelul
llm = LLM(model="meta-llama/Llama-2-13b-hf")</p>
<p># PregÄtiČi prompturile
prompturi = [
"ScrieČi un scurt poem despre inteligenČa artificialÄ:",
"ExplicaČi calculul cuantic ÃŪn termeni simpli:"
]</p>
<p># SetÄri parametri de eÅantionare
sampling_params = SamplingParams(temperatura=0.8, max_tokens=100)</p>
<p># GenereazÄ rÄspunsuri
ieČiri = llm.generate(prompturi, sampling_params)</p>
<p># PrintaČi rezultatele
pentru ieČire ÃŪn ieČiri:
print(f"Prompt: {ieČire.prompt}")
print(f"Text generat: {ieČire.ieČiri[0].text}\n")
Acest script demonstreazÄ cum sÄ ÃŪncÄrcaČi un model, sÄ setaČi parametri de eÅantionare Či sÄ generaČi text pentru mai multe prompturi.
6.3 Configurarea unui Server vLLM
Pentru servirea online, vLLM oferÄ un server API compatibil cu OpenAI. IatÄ cum sÄ ÃŪl configuraČi:
1. PorniČi serverul:
python -m vllm.entrypoints.openai.api_server --model meta-llama/Llama-2-13b-hf
2. InterogaČi serverul utilizÃĒnd curl:
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{"model": "meta-llama/Llama-2-13b-hf", "prompt": "Beneficiile inteligenČei artificiale includ:", "max_tokens": 100, "temperatura": 0.7}'
AceastÄ configurare vÄ permite sÄ serviČi LLM cu o interfaČÄ compatibilÄ cu API-ul OpenAI, facilitÃĒnd integrarea ÃŪn aplicaČii existente.
Subiecte Avansate despre vLLM
DeČi vLLM oferÄ ÃŪmbunÄtÄČiri semnificative ÃŪn servirea LLM, existÄ consideraČii Či subiecte avansate de explorat:
7.1 Cuantificarea Modelului
Pentru o servire Či mai eficientÄ, ÃŪn special pe hardware cu memorie limitatÄ, pot fi utilizate tehnici de cuantificare. DeČi vLLM ÃŪnsuČi nu suportÄ ÃŪn prezent cuantificarea, poate fi utilizat ÃŪn conjuncČie cu modele cuantificate:
from transformers import AutoModelForCausalLM, AutoTokenizer import torch <p># ÃncÄrcaČi un model cuantificat nume_model = "meta-llama/Llama-2-13b-hf" model = AutoModelForCausalLM.from_pretrained(nume_model, device_map="auto", load_in_8bit=True) tokenizer = AutoTokenizer.from_pretrained(nume_model)</p> <p># UtilizaČi modelul cuantificat cu vLLM from vllm import LLM</p> <p>llm = LLM(model=model, tokenizer=tokenizer)
7.2 InferenČÄ DistribuitÄ
Pentru modele extrem de mari sau aplicaČii cu trafic ridicat, inferenČa distribuitÄ pe mai multe GPU-uri sau maČini poate fi necesarÄ. DeČi vLLM nu suportÄ ÃŪn mod nativ acest lucru, poate fi integrat ÃŪn sisteme distribuite utilizÃĒnd cadre precum Ray:
import ray
from vllm import LLM
<p>@ray.remote(num_gpus=1)
class DistributedLLM:
def __init__(self, nume_model):
self.llm = LLM(model=nume_model)</p>
<p>def genereazÄ(self, prompt, parametri):
return self.llm.generate(prompt, parametri)</p>
<p># IniČializaČi LLM-uri distribuite
llm1 = DistributedLLM.remote("meta-llama/Llama-2-13b-hf")
llm2 = DistributedLLM.remote("meta-llama/Llama-2-13b-hf")</p>
<p># UtilizaČi-le ÃŪn paralel
rezultat1 = llm1.generate.remote("Prompt 1", parametri_de_eČantionare)
rezultat2 = llm2.generate.remote("Prompt 2", parametri_de_eČantionare)</p>
<p># ObČineČi rezultatele
print(ray.get([rezultat1, rezultat2]))
7.3 Monitorizare Či Observabilitate
Atunci cÃĒnd serviČi LLM ÃŪn producČie, monitorizarea este crucialÄ. DeČi vLLM nu oferÄ monitorizare ÃŪncorporatÄ, poate fi integrat cu unelte precum Prometheus Či Grafana:
from prometheus_client import start_http_server, Summary
from vllm import LLM
<p># DefiniČi metrici
TIMP_DE_PROCESARE = Summary('timp_de_procesare_secunde', 'Timp petrecut procesÃĒnd solicitarea')</p>
<p># IniČializaČi vLLM
llm = LLM(model="meta-llama/Llama-2-13b-hf")</p>
<p># ExpuneČi metrici
start_http_server(8000)</p>
<p>@TIMP_DE_PROCESARE.time()
def proceseazÄ_solicitare(prompt):
return llm.generate(prompt)</p>
# Ciclul dvs. de servire aici
AceastÄ configurare vÄ permite sÄ urmÄriČi metrici precum timpul de procesare a solicitÄrilor, care pot fi visualizate ÃŪn dashboarde Grafana.
Concluzie
Servirea eficientÄ a Modelelor de Limbaj Mari este o sarcinÄ complexÄ, dar crucialÄ, ÃŪn era inteligenČei artificiale. vLLM, cu algoritmul sÄu inovator PagedAttention Či implementarea optimizatÄ, reprezintÄ un pas semnificativ ÃŪnainte ÃŪn direcČia facilitÄrii implementÄrii Či cost-eficienČei LLM.
Prin ÃŪmbunÄtÄČirea dramaticÄ a debitului, reducerea pierderilor de memorie Či oferirea unor opČiuni de servire mai flexibile, vLLM deschide noi posibilitÄČi pentru integrarea modelelor de limbaj puternice ÃŪntr-o gamÄ largÄ de aplicaČii. Indiferent dacÄ construiČi un chatbot, un sistem de generare de conČinut sau orice altÄ aplicaČie alimentatÄ de NLP, ÃŪnČelegerea Či valorificarea unor unelte precum vLLM va fi cheia succesului.
















