563 lines
26 KiB
Markdown
563 lines
26 KiB
Markdown
# 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.
|
||
Konfiguráčny súbor je
|
||
```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.
|