Back to Blog
EnglishTutorial

Model Distillation in Python: Fit a Tiny Student to Soft Teacher Labels

An executable two-parameter student learns probabilities from a synthetic teacher. Nine training inputs, four held-out points and four checks illustrate distillation without claiming an LLM was trained.

B
Boluo Z
March 30, 2026 / 1464 views
Share:
Model Distillation in Python: Fit a Tiny Student to Soft Teacher Labels

Distillation trains a student to match signals from a teacher. A small numerical experiment makes that objective visible: fit a logistic student to soft probabilities, then evaluate on inputs excluded from training.

Crazyrouter publishes this local distillation demonstration with nine training inputs, four held-out points and four executed checks; it does not claim to have trained an LLM.

By Boluo Z · Tested November 3, 2026

How does a student model learn from soft teacher labels?#

The teacher is sigmoid(2x − 0.5), a deterministic function with no API call and no proprietary training data. The student starts with two zero-valued parameters and learns a logistic function from nine training inputs. Each target is a probability rather than a hard zero-or-one class.

The objective is binary cross-entropy against those soft targets. Gradient descent performs 800 fixed updates at learning rate 0.1. The script uses only Python’s standard library; saving the code and executing it reproduces the fitted parameters and every observation.

November 3 experiment and observed results#

This local Python experiment used no API and needs no credential. Each result describes this run only. A test program exiting successfully means its observations were recorded, not that every model response passed.

Executed local caseExpected behavior met
disjoint held-out inputsYes
cross entropy decreasedYes
probability error below 0.01Yes
probabilities boundedYes
Held-out xTeacher probabilityStudent probabilityAbsolute error
-1.750.0179860.0181580.000172
-0.750.1192030.1197790.000576
0.250.5000000.5003130.000313
1.250.8807970.8804850.000312

Training cross-entropy decreased from 0.693147 to 0.348672 after 800 updates. This is a synthetic two-parameter experiment.

Training objective: Soft targets from a local synthetic teacher

Keep the held-out inputs outside training#

Four distinct x values are used only for evaluation. The checks require disjoint train/test inputs, decreasing training loss, bounded probabilities and a maximum held-out probability error below 0.01. All four checks passed.

This toy teacher belongs to the same two-parameter family as the student, so the exercise is intentionally easy. It demonstrates matching probability targets, not compressing a large neural network or proving out-of-distribution generalization. Cross-entropy need not reach zero when the teacher probabilities themselves have uncertainty.

Translate the lesson carefully to language models#

Real language-model distillation introduces a much larger vocabulary, sequence data, a model architecture, optimizer choices and evaluation challenges. Soft-label distillation can use temperature-scaled distributions; this toy uses a binary distribution at temperature one. Response-based datasets are another approach and do not expose the same teacher information.

Before building such a dataset, verify permissions for the source model and data. This example avoids external teacher outputs entirely and makes no legal claim about a specific provider. Keep evaluation examples independent, report the teacher’s weaknesses and measure the actual student workload rather than assuming matching a few labels transfers all capabilities.

Reproduce the experiment#

Save the script and run it with Python 3.10 or later; only the standard library is used.

python
import json
import math

def sigmoid(x):return 1/(1+math.exp(-x))
def teacher(x):return sigmoid(2*x-0.5)
def loss(w,b,points):
    return sum(-teacher(x)*math.log(sigmoid(w*x+b))-(1-teacher(x))*math.log(1-sigmoid(w*x+b)) for x in points)/len(points)

train=[-2,-1.5,-1,-0.5,0,0.5,1,1.5,2]
holdout=[-1.75,-0.75,0.25,1.25]
w=b=0.;initial=loss(w,b,train)
for step in range(800):
    errors=[sigmoid(w*x+b)-teacher(x) for x in train]
    w-=0.1*sum(e*x for e,x in zip(errors,train))/len(train)
    b-=0.1*sum(errors)/len(train)
rows=[{"x":x,"teacher_probability":teacher(x),"student_probability":sigmoid(w*x+b),"absolute_error":abs(teacher(x)-sigmoid(w*x+b))} for x in holdout]
tests=[{"case":"disjoint held-out inputs","passed":not set(train)&set(holdout)},
{"case":"cross entropy decreased","passed":loss(w,b,train)<initial},
{"case":"probability error below 0.01","passed":max(r["absolute_error"] for r in rows)<.01},
{"case":"probabilities bounded","passed":all(0<r["student_probability"]<1 for r in rows)}]
assert all(t["passed"] for t in tests)
print(json.dumps({"local_tests":tests,"requests":[],"steps":800,"training_points":len(train),"heldout":rows,"initial_loss":initial,"final_loss":loss(w,b,train),"student_parameters":{"w":w,"b":b},"scope":"Two-parameter logistic student fitted to a local synthetic teacher; no LLM trained or API called"}))

Held-out probability error: Four points excluded from training; not an LLM benchmark

Sources checked November 3, 2026: Distilling the Knowledge in a Neural Network. Official descriptions and gateway observations are separate evidence.

FAQ#

Was an LLM trained?#

No. A two-parameter logistic student was fitted to a local synthetic teacher.

How many examples were used?#

Nine training inputs and four disjoint held-out inputs.

Why use probabilities?#

They provide the student with the teacher’s confidence, not just a hard class label.

Why is the final loss nonzero?#

Soft target distributions have uncertainty; matching them does not generally make cross-entropy zero.

Does this demonstrate a smaller production model?#

No. The teacher and student share a deliberately simple function family.

Do I need an API key?#

No. This particular experiment runs entirely locally with Python’s standard library.

Last actually tested: November 3, 2026. This local conceptual tutorial is due for review February 1, 2027.

Implementation Guides

Podcast

AI Dev Tools: The Crazyrouter Podcast

Short episodes for developers on AI APIs, gateways, cost control and coding tools.

Latest episodes

  • EP196 · Oct 29, 2026 · 6:53

    AI API Security Posture — Turn Controls Into Continuous Evidence

    A practical guide to AI API security posture: inventory exposure, verify controls continuously, protect keys and data, constrain tools, and turn security assumptions into evidence that operators can act on.

  • EP195 · Oct 28, 2026 · 7:21

    AI API Policy Drift — Detect When Production Rules Stop Matching Intent

    A practical guide to policy drift in AI APIs: version routing and safety rules, detect stale enforcement, compare intended and observed behavior, and restore control before small gaps become incidents.

Episodes with written show notes →

Topics

API GuidesTutorial

Related Articles