Diplomovka/perun/README.md
2026-11-04 23:46:33 +01:00

20 KiB
Raw Blame History

Slovenská Aya: Mistral-SK a OLMo

Scenár

Cieľom je inštrukčne dotrénovať Mistral-SK-7B a základný OLMo 2 7B na spoločnej slovenskej časti Aya Collection a porovnať ich adaptáciu. Použije sa SFT s LoRA v LLaMA-Factory, zrýchlený Unslothom. Jeden tréning využije štyri H200 na jednom uzle Peruna cez DDP.

Možnosti LoRA do návrhu scenára:

  • LoRA (Low-Rank Adaptation)
  • QLoRA (Quantized Low-Rank Adaptation)
  • rsLoRA (Rank-Stabilized LoRA)
  • DoRA (Weight-Decomposed Low-Rank Adaptation)

Prehľad súborov

Súbor Úloha
configs/mistral.yaml Základný tréningový config pre slovak-nlp/mistral-sk-7b.
configs/olmo.yaml Základný tréningový config pre allenai/OLMo-2-1124-7B.
scripts/prepare_data.py Načítanie, čistenie, deduplikácia a rozdelenie dát.
scripts/train.py Spustenie LLaMA-Factory podľa zvoleného configu.
scripts/evaluate.py Loss, perplexita, generovanie a slovný F1 / presná zhoda na eval alebo test množine.

Balík má spolu šesť súborov. evaluate.py odvodí nastavenia z rovnakého modelového YAML a konkrétnu použitú konfiguráciu uloží až k výsledkom.

Poradie používania je príprava dát → tréning → vyhodnotenie. Príprava dát sa vykoná raz pre oba modely. Tréning sa spustí samostatne pre každý model alebo experiment a následne sa vyhodnotí vytvorený adaptér. Model a hyperparametre sa nastavujú v YAML; Python skripty vykonávajú jednotlivé kroky.

Spoločný dataset do 4 096 tokenov a nastavenie H200

Oba modely používajú cutoff_len: 4096. Limit zahŕňa celú SFT sekvenciu: systémový text Alpaca, inštrukciu a prípadný vstup, celú referenčnú odpoveď, EOS a koncové oddeľovače. Spúšťací skript kontroluje pôvodnú kontextovú kapacitu modelu podľa cutoff_len.

prepare_data.py si načíta oba YAML configy a ich presné tokenizéry. Celý pár vyradí, ak prekročí limit čo i len pri jednom modeli. Všetky ponechané príklady zapíše bez orezania. Filtrovanie prebehne pred deduplikáciou a spoločným rozdelením na train/eval/test, takže oba modely dostanú rovnaké príklady. Inštrukcia a pole input sa spájajú rovnako ako v Alpaca konvertore LLaMA-Factory.

Nastavenie jedného tréningu:

  • štyri H200 cez DDP, bf16: true, use_unsloth: true, use_unsloth_gc: true, bez kvantizácie;
  • batch 8 na GPU, akumulácia 1: 4 × 8 × 1 = efektívny batch 32;
  • eval loss s batchom 8 na GPU, záverečné generovanie po jednom príklade;
  • LoRA rank 16, alpha 32, dropout 0, projekcie attention aj MLP;
  • jedna epocha, AdamW, cosine scheduler, warmup 8 %, clipping gradientov 0,5;
  • loss iba z odpovedí, bez packingu, dynamický padding na dĺžku aktuálnej dávky;
  • validácia/checkpoint každých 1 000 optimizer krokov, výber podľa najnižšieho loss, limit checkpointov 2.

Spúšťač overuje, že dáta majú záznam o dĺžkovom filtrovaní pre daný model, revíziu, šablónu a limit. Kontrola pri tokenizácii tiež zastaví beh, ak by predspracovanie chcelo orezať vstup alebo odpoveď. Konfigurácia načítaného základného modelu sa uloží do adapter/base_model_config.json.

