uutiset

Tuhansia sanoja teknistä tietoa! Pakollinen kvantifiointiopas LLM-insinööreille, visuaaliset kuvat paljastavat, kuinka suuria malleja pakataan

2024-07-31

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina


Uusi viisausraportti

Toimittaja: Toimitusosasto

[Johdatus uuteen viisauteen] LLM:n asteittain laajenevan parametriskaalan edessä kehittäjät ja tutkijat, joilla ei ole H100:aa, ovat keksineet monia tapoja kompensoida sitä, ja "kvantifiointi"-tekniikka on yksi niistä. Tämä visuaalinen opas käyttää erilaisia ​​​​kuvituksia kattavan yhteenvedon "kvantifioinnin" peruskäsitteistä ja haaramenetelmistä.

Suuret kielimallit (LLM) ovat usein liian suuria käytettäviksi kuluttajatason laitteistoissa. Näissä malleissa voi olla yli miljardeja parametreja, ja ne vaativat usein suurella muistilla varustettuja GPU:ita päättelyprosessin nopeuttamiseksi.

Siksi yhä enemmän tutkimusta on alettu keskittyä mallin kutistamiseen, kuten koulutusmenetelmien parantamiseen tai sovittimien käyttöön. Yksi tämän alan päätekniikoista on nimeltään kvantisointi.

ML-insinööri Maarten Grootendorst kirjoitti blogikirjoituksen, joka esittelee erityisesti kvantifiointiteknologiaa kielimallinnuksen yhteydessä ja tutkii siihen liittyviä käsitteitä yksitellen visuaalisten menetelmien avulla, jotta voimme rakentaa intuitiivisen ymmärryksen tekniikasta.


Tässä blogikirjoituksessa Maarten tutkii erilaisia ​​menetelmiä, käyttötapauksia ja kvantifioinnin taustalla olevia periaatteita.

Artikkelin sisällysluettelo ja sisältö on esitetty alla olevassa kuvassa. Se esittelee pääasiassa kaksi koulutuksen jälkeistä kvantifiointia (PTQ) ja kvantisointitietoista koulutusta (QAT). suoraan symmetriseen kvantisointiosaan:


Osa yksi: LLM:n "ongelma".

"Suuret kielimallit" ovat suuria malliparametrien lukumäärän suhteen, ja niiden mittakaava on yleensä miljardeja (pääasiassa painoja).

Näiden parametrien säilytyskustannukset eivät ole vain melko korkeat, vaan myös laskennan määrä päättelyvaiheessa on suuri.

Päättelyn aikana aktivointiarvo on syötteen ja painon tulo, joten mitä suurempi on painojen lukumäärä, sitä suurempi aktivointiarvo.


Siksi haluamme esittää miljardeja arvoja mahdollisimman tehokkaasti ja minimoiden siten parametrien tallentamiseen tarvittavan tilan.

Aloitetaan alusta ja tutkitaan, miten arvot esitetään ennen optimointia.

Kuinka esittää numeerisia arvoja

Numeeriset arvot tallennetaan yleensä liukulukuina (tai yksinkertaisesti kelluvat): positiivinen tai negatiivinen luku, jossa on desimaalipilkku.

Nämä arvot esitetään binäärinumeroina jokaisessa bitissä.

IEEE-754-standardi kuvaa, kuinka kunkin numeron numerot edustavat tiettyä arvoa. Erityisesti on olemassa kolme kuvausta: etumerkki, eksponentti tai desimaali (mantissa).


Nämä kolme osaa voidaan yhdistää esitettävän arvon laskemiseksi bittiarvojen joukon perusteella:


Mitä enemmän numeroita käytetään, sitä tarkempi numeerinen arvo on. Esimerkiksi FP32-lomake voi olla tarkempi desimaalipilkun jälkeen kuin FP16:


muistin raja

Mitä enemmän numeroita on saatavilla, sitä tarkempi arvo on myös sitä laajempi arvoalue, joka voidaan esittää.


Kun bittinumero ja esitys on annettu, esitettävissä olevaa arvoaluetta kutsutaan dynaamiseksi alueeksi ja kahden vierekkäisen arvon välistä etäisyyttä kutsutaan tarkkuudella.


Tämän esityksen siisti ominaisuus on, että voimme laskea kuinka paljon muistia laite tarvitsee tietyn arvon tallentamiseen.

