Fine-Tuning von Laya auf deinen eigenen Entscheidungen
Auf dem typed-decisions-Benchmark liegen die Basis-Checkpoints zero-shot nahe am Zufall — 0.36 und 0.35 gegenüber einer Zufalls-Baseline von 0.318 —, während der Fine-Tuning-Checkpoint 0.766 auf denselben 2,000 Entscheidungen erreicht, über den veröffentlichten 0.727 von TypeSafe Jev und über der Obergrenze von 0.735 der Selbstübereinstimmung des Lehrers. Fine-Tuning ist der Teil, in dem der größte Teil des Werts steckt, und das öffentliche Fine-Tuning-Notebook führt die ganze Schleife auf Kaggles kostenlosen 2xT4-GPUs aus: den Datensatz aufbauen, mit RLCD trainieren, Kalibrierungstemperaturen anpassen, evaluieren und das Ergebnis auf den Hub hochladen. Diese Seite geht dieses Notebook durch und zeigt auf die Teile, die tragend bleiben, wenn du die Daten durch deine eigenen ersetzt.
Das andere durchgearbeitete Beispiel — ein Entscheidungskopf für einen Browser-Agenten auf einer einzigen 16-GB-GPU ohne bezahlte API — findest du unter Fine-Tuning von Laya als Entscheidungskopf für einen Browser-Agenten.
Was das Notebook der Reihe nach tut
| # | Schritt | Was passiert |
|---|---|---|
| 1 | Umgebung | prüft, dass beide T4-GPUs sichtbar und zugewiesen sind |
| 2 | Installation | laya, transformers, datasets und die Trainingsabhängigkeiten |
| 3 | Vorverarbeitung | die 1,200 Trainingsfälle (6,000 typisierte Entscheidungen) werden zu tokenisierten Elementen mit weichen Zielen, für beide DDP-Ränge auf die Festplatte geschrieben |
| 4 | Training | train_ddp.py unter torchrun --nproc_per_node=2, vier Epochen |
| 5 | Kalibrierung | eine Temperatur pro Typ, angepasst auf einer vor dem Training zurückgehaltenen Teilmenge (innerhalb des Trainingsskripts, nach der letzten Epoche) |
| 6 | Evaluierung | der offizielle test-Split, vom Fine-Tuning-Checkpoint beantwortet — 400 Fälle, 2,000 Entscheidungen — mit Latenz pro Fall |
| 7 | Metriken | Genauigkeit, weiche Genauigkeit, Brier, ECE, score-MAE, within-one-level, KL/TV und Latenz-Perzentile; eine Direktvergleichstabelle gegen Jev und die Obergrenze des Lehrers |
| 8 | Veröffentlichung | (optional) eine Modellkarte aus den eigenen Zahlen des Laufs, der Ordner wird auf den Hub hochgeladen |
| 9 | Bericht | benchmark_report.json mit der Metriktabelle und der Genauigkeit pro Workflow |
Kaggle-Einstellungen: Accelerator GPU T4 x2, Internet On. Die Ausgaben landen in
/kaggle/working/laya_finetuned_typed_decisions.
Das Trainingsrezept
RLCD trainiert auf den gold-Verteilungen des Benchmarks, nicht auf harten Labels: jedes Element trägt die Wahrscheinlichkeit, die der Lehrer jeder Option zugewiesen hat, und beide Hälften des Verlusts lesen dieses Ziel —
- ein Policy-Gradient-Term über abgetastete verrauschte Logit-Projektionen (GRPO-Stil: vier Stichproben pro Element, Explorationsrauschen von 0.4 auf 0.1 abgekühlt), belohnt durch Proper-Scoring-Regeln (sphärisch 0.75, ranked probability 1.0);
- ein Soft-Cross-Entropy-Term mit vollem Gewicht gegen dieselbe Verteilung.
Die Stellschrauben, die das Notebook für eine 16-GB-Karte setzt:
| Epochen | 4 |
| effektive Batch-Größe | 64 Sequenzen (8 pro Mikro-Batch, 2 GPUs, 4 Akkumulationsschritte) |
| Lernraten | Encoder 2.5e-5, Kopf 1e-4 — AdamW, Cosine-Schedule |
| Speicher | fp16-Autocast, Gradient-Checkpointing auf Encoder und Kopf, Gradient-Norm-Clipping 1.0 |
| Sequenzbudget | max_len 1024, head_max_len 256, max_tokens_per_batch 4096 |
Die Laufzeit auf 2xT4 ist Minuten für die Demo und Stunden für echte Daten: etwa 4–6 Minuten für die 6,000 Entscheidungen der Demo und rund 4–5 Stunden für vier Epochen über ~30k Fragen.
Um es auf deine Daten zu richten, ersetze die beiden load_dataset-Aufrufe und behalte das Zeilenschema
bei: jeder Fall trägt state, questions und gold (die Lehrer-Wahrscheinlichkeiten pro Frage), und der
Vorverarbeiter macht daraus Elemente. Die Fragetypen sind choice, score und noul; alles, was du
damit über einen Zustand ausdrücken kannst, ist erlaubt.
Kalibrierung ist Teil des Laufs
Das ist der Schritt, der beim Kopieren der Schleife am ehesten weggelassen wird, und er ist tragend, sobald jemand Gating auf die Konfidenz anwendet.
Das Notebook nimmt eine Kalibrierungsteilmenge aus den Trainingsdaten heraus, bevor es sie über die Ränge aufteilt (bis zu 400 Elemente, oder 10%, mit festem Seed, auf jedem Rang identisch). Temperaturen auf Elementen anzupassen, auf denen der Lauf bereits trainiert wurde, misst die Anpassung statt der Kalibrierung — das Modell ist bei ihnen nahezu sicher und nahezu richtig, der Optimierer hat also nichts zu mildern und liefert eine degenerierte Skala.
Nach der letzten Epoche passt Rang 0 eine Temperatur pro Fragetyp (choice, score, noul) per
LBFGS auf dem Log-Temperaturwert an, begrenzt auf [0.1, 10] (1.0 für eine Teilmenge unter zehn
Elementen, 1.2 falls die Anpassung fehlschlägt). Die Werte gehen als temperature in
rl_agent_config.json, und das Notebook entfernt jede geerbte temperature_by_options im selben
Schreibvorgang: diese alten Bucket-Werte haben bei der Inferenz Vorrang und würden die neue Anpassung
still verdecken.
Temperaturskalierung lässt das Argmax — und die Genauigkeit — unverändert; was sich bewegt, ist die Konfidenz. Die Checkpoints in der ausgelieferten Form sind überkonfident, passe also an, bevor du dich auf einen Schwellenwert verlässt, und evaluiere das Ergebnis auf zurückgehaltenen Daten, bevor du eine Verbesserung behauptest. Die Regression zur Konfigurationspersistenz läuft ohne Downloads und Training:
python tests/test_calibration_persistence.py
Evaluieren, bevor du ihm vertraust
Die Evaluierung ist ein vollständiger Durchlauf über den offiziellen Test-Split: 400 Fälle, 2,000
Entscheidungen über Agent Trace Observability, Customer Service, Invoice Processing und Security
Incidents. Sie berechnet Genauigkeit, weiche Genauigkeit, Brier, ECE (über laya.common.ece_score),
score-MAE, within-one-level und Latenz-Perzentile und baut dann eine Direktvergleichstabelle, deren
Referenzzeilen feststehen:
| Modell | Art | Genauigkeit | ECE |
|---|---|---|---|
| TypeSafe Jev 1.13.0 | allgemein | 0.727 | 0.144 |
| ModernBERT-base (149M) | Spezialist | 0.646 | 0.179 |
| Teacher Self-Agreement | Obergrenze | 0.735 | — |
| Laya (veröffentlichter Checkpoint) | fine-tuned | 0.766 | — |
Die Laya-Zeile deines eigenen Laufs wird genauso berechnet — das Notebook baut die Tabelle aus den
eigenen Zahlen des Laufs neu auf. Zwei Gewohnheiten, die es sich zu übernehmen lohnt: behalte die
Teilmengen, die dir wichtig sind (eine Sprache, einen Workflow), innerhalb der zurückgehaltenen Daten, und
berichte die Kalibrierung neben der Genauigkeit, weil das Trainingssignal eine Verteilung ist, nicht nur
ein Label. Wenn du Zahlen hast, ist ein Beitrag in den
Discussions des Repositorys der richtige Ort, um sie
zu teilen; Benchmarks und bekannte Grenzen stehen in BENCHMARKS.md im Wurzelverzeichnis des Repositorys.
Auf den Hub hochladen
Die Veröffentlichungszelle ist die letzte Meile der Schleife, und sie ist bewusst langweilig:
- Lege ein Schreib-
HF_TOKENin Kaggle ab (Add-ons → Secrets). Die Zelle löst mit der genauen Anleitung eine Ausnahme aus, wenn es fehlt. - Setze das Ziel-Repository — die ausgelieferte Zelle verwendet standardmäßig einen Namen im eigenen Namensraum des Projekts, also ändere ihn vor der Ausführung.
- Führe sie aus. Sie schreibt eine Modellkarte, deren Zahlen aus der Vergleichstabelle dieses Laufs
stammen, und lädt dann
model.safetensors,encoder/,tokenizer/,rl_agent_config.json, die Karte und den Benchmark-Bericht hoch.
Das Ergebnis lädt wie jeder andere Checkpoint — es gibt keine Fine-Tuning-spezifische API:
import laya
agent = laya.load("your-org/your-checkpoint") # the repo you just pushed
result = agent.predict(state, questions)
Ein rollierendes checkpoint_latest/ wird nach jeder Epoche überschrieben, sodass ein Kaggle-Timeout oder
OOM eine Epoche kostet statt den ganzen Lauf.
Worauf du achten solltest
- Die Schleife ist nur so gut wie die Ziele. RLCD imitiert die Verteilung eines Lehrers über deine Fragen; sammle die Konfidenzen des Lehrers vor (oder zusammen mit) dem Training und behandle ihre Qualität als Obergrenze.
- Die Kalibrierungsteilmenge ist bewusst klein. Bis zu 400 Elemente oder 10% — genug für drei Skalare pro Typ, nicht genug, um dagegen zu validieren. Halte deine eigenen Evaluierungsdaten zurück.
- Deine Labels müssen zu den drei Primitiven passen. Wenn deine Entscheidung keine choice, keine Skala oder keine Ja/Nein-Wahrscheinlichkeit ist, forme sie zuerst in eine um. Zwei scharfe Kanten sind bereits dokumentiert: hohe Optionszahlen verschlechtern die Konfidenzauswahl (#394), und Negation bei erzwungener Wahl kann der Frage statt dem Zustand folgen (#377).
- Liefere die Konfiguration, nicht nur die Gewichte. Das entfernte
temperature_by_optionsist der Teil, der eine Kalibrierung still un-angepasst macht, wenn er in einer kopierten Konfiguration überlebt.