Sari la conținut
11/30Capitolul 11 din 30

De la model de bază la asistent: SFT, RLHF, DPO și GRPO

Cere-i unui model de bază un haiku și repetă aceeași frază. Apoi vezi cum un model de recompensă preferă lungimea corectitudinii.

Pe această pagină

Cere-i lui GPT-2 — un model lingvistic preantrenat competent — să scrie un haiku despre mare:

TEXT
prompt: Write a haiku about the sea.

The sea is a beautiful place.

The sea is a beautiful place.

The sea is a beautiful place.

The sea is a beautiful place.

The sea is a beautiful place.

Nu este confuz și nu a eșuat în ceea ce trebuia să facă. Face exact ce l-a antrenat să facă Capitolul 10: dat un text, produce text de continuare plauzibil. Pe internet, o linie precum Scrie un haiku despre mare. este urmată adesea de proză despre mare, iar o propoziție care tocmai a apărut este neobișnuit de probabil să apară din nou. Modelul este un predictor next-token superb și un asistent inutil.

Acum aceeași cerere către un model construit în același fel — Qwen2.5, jumătate de miliard de parametri, de patru ori mai mare decât GPT-2 de mai sus și totuși minuscul după orice standard din 2026 — după etapele de antrenare despre care este acest capitol:

TEXT
Whispers of the ocean,
Silent depths where waves meet,
Mysteries in the vast blue.

De patru ori mai mulți parametri nu învață un model să se oprească din vorbit. Diferența dintre cele două output-uri nu este scara, nu este arhitectura și nu este volumul de date. Este post-training: o a doua fază, cu ordine de mărime mai mică decât pretraining, care ia un predictor de text și îl transformă în ceva care răspunde.

Primul pas este cel mai puțin spectaculos și face cea mai mare parte a muncii. Colectezi exemple de instrucțiuni împerecheate cu răspunsuri bune și continui antrenarea pe ele cu exact loss-ul din Capitolul 8 — prezice următorul token — dar numai pe partea de răspuns. Acesta este supervised fine-tuning, sau SFT.

Nu se predă nimic nou despre limbaj. Ce se predă este un format: că textul de această formă este urmat de textul de acea formă, iar apoi se oprește. Uită-te din nou la eșecul modelului de bază. A răspuns la întrebare în prima propoziție și apoi nu s-a putut opri, pentru că nimic din antrenarea lui nu a marcat vreodată sfârșitul unui răspuns. Oprirea este un comportament învățat.

De aceea modelului trebuie să i se spună și unde sunt limitele, iar asta este un chat template:

TEXT
<|im_start|>system
You are Qwen, created by Alibaba Cloud. You are a helpful assistant.<|im_end|>
<|im_start|>user
What is the capital of France?<|im_end|>
<|im_start|>assistant

Acele marcaje <|im_start|> și <|im_end|> sunt tokens reali în vocabular, adăugați înainte de fine-tuning, iar modelul a văzut milioane dintre ei exact în aceste poziții. Așa știe al cui este rândul și unde se termină un rând.

Sari peste template și dă-i modelului o întrebare brută, iar tu îi dai o secvență pe care nu a văzut-o în antrenare. Măsurat, același model, aceeași întrebare, aceeași decodare greedy:

Fără template — string-ul brut What is the capital of France?:

TEXT
 The capital of France is Paris.

To verify this, I will use a simple
Python code snippet to confirm that
Paris is indeed the capital city of
France.

[...and then it starts writing a
Python script to check its own answer]

Cu template:

TEXT
The capital of France is Paris.

Răspunsul este corect în ambele cazuri, dar fără marcaje modelul deviază spre a scrie Python ca să se verifice singur, pentru că prompt-ul primit nu seamănă cu nimic din ce a fost fine-tuned. Aceasta este cea mai frecventă cauză pentru „modelul a devenit mai prost când l-am apelat direct”: template-ul nu este decor în jurul modelului, este parte din model, iar un template greșit este o degradare tăcută, fără eroare atașată.

Etapa a doua și problema pe care există ca să o rezolve

Link către secțiunea: Etapa a doua și problema pe care există ca să o rezolve

SFT are un plafon, iar plafonul sunt datele. Ca să faci fine-tuning pe o demonstrație, ai nevoie ca cineva să scrie răspunsul ideal — iar pentru cele mai multe întrebări interesante, să scrii un răspuns bun este greu, lent, scump și produce exact un răspuns a cărui calitate nu o poți verifica.