Koska jokainen muistin tavu sisältää 8 bittiä, voimme luoda peruskaavan useimmille liukulukujen muodoille -


Todellisissa sovelluksissa on monia muita tekijöitä, jotka vaikuttavat päättelyn aikana tarvittavan grafiikan/muistin määrään, kuten kontekstin koko ja malliarkkitehtuuri.

Kuvittele nyt, että meillä on malli, jossa on 70 miljardia parametria. Useimmat itse mallit on esitetty 32-bittisillä liukulukuilla (kutsutaan usein täydeksi tarkkuudella), mikä vaatii 280 Gt muistia mallin lataamiseen.


Mutta jos kaikki parametrit voidaan ilmaista 16-bittisinä liukulukuina, tarvittavaa muistin kokoa voidaan pienentää suoraan yhdellä kertaa.

Siksi on erittäin houkuttelevaa minimoida malliparametrien esitysten lukumäärä (ei pelkästään päättelyä varten, vaan myös harjoittelua varten).

Tämä lähestymistapa ei kuitenkaan tule ilman kustannuksia. Mallin tarkkuus tyypillisesti heikkenee esitysbittien määrän pienentyessä, mikä heikentää tarkkuutta.

Haluamme vähentää arvon esittämiseen käytettävien numeroiden määrää säilyttäen samalla tarkkuuden... tässä kvantisointitekniikat ovat hyödyllisiä.

Osa 2: Johdatus kvantifiointiin

Tiedämme nyt, että kvantisoinnin tarkoitus on vähentää malliparametrien tarkkuutta suuremmista bittileveyksistä (kuten 32-bittiset liukulukuluvut) pienempiin bittileveyksiin (kuten 8-bittisiin kokonaislukuihin).


Alkuperäisiä parametreja edustavien bittien lukumäärää pienennettäessä tapahtuu yleensä jonkin verran tarkkuuden (rakeuden) menetystä.

Jotta tämä tehoste olisi intuitiivisempi, voimme käyttää valokuvavärejä analogiana. Valitse esimerkiksi mikä tahansa kuva (vasemmalla), mutta käytä vain 8 väriä (oikealla):


Huomaa, että suurennettu keksi näyttää "rakeisemmalta" kuin alkuperäinen.

Samoin kvantisoinnin päätavoite on vähentää alkuperäisten parametrien esittämiseen vaadittavien bittien (värien) määrää säilyttäen samalla mahdollisimman paljon alkuperäisten parametrien tarkkuutta.

Yleisiä tietotyyppejä

Tarkastellaan ensin yleisiä tietotyyppejä ja niiden käytön vaikutuksia 32-bittisen (kutsutaan täyden tarkkuuden tai FP32) -esityksen sijaan.

FP16

Ensimmäinen on esimerkki siirtymisestä 32-bittisestä 16-bittiseen (kutsutaan puolitarkkuus- tai FP16-liukulukuksi):


FP16:n mahdollisten arvojen alue on paljon pienempi kuin FP32:n.

BF16

Jotta saataisiin samanlainen numeerinen alue kuin alkuperäinen FP32, bfloat 16 otettiin käyttöön "typistettynä FP32"-tyyppinä:


BF16 käyttää samaa määrää bittejä kuin FP16, mutta lisää eksponentiaalisen bitin, joten se voi saada laajemman arvoalueen ja sitä käytetään usein syväoppimisen alalla.

INT8

Kun pienennät bittien määrää entisestään, esitys tulee lähemmäksi kokonaislukua eikä liukulukua. Esimerkiksi siirtyminen FP32:sta INT8:aan, jossa on vain 8 bittiä, vain 1/4 alkuperäisestä bittien määrästä:


Joka kerta kun bittien määrää vähennetään, suoritetaan kartoitus alkuperäisen FP32-esityksen "pakkaamiseksi" harvemmille biteille.

Mutta todellisessa käytössä meidän ei tarvitse yhdistää koko FP32-aluetta [-3.4e38, 3.4e38] INT8:aan. Meidän on vain löydettävä tapa kartoittaa todellisten malliparametrien tietoalue INT8:aan.

Yleisiä pakkaus-/kartoitusmenetelmiä ovat symmetrinen kvantisointi ja epäsymmetrinen kvantisointi, jotka molemmat ovat lineaarista kartoitusta.

