Forbedre ydeevnen af ​​Falcon-modeller med Amazon SageMaker | Amazon Web Services

Forbedre ydeevnen af ​​Falcon-modeller med Amazon SageMaker | Amazon Web Services

Hvad er den optimale ramme og konfiguration til hosting af store sprogmodeller (LLM'er) til tekstgenererende generative AI-applikationer? På trods af de mange muligheder for at betjene LLM'er, er dette et svært spørgsmål at besvare på grund af størrelsen af ​​modellerne, varierende modelarkitekturer, ydeevnekrav til applikationer og mere. Det Amazon SageMaker Large Model Inference (LMI) container gør det ligetil at betjene LLM'er ved at samle en lang række forskellige rammer og teknikker, der optimerer implementeringen af ​​LLM'er. LMI-beholderen har en kraftfuld serveringsstack kaldet DJL servering det er agnostisk over for den underliggende LLM. Det giver konfigurationsparametre på systemniveau, der kan indstilles til at udtrække den bedste ydeevne af hostinginfrastrukturen for en given LLM. Det har også understøttelse af nyere optimeringer som kontinuerlig batching, også kendt som iterativ batching eller rullende batching, som giver betydelige forbedringer i gennemløbet.

I et tidligere indlæg, viste vi, hvordan du kan bruge LMI-beholderen til at implementere Falcon-familien af ​​modeller på SageMaker. I dette indlæg demonstrerer vi, hvordan man forbedrer gennemløbet og latensen ved at betjene Falcon-40B med teknikker som kontinuerlig batching. Vi giver også en intuitiv forståelse af konfigurationsparametre leveret af SageMaker LMI-beholderen, som kan hjælpe dig med at finde den bedste konfiguration til din virkelige applikation.

Grundlæggende om tekstgenerativ slutning for LLM'er

Lad os først se på nogle få grundlæggende principper om, hvordan man udfører slutninger for LLM'er til tekstgenerering.

Videresend pass, aktiveringer og KV-cachen

Givet en inputsekvens af tokens køres de i en forward pass på tværs af alle lagene i LLM (som Falcon) for at generere det næste token. EN forward pass refererer til processen med inputdata, der sendes gennem et neuralt netværk for at producere et output. I tilfælde af tekstgenerering involverer den fremadrettede passage at fodre et indledende frø eller kontekst ind i sprogmodellen og generere det næste tegn eller token i sekvensen. For at generere en tekstsekvens udføres processen ofte iterativt, hvilket betyder, at den gentages for hvert trin eller hver position i outputsekvensen. Ved hver iteration genererer modellen det næste tegn eller token, som bliver en del af den genererede tekst, og denne proces fortsætter, indtil den ønskede længde af tekst er genereret.

Tekstgenerering med sprogmodeller som Falcon eller GPT er autoregressive. Det betyder, at modellen genererer én token ad gangen, mens den konditionerer på de tidligere genererede tokens. Med andre ord, ved hver iteration tager modellen den tidligere genererede tekst som input og forudsiger det næste token baseret på den kontekst. Som nævnt i vLLM: Nem, hurtig og billig LLM-servering med PagedAttention, i denne autoregressive afkodningsproces producerer alle inputtokens til LLM deres opmærksomhedsnøgle- og værditensorer, og disse tensorer opbevares i GPU-hukommelsen for at generere næste tokens. Disse cachelagrede nøgle- og værditensorer omtales ofte som KV cache.

Forudfyld og afkode faser

I en autoregressiv afkodningsproces, som den der bruges i tekstgenerering med sprogmodeller såsom Falcon, er der typisk to hovedfaser: prefill fase og decode fase. Disse faser er afgørende for at skabe sammenhængende og kontekstuelt relevant tekst.

Forfyldningsfasen omfatter følgende:

  • Indledende kontekst – Forudfyldningsfasen begynder med en indledende kontekst eller starttekst leveret af brugeren. Denne indledende kontekst kan være en sætning, en sætning eller endda bare et enkelt ord. Det sætter udgangspunktet for tekstgenerering og giver kontekst for, hvad der kommer næste gang.
  • Model konditionering – Den angivne kontekst bruges til at betinge sprogmodellen. Modellen tager denne kontekst som input og genererer det næste token (ord eller tegn) i sekvensen baseret på dens forståelse af konteksten.
  • Token generation – Modellen genererer et token ad gangen og forudsiger, hvad der skal komme næste gang i teksten. Dette token føjes til konteksten, hvilket effektivt udvider den.
  • Iterativ proces – Processen med at generere tokens gentages iterativt. Ved hvert trin genererer modellen et token, mens den overvejer den opdaterede kontekst, som nu inkluderer de tokens, der er genereret i tidligere trin.

Forfyldningsfasen fortsætter, indtil en forudbestemt stopbetingelse er opfyldt. Denne betingelse kan være en maksimal længde for den genererede tekst, et specifikt token, der signalerer slutningen af ​​teksten, eller ethvert andet kriterium, der er angivet af brugeren eller applikationen.

Afkodningsfasen omfatter følgende:

  • Afslutning – Efter prefill-fasen har du en delvist genereret tekst, der kan være ufuldstændig eller afskåret på et tidspunkt. Afkodningsfasen er ansvarlig for at færdiggøre teksten for at gøre den sammenhængende og grammatisk korrekt.
  • Fortsættelse fra sidste token – I afkodningsfasen starter modellen fra det sidste token, der blev genereret under forfyldningsfasen. Den bruger dette token som den indledende kontekst og genererer det næste token for at fortsætte teksten.
  • Iterativ afslutning – Ligesom i prefill-fasen er processen med at generere tokens igen iterativ. Modellen genererer én token ad gangen, idet den er betinget af de foregående tokens i sekvensen.
  • Standsningstilstand – Afkodningsfasen har også en standsningstilstand, som kan være den samme som i prefill-fasen, såsom at nå en maksimal længde eller støde på et slut-på-tekst-token. Når denne betingelse er opfyldt, stopper genereringsprocessen.

Kombinationen af ​​forfyldnings- og afkodningsfaserne tillader autoregressive modeller at generere tekst, der bygger på en indledende kontekst og producerer sammenhængende, kontekstuelt relevante og kontekstuelt konsistente sekvenser af tekst.

Der henvises til Et distribueret serveringssystem til transformatorbaserede generative modeller for en detaljeret forklaring af processen.

Optimering af gennemløb ved hjælp af dynamisk batching

Indtil videre har vi kun talt om et enkelt input. I praksis forventer vi at håndtere flere anmodninger, der kommer tilfældigt ind fra applikationsklienterne til slutninger samtidigt eller på en forskudt måde. På traditionel vis kan grundlæggende batching bruges til at øge gennemløbet og udnyttelsen af ​​GPU'ens computerressourcer. Batching er effektivt at kombinere de numeriske repræsentationer af mere end én anmodning i en batch og udføre parallelle kørsler af de autoregressive fremadgående gennemløb. Denne intelligente batching udføres på serveringssiden. SageMaker LMI's DJLServing-server kan konfigureres til at samle flere anmodninger for at behandle dem parallelt ved at indstille følgende parametre i serveringsejendomme:

  • max_batch_delay = 100 – Den maksimale forsinkelse for batch-aggregering i millisekunder. Standardværdien er 100 millisekunder.
  • batch_size = 32 – Den dynamiske batchstørrelse. Standard er 1.

Dette viser dybest set, at DJLServing vil stille anmodninger i kø i 100 millisekunder ad gangen, eller hvis antallet af anmodninger, der er i kø, er op til den specificerede batch_size, vil batchen blive planlagt til at køre til backend for slutning. Dette er kendt som dynamic batching. Det er dynamisk, fordi batchstørrelsen kan ændre sig på tværs af batcher afhængigt af, hvor mange anmodninger, der blev tilføjet i den pågældende tidsperiode. Men fordi anmodninger kan have forskellige karakteristika (for eksempel kan nogle anmodninger have form 20 tokens af input og 500 tokens af output, mens andre kan være omvendt, med 500 tokens af input, men kun 20 for output), kan nogle anmodninger fuldføre behandlingen hurtigere end andre i samme batch. Dette kan resultere i underudnyttelse af GPU'en, mens man venter på, at alle anmodninger under flyvningen i batchen fuldfører sin afkodningsfase, selvom der er yderligere anmodninger, der venter på at blive behandlet i køen. Følgende diagram illustrerer denne proces.

Simpel Dynamic Batching Visual

Dynamic Batching Visual – læg mærke til de ledige vinduer i slutningen af ​​anmodning 2 og 3

Optimering af gennemløb ved hjælp af kontinuerlig batching

Med continuous batching, også kendt som iterative or rolling batching, udnytter vi forskellene mellem forfyldnings- og afkodningsstadierne. For at aktivere kontinuerlig batching giver DJServing følgende yderligere konfigurationer i henhold til serving.properties:

  • motor=MPI – Vi opfordrer dig til at bruge MPI-motoren til kontinuerlig batchning.
  • option.rolling_batch=auto eller lmi-dist – Vi anbefaler at bruge auto, fordi det automatisk vil vælge den mest passende rullende batch-algoritme sammen med andre optimeringer i fremtiden.
  • option.max_rolling_batch_size=32 – Dette begrænser antallet af samtidige anmodninger. Standard er 32.

Med kontinuerlig batching venter serveringsstakken (DJLServing) ikke på, at alle anmodninger under flyvningen i en batch fuldfører sit afkodningstrin. I stedet for, ved logiske pauser (ved slutningen af ​​en iteration i afkodningsfasen), trækker den yderligere anmodninger ind, der venter i køen, mens den aktuelle batch stadig behandles (deraf navnet rullende parti). Det foretager denne kontrol for afventende anmodninger i slutningen af ​​hver iteration af afkodningsstadiet. Husk, at vi for hver anmodning skal køre prefill-stadiet efterfulgt af det sekventielle afkodningstrin. Fordi vi kan behandle alle tokens fra den indledende prompt af en anmodning parallelt til dens forudfyldningsfase, hver gang en ny anmodning trækkes ind, sætter vi midlertidigt pause i afkodningsfasen for anmodninger under flyvningen af ​​batchen - vi gemmer midlertidigt dens KV-cache og aktiveringer i hukommelsen og kør forudfyldningsfasen for de nye anmodninger.

Størrelsen på denne cache kan konfigureres med følgende mulighed:

Når prefill er færdig, kombinerer vi de nye anmodninger og de gamle pausede anmodninger i en ny rullende batch, som kan fortsætte med deres afkodningsfase parallelt. Bemærk, at de gamle pausede anmodninger kan fortsætte deres afkodningsfase, hvor de slap, og de nye anmodninger starter fra deres første nye token.

Kontinuerlig eller iterativ visuel batching

Kontinuerlig eller iterativ batching Visuel – bemærk, at tomgangstider er erstattet med følg efter anmodninger

Du har måske allerede indset, at kontinuerlig batching er en næsten lignende tilgang, hvormed vi naturligt paralleliserer opgaver i vores daglige liv. Vi har beskeder, e-mails, telefonmeddelelser (potentielt nye anmodninger), der kommer ind på tilfældige tidspunkter (analogt med flere anmodninger, der kommer på en tilfældig forskudt måde for GPU'er). Alt dette sker, mens vi udfører vores opgaver under flyvningen – at skrive e-mails, kode, deltage i møder (analogt med de aktuelt behandlende opgaver i GPU'erne). Ved logiske pauser sætter vi vores opgaver under flyvningen på pause og tjekker vores meddelelser for at afgøre, om der er en handling påkrævet fra vores side, og hvis der er, føjer vi det til vores opgaver under flyvningen (real-life rullende batch), eller sætte det på en to-do liste (køen).

At sætte det hele sammen: Sådan tænker du på hukommelsesudnyttelse af GPU'er

Det anbefales at indlæse teste din model for at se, hvilken konfiguration der er den mest omkostningseffektive for din virksomhed. For at opbygge en forståelse, lad os visualisere GPU'ernes hukommelsesfodaftryk, når modellen indlæses, og efterhånden som successive anmodninger behandles i en rullende batch. For dette indlæg, lad os antage, at vi indlæser Falcon-40B-modellen på en af ​​G5-instanstyperne, der er installeret med NVIDIA A10G GPU'er, hver med 24 GB hukommelse. Bemærk, at en lignende forståelse gælder for instanstyperne p3, p4 og p5, som følger med V100, A100 og H100 GPU-serien.

Følgende er oversigten over at få en omtrentlig værdi af den samlede hukommelse, der kræves for at betjene Falcon-40B:

  • Modelstørrelse = Antal modelparametre (40 milliarder for Falcon-40B) x 4 bytes pr. parameter (for FP32) = 160 GB
  • Omtrentlig samlet hukommelse, der kræves for at indlæse Falcon-40B til slutning = Modelstørrelse (=160 GB) + KV Cache (Attention Cache) (=*20 GB) + Ekstra hukommelsesomkostninger fra ML Frameworks (ca. 2 GB)
Visuel hukommelse

Hukommelse Visuel – Forståelse af hukommelsesfodaftrykket for en indlæst Falcon-40B-model

For Falcon-40B, hvis vi komprimerer modellen ved at kvantisere modellen til bfloat16 (2 bytes) datatypen, bliver modelstørrelsen cirka 80 GB. Som du kan se, er dette stadig større end den hukommelse, der understøttes af en acceleratorenhed, så vi er nødt til at anvende en modelopdelingsteknik (sharding) med en speciel tensor parallelisme (TP) nærmer sig og skærer modellen på tværs af flere acceleratorenheder. Lad os antage, at vi har valgt g5.24xlarge, som har 4 A10G GPU-enheder. Hvis vi konfigurerer DJLServing (serving.properties) med følgende, kan vi forvente, at de 80 GB modelvægte vil blive fordelt ligeligt på tværs af alle 4 GPU'er:

Med tensor_parallel_degree sat til 4, er omkring 20 GB af den 24 GB GPU-hukommelse (ca. 84%) allerede brugt, selv før en enkelt anmodning er blevet behandlet. De resterende 16% af GPU'en vil blive brugt til KV-cachen til de indkommende anmodninger. Det er muligt, at 2-3 GB af den resterende hukommelse er mere end nok til dit forretningsscenario og dets latens- og gennemløbskrav. Hvis ikke, kan du øge instansstørrelsen til g5.48xlarge, som har 8 GPU'er og bruger tensor_parallel_degree sat til 8. I et sådant tilfælde bliver kun cirka 10 GB af den tilgængelige 24 GB hukommelse i hver GPU brugt til modelvægte, og vi har omkring 60% af den resterende GPU til aktiveringerne og KV-cachen. Intuitivt kan vi se, at denne konfiguration kan tillade os at have en højere gennemstrømning. Derudover, fordi vi har en større buffer nu, kan vi øge max_rolling_batch_prefill_tokens , max_rolling_batch_size parametre for yderligere at optimere gennemløbet. Sammen vil disse to parametre styre præallokeringerne af aktiveringspræfill og KV-cache for modellen. Et større tal for disse to parametre vil sammen relatere til en større gennemløb, forudsat at du har nok buffer til KV-cachen i GPU-hukommelsen.

Kontinuerlig batchning med PagedAttention

PagedAttention er en ny optimeringsalgoritme udviklet af UC Berkeley, der forbedrer den kontinuerlige batchproces ved at tillade opmærksomhedscachen (KV-cachen) at være ikke-sammenhængende ved at allokere hukommelse i faste sider eller blokke. Dette er inspireret af virtuel hukommelse og personsøgningskoncepter, der bruges af operativsystemer.

Som pr vLLM papir, opdeles opmærksomhedscachen for hver sekvens af tokens i blokke og kortlægges til fysiske blokke gennem en bloktabel. Under beregningen af ​​opmærksomhed kan en PagedAttention-kerne bruge bloktabellen til effektivt at hente blokkene fra den fysiske hukommelse. Dette resulterer i en betydelig reduktion af hukommelsesspild og giver mulighed for større batchstørrelse, øget GPU-udnyttelse og højere gennemløb.

Præstationssammenligning

For at sikre effektiv belastningstest af din implementeringskonfiguration anbefales det at begynde med at overveje forretningsscenariet og klart definere egenskaberne for input og output for den LLM-baserede applikation. For eksempel, hvis du arbejder på et callcenter-opsummeringsbrug, kan input bestå af større tekst, såsom en 500-tokens chatudskrift mellem en kundeservicemedarbejder og en kunde, men outputtet kan være relativt mindre, omkring 100 tokens, der repræsenterer et resumé af transskriptionen. På den anden side, hvis du arbejder på et kodegenereringsscenario, kan inputtet være så kort som 15 tokens, som "skriv en effektiv implementering i Python til beskrivelse af alle EC2-ressourcer, inklusive paginering", men outputtet kan være meget større og når 500 tokens. Det er også vigtigt at overveje, om opnåelse af lavere latenstid eller maksimering af gennemløbet er topprioriteten for dit specifikke scenarie.

Efter at have opnået en omfattende forståelse af forretningsscenariet, kan du analysere og bestemme den optimale konfiguration til dit hostingmiljø. I denne sammenhæng omfatter hostingmiljøet forskellige nøgleelementer, herunder instanstypen og andre konfigurationsparametre som f.eks. tensor_parallel_grad, max_rolling_batch_size, max_rolling_batch_prefill_tokens, og mere. Vores mål er at identificere den mest effektive opsætning til at understøtte vores responstid, gennemløb og modeludgangskvalitetskrav.

I vores analyse benchmarkede vi ydeevnen for at illustrere fordelene ved kontinuerlig batching i forhold til traditionel dynamisk batching. Vi brugte de konfigurationer, der er beskrevet i følgende tabel i serving.properties til dynamisk batching og iterativ batching, ved hjælp af en LMI-beholder på SageMaker.

Dynamisk batching Kontinuerlig batching Kontinuerlig batching med PagedAttention

motor=Python

option.model_id=tiiuae/falcon-40b

option.tensor_parallel_degree=8

option.dtype=fp16

batch_size=4

max_batch_delay=100

option.trust_remote_code = sand

motor = MPI

option.model_id = {{s3_url}}

option.trust_remote_code = sand

option.tensor_parallel_degree = 8

option.max_rolling_batch_size = 32

option.rolling_batch = auto

option.dtype = fp16

option.max_rolling_batch_prefill_tokens = 1024

option.paged_attention = Falsk

motor = MPI

option.model_id = {{s3_url}}

option.trust_remote_code = sand

option.tensor_parallel_degree = 8

option.max_rolling_batch_size = 32

option.rolling_batch = auto

option.dtype = fp16

option.max_rolling_batch_prefill_tokens = 1024

option.paged_attention = Sandt

De to konfigurationer blev benchmarket for Falcon-40B med FP16-datatypen implementeret på ml.g5.48xlarge i et par forskellige scenarier, der repræsenterer applikationer fra den virkelige verden:

  • Et lille antal input-tokens med et stort antal tokens, der genereres – I dette scenarie blev antallet af input-tokens fastsat til 32 og 128 nye tokens blev genereret
Batching strategi Gennemløb (tokens/sek.) Latens p90 (sek.)
Dynamisk batching 5.53 58.34
Kontinuerlig batching 56.04 4.74
Kontinuerlig batching med PagedAttention 59.18 4.76
  • Et stort input med et lille antal tokens, der genereres – Her fastsætter vi antallet af input tokens til 256 og beder LLM om at opsummere inputtet til 32 tokens
Batching strategi Gennemløb (tokens/sek.) Latens p90 (sek.)
Dynamisk batching 19.96 59.31
Kontinuerlig batching 46.69 3.88
Kontinuerlig batching med PagedAttention 44.75 2.67

Vi kan se, at kontinuerlig batching med PagedAttention giver en kapacitetsforbedring på 10 gange større i scenarie 1 og 2.3 gange i scenarie 2 sammenlignet med at bruge dynamisk batching på SageMaker, mens man bruger LMI-beholderen.

Konklusion

I dette indlæg så vi på, hvordan LLM'er bruger hukommelse og forklarede, hvordan kontinuerlig batching forbedrer gennemløbet ved hjælp af en LMI-beholder på SageMaker. Vi demonstrerede fordelene ved kontinuerlig batching for Falcon-40B ved hjælp af en LMI-beholder på SageMaker ved at vise benchmark-resultater. Du kan finde koden på GitHub repo.


Om forfatterne

Abhigyan ShivadityaAbhi Shivaditya er en Senior Solutions Architect hos AWS, der arbejder med strategiske globale virksomhedsorganisationer for at lette overtagelsen af ​​AWS-tjenester inden for områder som kunstig intelligens, distribueret computing, netværk og storage. Hans ekspertise ligger i Deep Learning inden for områderne Natural Language Processing (NLP) og Computer Vision. Abhi hjælper kunder med at implementere højtydende maskinlæringsmodeller effektivt i AWS-økosystemet.

Improve performance of Falcon models with Amazon SageMaker | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.Dhawal Patel er Principal Machine Learning Architect hos AWS. Han har arbejdet med organisationer lige fra store virksomheder til mellemstore startups om problemer relateret til distribueret computing og kunstig intelligens. Han fokuserer på Deep learning, herunder NLP og Computer Vision domæner. Han hjælper kunder med at opnå højtydende modelslutning på SageMaker.

Improve performance of Falcon models with Amazon SageMaker | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.Pinak Panigrahi arbejder sammen med kunder om at bygge maskinlæringsdrevne løsninger til at løse strategiske forretningsproblemer på AWS. Når han ikke er beskæftiget med maskinlæring, kan han blive fundet på at tage en vandretur, læse en bog eller se sport.

Improve performance of Falcon models with Amazon SageMaker | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.Abhi Sodhani besidder stillingen som Senior AI/ML Solutions Architect hos AWS, hvor han har specialiseret sig i at tilbyde teknisk ekspertise og vejledning om Generative AI- og ML-løsninger til kunder. Hans primære fokus er at hjælpe Digital Native Businesses med at realisere det fulde potentiale af Generative AI- og ML-teknologier, hvilket gør dem i stand til at nå deres forretningsmål effektivt. Ud over sine professionelle bestræbelser udviser Abhi en stærk passion for intellektuelle sysler såsom læsning, såvel som at deltage i aktiviteter, der fremmer fysisk og mentalt velvære, såsom yoga, meditation.

Improve performance of Falcon models with Amazon SageMaker | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.Qing Lan er softwareudviklingsingeniør i AWS. Han har arbejdet på adskillige udfordrende produkter i Amazon, herunder højtydende ML-inferensløsninger og højtydende logningssystem. Qings team lancerede med succes den første Billion-parameter model i Amazon Advertising med meget lav forsinkelse påkrævet. Qing har indgående viden om infrastrukturoptimering og Deep Learning acceleration.

Tidsstempel:

Mere fra AWS maskinindlæring