LR 0.0001 pri Mistrale nadväzuje na 300k experiment; pri OLMo je východiskový kandidát. Zmenené nastavenia stále treba overiť podľa eval dát. OLMo je základný model pre vlastné SFT a jeho karta uvádza angličtinu.

Prostredie na Perunovi

Na spustenie sa používa kompatibilné GPU prostredie s LLaMA-Factory, Unsloth, Unsloth Zoo, PyTorch a CUDA pre H200. LLaMA-Factory používa aj datasets, huggingface_hub a PyYAML; generatívna evaluácia potrebuje rouge-chinese, jieba a nltk. Python má byť aspoň 3.11 podľa aktuálnych požiadaviek LLaMA-Factory. Dĺžkový filter pri príprave dát používa Transformers a PyYAML a načíta oba tokenizéry; váhy modelov na túto CPU úlohu nepotrebuje.

Požiadavky a inštalácia prostredí

Priečinok requirements obsahuje verzie odvodené z exportu Hrušky.

Súbor Prostredie
requirements/training.txt Python 3.11.16; LLaMA-Factory, Unsloth, PyTorch 2.6.0 s CUDA 12.4 a generatívna evaluácia.
requirements/lm-eval.txt Python 3.11.16; lm-evaluation-harness, Transformers 4.48.2 a PyTorch 2.6.0 s CUDA 12.4.
requirements/skbench.txt Python 3.13.17; export 308 balíkov SK-bench vrátane vLLM 0.28.0, Transformers 5.12.1 a PyTorch 2.13.0.
requirements/skbench/pyproject.toml a uv.lock Pôvodné závislosti a uzamknuté verzie SK-bench pre obnovenie cez uv.

Git závislosti LLaMA-Factory, lm-eval a lighteval sú pripnuté na pôvodné commity. Neplatná lokálna cesta k pip bola v tréningovom a lm-eval exporte nahradená verziou pip==26.2.1 z Condy. Výpočtové knižnice zachovávajú pôvodné verzie.

Do tréningových požiadaviek boli doplnené jieba==0.42.1, rouge-chinese==1.0.3, nltk==3.10.3 a jeho závislosti joblib==1.6.0 a defusedxml==0.7.1 pre generatívnu evaluáciu. Doplnený je aj torchao==0.13.0, pretože ho vyžaduje zachytená verzia Unsloth Zoo a export ho neobsahoval. Táto verzia TorchAO podporuje Python API s PyTorch 2.6; jej natívne C++ rozšírenia sú určené pre PyTorch 2.8. Scenár používa LoRA bez kvantizácie TorchAO.

Pre tréning je setuptools upravený na 80.10.2, rovnako ako vo funkčnom SK-bench exporte. Knižnica jieba používa pkg_resources, ktorý bol zo setuptools 82 odstránený. Tréningové a benchmarkové verzie ostatných zachytených balíkov sa nemenia.

Ide o požiadavky pripravené z funkčných prostredí Hrušky a uvedených doplnení. Čistá inštalácia a výpočet na H200 sa overia na Perunovi.

Tréning a evaluácia na pripravených Aya dátach

Nasledujúce príkazy sa zadávajú z koreňa balíka v prostredí s dostupnou Condou a Gitom. PyTorch a xformers sa najprv nainštalujú z rovnakého oficiálneho CUDA 12.4 indexu:

conda create -n aya_train_perun python=3.11.16 pip=26.2.1 -y
conda activate aya_train_perun

python -m pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 xformers==0.0.29.post3 \
  --index-url https://download.pytorch.org/whl/cu124

python -m pip install -r requirements/training.txt
python -m pip check

Na pridelenom GPU uzle sa overia importy, CUDA a BF16:

python -c 'import unsloth, torch, jieba, nltk; from rouge_chinese import Rouge; assert torch.cuda.is_available(); assert torch.cuda.is_bf16_supported(); print("GPU:", torch.cuda.get_device_name(0)); print("Viditelne GPU:", torch.cuda.device_count()); print("CUDA:", torch.version.cuda)'