Seuraavaksi keskustelemme kvantisointimenetelmästä FP32:sta INT8:aan.

Symmetrinen kvantisointi

Symmetrisessä kvantisoinnissa alkuperäisen liukulukuarvon alue kartoitetaan symmetriseen alueeseen, jonka keskipiste on nolla kvantisointiavaruudessa, ja nolla on alueen keskipiste ennen kvantisointia ja sen jälkeen.

Tämä tarkoittaa, että alkuperäinen nolla liukulukuavaruudessa on täsmälleen nolla, kun se on kartoitettu kvantisoituun avaruuteen.


Tyypillinen esimerkki symmetrisestä kvantisoinnista on absoluuttinen maksimi (absmax) kvantisointi.

Arvoluettelon perusteella otamme korkeimman absoluuttisen arvon (α) lineaarisen kartoituksen suorittamisalueeksi.


[-127, 127] edustaa rajoitettua aluetta ja rajoittamaton alue on [-128, 127] kvantisointimenetelmästä riippuen

Koska tämä on lineaarinen kartta, jonka keskipiste on nolla, kaava on yksinkertainen.

Laske ensin skaalaustekijä(t) seuraavalla kaavalla:

- b on tavujen määrä, jotka haluamme kvantisoida (8)

- α on suurin itseisarvo

Käytämme sitten s:n syötteen x kvantisoimiseen:


Kuten yllä olevasta kuvasta näkyy, suurin absoluuttinen arvo α on 10,8 Kun FP32 kartoitetaan INT8:aan, saadaan seuraava kaava:


Jos haluat palauttaa alkuperäiset FP32-arvot, voit käyttää myös aiemmin laskettuja skaalauskertoimia käänteiskvantisoinnissa.


Kvantisoi ensin ja dekvantoi sitten alkuperäisen arvon palauttamiseksi. Koko prosessi on seuraava:


Voit nähdä, että jotkin arvot, kuten 3.08 ja 3.02, ovat molemmat 36, kun ne kvantisoidaan arvoon INT8. Joten kun dekvantisoidaan takaisin FP32:een, ne menettävät jonkin verran tarkkuutta eivätkä ole enää erotettavissa.

Tätä eroa alkuperäisen arvon ja käänteisen kvantisoidun arvon välillä kutsutaan kvantisointivirheeksi. Yleensä mitä vähemmän bittejä kvantisoinnin tuloksessa on, sitä suurempi on virhe.


epäsymmetrinen kvantisointi

Toisin kuin symmetrinen kvantisointi, epäsymmetrinen kvantisointi ei ole nollakeskeistä symmetriaa. Sen sijaan se kartoittaa liukulukualueen minimi- (β) ja maksimiarvot (α) kvantisoidun alueen minimi- ja maksimiarvoihin, vastaavasti.

Tässä tutkimaamme menetelmää kutsutaan nollapistekvantisoinniksi.


Huomaa kuinka 0:n sijainti on siirtynyt. Siksi sitä kutsutaan epäsymmetriseksi kvantisoinniksi. Alueella [-7,59, 10,8] maksimi- ja minimiarvot ovat eri etäisyyksillä 0:sta.

Nollapisteen sijainnin siirtymän vuoksi meidän on laskettava nollapiste INT8-alueella lineaarisen kartoituksen suorittamiseksi. Kuten aiemmin, meidän on myös laskettava skaalaustekijä(t), mutta käyttämällä eroa INT8-alueella [-128, 127].


Tämä on hieman monimutkaista, koska nollapiste (z) on laskettava INT8-alueella painojen siirtämiseksi.

Kuten ennenkin, täytetään kaava:


Jotta kvantisoitu arvo voidaan dekvantisoida INT8:sta takaisin FP32:een, meidän on käytettävä aiemmin laskettua skaalaustekijää (s) ja nollapistettä (z).

Muuten dekvantisointi on yksinkertaista:


Kun laitamme symmetrisen ja epäsymmetrisen kvantisoinnin vierekkäin, näemme nopeasti eron näiden kahden menetelmän välillä:


Yllä olevassa kuvassa näemme symmetrisen kvantisoinnin nollakeskuksen ominaisuuden ja epäsymmetrisen kvantisoinnin offsetin.