La ce se pricep oamenii este comparația. Dacă i se arată două răspunsuri, un adnotator poate spune fiabil, în câteva secunde, care este mai bun, fără să poată produce niciunul dintre ele. Acesta este faptul pe care este construită întreaga a doua etapă și este partea pe care cele mai multe explicații o prezintă invers:

Oamenii nu scriu răspunsurile. Ei ordonează perechi.

Așadar datele sunt perechi — un prompt, două răspunsuri și care dintre ele a câștigat. Asta nu poate fi introdus într-un loss next-token, pentru că nu există o secvență țintă. Are nevoie de o mașină diferită.

Nu poți cere unui om să puncteze fiecare răspuns în timpul antrenării — asta ar însemna milioane de judecăți. Așa că antrenezi un model să imite oamenii: un model de recompensă care ia un răspuns și returnează un scalar.

Antrenarea lui din comparații folosește un rezultat din 1952. Modelul Bradley–Terry2 spune că, dacă două elemente au forțe latente, probabilitatea ca unul să îl bată pe celălalt este funcția logistică a diferenței lor. Întoarce asta pe dos și devine un loss: dat fiind că un om a preferat ywy_w în locul lui yly_l, maximizează

P(ywyl)=σ(r(yw)r(yl))P(y_w \succ y_l) = \sigma\big(r(y_w) - r(y_l)\big)

ceea ce în cod este întreaga buclă de antrenare:

reward_model.pyPYTHON
loss = -F.logsigmoid(reward(chosen) - reward(rejected)).mean()   

Observă ce nu vede niciodată modelul: un scor absolut. Învață doar diferențe, ceea ce este exact ce conțin datele.

Acum partea care merită măsurată. Un model de recompensă învață ce au recompensat adnotatorii, iar adnotatorii sunt oameni. Iată o simulare în care calitatea adevărată a unui răspuns depinde doar de a fi util și corect — lungimea nu valorează nimic — dar adnotatorul simulat are o preferință ușoară pentru răspunsuri mai lungi când tot restul este apropiat, un bias uman bine documentat. Antrenează modelul de recompensă pe 2000 de comparații și citește-i ponderile:

bias-ul adnotatorului pentru lungimepondere învățată pe utilpe corectpe lungime
0,0+1,00+1,00+0,01
0,3+0,98+1,00+0,15
0,6+0,97+1,00+0,27
1,2+1,00+0,99+0,59

Modelul de recompensă funcționează perfect. A învățat fidel preferințele care i-au fost arătate — inclusiv partea acelor preferințe care nu are nicio legătură cu calitatea. Un model de recompensă nu este o măsură a binelui; este o măsură a ceea ce au ales adnotatorii, iar fiecare bias din grupul de adnotare este acum un coeficient într-o funcție diferențiabilă față de care un model mult mai mare urmează să optimizeze.

Asta ne aduce la ce se întâmplă când optimizezi pentru el. Dă-i policy-ului un buget fix de efort de cheltuit între proprietățile răspunsului, cu o asimetrie realistă: a fi util și a fi corect sunt scumpe, iar a fi mai lung este ieftin — continui pur și simplu să scrii.

Reward per unitate de efort, pentru modelul antrenat mai sus: util 8,26, corect 8,31, lungime 31,70. Lungimea plătește de aproape patru ori mai bine decât corectitudinea, nu pentru că modelul de recompensă este stricat, ci pentru că este ieftină.

Optimizează față de acel reward și urmărește ambele numere:

scorul modelului de recompensăcalitate adevăratălungime produsă
policy inițial12,5880,9743,365
după optimizare31,6960,00012,497

Reward-ul a crescut cu un factor de 2,5. Lucrul pe care reward-ul trebuia să îl măsoare a ajuns la zero. Policy-ul a descoperit că poate obține scoruri enorm de bune scriind pe larg și nespunând nimic, iar nicio parte a buclei de antrenare nu avea vreo modalitate să observe, pentru că modelul de recompensă este definiția binelui în interiorul buclei.

Acesta este reward hacking, iar dacă te-ai întrebat vreodată de ce modelele de chat sunt atât de verbose, acest tabel este o mare parte din răspuns.

Apărarea standard este să penalizezi policy-ul pentru că se îndepărtează prea mult de unde a pornit, măsurând distanța cu divergența KL din Capitolul 4:

