mixle.task.distill module¶
Distill a teacher callable into a local TaskModel.
The teacher can be any callable that labels text: an LLM endpoint, a slow rule,
or a human-reviewed map. The student is a compact classifier over
dependency-free hashed n-gram features (HashedNGram),
trained to reproduce the teacher’s labels and returned as a durable
TaskModel. agreement measures held-out fidelity
to the teacher and is the objective tune_recipe()
optimizes when it searches student recipes with mixle.doe.
Only the student fit needs torch; the teacher is opaque. distill is deterministic given seed.
distill_for_routing/distill_records_for_routing are the routing-ready siblings: they hold out a
calibration slice, fit the student on the rest, and return a CalibratedTaskModel
– decide()-able out of the box, so it drops straight into Cascade or
Router with no separate calibration step to remember or get wrong.
- distill(teacher, texts, *, labels=None, n=3, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu', n_jobs=1)[source]
Label
textswithteacher, fit a local student, and return a callableTaskModel.n/dimsize the hashed n-gram featurizer;hiddenthe student MLP.labelsfixes the label set (else inferred from the teacher’s outputs). The student’s train-set agreement with the teacher is recorded inmeta.n_jobs > 1fans teacher labeling across that many threads (order-preserving; the win is parallel in-flight requests against a network-bound teacher) – everydistill_*teacher entry point takes the same knob.
- distill_from_labels(texts, teacher_labels, *, labels=None, n=3, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu')[source]
Fit a student from already-labeled
(texts, teacher_labels)– the teacher-free training core ofdistill.Active labeling (
mixle.task.active) uses this to avoid re-querying the teacher: it controls exactly which examples were paid for and passes their labels straight in.labelsfixes the label set so a student trained on a partial sample still spans every class.
- distill_for_routing(teacher, texts, *, labels=None, calibration_frac=0.2, alpha=0.1, n=3, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu', density_gate=False, density_gate_alpha=0.05, n_jobs=1)[source]
Label
textswithteacher, fit a student, and calibrate it for routing – all in one call.A
calibration_fracslice of the (teacher-)labeled data is held out from training and used to set a conformal threshold, so the returnedCalibratedTaskModelis immediatelydecide()-able: confident, in-distribution inputs get the student’s label; everything else isESCALATE. Pass it straight toCascade(withteacher) orRouterfor tiered serving – no separate calibration split to manage by hand. Deterministic givenseed; the calibration slice is disjoint from the student’s training data.density_gate=Trueadditionally escalates inputs a softmax cannot see are atypical: seedistill_from_labels_for_routing().- Parameters:
- Return type:
CalibratedTaskModel
- distill_from_labels_for_routing(texts, teacher_labels, *, labels=None, calibration_frac=0.2, alpha=0.1, n=3, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu', density_gate=False, density_gate_alpha=0.05)[source]
Teacher-free training core of
distill_for_routing(): fit + calibrate from labels already in hand.Splits
(texts, teacher_labels)into a training slice and a held-outcalibration_fracslice (fixed byseed), trains the student on the former viadistill_from_labels(), then calibrates (calibrate()) on the latter.labels(if given, else inferred from all ofteacher_labelsbefore the split) is shared by both slices so a class that lands entirely on one side of the split doesn’t shrink the label set out from under the other.density_gate=Truefits aDensityGateon the training slice’s features (reusing the student’s own featurizer, so there is no second feature space to keep in sync), calibrates its OOD floor (density_gate_alpha) on the disjoint calibration slice, and wires it into the returned model – an input whoselog p(x)falls below that floor escalates even if the conformal set is a confident singleton.- Parameters:
- Return type:
CalibratedTaskModel
- distill_records(teacher, records, *, labels=None, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu', n_jobs=1)[source]
Distill a teacher into a record classifier (
record -> labelover tuples/dicts of mixed fields).The structured-data sibling of
distill(): classify a transaction, route a ticket, categorize a record. Uses the hashing-trickHashedRecordfeaturizer, so it needs no fitted encoder.
- distill_records_from_labels(records, teacher_labels, *, labels=None, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu')[source]
Teacher-free record-classifier training core (mirrors
distill_from_labels()for structured records).
- distill_records_for_routing(teacher, records, *, labels=None, calibration_frac=0.2, alpha=0.1, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu', density_gate=False, density_gate_alpha=0.05, n_jobs=1)[source]
The structured-record sibling of
distill_for_routing(): fit + calibrate a record classifier in one call, returning a routing-readyCalibratedTaskModel.- Parameters:
- Return type:
CalibratedTaskModel
- distill_records_from_labels_for_routing(records, teacher_labels, *, labels=None, calibration_frac=0.2, alpha=0.1, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu', density_gate=False, density_gate_alpha=0.05)[source]
Teacher-free training core of
distill_records_for_routing()(mirrorsdistill_from_labels_for_routing()for structured records).density_gate=Truefits the OOD gate on the training slice’s record features and calibrates it on the calibration slice, same as the text path.- Parameters:
- Return type:
CalibratedTaskModel
- distill_structured(teacher, records, *, labels=None, n_components=1, min_gain=0.0, n_bins=4, max_its=30, seed=0, task='', n_jobs=1)[source]
Distill a teacher into a structured probabilistic classifier – a learned Bayesian network, not an MLP.
The teacher labels
records;mixle.inference.structure.learn_structure()then discovers the dependency forest over the joint(field_1, ..., field_m, label)and fits it. The student classifies by the generative ruleargmax_label P(features, label)– and becausesoftmax_label log P(features, label) = P(label | features)exactly, its confidence is a real posterior the cascade/calibration stack can trust. Unlikedistill_records()(a hashed-feature MLP), this student is interpretable (model.edges()lists the discovered dependencies), a few kilobytes on disk, and needs no torch to run.n_components > 1fits aMixtureOfDependencyTrees– a latent-cluster student whose sub-structures differ by regime. Assumes a fixed record schema (seeStructuredClassifierIO).
- distill_structured_from_labels(records, teacher_labels, *, labels=None, n_components=1, min_gain=0.0, n_bins=4, max_its=30, seed=0, task='')[source]
Teacher-free core of
distill_structured(): fit a structured classifier from labeled records.