Alueen kartoitus ja leikkaus (leikkaus)

Edellisessä esimerkissä tutkimme, kuinka kartoittaa tietyn vektorin arvoalue matalabittiseen esitykseen. Vaikka tämä voi kartoittaa koko vektoriarvoalueen, sillä on yksi suuri haittapuoli, nimittäin poikkeamat.

Kuvittele, että sinulla on vektori, joka sisältää seuraavat arvot:


Arvoa, joka on paljon suurempi kuin kaikki muut, voidaan pitää poikkeavana arvona. Jos kartoitamme koko vektoreiden alueen, kaikki pienet arvot kartoitetaan samaan matalan asteen esitykseen ja menettävät erottuvuutensa:


Tämä on aiemmin käytetty absmax-menetelmä.Sama tapahtuu epäsymmetrisellä kvantisoinnilla ilman leikkausta

Sen sijaan voimme leikata tiettyjä arvoja. Leikkaaminen tarkoittaa alkuperäisten arvojen erilaisen dynaamisen alueen asettamista siten, että kaikki poikkeavat arvot asetetaan samalle arvolle.

Alla olevassa esimerkissä asetamme manuaalisesti dynaamisen alueen arvoon [-5, 5], ja kaikki tämän alueen ulkopuolella olevat arvot kartoitetaan arvoon -127 tai 127 niiden todellisesta arvosta riippumatta:


Tämän lähestymistavan tärkein etu on, että kvantisointivirhe ei-poikkeaville arvoille vähenee merkittävästi. Se johtaa kuitenkin lisääntyneeseen kvantisointivirheeseen poikkeaville arvoille.

Kalibrointi

Yllä olevassa esimerkissä asetimme satunnaisesti dynaamisen alueen arvoon [-5, 5], mutta päätös tulisi tehdä "kalibrointi"-prosessin kautta sopivan alueen löytämiseksi, joka kattaa mahdollisimman monta arvoa samalla kun kvantisointivirhe minimoidaan.

Kalibrointivaiheiden suoritus on erilainen erityyppisille parametreille.

Painot (ja painotukset)

Voimme ajatella suuren kielimallin (LLM) painotuksia ja harhoja staattisina arvoina, koska ne tunnetaan ennen mallin suorittamista. Esimerkiksi Llama 3:n ~20 Gt:n tiedosto koostuu enimmäkseen sen painoista ja painotuksista.

Koska bias-muuttujien määrä (miljoonia) on huomattavasti pienempi kuin painot (miljardeja), biasit säilyttävät yleensä suuremman tarkkuuden (kuten INT16), kun taas pääasiallinen kvantisointityö keskittyy painotuksiin.

Tunnetuille staattisille painoille kalibrointitekniikoita alueen valitsemiseksi ovat:

- Valitse manuaalisesti syöttöalueen prosenttipisteet

- Optimoi keskimääräinen neliövirhe (MSE) alkuperäisten painojen ja kvantisoitujen painojen välillä

- Minimoi alkuperäisen arvon ja kvantisoidun arvon välinen entropia (KL-divergenssi)


Esimerkiksi prosenttipisteen valitseminen johtaa leikkauskäyttäytymiseen, joka on samanlainen kuin aiemmin.

aktivointiarvo

Syöttöjä, joita päivitetään jatkuvasti laajassa kielimallissa, kutsutaan usein aktivaatioiksi.


Niitä kutsutaan aktivointiarvoiksi, koska ne yleensä käyvät läpi jonkin aktivointitoiminnon, kuten sigmoidin tai relu

Toisin kuin painot, aktivaatiot muuttuvat syötetietojen mukaan päättelyn aikana, ja siksi niitä on vaikea määrittää tarkasti.

Koska nämä arvot päivitetään jokaisen piilotetun kerroksen jälkeen, niiden erityiset arvot eivät ole tiedossa päättelyvaiheessa ennen kuin syöttödata kulkee mallin läpi.


Yleensä on olemassa kaksi menetelmää painojen ja aktivointien kalibroimiseksi, joita käytetään mallin eri vaiheissa:

- Harjoittelun jälkeinen kvantisointi (PTQ)

- Kuten nimestä voi päätellä, se on kvantifiointi harjoituksen jälkeen

- Quantization Aware Training (QAT)