Príprava dát, tréning aj scripts/evaluate.py sa potom spúšťajú v aya_train_perun podľa ďalších častí dokumentácie. Overené opravy generovania z Titanu sú súčasťou scripts/train.py.

lm-evaluation-harness

Príkazy sa zadávajú z koreňa balíka:

conda create -n aya_lmeval_perun python=3.11.16 pip=26.2.1 -y
conda activate aya_lmeval_perun

python -m pip install torch==2.6.0 --index-url https://download.pytorch.org/whl/cu124
python -m pip install -r requirements/lm-eval.txt
python -m pip check
lm_eval --help

Súbor inštaluje framework pri revízii 6d2abda4fd171e68a8789330c4149e37c1ca0bda. Vlastné slovenské úlohy, zoznam benchmarkov a evaluačné dáta sa prenášajú samostatne; požiadavky obsahujú Python knižnice.

SK-bench

Na obnovenie SK-bench sa používa uv 0.13.5 a zdrojová kópia projektu z Hrušky pri revízii 15823bbcc2d995e69441fcb7d34abb61bd8180c5. Súbory pyproject.toml a uv.lock sa skopírujú z tohto balíka do koreňa zdrojovej kópie SK-bench. Ak je uv potrebné doplniť, nainštaluje sa cez python -m pip install uv==0.13.5 v existujúcom Python prostredí; vlastné závislosti SK-bench sa vytvoria v jeho samostatnej .venv.

Z koreňa balíka, pri zdrojovej kópii SK-bench uloženej v ../sk-bench:

cp requirements/skbench/pyproject.toml requirements/skbench/uv.lock ../sk-bench/
cd ../sk-bench

uv sync --locked --no-default-groups --python 3.13.17
uv pip check --python .venv/bin/python
uv run --locked python -c 'import torch, vllm, transformers; print(torch.__version__, vllm.__version__, transformers.__version__)'

Základná uzamknutá zostava zodpovedá všetkým 308 balíkom exportovaným z Hrušky. Skupiny dev a hpc sa pri tomto obnovení nepridávajú. requirements/skbench.txt uchováva rovnaké konkrétne verzie v pip formáte; pri používaní projektu cez uv sa vychádza z jeho uv.lock.

SK-bench používa CUDA 13; pri jeho prenose sa na pridelenom GPU uzle overí ovládač cez nvidia-smi a dostupnosť CUDA v PyTorchi. Pôvodný export Hrušky uvádza ovládač 580.178.04.

Zdroje: PyTorch CUDA zostavy, kompatibilita TorchAO, závislosti Unsloth Zoo 2026.8.16, zmeny setuptools, uzamknuté prostredia uv.

Odosielanie úloh cez Slurm

Priame Python príkazy sú určené pre už pridelený výpočtový uzol. Z prihlasovacieho uzla sa úlohy odosielajú cez sbatch --wrap. Príkazy sa zadávajú z koreňa balíka s aktivovaným Python prostredím; tento priečinok sa použije aj pri výpočte.

Pred odoslaním sa v rovnakom termináli nastavia projektový účet a QoS. Hodnoty NAZOV_PROJEKTU a PRIDELENE_QOS sa nahradia údajmi prideleného projektu:

AYA_ACCOUNT="NAZOV_PROJEKTU"
AYA_QOS="PRIDELENE_QOS"

Na Perunovi sa pre výpočet používa pracovný priečinok na SCRATCH. Dáta a výsledky určené na uchovanie sa po výpočte skopírujú do projektového úložiska. Parameter --time určuje maximálny čas úlohy.

1. Príprava dát

Príkazy sa spúšťajú z koreňa balíka s aktivovaným Python prostredím. Príprava dát používa CPU; na Perunovi sa vykonáva na výpočtovom uzle s pridelenými CPU.

python scripts/prepare_data.py --output-dir data/aya_slovak_4096

Odoslanie prípravy dát ako CPU úlohy:

