Astazi Ember zboara. Vei alege un model de baza, vei atasa adaptere LoRA si vei rula un fine-tune adevarat pe propria masina — calea Mac cu MLX, calea PC cu Unsloth. La finalul acestei lectii vei avea ponderi de adapter pe disc si un model care deja suna diferit fata de baza.
Ce face LoRA de fapt (60 de secunde de teorie)
Fine-tuning-ul tuturor ponderilor chiar si al unui model 4B are nevoie de ~70 GB. Ideea LoRA: nu trebuie sa schimbi matricile mari de ponderi — poti adauga o mica corectie langa ele. Pentru fiecare matrice vizata, LoRA antreneaza doua matrici subtiri (A si B) al caror produs este corectia. Doar acelea se antreneaza; baza ramane inghetata.
Concept
Butonul numit rank (r) este grosimea acelor matrici adapter. r=8 e o atingere usoara (ton), r=16–32 e standard (proiectul nostru), r=64+ pentru invatare mai grea de sarcini. Rank mai mare = mai multa capacitate de invatare = mai multa memorie si mai mult risc sa memoreze datele tale in loc sa invete din ele.Alegerea modelului de baza
Pentru Ember vrem un model mic, modern, instruction-tuned, cu abilitati multilingve bune. In 2026, punctul dulce pentru acest proiect este Qwen3-4B-Instruct (multilingv excelent, licenta permisiva) — cu Llama-3.2-3B-Instruct si Gemma-3-4B ca alternative solide. Din matematica lectiei 3: QLoRA pe 4B are nevoie de ~4–6 GB. Ambele masini incap lejer — in mod deliberat, pentru ca primul tau run nu ar trebui sa fie in acelasi timp si o lupta cu memoria.
Porneste intotdeauna de la versiunea -Instruct, nu de la baza bruta — ea stie deja sa poarte o conversatie; tu ajustezi comportamentul, nu predai dialogul de la zero.
Calea A — Mac Studio (MLX)
Instalezi o data, apoi antrenezi:
pip install mlx-lm
mlx_lm.lora \
--model Qwen/Qwen3-4B-Instruct \
--train \
--data ./data \
--batch-size 4 \
--iters 600 \
--learning-rate 1e-5 \
--adapter-path adapters/ember-v1
--data ./data arata catre folderul cu train.jsonl / valid.jsonl din lectia 4. MLX descarca modelul la primul run, apoi vei vedea un contor de pasi cu train loss si, periodic, val loss. Pe M3 Ultra, acest run dureaza aproximativ 20–40 de minute.
Vorbeste cu dragonul tau (baza + adaptere, fara merge necesar):
mlx_lm.generate \
--model Qwen/Qwen3-4B-Instruct \
--adapter-path adapters/ember-v1 \
--prompt "My order hasn't arrived and it's been 10 days."
Calea B — PC cu RTX 4090 (Unsloth)
Instalezi (trebuie sa existe un PyTorch cu CUDA), apoi acesta e intregul script de antrenare:
from unsloth import FastLanguageModel
from trl import SFTTrainer, SFTConfig
from datasets import load_dataset
model, tokenizer = FastLanguageModel.from_pretrained(
"unsloth/Qwen3-4B-Instruct",
max_seq_length=2048,
load_in_4bit=True, # QLoRA: 4-bit frozen base
)
model = FastLanguageModel.get_peft_model(model, r=16, lora_alpha=16)
dataset = load_dataset("json", data_files="data/train.jsonl", split="train")
dataset = dataset.map(lambda ex: {"text": tokenizer.apply_chat_template(
ex["messages"], tokenize=False)})
trainer = SFTTrainer(
model=model, tokenizer=tokenizer, train_dataset=dataset,
args=SFTConfig(
per_device_train_batch_size=4,
gradient_accumulation_steps=2,
num_train_epochs=3,
learning_rate=2e-4,
logging_steps=10,
output_dir="adapters/ember-v1",
),
)
trainer.train()
model.save_pretrained("adapters/ember-v1")
Pe 4090 asta se termina in aproximativ 8–15 minute. Unsloth afiseaza loss-ul la fiecare 10 pasi — aceleasi numere de urmarit, acelasi inteles.
Pro Tip
Daca dai de out-of-memory, roteste aceste trei butoane in ordine: (1) redumax_seq_length (2048 → 1024), (2) redu batch size si creste gradient accumulation ca sa compensezi, (3) activeaza gradient checkpointing (use_gradient_checkpointing="unsloth" / MLX --grad-checkpoint). Aceleasi parghii pe ambele masini, in aceeasi ordine.
Citirea loss-ului (primele tale instrumente de zbor)
Loss-ul masoara "cat de surprins este modelul de raspunsul corect" — mai mic e mai bine. Un prim zbor sanatos:
- Train loss scade rapid la inceput (sa zicem 2.1 → 1.3 in primii 100 de pasi), apoi se aplatizeaza usor.
- Val loss il urmeaza in jos, putin mai sus.
- Semnal de alarma: val loss incepe sa urce in timp ce train loss continua sa scada. Acela e overfitting — dragonul memoreaza mancarea in loc sa invete sa vaneze. Lectia 6 se ocupa de el cum trebuie.