- Kvantisointi harjoituksen/hienosäädön aikana

Osa 3: Harjoittelun jälkeinen kvantifiointi (PTQ)

Harjoittelun jälkeinen kvantisointi (PTQ) on yksi suosituimmista kvantisointitekniikoista. Se kvantifioi mallin parametrit (mukaan lukien painot ja aktivointiarvot) mallikoulutuksen jälkeen.

Painotusten kvantisoinnissa voidaan käyttää symmetristä kvantisointia tai epäsymmetristä kvantisointia.

Aktivointiarvojen kvantifiointi vaatii kuitenkin päättelyvaiheen niiden taustalla olevan jakauman saamiseksi, koska emme tiedä niiden vaihteluväliä etukäteen.

Aktivointiarvot voidaan kvantisoida kahdella tavalla:

- dynaaminen kvantisointi

- staattinen kvantisointi

dynaaminen kvantisointi

Kun tiedot kulkevat piilotetun kerroksen läpi, sen aktivointiarvot kerätään ja kunkin kerroksen maksimiarvoa (α) ja minimiarvoa (β) verrataan:


Näiden aktivointien jakautumista käytetään sitten kvantisoidulle lähdölle vaadittavien nollapisteen (z) ja skaalauskertoimen (s) arvojen laskemiseen:


Tämä prosessi toistuu aina, kun tiedot kulkevat uuden verkkokerroksen läpi. Siksi jokaisella kerroksella on omat itsenäiset z- ja s-arvonsa, jolloin käytetään erilaista kvantisointimenetelmää.

staattinen kvantisointi

Toisin kuin dynaaminen kvantisointi, staattinen kvantisointi ei laske nollapistettä (z) ja skaalaustekijää (s) päättelyn aikana, vaan laskee nämä arvot ennen päättelyä.

Näiden arvojen löytämiseksi käytämme kalibrointitietojoukkoa ja syötämme sen malliin näiden taustalla olevien aktivointiarvojen jakaumien keräämiseksi.


Kun nämä jakaumat on kerätty, s- ja z-arvot, jotka tarvitaan kvantifiointiin päättelyn aikana, voidaan laskea.

Todellisena päättelyhetkenä s- ja z-arvoja ei lasketa uudelleen, vaan niitä käytetään maailmanlaajuisesti kaikissa aktivaatioissa niiden kvantisoimiseksi.

Kaiken kaikkiaan dynaaminen kvantisointi, joka laskee s- ja z-arvot kullekin piilotetulle kerrokselle, on yleensä tarkempi. Tämä voi kuitenkin pidentää laskenta-aikaa, koska nämä arvot on laskettava jokaisella päättelyhetkellä.

Sitä vastoin staattinen kvantisointi, vaikkakaan ei niin tarkka kuin dynaaminen kvantisointi, on nopeampaa, koska se tietää jo etukäteen kvantisoinnissa käytetyt s- ja z-arvot.

4-bittinen kvantitatiivinen kenttä

Alle 8-bittinen kvantisointi on aina ollut haaste, koska kvantisointivirhe kasvaa jokaisen kadonneen bitin myötä. Onneksi on olemassa useita älykkäitä tapoja vähentää bittien määrää 6-, 4- tai jopa 2-bittiseksi (vaikka bittien määrän vähentäminen alle 4-bittiseen ei yleensä ole suositeltavaa).

Tutkimme kahta yleistä tapaa HuggingFacessa:

- GPTQ (täysi malli toimii GPU:lla)

- GGUF (mahdollisesti siirtää tasot prosessorille)

GPTQ

GPTQ:n voidaan sanoa olevan yksi tunnetuimmista 4-bittisistä kvantisointimenetelmistä käytännön sovelluksissa.

Se käyttää epäsymmetristä kvantisointia ja käsittelee sen kerros kerrokselta ja käsittelee jokaisen kerroksen itsenäisesti ennen siirtymistä seuraavaan kerrokseen:


Tässä kerros kerrokselta kvantisointiprosessissa se ensin muuntaa kerrosten painot käänteisiksi Hessin matriiseiksi. Käänteinen Hessin matriisi on mallihäviöfunktion toinen derivaatta ja edustaa mallin lähdön herkkyyttä jokaiselle painonmuutokselle.