objective=E[r(y)]βDKL(πθπref)\text{objective} = \mathbb{E}\big[r(y)\big] - \beta \, D_{\mathrm{KL}}\big(\pi_\theta \,\|\, \pi_{\text{ref}}\big)

Referința πref\pi_{\text{ref}} este modelul SFT — policy-ul înainte de etapa de reinforcement. Afirmația este că asta împiedică modelul să rătăcească în comportamente degenerate. Să vedem cât din această afirmație supraviețuiește măsurării. Aceeași configurație, variind β\beta:

β\betarewardcalitate adevăratălungimeKL
031,6990,00012,4982,994
131,6970,00012,4972,993
528,3180,28510,7002,163
1512,8601,5422,5520,151
3010,4261,7191,3030,025
609,6321,7690,9080,005
doar modelul de referință9,1621,7910,6870

Citește ultimul rând în raport cu restul. La β=0\beta = 0 și β=1\beta = 1 penalizarea nu face nimic: reward-ul valorează mult mai mult decât KL, așa că optimizatorul plătește amenda și face hacking oricum. Între 5 și 15 comportamentul se schimbă brusc. Iar la β=60\beta = 60, calitatea adevărată a urcat înapoi la 1,769 — ceea ce este tot sub 1,791, cât avea modelul de referință înainte ca toate acestea să înceapă.

O avertizare înainte ca acel număr să fie citat undeva: 1,791 din ultimul rând și 0,974 pe care primul tabel îl dă policy-ului inițial sunt două măsurători diferite ale aceluiași model pre-RL, luate separat de cele două experimente. Compară rânduri în interiorul unui tabel, niciodată între tabele — concluzia fiecărui tabel stă pe propriile rânduri și niciuna nu depinde de baseline-ul celuilalt.

Așadar rezumatul onest nu este „penalizarea KL previne reward hacking”. Este:

Penalizarea KL nu previne reward hacking. Limitează cât de departe se poate mișca policy-ul față de referință — și, fiindcă eșecul necesită mișcare, asta ajută. Dar este o lesă, nu o corecție: la β\beta mic, lesa se rupe, iar la β\beta mare primești înapoi modelul de referință și întreaga etapă scumpă nu a cumpărat nimic.

Banda utilă este îngustă, poziția ei depinde de modelul de recompensă și nu există nicio modalitate de a o găsi decât uitându-te. De aceea modelul de referință trebuie să fie bun — KL este o podea la calitatea referinței, nu un plafon asupra eșecului — și aceasta este o mare parte din motivul pentru care etapa este dificilă în practică, nu în principiu.

Algoritmul care a făcut ca asta să funcționeze la scară este Proximal Policy Optimization.3 Într-un paragraf: estimează advantage-ul fiecărui răspuns, actualizează policy-ul ca să crească probabilitatea răspunsurilor peste baseline și limitează dimensiunea oricărei actualizări individuale, astfel încât o estimare mare de advantage să nu distrugă policy-ul dintr-un singur pas. Aplicat modelelor lingvistice4, asta înseamnă să ții în joc patru modele deodată — policy-ul, referința, modelul de recompensă și un critic — cu policy-ul generând mostre proaspete pe tot parcursul antrenării.

Funcționează, a produs InstructGPT și tot ce a coborât din el, și este cu adevărat dificil: patru modele în memorie, sampling în bucla de antrenare și o reputație de instabilitate pe deplin meritată. Să pretinzi că îl poți implementa într-un articol de blog ar fi necinstit, așa că acest capitol nu o face.

Ce l-a înlocuit pentru cele mai multe scopuri a venit din observarea unui lucru. Obiectivul regularizat cu KL de mai sus are o policy optimă în formă închisă, iar acea expresie poate fi inversată: reward-ul poate fi scris în funcție de policy-ul optim și de referință. Înlocuind asta în loss-ul Bradley–Terry, modelul de recompensă dispare complet. Ce rămâne este un loss supravegheat pe perechi de preferințe — fără sampling, fără critic, fără model de recompensă, două modele în memorie în loc de patru.

Acesta este Direct Preference Optimization,5 și are două linii:

dpo.pyPYTHON
def dpo_loss(pi_w, pi_l, ref_w, ref_l, beta=0.1):
    """pi_* and ref_* are summed log-probabilities of a full response."""
    logits = beta * ((pi_w - ref_w) - (pi_l - ref_l))   
    return -F.logsigmoid(logits)                        