sbatch --job-name=aya_prepare \
  --account="$AYA_ACCOUNT" --qos="$AYA_QOS" \
  --partition=cpu_short --nodes=1 --ntasks=1 \
  --cpus-per-task=8 --mem=64G --time=12:00:00 \
  --output=%x_%j.log \
  --wrap='python -u scripts/prepare_data.py --output-dir data/aya_slovak_4096'

Tréningové úlohy sa odosielajú po úspešnom dokončení prípravy dát.

Výstupný priečinok prípravy dát musí byť nový alebo prázdny.

prepare_data.py

Jeho vstupom sú slovenské zdrojové dáta Aya Collection a obe modelové konfigurácie. Používa CPU a tokenizéry Mistralu a OLMo. Výsledkom je jeden spoločný dátový balík pre oba modely.

  1. Načíta slovenský split train datasetu CohereLabs/aya_collection_language_split pri pevnej revízii. Zdroj číta postupne.
  2. Vyradí neplatné riadky, prázdne zadania a prázdne odpovede. Polia inputs a targets prevedie na instruction/input/output a odstráni okrajové medzery.
  3. Pomocou oboch tokenizérov zmeria celú SFT sekvenciu vrátane formátu Alpaca a odpovede. Ak príklad prekročí cutoff_len pri ktoromkoľvek modeli, vyradí celý pár.
  4. Odstráni duplicitné normalizované páry zadania a odpovede. Rovnaké normalizované zadanie s rôznymi odpoveďami ponechá ako jednu skupinu.
  5. Podľa seedu, predvolene 42, vytvorí train/eval/test. Celá skupina zadania zostane v jednej množine. Do eval a test vyberie najviac 1 000 príkladov na každú množinu; ostatné ponechané príklady patria do train.
  6. Uloží dáta vo formáte, ktorý následne načíta LLaMA-Factory.

Príklad uloženého riadka:

{"instruction":"Aké je hlavné mesto Slovenska?","input":"","output":"Bratislava."}

Výstupy v data/aya_slovak_4096:

Súbor Obsah a použitie
train.jsonl Príklady na učenie LoRA parametrov.
eval.jsonl Validačné príklady na sledovanie loss a ladenie.
test.jsonl Odložené príklady na záverečné vyhodnotenie.
dataset_info.json Registrácia súborov pod názvami aya_train, aya_eval, aya_test a mapovanie ich stĺpcov pre LLaMA-Factory.
manifest.json Zdrojová revízia, seed, skutočné počty, nastavenia dĺžkového filtra a kontrolné súčty súborov.
*.metadata.jsonl Pôvod a identifikácia príkladov v rovnakom poradí ako v príslušnom dátovom súbore.
excluded_long.jsonl Identifikácia a namerané dĺžky vyradených dlhých príkladov.

Na deduplikáciu a rozdelenie dát používa dočasnú SQLite databázu. Po úspešnom dokončení ju odstráni; prepínač --keep-db ju ponechá. Počty eval a test príkladov možno nastaviť cez --eval-size a --test-size, seed cez --seed. Vlastný vstupný JSONL možno načítať cez --local-jsonl.

Oba modely potom používajú tie isté výsledné súbory. Každý model si ich pri tréningu tokenizuje svojím tokenizérom. LLaMA-Factory používa pripravené aya_train a aya_eval bez ďalšieho automatického delenia cez val_size.

2. Tréning

train.py

Je to spúšťač tréningu v LLaMA-Factory. Ako vstup dostane modelový YAML a už pripravený dátový balík.

  1. Načíta model, revíziu, cesty k dátam, LoRA parametre, learning rate, batch a ostatné nastavenia z YAML.
  2. Skontroluje existenciu dát, ich kontrolné súčty a zhodu dĺžkového filtra s použitým modelom, revíziou, šablónou a limitom.
  3. Uloží presnú použitú konfiguráciu a záznam behu.
  4. Cez torchrun spustí štyri procesy DDP a v každom zavolá tréning LLaMA-Factory.