Yksinkertaisesti sanottuna se näyttää olennaisesti kunkin kerroksen painojen tärkeyden (käänteisen tärkeyden).

Pienemmät arvopainot Hessen-matriisissa ovat tärkeämpiä, koska pienet muutokset näissä painoissa voivat johtaa merkittäviin muutoksiin mallin suorituskyvyssä.


Käänteisessä Hessen-matriisissa pienemmät arvot edustavat enemmän "tärkeitä" painoja

Seuraavaksi kvantisoimme ja dekvantisoimme painomatriisin ensimmäisen rivin:


Tämän prosessin avulla voimme laskea kvantisointivirheen (q), jonka voimme painottaa käyttämällä aiemmin laskettua käänteistä Hessin arvoa (h_1).

Pohjimmiltaan luomme painotetun kvantisoidun virheen painojen tärkeyden perusteella:


Seuraavaksi jaamme tämän painotetun kvantisointivirheen uudelleen rivin muihin painotuksiin. Tämä auttaa ylläpitämään verkon yleistä toimivuutta ja tehoa.

Jos esimerkiksi teemme tämän toiselle painolle (eli x_2=0,3), kerromme kvantisointivirheen (q) toisen painon (h_2) Hessianin käänteisluvulla ja lisäämme siihen:


Jatka seuraavaksi samaa toimenpidettä tietyn rivin kolmannelle painolle:


Tätä painotetun kvantisointivirheen q uudelleenjakoprosessia toistetaan, kunnes kaikki arvot on kvantisoitu.

Tämä menetelmä toimii, koska painot liittyvät yleensä toisiinsa. Siksi, kun painossa on kvantisointivirhe, siihen liittyvä paino päivitetään vastaavasti käänteisen Hessenin kautta.

GGUF

Vaikka GPTQ on hyvä kvantisointimenetelmä koko suuren kielimallin (LLM) ajamiseen GPU:ssa, jos vastaavia laitteistoehtoja ei ole, mikä tahansa LLM:n kerros voidaan myös ladata CPU:lle GGUF:n kautta.

Se vastaa mallin käyttämistä CPU:ssa ja GPU:ssa samanaikaisesti videomuistin (VRAM) puutteen korvaamiseksi.

Kvantisointimenetelmää GGUF päivitetään usein ja se riippuu kvantisointibittien tietystä määrästä, mutta perusperiaate on seuraava.

Ensinnäkin tietyn kerroksen painot jaetaan "superlohkoihin", joista jokainen sisältää joukon "alilohkoja". Näistä "alilohkoista" lasketaan skaalaustekijä(t) ja alfa-arvo:


Tietyn "alilohkon" kvantisoimiseksi voit käyttää edellä mainittua absmax-kvantisointia kertomalla annettu paino skaalauskertoimella (s_sub):


Skaalauskerroin s_sub lasketaan käyttämällä "alilohkon" tietoja, mutta kvantisoidaan käyttämällä "super-lohkon" tietoja s_super:


Yhteenvetona voidaan todeta, että tämä lohkokohtainen kvantisointi käyttää "superlohkon" (s_super) skaalaustekijää "alilohkon" (s_sub) skaalaustekijän kvantisoimiseksi.

Kunkin skaalaustekijän kvantisointitaso voi olla erilainen, ja "superlohkon" skaalaustekijöillä on yleensä suurempi tarkkuus kuin "alilohkon" skaalaustekijöillä.

Tämän havainnollistamiseksi tutkitaan useita kvantisointitasoja (2-bittinen, 4-bittinen ja 6-bittinen):


Kvantisointityypistä riippuen vaaditaan myös ylimääräinen minimiarvo (m) nollapisteen säätämiseen, nämä kvantisoidaan samoin kuin skaalaustekijä(t)

Osa 4: Quantitative Awareness Training (QAT)

Kolmannessa osassa kuvataan kuinka malli kvantisoidaan harjoituksen jälkeen. Tämän menetelmän haittana on, että se ei ota huomioon varsinaista koulutusprosessia.

Tässä kvantitatiivisen tietoisuuden koulutus (QAT) on hyödyllinen. Toisin kuin harjoituksen jälkeinen kvantifiointi (PTQ), QAT:n tavoitteena on oppia kvantisointiprosessi harjoituksen aikana.


