-
Suurten kielimallien käyttö supertietokoneilla
Suurten kielimallien käyttö supertietokoneilla
Tässä oppaassa annetaan esimerkkejä ja vinkkejä siihen, miten suurten kielimallien (LLM) kanssa työskennellään CSC:n supertietokoneilla. Se on osa koneoppimisen opastamme.
LLM:t ja GPU-muisti
Jos teet inferenssiä (eli käytät mallia etkä kouluta sitä), voit joissakin tapauksissa pärjätä ilman GPU:ta, esimerkiksi jos malli on riittävän pieni tai sitä on pienennetty kvantisoinnilla. Useimmissa muissa tapauksissa tarvitset kuitenkin GPU:n.
Jotta voit käyttää LLM:ää (tai mitä tahansa neuroverkkoa) GPU:n kanssa, malli on ladattava GPU-muistiin (VRAM). LLM:t voivat olla hyvin suuria, ja tällöin GPU-muistin koko on kriittinen. Voit katsoa GPU-tilastotaulukostamme täydet tiedot, mutta GPU:idemme VRAM-muistit ovat seuraavat:
- 32 Gt Puhdissa (NVIDIA V100)
- 40 Gt Mahdissa (NVIDIA A100)
- 64 Gt LUMIssa (yhden AMD MI250x:n GCD)
- 96 Gt Roihussa (NVIDIA GH200, saatavilla toukokuussa 2026)
Mallin koko muistissa riippuu siitä, miten painot on tallennettu. Tavallisesti tietokoneen liukulukuarvo tallennetaan muotoon nimeltä fp32, joka käyttää 32 bittiä muistia eli 4 tavua (muista, että 8 bittiä = 1 tavu). Syväoppimisessa 16-bittisiä liukulukumuotoja (fp16 tai bf16) on käytetty pitkään osan laskennasta nopeuttamiseen. Ne käyttävät 2 tavua muistia painoa kohden. Viime aikoina mallikokojen kasvaessa vieläkin matalamman tarkkuuden muodot, aina 8 tai jopa 4 bittiin asti, ovat yleistyneet. Yleisiä kvantisointimenetelmiä ovat GPTQ, SpQR ja GGML/GGUF. Jos kvantisointi ei ole sinulle tuttu, katso esimerkiksi tämä verkko-opas LLM-mallien kvantisoinnista.
Mallin koko muistissa on tällöin parametrien määrä kerrottuna yhdelle painolle tarvittavien tavujen määrällä. Esimerkiksi 30 miljardin parametrin malli fp16-muodossa vie 60 Gt muistia. Käytännössä inferenssissä on jopa 20 % yleiskustannusta, joten saatat todellisuudessa tarvita noin 70 Gt muistia, jolloin edes yksi GCD LUMIssa ei ehkä riitä esimerkkimallillemme. Jos taas tallentaisit mallin 4-bittisellä kvantisoinnilla, se olisi noin 0,5 tavua parametria kohden, eli noin 15 Gt esimerkissämme (tai noin 18 Gt yleiskustannuksen kanssa).
Koulutuksessa muistia tarvitaan paljon enemmän, koska mallin lisäksi on tallennettava myös optimoijan tilat, gradientit ja aktivaatiot. Hyvin karkeana arviona mallin hienosäätöön tarvitaan noin 4–6 kertaa mallin koko (Gt), mutta tämä riippuu paljon yksityiskohdista. Niinpä esimerkkimme 30B parametrin fp16-malli saattaa vaatia koulutukseen 60 Gt x 6 = 360 Gt GPU-muistia! Käsittelemme tämän ongelman ratkaisukeinoja seuraavissa osioissa. Katso lisätietoja EleutherAI:n Transformer Math 101 -blogikirjoituksesta.
LLM-mallien hienosäätö
Meillä on git-repositorio, jossa on esimerkkiskriptejä LLM-mallien hienosäätöön Puhdissa, Mahdissa tai LUMIssa. Esimerkissä käytetään Hugging Face (HF) -kirjastoja ja erityisesti HF Traineria annetun mallin kouluttamiseen (malli haetaan HF:n mallirepositorioista) IMDb:n elokuva-arvosteluaineistolla. Itse tehtävä ei ehkä ole kovin mielekäs; sitä käytetään vain havainnollistamaan teknistä tehtävää, jossa malli hienosäädetään annetulla aineistolla.
Esimerkit käyttävät oletuksena mallia EleutherAI/gpt-neo-1.3B, koska se mahtuu yhden GPU:n muistiin Puhdissa. Koska kyseessä on 1,37 miljardin parametrin malli 32-bittisillä painoilla, yllä mainitun nyrkkisäännön mukaan se saattaa vaatia koulutukseen jopa 1.37x4x6 = 32 Gt muistia, joten sen pitäisi juuri ja juuri mahtua Puhdin V100-GPU:n 32 Gt:n enimmäismuistiin (jos käy hyvä tuuri).
Repositoriossa on peruskäynnistysskriptit Puhdille, Mahdille ja LUMIlle yhdelle GPU:lle, kokonaiselle noodille (4 GPU:ta Puhdissa/Mahdissa ja 8 GPU:ta LUMIssa) sekä kahdelle kokonaiselle noodille (vastaavasti 8 ja 16 GPU:ta). Slurm-skriptit ovat käytännössä samat kuin missä tahansa PyTorch DDP -ajossa; katso esimerkkejä monen GPU:n ja monen noodin koneoppimisoppaastamme tai katso suoraan GitHub-repositorion skriptejä:
run-finetuning-puhti-gpu1.sh- hienosäätö Puhdissa yhdellä GPU:llarun-finetuning-puhti-gpu4.sh- hienosäätö Puhdissa yhdellä täydellä noodilla (4 GPU:ta)run-finetuning-puhti-gpu8.sh- hienosäätö Puhdissa kahdella täydellä noodilla (yhteensä 8 GPU:ta)
(Repositoriossa on myös skriptejä Mahdille ja LUMIlle, jos katsot tiedostoluetteloa.)
Perusversiot usealle GPU:lle käyttävät kaikki PyTorch Distributed Data Parallel (DDP) -tilaa, jossa jokaisella GPU:lla on täydellinen kopio mallista. Vain koulutusdata jaetaan eri GPU:iden kesken. Tämä tarkoittaa, että koko mallin on mahduttava yhdelle GPU:lle.
Jos mallisi ei mahdu yhdelle GPU:lle Puhdissa, se saattaa toimia Mahdissa tai LUMIssa, mutta tarkista ensin yllä mainitulla nyrkkisääntölaskelmalla, onko siihen edes mahdollisuutta! Jos ei, jatka lukemista PEFT- ja FSDP-lähestymistavoista.
Vahvistusoppiminen LLM-malleilla
Esimerkkiskriptejä vahvistusoppimiseen LLM-malleilla on saatavilla
vahvistusoppimisen hienosäätörepositoriossa. Esimerkeissä
käytetään verl-kirjastoa, joka on avoimen lähdekoodin kehys
LLM-mallien vahvistusoppimisen jälkikoulutukseen. verl tukee monia
olemassa olevia LLM-kehyksiä, ja esimerkeissä käytetään FSDP2:ta
tai Megatronia mallin koulutukseen sekä vLLM:ää
vastausten tuottamiseen.
Esimerkit havainnollistavat vahvistusoppimista todennettavilla palkkioilla (RLVR) käyttäen GRPO-algoritmia. Niissä hienosäädetään Qwen3-0.6B- ja Qwen3-8B-malleja GSM8K-matematiikka-aineistolla. Repositorio sisältää ympäristön asetukset ja Slurm-skriptit esimerkkien ajamiseen yhdellä ja kahdella LUMI-noodilla.
PEFT:n ja LoRAn käyttö
Vaikka mallisi mahtuisi GPU-muistiin, on silti mahdollista, että hienosäätöprosessin yleiskustannusten vaatima lisämuisti ei mahdu (muistat tämän nopeasti, kun ohjelma kaatuu CUDA- tai ROCm-muistin loppumisvirheeseen!). Tällöin ratkaisuna voi olla Parameter Efficient Fine-Tuning (PEFT) -kirjaston käyttö, joka kouluttaa pienemmän määrän lisäparametreja ja vähentää siten koulutuksen yleiskustannusta merkittävästi. PEFT tukee monia menetelmiä, kuten LoRA ja QLoRA.
PEFT:llä on tyypillisesti noin 10 % alkuperäisestä parametrimäärästä, mutta säästetyn GPU-muistin määrä vaihtelee tilanteen mukaan. Olemme nähneet säästöjä 5 %:sta 60 %:iin.
PEFT on erittäin helppo ottaa käyttöön; katso esimerkki
PEFT:n pikaoppaasta. Yllä olevaan esimerkkiin PEFT voidaan ottaa
käyttöön yksinkertaisesti lisäämällä lippu --peft. Voi myös olla
hyödyllistä perehtyä hieman syvemmin esimerkiksi LoRAn parhaisiin
parametreihin.
Acceleraten ja FSDP:n käyttö
Suuremmille malleille, jotka eivät mahdu GPU-muistiin (edes inferenssissä), on käytettävä lähestymistapaa, jossa varsinainen malli (ja koulutuksen yleiskustannus) jaetaan usealle GPU:lle. Emme voi enää säilyttää täydellistä kopiota mallista jokaisella GPU:lla.
Hyvä lähestymistapa, jota PyTorch tukee natiivisti, on Fully Sharded Data Parallel (FSDP). FSDP:ssä mallin parametreja, gradientteja ja optimoijan tiloja ei tallenneta kokonaan jokaiselle GPU:lle, vaan ne jaetaan (shardataan) kaikkien GPU:iden kesken ja kootaan yhteen vain tarpeen mukaan koulutuksen kulloisessakin vaiheessa.
Ehkä helpoin tapa ottaa FSDP käyttöön suurille kielimalleille on
käyttää Hugging Facen Accelerate-kehystä. PyTorch-skriptiin ei tarvita
muutoksia; tarvitsee vain vaihtaa käynnistimeksi accelerate.
GitHub-repositoriossamme on esimerkkiskriptejä käynnistämiseen
yhdellä tai kahdella täydellä noodilla Puhdissa:
run-finetuning-puhti-gpu4-accelerate.sh- hienosäätö Puhdissa yhdellä täydellä noodilla käyttäen Acceleratearun-finetuning-puhti-gpu8-accelerate.sh- hienosäätö Puhdissa kahdella täydellä noodilla käyttäen Acceleratea
(Repositoriossa on myös skriptejä Mahdille ja LUMIlle, jos katsot tiedostoluetteloa.)
Monen GPU:n ja monen noodin koneoppimisoppaassamme on myös Slurm-skriptiesimerkkejä Acceleraten käytöstä FSDP:n kanssa.
Acceleratea käytettäessä on huomioitava kaksi asiaa:
-
accelerate-käynnistin odottaa konfiguraatio-YAML-tiedostoa. Olemme toimittaneet GitHub-repositorioon kaksi esimerkkiä:accelerate_config.yamlperusesimerkkiä varten jaaccelerate_config_fsdp.yamlFSDP:n käyttöä varten. Nämä konfiguraatiot käyttävät järkeviä oletusparametreja, mutta niitä voi olla hyödyllistä säätää, erityisesti kannattaa katsoa FSDP:n parametreja. -
Monen noodin ajoissa sinun on käynnistettävä
accelerate-käynnistin erikseen jokaisella noodilla siten, että argumentti--machine_rankasetetaan noodin rankin mukaan (0 = ensimmäinen noodi, 1 = toinen noodi jne.). Tämän asettamiseen voidaan käyttää muuttujaa$SLURM_NODEID, mutta tarvitaan shell-temppu, jotta sitä ei evaluoida ennen kuin se todella suoritetaan kyseisellä noodilla. (Katso skriptistärun-finetuning-puhti-gpu8-accelerate.shesimerkki siitä, miten tämä voidaan tehdä.)
Voit käyttää myös PEFT:iä (LoRAa) Acceleraten kanssa lisäämällä
esimerkkiskriptiimme lipun --peft.
Vaihtoehtoiset trainerit
Vaihtoehto tavalliselle Hugging Face Trainerille LLM-mallien hienosäädössä on SFTTrainer TRL-kirjastosta. Näitä ei käsitellä tässä oppaassa. Suosittelemme tutustumaan esimerkiksi tähän Hugging Facen hienosäätöoppaaseen, joka käsittelee myös Unsloth-kirjastoa.
Hienosäätöesimerkki ilmastodatalla
Käytännön hienosäätöesimerkki löytyy repositoriostamme. Esimerkki keskittyy ilmastoon liittyvien tieteellisten artikkeleiden hyödyntämiseen Copernicuksesta pienempikokoisten LLM-mallien hienosäätöön (tässä tapauksessa Llama-3.1-8B-Instruct-malli).
Kvantisointi
Kvantisointi on prosessi, jossa LLM:n painot ja aktivaatiot muunnetaan korkean tarkkuuden arvoista, kuten 32-bittisistä liukuluvuista, matalamman tarkkuuden arvoiksi, kuten 8-bittisiksi kokonaisluvuiksi. Tämä pienentää mallin kokonaiskokoa merkittävästi, mikä vähentää muistitarvetta pienen tarkkuuden heikkenemisen kustannuksella. Voit oppia lisää kvantisoinnista esimerkiksi tästä oppaasta.
Kvantisointi voidaan tehdä inferenssin tai koulutuksen aikana. Post-Training Quantization (PTQ) tarkoittaa valmiiksi koulutetun mallin kvantisointia inferenssivaiheessa. Quantization-Aware Training (QAT) tehdään koulutuksen aikana kvantisoinnin vaikutusten simuloimiseksi, minkä tuloksena saadaan kvantisointikohinaa paremmin sietävä malli. Tämä opas keskittyy Post-Training Quantizationiin.
Hyvin suurten mallien kvantisointi voi kestää tunteja, mutta onneksi monista malleista on jo saatavilla kvantisoitu versio esimerkiksi Hugging Facessa. Voit etsiä kvantisoituja malleja mallinimen loppuliitteestä, joka ilmaisee kvantisointimenetelmän, kuten AWQ, GPTQ tai GGUF, tai vaihtoehtoisesti mallin tarkkuuden, kuten 8bit tai 4bit.
bitsandbytes-kvantisoinnin käyttö
Hugging Face Transformersin bitsandbytes-kirjasto tarjoaa ajonaikaisen kvantisoinnin, joka pakkaa painot 8- tai 4-bittisiksi lennossa inferenssin aikana muistin säästämiseksi.
from transformers import BitsAndBytesConfig, AutoModelForCausalLM
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_storage=torch.bfloat16,
)
model = AutoModelForCausalLM.from_pretrained(
args.model,
quantization_config=bnb_config,
...
)
--4bit. Vaihtoehtoisesti katso
Github-repositoriostamme
täysi esimerkki mallin kvantisoinnista bitsandbytesilla Puhdissa,
Mahdissa tai LUMIssa.
GPTQ-kvantisoinnin käyttö
bitsandbytesin lisäksi Hugging Face Transformersiin on integroitu myös Gradient Post-Training Quantization (GPTQ). GPTQ suorittaa painomatriisien rivikohtaisen kvantisoinnin optimoiden jokaisen rivin erikseen niin, että kvantisoidut painot vastaavat alkuperäisiä arvoja mahdollisimman hyvin minimaalisella rekonstruktio-virheellä.
Toisin kuin ajonaikaiset kvantisointikirjastot, kuten bitsandbytes, GPTQ tekee kertaluonteisen pakkausvaiheen kalibrointiaineiston avulla, minkä tuloksena syntyy uusi kvantisoitu malli, joka voidaan tallentaa ja ladata ilman alkuperäisiä täystarkkuuspainoja. Jotta voit käyttää transformersin GPTQ-kvantisointia, luo GPTQConfig -luokka, jossa määritellään kvantisointibittien määrä, aineisto painojen kalibrointiin kvantisointia varten sekä tokenisaattori.
from transformers import GPTQConfig, AutoModelForCausalLM
gptq_config = GPTQConfig(
bits=4,
dataset="c4",
tokenizer=tokenizer
)
model = AutoModelForCausalLM.from_pretrained(
args.model,
quantization_config=gptq_config,
...
)
GPTQ tukee eri taustajärjestelmiä nopeampaa inferenssiä varten, kuten
Marlinia (optimoitu A100:lle) ja ExLlamaV2:ta (optimoitu LLaMA-malleille
kuluttajatason GPU:illa). Ota tietty taustajärjestelmä käyttöön
välittämällä backend="marlin" tai exllama_config={"version": 2}
GPTQConfig-luokalle.
Hugging Facen blogikirjoitus vertailee bitsandbytesin ja GPTQ:n ominaisuuksia, mikä voi auttaa päättämään, kumpi sopii paremmin käyttötapaukseesi. Katso myös Github-repositoriostamme täysi esimerkki mallin kvantisoinnista GPTQ:lla Hugging Face Transformersin avulla Puhdissa, Mahdissa tai LUMIssa.
GPTQ-kvantisoinnin käyttö LLM Compressorin kautta
Toinen tapa tehdä kvantisointia on käyttää GPTQ-modifioijaa
LLM Compressor
-kirjastosta. LLM Compressor on Hugging Face -mallien koulutuksen
jälkeinen pakkaustyökalupakki. Se soveltaa jo koulutettuun malliin
reseptiä (esim. GPTQ-kvantisointia) ja tallentaa pakatun checkpointin,
joka voidaan ladata takaisin transformers-kirjastoon. Ajonaikana se
vaihtaa mallin lineaarikerrokset pakattuihin ytimiin, jolloin generointi
käyttää kvantisoituja matriisikertolaskuja ilman muutoksia
inferenssikoodiisi. GPTQModifier on kvantisointireseptin komponentti,
joka suorittaa GPTQ:n ja kvantisoi painot esimerkiksi muotoon W4A16
(4-bittiset painot, 16-bittiset aktivaatiot) käyttäen pientä
kalibrointijoukkoa, ja sen avulla voit kvantisoida kohdekerroksia
(esim. Linear) ja ohittaa päitä (esim. lm_head) tulosteen laadun
säilyttämiseksi.
from llmcompressor.entrypoints.oneshot import oneshot
from llmcompressor.modifiers.quantization import GPTQModifier
# Define a GPTQ recipe: 4-bit weights (W4A16), target Linear layers, skip the LM head
recipe = GPTQModifier(targets="Linear", scheme="W4A16", ignore=["lm_head"])
# Apply GPTQ using a small calibration dataset (internally sampled by your script/flags).
# The dataset below ("HuggingFaceH4/ultrachat_200k") is only an example—replace with one suited to your model.
oneshot(model=model, dataset="HuggingFaceH4/ultrachat_200k", recipe=recipe)
AWQ-kvantisoinnin käyttö LLM Compressorin kautta
LLM Compressor -kirjastolla voit kvantisoida mallin myös Activation-Aware Weight Quantization (AWQ) -menetelmällä. AWQ perustuu havaintoon, että kaikki LLM:n painot eivät vaikuta mallin suorituskykyyn yhtä paljon. Suojaamalla vain noin \~1 % merkittävimmistä painokanavista kvantisointivirhettä voidaan vähentää huomattavasti. Nämä merkittävät kanavat tunnistetaan aktivaatioiden jakaumien perusteella eikä raakojen painoarvojen mukaan.
from llmcompressor.entrypoints.oneshot import oneshot
from llmcompressor.modifiers.quantization import GPTQModifier
# Define AWQ recipe: 4-bit weights (W4A16_ASYM), target Linear layers, skip LM head
recipe = [AWQModifier(targets=["Linear"], scheme="W4A16_ASYM", ignore=["lm_head"])]
# Apply AWQ with a small calibration set (dataset can be your own or a public one)
# The dataset below ("HuggingFaceH4/ultrachat_200k") is only an example—replace with one suited to your model.
oneshot(
model=model,
dataset="HuggingFaceH4/ultrachat_200k", # uses 'validation' split by default inside your script/flags
recipe=recipe,
)
Retrieval-augmented generation (RAG)
Retrieval-augmented generation (RAG) on tapa käyttää valmiiksi koulutettua suurta kielimallia yhdessä käyttäjän oman aineiston kanssa ilman laskennallisesti kallista hienosäätöä tai mallin uudelleenkoulutusta. Lyhyesti tämä toimii siten, että aineistossa tehdään haku ja parhaat tulokset annetaan kielimallille lisäkontekstiksi.
RAG:ssa haku on järjestelmän kriittinen osa, sillä epäonnistunut haku antaa LLM:lle väärän kontekstin, mikä johtaa helposti siihen, että LLM tuottaa epäolennaista tietoa. Tehokkaassa haussa voidaan hyödyntää upotusmalleja ja nopeita vektorihakumenetelmiä. Katso esimerkki siitä, miten supertietokoneita voidaan hyödyntää Faiss-vektorivaraston valmisteluun uusinta tasoa edustavilla upotusmalleilla, RAG-60K-repositoriostamme.
Inferenssi
Inferenssi, eli mallin käyttäminen sen kouluttamisen sijaan, on yleensä
paljon yksinkertaisempaa. Esimerkkigit-repositoriossamme on
inferenssiesimerkki tiedostoissa inference-demo.py ja
run-inference-puhti.sh. Jos mallisi ei mahdu yhdelle GPU:lle, voit
yksinkertaisesti varata enemmän GPU:ita ja antaa sitten Hugging Facen
hoitaa loput asettamalla mallia ladattaessa device_map='auto',
esimerkiksi näin:
Inferenssi Ollamalla
Ollama on suosittu työkalu LLM-mallien käyttöön, sillä se tukee useita uusinta tasoa edustavia malleja, joita voidaan käyttää API:n kautta. Ollama on suunniteltu toimimaan palveluna, eikä se siksi sovellu suoraan eräajoksi supertietokoneilla. Sitä voidaan kuitenkin ajaa osana eräajoa käynnistämällä palvelu työn alussa ja pysäyttämällä se työn päättyessä.
Ensin voit asentaa Ollaman projektikansioosi näin:
cd /projappl/project_2001234 # replace with the appropriate path for you
mkdir ollama
cd ollama
wget https://ollama.com/download/ollama-linux-amd64.tar.zst
tar -xf ollama-linux-amd64.tar.zst
rm ollama-linux-amd64.tar.zst
LUMIssa sinun on tehtävä lisäksi tämä (samassa yllä olevassa hakemistossa). Huomaa, että ylimääräisten ROCm-tiedostojen kanssa asennus vie 14 Gt levytilaa!
wget https://ollama.com/download/ollama-linux-amd64-rocm.tar.zst
tar xf ollama-linux-amd64-rocm.tar.zst
rm ollama-linux-amd64-rocm.tar.zst
Eräajossasi sinun tarvitsee sitten vain käynnistää palvelu komennolla
ollama serve. Sen jälkeen työsi voi käyttää API:a localhostissa
portissa 11434. On myös hyvä idea asettaa ympäristömuuttuja
OLLAMA_MODELS osoittamaan projektin scratch-alueelle, koska muuten se
lataa valtavat mallitiedostot kotihakemistoosi. Katso
esimerkkislurm-skriptimme run-ollama.sh Ollaman kanssa ajamiseen.
ai-inference-examples-repositoriossa on myös joitakin esimerkkejä
Ollaman ajamisesta täydellä noodilla, jossa on 4 GPU:ta Puhdissa ja
8 GPU:ta LUMIssa.
Inferenssi vLLM:llä
vLLM on toinen kirjasto LLM-inferenssin ajamiseen. vLLM tukee offline-eräinferenssiä, joka on supertietokoneilla ajamiseen parhaiten soveltuva tila. Tämä toimii tavallisena Python-eräajona.
Tässä on käyttäjän laatima esimerkki suuren aineiston tehokkaasta käsittelystä vLLM:llä: https://github.com/TurkuNLP/ECCO-ocr-large-run.
Joissakin tilanteissa tarvitaan silti OpenAI-yhteensopiva palvelin,
esimerkiksi kun liitytään muihin ohjelmiin. Esimerkkiskriptejä
vLLM:n ajamiseen Puhdissa, Mahdissa ja LUMIssa löytyy
ai-inference-examples-repositoriostamme. Mukana on myös
esimerkki ajamisesta usealla noodilla LUMIssa
(run-vllm-lumi16.sh).