Citește ce spune. Cantitatea împinsă în sus este cât de mult mai mult preferă policy-ul câștigătorul decât o făcea referința, minus cât de mult mai mult preferă învinsul. Referința nu este o penalizare atașată ulterior — este în interiorul loss-ului, motiv pentru care DPO nu are nevoie de un termen KL separat.

Proprietatea care contează cel mai mult este în gradient. Evaluează loss-ul și gradient-ul lui pe aceeași pereche în cinci stări diferite ale policy-ului:

starea policy-uluilossmagnitudinea gradient-ului
preferă deja puternic câștigătorul0,51300,0401
îl preferă deja, slab0,66850,0488
identic cu referința0,69310,0500
preferă învinsul0,79810,0550
preferă puternic învinsul1,00550,0634

Gradient-ul crește pe măsură ce policy-ul greșește mai mult. Perechile pe care modelul le gestionează deja contribuie aproape deloc; perechile pe care le inversează domină actualizarea. DPO ponderează fiecare exemplu după cât de greșit este policy-ul în acel moment, automat, fără programare — iar această auto-ponderare este mecanismul care face munca pe care estimarea de advantage și criticul din PPO o făceau. (Loss-ul de pe al treilea rând este exact ln2\ln 2, ancora față de care poți verifica orice implementare: o policy identică cu referința ei nu a învățat nimic și ar trebui să stea la ln2\ln 2.)

GRPO6 ia o rută diferită pentru a ieși din aceeași problemă. Păstrează bucla de sampling, dar șterge criticul: în loc să antreneze un model să prezică baseline-ul, eșantionează un grup de răspunsuri la același prompt și folosește direct reward-ul mediu al grupului ca baseline. Advantage-ul unui răspuns este cât de mult mai bun a fost decât frații lui. Asta schimbă un model întreg pe un batch mai mare și este ce a făcut practică antrenarea cu reward verificabil — subiectul Capitolului 12.

Afișează detaliile

Încă trei piese din peisajul post-training, pe scurt.

RLAIF și Constitutional AI.7 Adnotatorul nu trebuie să fie om. Dă-i unui model un set scris de principii și cere-i să își critice și să își revizuiască propriile output-uri sau să aleagă între doi candidați, iar tu ai un set de date de preferințe produs la viteza și costul mașinii. Obiecția evidentă — modelul își corectează singur tema — este reală, iar răspunsul onest este că funcționează mai bine decât pare, fiindcă a judeca este mai ușor decât a genera, aceeași asimetrie pe care se sprijină întregul capitol.

LIMA și cât de puține date cere asta.8 O mie de demonstrații atent curate au produs un asistent competitiv. Explicația propusă este că pretraining a instalat deja cunoașterea și formatul, iar post-training trebuie doar să selecteze care dintre comportamentele existente ale modelului să iasă la suprafață. Dacă este adevărat, calitatea datelor de post-training domină cantitatea — iar comportamentul domeniului de atunci încoace sugerează că oamenii cred asta.

LoRA și QLoRA.910 Fine-tuning pentru fiecare pondere a unui model mare necesită memorie pentru ponderi, gradient-urile lor și starea optimizatorului — cei șaisprezece bytes per parametru din Capitolul 10, peste cele două medii pe care Capitolul 6 le-a construit manual — la o scară care cere un cluster. LoRA îngheață ponderile originale și antrenează alături de ele o pereche de matrice de rang mic, reducând parametrii antrenabili cu ordine de mărime; QLoRA cuantizează suplimentar baza înghețată la 4 biți. Ambele sunt acoperite aici ca tehnică. Dacă fine-tuning este sau nu lucrul potrivit pe care să cheltui bani este o altă întrebare, iar ea aparține Capitolului 20.

Taxa de alignment și întrebarea la care nimeni nu a răspuns

Link către secțiunea: Taxa de alignment și întrebarea la care nimeni nu a răspuns

Două lucruri de dus mai departe.

Primul este că această etapă are un cost, iar el apare ca abilitate. Modelele devin adesea măsurabil mai slabe la unele sarcini de benchmark după antrenarea de alignment — taxa de alignment — fiindcă obiectivul s-a schimbat: un răspuns sigur, prudent și bine formatat nu este întotdeauna răspunsul care maximizează acuratețea. O parte din acel decalaj a fost eliminată prin inginerie, iar o parte este un compromis real, nu un bug de reparat.