QAT on yleensä tarkempi kuin PTQ, koska kvantisointi otetaan huomioon jo koulutusprosessin aikana. Näin se toimii:

Harjoitteluprosessin aikana otetaan käyttöön niin kutsuttu "fake" kvantisointi. Esimerkiksi kvantisoi painot ensin INT4:ään ja dekvantisoi ne sitten takaisin FP32:een:


Tämä prosessi mahdollistaa sen, että malli ottaa kvantisointivirheen huomioon laskeessaan häviöitä ja päivittäessään painoja harjoitusvaiheen aikana.

Kuten alla olevasta kuvasta näkyy, QAT yrittää tutkia häviön arvoa "leveiden" minimien tapauksessa kvantisointivirheiden vähentämiseksi, koska "kapeat" minimit johtavat usein suurempiin kvantisointivirheisiin.


Olettaen, että kvantisointia ei oteta huomioon taaksepäin leviämisen aikana, gradienttilaskeutumisprosessi valitsee painon, jolla on pienin häviöarvo. Jos se on kuitenkin "kapeassa" minimissä, se aiheuttaa suurempia kvantisointivirheitä.

Sitä vastoin, jos tarkastelemme kvantisointia, "leveissä" minimimäärissä valitaan eri päivityspaino, jossa kvantisointivirhe on paljon pienempi.


Siksi, vaikka PTQ-menetelmällä on pieni häviöarvo suurella tarkkuudella (esim. FP32), QAT:lla on myös pieni häviöarvo alhaisella tarkkuudella (esim. INT4), mihin pyrimme.

1-bittinen aikakausi: BitNet

Näimme aiemmin, että kvantisointitarkkuuden vähentäminen 4-bittiseksi on jo melko pientä, mutta entä jos pienennämme sitä edelleen?

Tässä tulee BitNet, se edustaa mallin painot yhtenä bittinä, joko -1 tai 1, ja tekee tämän syöttämällä kvantisointiprosessin suoraan Transformer-arkkitehtuuriin.

Transformer-arkkitehtuuri on useimpien LLM:ien perusta, ja se koostuu laskelmista, jotka sisältävät lineaarisia kerroksia:


Nämä lineaariset kerrokset esitetään tyypillisesti suuremmalla tarkkuudella, kuten FP16, ja niissä on suurin osa painoista.

BitNet korvaa nämä lineaariset kerrokset BitLinear-tasoilla:


BitLinear-kerrokset toimivat samalla tavalla kuin tavalliset lineaariset kerrokset, kertomalla painot aktivointiarvoilla tulosten laskemiseksi.

Mutta ero on siinä, että BitLinear-kerros käyttää vain yhtä bittiä edustamaan mallin painoa ja käyttää INT8:aa aktivointiarvon esittämiseen:


BitLinear-kerrokset, kuten kvantisointitietoinen harjoitus (QAT), suorittavat harjoituksen aikana eräänlaisen "väärennöksen" analysoidakseen painojen ja aktivointien kvantisointivaikutusta:


Ymmärretään BitLinear askel askeleelta.

painon kvantifiointi

Harjoittelun aikana painot tallennetaan nimellä INT8 ja kvantisoidaan sitten 1 bitiksi käyttämällä perusstrategiaa, jota kutsutaan signum-funktioksi.

Pohjimmiltaan se siirtää painojen jakauman keskitettäväksi nollaan ja määrittää sitten kaikki arvot alle 0 arvoon -1 ja kaikki arvot, jotka ovat suuremmat kuin 0:1:


Lisäksi se pitää kirjaa arvosta β (keskiarvo absoluuttisesta arvosta), jota käytämme myöhemmin käänteiskvantisointiprosessissa.

Aktivoinnin kvantisointi

Aktivointien kvantifiointia varten BitLinear mahdollistaa absoluuttisen maksimiarvon menetelmän (absmax) muuntaa aktivoinnit FP16:sta INT8:ksi, koska ne edellyttävät matriisikertoa (×) suuremmalla tarkkuudella.


Lisäksi se pitää kirjaa arvosta α (maksimi absoluuttinen arvo), jota käytämme myöhemmin dekvantisointiprosessissa.

käänteinen kvantisointi

Pidämme kirjaa α:sta (aktivointien absoluuttinen enimmäisarvo) ja β:sta (painojen keskimääräinen absoluuttinen arvo), mikä auttaa meitä dekvantisoimaan aktivaatiot takaisin FP16:een.

