Grunnleggende AI
Din KV-cache har ikke et bit-problem. Den har et geometri-problem.

Ved identisk 2-bit presisjon, kan en beslutning om hvilken akse du kvantiserer langs, svinge en benchmark-score fra 2,88 til 63,53. Nøkler og verdier trenger motsatt behandling — og grunnen ligger i oppmerksomhetsligningen, ikke i maskinvaren.
Ta Llama-2-13B. Gruppér nøkkel-verdi-cachen etter en kvantisering-gruppe-størrelse på 32 inn i to biter, mens alt annet forblir på plass — samme modell, samme bit-budsjett, samme gruppestørrelser, samme benchmark.
Avhengig av ett enkelt element i en implementeringsbeslutning, resulterer CoQA-nøyaktighet i enten 2,88 eller 63,53. Scorer med full presisjon er 66,37.
Beslutningen handler ikke om hvor mange totale biter som brukes. Spørsmålet er bare hva akse du velger å gruppere over når du beregner hver skala-faktor? Når du bestemmer deg for å bruke kanalen som din grupperingsdimensjon (nøkler) og tokenet som din grupperingsdimensjon (verdier), ender du opp et sted innenfor fire poeng fra full presisjons-ytelse. Hvis du flipper enten av disse valgene, opplever du en kvalitets-tap. Hvis du flipper begge disse valgene, fungerer modellen ikke lenger.