Al doilea este întrebarea pe care cuvântul aligned o ascunde. Aliniat cu cine? Lanțul este: o companie scrie ghiduri, contractori le interpretează, comparațiile lor antrenează un model de recompensă, modelul de recompensă modelează o policy, iar policy-ul răspunde la o întrebare de la cineva care nu a văzut nimic din toate acestea. Fiecare verigă este o alegere făcută de oameni anume, iar niciunul dintre algoritmii din acest capitol nu are vreo opinie despre dacă acele alegeri sunt bune.

Aceasta nu este o înfloritură retorică. Este motivul concret pentru care două modele frontier refuză cereri diferite, de ce același model se răzgândește între versiuni și de ce „aligned” este o descriere a unui proces, nu o proprietate a unui artefact. Matematica din acest capitol este stabilită. Acea parte nu este.

Post-training a învățat modelul să răspundă. Nu l-a învățat să gândească înainte să răspundă, iar cele două sunt diferite într-un fel care se dovedește a fi antrenabil.

Capitolul 12 este despre ce se întâmplă când lași un model să cheltuiască mai multă computație pe o întrebare grea la momentul răspunsului, nu la momentul antrenării — chain of thought, reinforcement learning din recompense verificabile și motivul pentru care un model care își arată lucrul nu doar se explică, ci calculează diferit. Achită și datoria din acest capitol: GRPO există în el, făcând treaba pe care o făcea înainte criticul PPO, pe rewards care nu au nevoie de niciun adnotator, fiindcă o demonstrație fie se verifică, fie nu.


Generările de mai sus vin din gpt2 și Qwen/Qwen2.5-0.5B-Instruct cu decodare greedy, așa că se reproduc exact. Capitolul 11 din Hugging Face LLM Course parcurge SFT și DPO cu trl și peft dacă vrei să rulezi lucrul real în locul simulării; capitolul 7 din Build a Large Language Model (From Scratch) de Sebastian Raschka implementează instruction fine-tuning cap-coadă fără o bibliotecă.

  1. Sutton, R. S. și Barto, A. G. Reinforcement Learning: An Introduction, ediția a 2-a (MIT Press, 2018). Delegarea este deliberată: caseta de vocabular de mai sus este cel mai mic subset utilizabil, iar subiectul real este o carte.

  2. Bradley, R. A. și Terry, M. E. Rank Analysis of Incomplete Block Designs: I. The Method of Paired Comparisons. Biometrika 39(3/4), pp. 324–345 (1952). Modelul de comparație pereche aflat sub fiecare model de recompensă folosit astăzi.

  3. Schulman, J., Wolski, F., Dhariwal, P., Radford, A. și Klimov, O. Proximal Policy Optimization Algorithms. arXiv:1707.06347 (2017).

  4. Ouyang, L. et al. Training language models to follow instructions with human feedback. arXiv:2203.02155 (2022). InstructGPT — lucrarea care a făcut standard rețeta în trei etape. Precedată de Christiano et al. (arXiv:1706.03741), care a introdus învățarea unui model de recompensă din comparații umane, și Stiennon et al. (arXiv:2009.01325), care a aplicat-o sumarizării.

  5. Rafailov, R., Sharma, A., Mitchell, E., Ermon, S., Manning, C. D. și Finn, C. Direct Preference Optimization: Your Language Model is Secretly a Reward Model. arXiv:2305.18290 (2023). Derivarea care elimină modelul de recompensă este în secțiunea 4 și merită citită integral; este mai scurtă decât reputația ei.

  6. Shao, Z. et al. DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models. arXiv:2402.03300 (2024). Introduce GRPO în secțiunea 4.1.

  7. Bai, Y. et al. Constitutional AI: Harmlessness from AI Feedback. arXiv:2212.08073 (2022).

  8. Zhou, C. et al. LIMA: Less Is More for Alignment. arXiv:2305.11206 (2023).

  9. Hu, E. J. et al. LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685 (2021).

  10. Dettmers, T., Pagnoni, A., Holtzman, A. și Zettlemoyer, L. QLoRA: Efficient Finetuning of Quantized LLMs. arXiv:2305.14314 (2023).

Gata să lași LIA să aleagă?

Construiește cu toate modelele AI într-un singur loc — începe gratuit azi.