Diplomovka/README.md
2026-09-30 21:05:56 +02:00

563 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Instruction fine-tuning slovenského Mistral 7B modelu
## Použitý model
Ako základný model bol použitý:
- `slovak-nlp/mistral-sk-7b`
Výsledný adaptér z prvého experimentu je dostupný na Hugging Face:
- `Jakub1320/mistral-sk-7b-slovak-alpaca-qlora`
---
## Hardvér
Experimenty boli realizované na dvoch serveroch.
### Titan
- 2× NVIDIA TITAN RTX
- 24 GB VRAM na GPU
- výpočty v `fp16`
### Hruška
- 2× NVIDIA RTX A4500
- približne 20 GB VRAM na GPU
- výpočty v `bf16`
---
# Prvý experiment – Slovak Alpaca
## Použitý dataset
Na supervised fine-tuning bol v prvom experimente použitý slovenský inštrukčný dataset:
- `saillab/alpaca-slovak-cleaned`
Dataset obsahuje polia:
- `instruction`
- `input`
- `output`
Dáta boli formátované v Alpaca štýle:
```text
### Inštrukcia:
...
### Vstup:
...
### Odpoveď:
...
```
## Metóda dotrénovania
Model bol dotrénovaný pomocou supervised fine-tuningu cez:
- Unsloth
- TRL `SFTTrainer`
- PEFT LoRA
- QLoRA štýl trénovania
Výsledkom tréningu je PEFT LoRA adaptér, ktorý sa pripája k základnému modelu `slovak-nlp/mistral-sk-7b`.
## Hlavné hyperparametre prvého experimentu
| Parameter | Hodnota |
|---|---:|
| Epochs | 1 |
| Max sequence length | 1024 |
| Batch size | 1 |
| Gradient accumulation | 8 |
| Effective batch size | 8 |
| Learning rate | 2e-4 |
| Optimizer | AdamW 8-bit |
| Scheduler | cosine |
| Warmup steps | 150 |
| LoRA rank | 16 |
| LoRA alpha | 32 |
| LoRA dropout | 0.05 |
| Quantization | 4-bit |
| Compute type | fp16 |
Použité LoRA cieľové moduly:
```text
q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
```
## Vyhodnotenie pomocou vlastného evaluačného skriptu
Model bol vyhodnotený na testovacích príkladoch z datasetu `saillab/alpaca-slovak-cleaned` pomocou metrík ROUGE, BLEU, eval loss a perplexity.
| Metrika | Výsledok |
|---|---:|
| ROUGE-1 | 0.3710 |
| ROUGE-2 | 0.1702 |
| ROUGE-L | 0.2732 |
| BLEU | 6.2850 |
| Eval loss | 0.8081 |
| Perplexity | 2.2435 |
## Vyhodnotenie pomocou lm-evaluation-harness
Hodnotený bol PEFT LoRA adaptér pripojený k základnému modelu:
```text
slovak-nlp/mistral-sk-7b
+
Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
```
### Použité benchmarky
| Benchmark | Popis |
|---|---|
| `arc_sk` | slovenské vedecké/školské otázky s výberom odpovede |
| `hellaswag_sk` | commonsense reasoning a výber najpravdepodobnejšieho pokračovania |
| `m_mmlu_sk` | slovenský všeobecný vedomostný benchmark |
| `truthfulqa_sk_mc1` | hodnotenie pravdivosti odpovedí, multiple choice MC1 |
| `truthfulqa_sk_mc2` | hodnotenie pravdivosti odpovedí, multiple choice MC2 |
| `sklegal` | slovenské právne otázky s výberom odpovede |
| `skquad` | slovenský question-answering benchmark |
Úlohy `sklegal` a `skquad` boli doplnené ako custom tasky.
## Výsledky lm-evaluation-harness
| Task | Počet vzoriek | Metrika | Výsledok |
|---|---:|---|---:|
| `arc_sk` | 1169 | acc | 0.3259 |
| `arc_sk` | 1169 | acc_norm | 0.3473 |
| `hellaswag_sk` | 9485 | acc | 0.4134 |
| `hellaswag_sk` | 9485 | acc_norm | 0.5106 |
| `m_mmlu_sk` | 13062 | acc | 0.2928 |
| `truthfulqa_sk_mc1` | 778 | acc | 0.2391 |
| `truthfulqa_sk_mc2` | 778 | acc | 0.3942 |
| `sklegal` | 1334 | acc | 0.2841 |
| `sklegal` | 1334 | acc_norm | 0.4693 |
| `skquad` | 9583 | exact | 1.9722 |
| `skquad` | 9583 | f1 | 27.7994 |
| `skquad` | 9583 | HasAns_exact | 2.4106 |
| `skquad` | 9583 | HasAns_f1 | 34.1456 |
| `skquad` | 9583 | NoAns_exact | 0.0561 |
| `skquad` | 9583 | NoAns_f1 | 0.0561 |
| `skquad` | 9583 | best_exact | 18.6163 |
| `skquad` | 9583 | best_f1 | 28.3012 |
---
# Experiment so strojovým prekladom datasetu
Cieľom experimentu bolo vyskúšať postup, pri ktorom sa anglické polia datasetu:
- `instruction`
- `input`
- `output`
automaticky preložia do slovenčiny a uložia do novej dátovej množiny so zachovaním pôvodnej štruktúry.
Výstupný formát obsahoval pôvodné anglické texty aj slovenské preklady:
```json
{
"instruction_en": "...",
"input_en": "...",
"output_en": "...",
"instruction_sk": "...",
"input_sk": "...",
"output_sk": "..."
}
```
Vznikla preložená vzorka datasetu s 1000 príkladmi.
Umiestnenie:
```text
translated_datasets/alpaca_translated_en_sk_1000.jsonl
```
---
# Experiment s datasetom Aya Collection
Pre ďalšie experimenty bol použitý dataset:
- `CohereLabs/aya_collection_language_split`
- subset: `slovak`
Používané polia boli mapované nasledovne:
| Pôvodné pole | Použitie pri tréningu |
|---|---|
| `inputs` | prompt / inštrukcia |
| `targets` | odpoveď |
---
# Prvý dlhý Aya tréning na serveri Titan – manuálne ukončený pokus
Pred úspešným 225 000-krokovým tréningom bol na serveri Titan spustený prvý dlhý tréning nad slovenskou časťou datasetu Aya Collection.
Tento experiment bežal na jednej NVIDIA TITAN RTX a používal streaming datasetu. Pôvodný konfiguračný súbor sa podarilo zachovať:
```text
train_mistral_sk_aya_slovak_full_lora.yaml
```
## Konfigurácia prvého dlhého tréningu
| Parameter | Hodnota |
|---|---:|
| Base model | `slovak-nlp/mistral-sk-7b` |
| Dataset | `aya_slovak_full` |
| Template | `alpaca` |
| Fine-tuning | LoRA |
| GPU | 1× NVIDIA TITAN RTX |
| Max sequence length | 1024 |
| Streaming | áno |
| Streaming buffer | 16 384 |
| Batch size per device | 1 |
| Gradient accumulation | 4 |
| Effective batch size | 4 |
| Max steps | 1 037 000 |
| Learning rate | 2e-4 |
| Scheduler | cosine |
| Warmup steps | 500 |
| Max grad norm | 1.0 |
| Optimizer | AdamW 8-bit |
| LoRA rank | 16 |
| LoRA alpha | 32 |
| LoRA dropout | 0.05 |
| Compute type | fp16 |
| Unsloth | áno |
| Unsloth gradient checkpointing | áno |
| Validation size | 1000 |
| Eval interval | každých 50 000 krokov |
| Save interval | každých 10 000 krokov |
| Save total limit | 2 |
Použité LoRA cieľové moduly:
```text
q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
```
Konfigurácia počítala približne s jedným prechodom cez celý slovenský Aya subset:
```text
4 148 187 príkladov / effective batch 4 ≈ 1 037 000 krokov
```
## Dôvod manuálneho ukončenia
Tréning technicky nespadol. Po približne 94 000 krokoch sa však začala výrazne zhoršovať stabilita optimalizácie.
V logu sa objavili extrémne hodnoty `grad_norm`, napríklad:
```text
grad_norm = 125.6
grad_norm = 105.9
grad_norm = 24000
grad_norm = 772.1
grad_norm = 11410
grad_norm = 2714
grad_norm = nan
```
Súčasne začal výrazne kolísať aj training loss, napríklad:
```text
loss = 3.232
loss = 7.081
loss = 5.206
loss = 14.82
```
Neskôr sa v logu objavila aj kombinácia:
```text
loss = 0.0
grad_norm = nan
```
Keďže tréning vykazoval známky numerickej nestability, bol manuálne ukončený približne pri kroku `104 238` z plánovaných `1 037 000`, teda približne po 10 % tréningu.
V čase ukončenia bol runtime približne:
```text
44 hodín 48 minút
```
Tento experiment ukázal, že pôvodné nastavenie nebolo vhodné na pokračovanie v takto dlhom tréningu bez ďalších úprav.
---
# Dlhý Aya tréning na serveri Titan
Na serveri Titan bol spustený dlhý LoRA fine-tuning nad slovenskou časťou Aya Collection.
Na rozdiel od prvého QLoRA experimentu nebola použitá 4-bit kvantizácia.
## Hlavná konfigurácia
| Parameter | Hodnota |
|---|---:|
| Base model | `slovak-nlp/mistral-sk-7b` |
| Dataset | Aya Collection – Slovak |
| Fine-tuning | LoRA |
| Unsloth | áno |
| GPU | 2× NVIDIA TITAN RTX |
| Batch size per device | 1 |
| Gradient accumulation | 8 |
| Effective batch size | 16 |
| Max sequence length | 1024 |
| Max steps | 225 000 |
| Learning rate | 5e-5 |
| Scheduler | cosine |
| Warmup steps | 10 000 |
| LoRA rank | 16 |
| LoRA alpha | 16 |
| LoRA dropout | 0.0 |
| Compute type | fp16 |
| Streaming | áno |
Použité LoRA cieľové moduly:
```text
q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
```
Tréning úspešne dobehol do kroku `225000`.
## Eval loss počas Titan tréningu
| Krok | Eval loss |
|---:|---:|
| 25 000 | 1.0599 |
| 50 000 | 1.174 |
| 75 000 | 1.284 |
| 100 000 | 1.429 |
| 125 000 | 1.342 |
| 150 000 | 1.323 |
| 175 000 | 1.321 |
| 200 000 | 1.213 |
| 225 000 | 1.221 |
Najnižší validačný loss bol zaznamenaný pri kroku `25000`. Tento checkpoint bol samostatne zachovaný pre ďalšie benchmarkové porovnanie s finálnym modelom.
---
# Hruška – 10 porovnávacích experimentov
Na serveri Hruška bola vytvorená séria menších experimentov s cieľom porovnať vplyv vybraných hyperparametrov LoRA fine-tuningu.
Cieľom bolo porovnať vplyv:
- learning rate,
- LoRA rank,
- LoRA alpha,
- optimalizátora,
- LoRA target modulov,
- batch size a gradient accumulation.
## Fixný dataset
Pre férové porovnanie všetkých experimentov bol vytvorený fixný dataset:
```text
aya_slovak_100k_fixed.jsonl
```
Dataset obsahuje presne `100 000` slovenských príkladov z Aya Collection.
Pri jeho vytvorení bol použitý fixný seed. Samotné experimenty už nepoužívali streaming, takže všetky konfigurácie pracovali s rovnakým poolom dát.
Dáta boli uložené vo formáte:
```json
{
"instruction": "...",
"input": "",
"output": "..."
}
```
Pri tréningu bolo `1000` príkladov použitých na validáciu.
## Spoločné nastavenia experimentov
| Parameter | Hodnota |
|---|---:|
| Base model | `slovak-nlp/mistral-sk-7b` |
| Dataset | `aya_slovak_100k_fixed` |
| GPU | 2× NVIDIA RTX A4500 |
| Fine-tuning | LoRA |
| Unsloth | áno |
| Streaming | nie |
| Max sequence length | 1024 |
| Max steps | 6250 |
| Effective batch size | 16 |
| Scheduler | cosine |
| Warmup steps | 500 |
| Max grad norm | 0.5 |
| LoRA dropout | 0.0 |
| Compute type | bf16 |
| Eval interval | každých 1250 krokov |
| Validation size | 1000 |
| Seed | 42 |
Štandardné LoRA cieľové moduly:
```text
q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
```
Výnimkou je experiment 08, ktorý používa iba:
```text
q_proj, k_proj, v_proj, o_proj
```
## Porovnávané konfigurácie
| Experiment | Hlavná zmena |
|---|---|
| `01_baseline_r16_a16_lr5e5_adamw` | baseline: rank 16, alpha 16, LR 5e-5, AdamW |
| `02_optimizer_adamw8bit_r16_a16_lr5e5` | AdamW 8-bit |
| `03_rank8_a16_lr5e5` | LoRA rank 8 |
| `04_rank32_a32_lr5e5` | LoRA rank 32, alpha 32 |
| `05_r16_alpha32_lr5e5` | alpha 32 pri rank 16 |
| `06_lr1e4_r16_a16` | learning rate 1e-4 |
| `07_lr2e5_r16_a16` | learning rate 2e-5 |
| `08_attention_only_r16_a16_lr5e5` | LoRA iba na attention projekciách |
| `09_batch2_accum4_r16_a16_lr5e5` | batch size 2, gradient accumulation 4 |
| `10_r16_a32_lr1e4` | kombinácia alpha 32 + learning rate 1e-4 |
## Výsledky Hruška experimentov
| Experiment | Train loss | Eval loss | Runtime |
|---|---:|---:|---:|
| `01_baseline_r16_a16_lr5e5_adamw` | 0.9290 | 0.7567 | 7:18:05 |
| `02_optimizer_adamw8bit_r16_a16_lr5e5` | 0.9248 | 0.7521 | 7:20:23 |
| `03_rank8_a16_lr5e5` | 0.9308 | 0.7586 | 7:16:23 |
| `04_rank32_a32_lr5e5` | 0.9003 | 0.7292 | 7:22:33 |
| `05_r16_alpha32_lr5e5` | 0.9026 | 0.7323 | 7:17:44 |
| `06_lr1e4_r16_a16` | 0.8890 | 0.7184 | 7:17:30 |
| `07_lr2e5_r16_a16` | 0.9674 | 0.7912 | 7:18:25 |
| `08_attention_only_r16_a16_lr5e5` | 0.9808 | 0.8094 | 6:51:25 |
| `09_batch2_accum4_r16_a16_lr5e5` | 0.9290 | 0.7563 | 8:24:57 |
| `10_r16_a32_lr1e4` | 0.8612 | 0.6918 | približne 7:15 h |
Najnižší finálny `eval_loss` dosiahol experiment:
```text
10_r16_a32_lr1e4
```
s hodnotou:
```text
eval_loss = 0.6918
```
V tomto experimente bola použitá kombinácia:
```text
LoRA rank = 16
LoRA alpha = 32
learning rate = 1e-4
optimizer = AdamW
effective batch size = 16
```
## Pozorované rozdiely
Z doterajších výsledkov:
- zvýšenie learning rate z `5e-5` na `1e-4` znížilo eval loss z `0.7567` na `0.7184`,
- zvýšenie LoRA alpha z `16` na `32` pri rank 16 znížilo eval loss na `0.7323`,
- kombinácia `alpha=32` a `learning_rate=1e-4` dosiahla najnižší eval loss `0.6918`,
- rank 32 priniesol eval loss `0.7292`,
- rank 8 dosiahol výsledok veľmi blízky baseline,
- attention-only LoRA bola rýchlejšia, ale mala vyšší eval loss,
- zmena z batch size 1 / accumulation 8 na batch size 2 / accumulation 4 nepriniesla zlepšenie validačného lossu ani runtime.
---
# Súbory Hruška experimentov
Výsledky experimentov sú uložené v priečinku:
```text
hruska_10_experiments_results/
```
Súčasťou sú:
```text
hruska_10_experiments_results/
├── aya_slovak_100k_fixed/
├── hruska_10_experiments_results/
│ ├── 01_baseline_r16_a16_lr5e5_adamw/
│ ├── 02_optimizer_adamw8bit_r16_a16_lr5e5/
│ ├── 03_rank8_a16_lr5e5/
│ ├── 04_rank32_a32_lr5e5/
│ ├── 05_r16_alpha32_lr5e5/
│ ├── 06_lr1e4_r16_a16/
│ ├── 07_lr2e5_r16_a16/
│ ├── 08_attention_only_r16_a16_lr5e5/
│ ├── 09_batch2_accum4_r16_a16_lr5e5/
│ └── 10_r16_a32_lr1e4/
├── hruska_experiment_eval_loss_ranking.png
├── hruska_experiment_train_loss_ranking.png
└── hruska_experiment_summary.csv
```
Každý experiment obsahuje:
```text
<experiment>.yaml
training.log
training_loss.png
training_eval_loss.png
```
---
# Benchmarkovanie Hruška experimentov a Titan modelu
Modely sú následne vyhodnocované pomocou `lm-evaluation-harness`.
Používané benchmarky:
```text
arc_sk
hellaswag_sk
m_mmlu_sk
truthfulqa_sk_mc1
truthfulqa_sk_mc2
sklegal
skquad
```
Na Hruške sú postupne benchmarkované všetky modely z 10 porovnávacích experimentov.
Na Titane sa porovnáva:
- finálny model po 225 000 krokoch,
- zachovaný checkpoint z kroku 25 000.
Výsledky tejto časti budú doplnené po dokončení benchmarkov.