Fire måter å bruke de samme 2 bitene på samme cache. Resultater fra KIVI-ablasjon på Llama-2-13B ved gruppe-størrelse 32.
Kvantisering regnes vanligvis som bare én kontroll: 8 biter, 4 biter, 2 biter, med en jevn nøyaktighets-kost. Innside KV-cache, er det ikke slik. Det handler om å velge koordinatsystemer, og forskjellige systemer gjelder for nøkler og verdier. Denne artikkelen forklarer hvorfor. Kort sagt: kvantisering-feil avhenger av verdienes rekkevidde innenfor grupper; nøkler og verdier har svært forskjellig struktur; og folk tripper ofte opp fordi du ikke kan avlede den riktige akse fra verdifordelingen på noen måte. Du må se på hvordan feilen endrer seg etter at oppmerksomheten har forbrukt den. Dette gir en generell prinsipp for å komprimere mellomliggende aktiveringer og en god grunn til å tvile på rekonstruksjons-feil som et proxy for kvalitet.
Hvorfor KV-cachen er der hvor dette biter
Under genereringsfasen lagrer en transformer alle nøkkel-verdi-projeksjonsdata (KV) fra tokenene det har behandlet tidligere i en cache, så den ikke må regne ut denne dataen igjen. Denne cachen vokser lineært med kontekst-lengde og batch-størrelse. Til slutt vil dette resultere i at cachen vokser større enn modellen selv.
Dette økningen i vekst kan lett identifiseres når man ser på minne-forbruket til forskjellige deler av modellen. I KVQuant-analyse av LLaMA-7B, står vekter for omtrent 98 prosent av minnet ved en sekvens-lengde på 512, med aktiveringer på 2 prosent. Ved 128K kontekst, inverteres forholdet til omtrent 16 prosent vekter og 84 prosent KV-cache. Når vi ser på en analyse av OPT-175B sitert av KIVI-forfatterne, fant de lignende resultater. Spesifikt, ved en batch-størrelse på 512 med en 512-token prompt, når KV-cachen 1,2 TB — flere ganger større enn modell-vektene.
Men kapasitet er bare halvparten av problemet her. GPU-en må lese hele KV-cachen fra enhets-minnet for hvert enkelt token det genererer. Dette betyr at mens GPU-en leser ut KV-cachen, sitter beregnings-kjernene inaktive. Derfor øker reduksjonen av cachen både den tilgjengelige prosesserings-hodet og reduserer tiden brukt på å vente på data-overføringer.
Hva kvantisering-feil faktisk består av
Uniform integer-kvantisering er rett frem matematisk. For en gruppe tall, registrerer du det minste tallet som et null-punkt og deler deretter rekkevidden av gruppen på antallet nivåer som kan representeres for å få en steg-størrelse. Du runder deretter hver element til nærmeste steg. To umiddelbare resultater følger. Først er feil per element begrenset av halv en steg-størrelse. Andre, steg-størrelsen er gruppenes rekkevidde delt på 2ᴮ − 1. Ved 2 biter, har du bare 4 nivåer å dekke hva som ennå finnes i gruppen. Så et element som er hundre ganger større sammenlignet med naboene, fungerer ikke bare dårlig. Det øker steg-størrelsen for alle andre elementer som deler samme gruppe, og alle blir grovere sammen. Gruppe er enheten for skade. Å velge en akse betyr å bestemme hvilke elementer lider sammen. Å ramme spørsmålet annerledes, er det ikke lenger “hvor mange biter kan jeg forholde meg til?” men “hvor er ekstreme verdier og kan jeg isolere dem?”
Nøkler: Outlierne bor i fikse kanaler
Store språk-modeller inneholder aktiveringer som er usedvanlig store sammenlignet med de fleste aktiveringer. Sun og kolleger katalogiserte disse svært store aktiveringer over forskjellige modell-familier: i Mixtral 8x7B, er den største størrelsen nær 7000, mens median-funksjons-størrelsen er rundt 0,3 — omtrent fire størrelse-ordener apart. Disse er svært sjeldne; de forblir fikse i dimensjoner som sjelden endrer seg med inndata, og de er ikke tilfeldige. De fungerer som implisitte forutinntak, og de er hva som fokuserer oppmerksomheten på bare noen få token: oppmerksomhets-senk-oppførsel. I nøkkel-cachen, er denne strukturen svært klar: bestemte kanaler bærer svært store størrelser konsistent over hver token i en sekvens. Gruppér over token, og hver gruppe inneholder disse outlier-kanalene, så hver gruppes steg-størrelse settes av outlier-kanalene, og alle vanlige kanalene betaler for det. Gruppér over kanaler, og outlier-kanalene danner sine egne grupper. Deres interne rekkevidde er stor, men selv-innesluttet; vanlige kanaler blir igjen alene. Resultatene matcher. Gjennomsnittlig over lag og hoder på Llama-2-13B, rapporterer KIVI nøkkel-rekonstruksjons-feil på 13,67 under per-token-gruppering mot 4,55 per-kanal, og — mer viktig — oppmerksomhets-score-feil på 47,00 mot 9,60. Kvantisering av nøkler per token produserer omtrent fem ganger større score-feil. Scorer samtykker med meningsfulle metrikker for nøkler; kanal-kvantisering utmerker seg på begge fronter.
Verdier: Hvor intuisjonen bryter
Verdi-cachen viser ikke en kanal-outlier-mønster. Den ser ut til å være ganske flat. På egen hånd, ved rekkevidde-argumentet, kunne vi forvente at enten av disse aksene ville produsere en lignende kvalitet på kompresjon.
De gjør ikke det. Uansett hvordan nøkkel-håndtering implementeres (2,80 og 2,88 resultater), kollapser kompresjon av verdier per kanal modellen.
Og her er fangen: hvis du målte denne tapen ved hjelp av den rå rekonstruksjons-feilen på den opprinnelige tensoren for hvilken hver verdi var komprimert, ser per-kanal-verdi-kvantisering ut til å være litt bedre, med 3,73 mot 4,57. Hvis du validerer kompresjonen på den åpenbare måten, ville du velge konfigurasjonen som ødelegger modellen.

