AI-mallit ja alustat
Suorituskyvyn Optimointi Isojen Kielimallien Inferenssille ja Hienosäätölle
Iset suuret kielimallit (LLM) kuten GPT-4, Bloom ja LLaMA ovat saavuttaneet merkittäviä kykyjä skaalautumalla miljardeihin parametreihin. Kuitenkin näiden massiivisten mallien käyttäminen inferenssille tai hienosäätölle on haasteellista niiden valtavien muistivaatimusten vuoksi. Tässä teknisessä blogissa tarkastelemme tekniikoita muistin kulutuksen arvioimiseksi ja optimoimiseksi LLM-inferenssissä ja hienosäätössä erilaisilla laitteistoilla.
Muistin Vaatimusten Ymmärtäminen
Muisti, jota vaaditaan LLM:n lataamiseen, määräytyy pääasiassa parametreiden määrän ja numeerisen tarkkuuden perusteella, jota käytetään parametreiden tallentamiseen. Yksinkertainen sääntö on:
- Mallin lataaminen, jossa on X miljardia parametreja, vaatii noin 4X GB VRAM:ia 32-bittisessä liukulukumuodossa
- Mallin lataaminen, jossa on X miljardia parametreja, vaatii noin 2X GB VRAM:ia 16-bittisessä bfloat16/float16 -tarkkuudessa
Esimerkiksi 175 miljardin parametrin GPT-3-mallin lataaminen vaatisi noin 350 GB VRAM:ia bfloat16-tarkkuudessa. Tällä hetkellä suurimmat kaupallisesti saatavissa olevat GPU:t, kuten NVIDIA A100 ja H100, tarjoavat vain 80 GB VRAM:ia, mikä edellyttää tensorin rinnakkaisuuden ja mallin rinnakkaisuuden tekniikoita.
Inferenssissä muistijalanjälki on pääasiassa määriteltynä mallin parametreilla ja tilapäisillä aktivaatiotensorilla, jotka tuotetaan. Korkean tason arvio inferenssin huippumuistinkäytölle on mallin parametreiden ja aktivaatioiden muistin summa.
Inferenssin Muistin Määritys
Määritellään inferenssin muistin vaatimukset OctoCode-mallin avulla, jossa on noin 15 miljardia parametreja bfloat16-muodossa (~ 31 GB). Käytetään Transformers-kirjastoa mallin lataamiseen ja tekstin generointiin:
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline import torch <p>model = AutoModelForCausalLM.from_pretrained("bigcode/octocoder", torch_dtype=torch.bfloat16, device_map="auto", pad_token_id=0) tokenizer = AutoTokenizer.from_pretrained("bigcode/octocoder") pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)</p> <p>prompt = "Kysymys: Kirjoita Python-funktio, joka muuttaa tavut gigatavuiksi.\n\nVastaus:" result = pipe(prompt, max_new_tokens=60)[0]["generated_text"][len(prompt):]</p> <p>def bytes_to_gigabytes(bytes): return bytes / 1024 / 1024 / 1024</p> <p>bytes_to_gigabytes(torch.cuda.max_memory_allocated())
Tuloste:
29.0260648727417Huippu-GPU-muistin käyttö on noin 29 GB, mikä vastaa arviotamme 31 GB:sta mallin parametreiden lataamiseksi bfloat16-muodossa.
Inferenssin Muistin Optimointi Kvantisaatiolla
Vaikka bfloat16 on yleinen tarkkuus LLM:ien koulutuksessa, tutkijat ovat havainneet, että mallipainojen kvantisaatio alempiin tarkkuuksiin, kuten 8-bittisiin kokonaislukuun (int8) tai 4-bittisiin kokonaislukuun, voi merkittävästi vähentää muistikäyttöä vähäisellä tarkkuuden heikkenemisellä inferenssitehtävissä kuten tekstin generoinnissa.
Tarkastellaan muistin säästöjä 8-bittisestä ja 4-bittisestä kvantisaatiosta OctoCode-mallissa:
&lt;/div&gt; # 8-bittinen kvantisaatio model = AutoModelForCausalLM.from_pretrained("bigcode/octocoder", load_in_8bit=True, pad_token_id=0) pipe = pipeline("text-generation", model=model, tokenizer=tokenizer) result = pipe(prompt, max_new_tokens=60)[0]["generated_text"][len(prompt):] bytes_to_gigabytes(torch.cuda.max_memory_allocated())</pre>
Tuloste:
15.219234466552734# 4-bittinen kvantisaatio model = AutoModelForCausalLM.from_pretrained("bigcode/octocoder", load_in_4bit=True, low_cpu_mem_usage=True, pad_token_id=0) pipe = pipeline("text-generation", model=model, tokenizer=tokenizer) result = pipe(prompt, max_new_tokens=60)[0]["generated_text"][len(prompt):] bytes_to_gigabytes(torch.cuda.max_memory_allocated())
Tuloste:
9.5435743331909188-bittisellä kvantisaatiolla muistin vaatimus laskee 31 GB:sta 15 GB:iin, kun taas 4-bittinen kvantisaatio laskee sen edelleen 9,5 GB:iin! Tämä mahdollistaa 15 miljardin parametrin OctoCode-mallin suorittamisen kuluttajien GPU:illa kuten RTX 3090 (24 GB VRAM).
Hienosäätömuistin Arvioiminen
Kvantisaatio on pääasiassa käytetty tehokkaasti inferenssissä, mutta tekniikat kuten tensorin rinnakkaisuus ja mallin rinnakkaisuus ovat ratkaisevia suurten kielimallien koulutuksen tai hienosäätö muistin hallinnassa.
Hienosäätössä huippumuistin kulutus on tyypillisesti 3-4 kertaa suurempi kuin inferenssissä johtuen lisämuistin tarpeista:
- Gradientit
- Optimointitilat
- Aktivaatiot eteenpäin suoritettavasta takaisin suoritettavaksi
Konservatiivinen arvio on, että hienosäätö LLM:llä, jossa on X miljardia parametreja, vaatii noin 4 * (2X) = 8X GB VRAM:ia bfloat16-tarkkuudessa.
Esimerkiksi hienosäätö 7 miljardin parametrin LLaMA-mallilla vaatisi noin 7 * 8 = 56 GB VRAM:ia GPU:lla bfloat16-tarkkuudessa. Tämä ylittää nykyisten GPU:iden muistikapasiteetin, mikä edellyttää hienosäätötekniikoita.
Hienosäätötekniikat
Useita hienosäätömenetelmiä on ehdotettu ylittämään GPU:n muistirajoitukset suurten mallien koulutuksessa:
- Data-rinnakkaisuus: Perinteinen data-rinnakkaisuusmenetelmä replikoi koko mallin useille GPU:ille ja jakaa ja jakaa koulutusdata-erät. Tämä vähentää koulutusaikaa lineaarisesti GPU:n määrän mukaan, mutta ei vähennä huippumuistin vaatimusta kussakin GPU:ssa.
- ZeRO Stage 3: Edistynyt data-rinnakkaisuusmenetelmä, joka jakaa mallin parametreja, gradientteja ja optimointitiloja GPU:ille. Se vähentää muistia verrattuna perinteiseen data-rinnakkaisuuteen pitämällä ainoastaan vaadittuja jaettuja tietoja kussakin GPU:ssa koulutuksen eri vaiheissa.
- Tensorin rinnakkaisuus: Sen sijaan, että malli replikoidaan, tensorin rinnakkaisuus jakaa mallin parametreja riveihin tai sarakkeisiin ja jakaa ne GPU:ille. Kunkin GPU:n toimii jaettujen parametrien, gradienttien ja optimointitilojen osalla, mikä johtaa merkittäviin muistisäästöihin.
- Pipeline-rinnakkaisuus: Tämä tekniikka jakaa mallin kerrokset eri GPU:ille/työntekijöille, joissa kunkin laite suorittaa osan kerroksista. Aktivaatiot siirretään työntekijöiden välillä, vähentäen huippumuistia, mutta lisäten viestintäkuormitusta.
Hienosäätömuistin arvioiminen näillä jakautumismenetelmillä on monimutkaista, koska parametreiden, gradienttien, aktivaatioiden ja optimointitilojen jakautuminen vaihtelee menetelmien mukaan. Lisäksi eri komponentit, kuten transformer-runko ja kielen mallintamisen pää, voivat osoittaa erilaisia muistin varauskäyttäytymisiä.
LLMem-ratkaisu
Tutkijat ovat ehdottaneet LLMem-ratkaisua, joka arvioi tarkasti GPU:n muistikäytön, kun sovelletaan hienosäätömenetelmiä LLM:lle useille GPU:ille.
LLMem ottaa huomioon tekijät, kuten parametreiden uudelleenyhdistäminen ennen laskentaa (ZeRO Stage 3), tulosteen kerääminen taaksepäin suoritettaessa (tensorin rinnakkaisuus) ja eri muistin varausstrategiat transformer-rungolle ja kielen mallintamisen päälle.
Kokeelliset tulokset osoittavat, että LLMem voi arvioida huippu-GPU-muistin käytön yhdellä GPU:lla hienosäätössä virheellisyydellä jopa 1,6 %, joka ylittää DNNMem:n keskimääräisen virheellisyyden 42,6 %. Kun sovelletaan hienosäätömenetelmiä LLM:lle, jolla on yli miljardi parametreja useille GPU:ille, LLMem saavuttaa vaikuttavan keskimääräisen virheellisyyden 3,0 %.