Lähtöaktivoinnit skaalataan uudelleen käyttämällä {α, γ} niiden dekvantisoimiseksi alkuperäiseen tarkkuuteen:


Tämä prosessi on suhteellisen yksinkertainen ja mahdollistaa mallin esittämisen vain kahdella arvolla, -1 tai 1.

Tämän lähestymistavan avulla kirjoittajat havaitsivat, että mallin koon kasvaessa suorituskyvyn ero 1-bittisen koulutuksen ja FP16-koulutuksen välillä pienenee ja pienenee.

Tämä koskee kuitenkin vain suurempia malleja (>30B parametrit), pienempien mallien välinen ero on edelleen suuri.

Kaikki LLM:t ovat 1,58-bittisiä

Aiemmin mainittujen skaalautuvuusongelmien parantamiseksi otettiin käyttöön BitNet 1.58b.

Tässä uudessa lähestymistavassa mallin jokainen paino ei voi olla vain -1 tai 1, vaan se voi olla myös 0, jolloin jokaisesta muuttujasta tulee kolmiosainen.

Mielenkiintoista on, että pelkkä 0:n lisääminen on yksinkertainen toimenpide, joka parantaa huomattavasti BitNetiä ja nopeuttaa laskentaprosessia.

0 tehoa

Miksi 0:n lisääminen on merkittävä parannus?

Tämä liittyy matriisikertomiseen!

Ensin tutkitaan matriisikertomisen perustoimintoja.

Tulosta laskettaessa painotusmatriisi kerrotaan tulovektorilla. Tässä on visualisointi painomatriisin ensimmäisen kerroksen ensimmäisen rivin kertomisesta:


Tämä kertolasku sisältää kaksi toimintoa, kerrotaan yksi painoarvo syötteellä ja sitten lisätään ne kaikki.

Sitä vastoin BitNet 1.58b onnistuu välttämään kertolaskun, koska kolmiarvoiset painot kertovat sinulle seuraavan:

- 1: Haluan lisätä tämän arvon

- 0: En halua tätä arvoa

- -1: Haluan vähentää tämän arvon

Joten jos painosi on kvantisoitu 1,58 bittiin, sinun tarvitsee vain tehdä summa:


Tämä ei ainoastaan ​​nopeutta merkittävästi laskelmia, vaan mahdollistaa myös ominaisuuksien suodattamisen.

Tietyn painon asettaminen arvoon 0 vastaa syötteen huomioimatta jättämistä sen sijaan, että syötteen arvoa lisätään tai vähennetään, kuten 1-bittinen.

Määritä määrä

Painon kvantisoinnin suorittamiseksi BitNet 1.58b käyttää keskimääräistä absoluuttisen arvon kvantisointia (absmean), muunnelmaa suurimmasta absoluuttisen arvon kvantisoinnista (absmax), jonka olemme nähneet aiemmin.

Se yksinkertaisesti pakkaa painojakauman ja käyttää absoluuttista keskiarvoa (α) arvojen kvantifiointiin. Pyöristä ne sitten arvoon -1, 0 tai 1:


Verrattuna BitNetiin aktivointikvantisointi on sama paitsi yhtä näkökohtaa lukuun ottamatta: sen sijaan, että skaalaamme aktivaatiot alueelle [0, 2ᵇ⁻¹], käytämme maksimiabsoluuttisen arvon menetelmää skaalataksemme arvoon [-2ᵇ⁻¹, 2ᵇ⁻¹] .

Yhteenvetona voidaan todeta, että 1,58-bittinen kvantisointi sisältää pääasiassa kaksi tekniikkaa:

- Lisää 0 luodaksesi kolmiarvoisen esityksen [-1, 0, 1]

- Painojen absoluuttinen keskiarvo

BitNet-paperissa on seuraava johtopäätös: "13B BitNet b1.58 on tehokkaampi kuin 3B FP16 LLM latenssin, muistin käytön ja energiankulutuksen suhteen."


Paperiosoite: https://arxiv.org/abs/2402.17764

Vain 1,58 laskennallisesti tehokkaalla bitillä saamme kevyen mallin.

Viitteet:

https://newsletter.maartengrootendorst.com/p/a-visual-guide-to-quantization