Verdi-cache kvantisering-feil på Llama-2-13B, målt på to måter. Lagret-tensor-metrikken og forbrukt-utgang-metrikken er uenige med mer enn en orden av størrelse.
Løsningen er at verdi-cachen aldri leses direkte. Den forbrukes av en matris-produkt: oppmerksomhets-utgangen er en vekt-sum av verdi-vektorer over token, med softmax-oppmerksomhets-scorer som vekter. Fordi av denne grunn, er den relevante feilen den som introduseres under denne prosessen, og ikke innenfor tensorene selv. Målt i forhold til oppmerksomhets-utgangen, var den relative feilen rapportert av KIVI for per-token-verdi-vektor-kvantisering 3,55 sammenlignet med 49,89 for per-kanal-kvantisering — over fjorten ganger høyere for hva som så ut til å være det bedre valget basert på hvor godt det var komprimert.
Forklaringen er oppmerksomhets-sparsehet, som de målte til 84,3 prosent. Majoriteten av informasjonen i utgangen kan tilskrives en liten mengde svært viktige token. Per-token-kvantisering begrenser hver tokens feil til det tokenet, så feil på uviktige token blir multiplisert med nær-null oppmerksomhets-vekt og forsvinner effektivt. Per-kanal-kvantisering spreder hver tokens feil over en delt kanal-skala, så dårlig representerte token forurenser representasjonen av de som betyr noe. Sparseheten som gjør oppmerksomheten effektiv er samme egenskap som gjør per-token-kvantisering trygg.
Den overførbare læren er bredere enn KV-cachen: mål kompresjons-feil der tensoren forbrukes, ikke der den lagres. En implisitt antagelse gjort av rekonstruksjons-feil er at hver komponent av en tensor har lik vekt når det bidrar til den endelige utgangen. Oppmerksomheten gjør ikke det eksplisitt. Enhver nedstrøms-operasjon som vekter, porter eller sparsifierer inndata, bryter denne antagelsen. Lesere som er kjent med min tidligere artikkel om blindspots i evaluering-metrikker i gjenvinningssystemer vil gjenkjenne at disse resultatene er lignende tidligere beskrevne feil: lett beregnede metrikker som rapporterer på noe annet enn hva som var ment.
Rotary-embeddings kompliserer nøklene
Det er noen problemer med å bruke Rotary Position Embeddings (RoPE). RoPE roterer par av kanaler basert på den relative posisjonen til hver token. Denne blandingen delvis oppløser den fikse-kanal-strukturen som gjorde per-kanal-nøkkel-kvantisering fungere på førsteplass — en outlier-kanal blir rotert inn i naboene, og naboene arver rekkevidden. KVQuants svar er ordering: kvantisér nøkler før rotasjonen blir brukt, og bruk RoPE etter de-kvantisering. Ved siden av per-kanal-nøkkel-kvantisering, ikke-uniforme datatyper og isolering av en liten fraksjon av outlier, får de dette under 0,1 perplexity-degradering ved 3 biter, og muliggjør å betjene LLaMA-7B opptil 1 million token i kontekst på en enkelt A100-80GB.
Det er også viktig å forstå nivået av påvirkning fra RoPE. Forfatterne av artikkelen “RotateKV” rapporterte en økning på 145 prosent i kvantisering-feil når RoPE ble lagt til, og noterte at outlier-kanaler skiller seg fra hverandre over oppmerksomhets-hoder — som er hvorfor å bruke en delt rotasjons-matrise overalt er utilstrekkelig, og hod-adaptive rotasjoner gjør bedre.
System-skatten og hvorfor den ikke er en detalj
Per-token-kvantisering passer godt for avkoding. Hvert token ankommer; du kvantiserer det, legger det til sekvensen (langs token-dimensjonen), ingenting annet beveger seg.
Men per-kanal-kvantisering passer ikke. Da en kanals statistikk spenner over token som ikke er generert ennå, kan du ikke beregne en skala-faktor når et token kommer inn. KIVIs workaround er å holde de siste tokenene — opp til 128 — i full presisjon i en rest-buffer, og kvantisér i grupper når nok har akkumulert.
Som det skjer, blir rest-bufferen bærebærere, snarere enn bare en tilfeldig ting. På GSM8K med Llama-2-7B, scorer full presisjon 13,50. Fullt kvantisert til 2 biter med de riktige aksene, scorer 5,76. Samme aksene og samme biter, pluss rest-bufferen med nylig produserte token i full presisjon, scorer 12,74. En glidende vindu av nylig produserte token i full presisjon vil gjenopprette mye av hva som ble tapt på grunn av aggressiv kvantisering på vanskelige multi-trinn-problemer — som ville være fornuftig hvis vi vurderte hvilke token som ble oppmerksomhet av en kjede av aritmetiske operasjoner.
Det er en betydelig fordel fra å gjøre alle disse tingene riktig — som KIVI rapporterer, 2,6 ganger mindre topp-minne-bruk for Llama-2-7B, som tillater batch-størrelser opp til 4 ganger større, samt 2,35 til 3,47 ganger bedre gjennomstrømming på en virkelig tjeneste-oppgave.
Hva du skal gjøre med dette
- Bruk aldri én kvantiserer for begge. Bruk forskjellige kvantiserere for nøkler (per-kanal) og for verdier (per token). En pipeline som anvender en enkelt kvantiserer til “KV-cachen” har sannsynligvis allerede ofret mest mulig kvalitet når du bruker et lite antall biter for å representere hver verdi.
- Kvantiser nøkler før RoPE. Dette er en spørsmål om korrekthet i motsetning til en spørsmål om preferanse.
- Lagre et fullt presisjons-vindu av nylig genererte token. Selv om lagring av et slikt vindu tar svært lite minne sammenlignet med hvor stor en cache kan være, er det nettopp dette området som genererer mye av nøyaktigheten for vanskelige oppgaver.
- Valider ikke på rekonstruksjons-feil. Valider alltid basert på oppmerksomhets-utgangen eller basert på slutt-oppgave-ytelse. Lagrings-metrikken er ikke bare støy — for verdier peker den feil vei.
- Valider ikke på kort-kontekst fler-valg-benchmark. KIVI-forfatterne unngikk bevisst lukkede oppgaver som MMLU for denne evalueringen, fordi en enkelt avkodings-steg som leser utgangs-logitt bare øver cachen litt. Enhver evaluering som ikke bygger en cache over tid og deretter utfører generering fra den, vil aldri kunne observere feilene som er innebygget i system-designet ditt.
Hvor arbeidet er rettet
Selv om det fortsatt er litt igjen å gjøre med den geometriske naturen av problemet, fortsetter mange forskere å studere måter å distribuere outlier-kanaler på forskjellige transformer-hoder, og hvordan maskinvare-begrensninger påvirker hvilke grupperinger som er billigst: InnerQ folder kanal-vis nøkkel-normalisering inn i nøkkel- og spørrings-vektene under forhånds-fylling. Derfor incelleres ingen ekstra overhode ved kjøretid. Videre lagrer InnerQ høypresisjons-vinduer for både nylig genererte token og oppmerksomhets-sink-token. Ved å gjøre dette, eliminerer InnerQ muligheten for outlier-kanaler til å forurense nabo-kanaler.
Andre foreslår at i stedet for å lagre hele cachen, bør vi lagre bare nok informasjon for å kunne gjenopprette nøkkel- og/eller verdi(er) på forespørsel fra en mindre cachet representasjon.
Til slutt er det viktig å huske at nøyaktighet ikke er den eneste parameteren som kvantisering påvirker. Nylig publisert forskning viste justerings-degradering som resultat av kvantisering av KV-cacher. Videre dokumenterte denne forskningen justerings-degradering selv i produksjons-vLLM-tjenester som bruker FP8-cacher sammen med en trening-fri gjenopprettings-protokoll som gjenopprettet opptil 97 prosent av hva som ble tapt i forhold til justering. Som sådan, selv om en konfigurasjon kan holde på benchmark-resultatene, betyr det ikke nødvendigvis at den beholder alle andre relevante parametre du bryr deg om.
Den generelle prinsippet
Idéen om kvantisering har blitt rammet som en “presisjons-budsjett”: hvor mange biter kan jeg ofre? KV-cachen viser at det mer nyttige spørsmålet er strukturelt. Presisjon blir tildelt i grupper; gruppen er enheten for skade, og aksen du grupperer langs bestemmer hvilke elementer deler skjebnen. Den riktige aksen er den som din tensor blir forbrukt på, dvs. måten du bruker din tensor på og IKKE hvordan din tensor ser ut når den lagres i minne. Nøkler blir brukt via en punkt-produkt-komputasjon mot spørringen. En enkelt korrupt kanal vil forgifte alle scorer. Verdier blir forbrukt gjennom en sparse-vekt-summering over token. Derfor er en enkelt korrupt token bare vektet ut.
To tensorer med identiske dimensjoner og generert av to påfølgende lag blir behandlet forskjellig. Det er verdt å spørre om noen aktivering du planlegger å komprimere: hva operasjon kontrakter denne vekk, og respekterer min gruppering det? Det er også verdt å spørre om noen aktivering du planlegger å komprimere: hva operasjon kontrakter denne vekk, og respekterer min gruppering det? rage computation across tokens. Derfor er en enkelt korrupt token bare vektet ut. To tensorer av identiske dimensjoner og generert av to påfølgende lag blir behandlet forskjellig. Det er verdt å spørre om noen aktivering du planlegger å komprimere: hva operasjon kontrakter denne vekk, og respekterer min gruppering det?