Pri aktuálnych konfiguráciách prebieha SFT s LoRA, Unslothom a BF16. Základné váhy modelu sú zmrazené a učia sa LoRA parametre. Loss sa počíta z odpovedí. LLaMA-Factory každých 1 000 optimizer krokov vykoná validáciu a uloží checkpoint; na konci načíta checkpoint s najnižším eval loss.

Kontrola pomocou --dry-run sa vykonáva po príprave dát. Overí základné nastavenia a dátové súbory bez načítania váh a bez spustenia tréningu.

Kontrola konfigurácie a pripravených dát bez spustenia tréningu:

python scripts/train.py configs/mistral.yaml --dry-run
python scripts/train.py configs/olmo.yaml --dry-run

Každý tréning sa spúšťa samostatne v prostredí so štyrmi dostupnými GPU:

python scripts/train.py configs/mistral.yaml
python scripts/train.py configs/olmo.yaml

Odoslanie tréningov cez Slurm na štyri H200. Nasledujúci príklad spustí modely postupne; afterok umožní spustenie OLMo po úspešnom dokončení Mistralu:

AYA_MISTRAL_JOB=$(sbatch --parsable --job-name=aya_mistral \
  --account="$AYA_ACCOUNT" --qos="$AYA_QOS" \
  --partition=gpu_long --nodes=1 --ntasks=1 --gres=gpu:4 \
  --cpus-per-task=32 --mem=256G --time=2-00:00:00 \
  --output=%x_%j.log \
  --wrap='python -u scripts/train.py configs/mistral.yaml')

sbatch --job-name=aya_olmo \
  --dependency="afterok:$AYA_MISTRAL_JOB" \
  --account="$AYA_ACCOUNT" --qos="$AYA_QOS" \
  --partition=gpu_long --nodes=1 --ntasks=1 --gres=gpu:4 \
  --cpus-per-task=32 --mem=256G --time=2-00:00:00 \
  --output=%x_%j.log \
  --wrap='python -u scripts/train.py configs/olmo.yaml'

Jedna úloha Slurmu spustí train.py, ktorý vytvorí štyri procesy DDP. Parametre --run-dir a --resume sa pri odosielaní uvádzajú v Python príkaze vo vnútri --wrap.

Každý proces DDP má na pridelenej GPU kópiu modelu a spracúva inú časť dávky. Gradienty sa synchronizujú medzi GPU, takže štyri GPU vykonávajú jeden spoločný tréning. Pri batchi 8 na GPU a akumulácii 1 je efektívny batch 4 × 8 × 1 = 32. Každý proces importuje Unsloth pred Transformers a LLaMA-Factory.

Výsledkom tréningu je LoRA adaptér, ktorý sa používa spolu so základným modelom. Pre Mistral sa uloží do runs/mistral/adapter, pre OLMo do runs/olmo/adapter. Checkpointy sú v podpriečinkoch adaptéra.

V nadradenom priečinku behu zostanú:

  • train.log – priebeh a hlásenia tréningu;
  • used_config.yaml – presné nastavenia odovzdané LLaMA-Factory;
  • run.json – záznam behu, efektívny batch a identifikácia použitých dát.

3. Vyhodnotenie na eval dátach

evaluate.py

Ako vstup dostane rovnaký modelový YAML, pripravené dáta a dotrénovaný adaptér. Načíta základný model spolu s adaptérom a vykoná dve samostatné fázy na jednej GPU:

  1. Eval loss a perplexita: model spracuje zadania s pôvodnými referenčnými odpoveďami. Vypočíta sa strata pri predpovedaní odpovedí a z nej perplexita.
  2. Generovanie a porovnanie odpovedí: model dostane zadania a vytvorí vlastné odpovede. Skript ich porovná s úplnými referenciami pomocou slovného F1 a normalizovanej presnej zhody.

Predvolene sa vyhodnotí pripravená množina eval.jsonl:

python scripts/evaluate.py configs/mistral.yaml --output-dir results/mistral_eval

python scripts/evaluate.py configs/olmo.yaml --output-dir results/olmo_eval

Po úspešnom dokončení príslušného tréningu sa vyhodnotenie odošle ako úloha s jednou GPU:

sbatch --job-name=aya_mistral_eval \
  --account="$AYA_ACCOUNT" --qos="$AYA_QOS" \
  --partition=gpu_short --nodes=1 --ntasks=1 --gres=gpu:1 \
  --cpus-per-task=8 --mem=64G --time=12:00:00 \
  --output=%x_%j.log \
  --wrap='python -u scripts/evaluate.py configs/mistral.yaml --output-dir results/mistral_eval'

sbatch --job-name=aya_olmo_eval \
  --account="$AYA_ACCOUNT" --qos="$AYA_QOS" \
  --partition=gpu_short --nodes=1 --ntasks=1 --gres=gpu:1 \
  --cpus-per-task=8 --mem=64G --time=12:00:00 \
  --output=%x_%j.log \
  --wrap='python -u scripts/evaluate.py configs/olmo.yaml --output-dir results/olmo_eval'

Pre vyhodnotenie test množiny sa do Python príkazu vo vnútri --wrap pridá --split test a zvolí sa nový výstupný priečinok, napríklad results/mistral_test.

V priečinku behu sa uchovávajú pôvodné súbory run.json a used_config.yaml. Vyhodnotenie porovná manifest pripravených dát so záznamom z tréningu; iné rozdelenie alebo iný dataset odmietne. Rovnaká kontrola platí pre eval aj test.

Adaptér z iného behu sa určí parametrom --adapter runs/mistral_dalsi/adapter. Predvolene sa použije adaptér z output_dir v modelovom YAML. Prepínač --dry-run overí pripravené vstupy a zobrazí odvodené evaluačné nastavenia.

Generovanie je greedy, s jedným lúčom a limitom najviac 256 nových tokenov. Limit možno zmeniť cez --max-new-tokens. Pri každom vstupe sa počet nových tokenov obmedzí aj zostávajúcim miestom do 4 096 tokenov. Celý vstup a úplná referencia zostávajú zachované; prípadné zníženie limitu sa zapíše do logu.

Skript zapisuje výsledky do priečinka z --output-dir:

Súbor Obsah súboru
summary.json Hlavný súhrn: eval loss, perplexita, F1, presná zhoda a počet vyhodnotených príkladov.
loss/eval_results.json Výsledky samostatného výpočtu eval loss v LLaMA-Factory.
generation/generated_predictions.jsonl Vygenerované odpovede modelu.
scores/per_sample.jsonl Predikcia, úplná referencia a skóre pre každý príklad.
scores/metrics.json Podrobné súhrny metrík aj rozdelenie podľa typu úlohy.
evaluation.json Zvolený split, modelový config, adaptér a stav vyhodnotenia.

Pri výsledkoch zostanú aj logy a konkrétne použité konfigurácie oboch evaluačných fáz. Pre vyhodnotenie možno ako vstupný config použiť aj runs/mistral/used_config.yaml alebo OLMo ekvivalent.

Eval slúži na ladenie a výber checkpointu. Po ukončení výberu nastavení sa vyhodnotí odložená testovacia množina a výsledky sa uložia do nového výstupného priečinka:

python scripts/evaluate.py configs/mistral.yaml --split test --output-dir results/mistral_test
python scripts/evaluate.py configs/olmo.yaml --split test --output-dir results/olmo_test

Externé lm-eval a SK-bench majú vlastné spúšťanie. Tento balík obsahuje prípravu dát, tréning a vyhodnotenie na pripravených eval/test dátach.

Sledovanie odoslaných úloh

squeue -u "$USER"

Výstup úlohy sa zapisuje do logu v pracovnom priečinku. V názve %x_%j.log sa %x nahradí názvom úlohy a %j jej číslom. Pre prípravu dát s číslom úlohy 12345:

tail -f aya_prepare_12345.log