mixle.task package¶
Small, local, task-specific models – train or distill one, save a durable artifact, call it as a function.
The unit is a TaskModel: a fitted model scoped to one task (classify, extract,
recommend a model shape, …), small enough to run locally and fast, with a durable artifact (artifact)
so a plain Python program can load it in a fresh process and just call it. Producers:
distill()– a teacher (any callable LM) labels data, a tiny student is fit to match;
tune_recipe()–mixle.doesearches the student recipe to minimize train cost.
This module’s public surface re-exports the artifact contract; the model/distill/tune layers land on top.
- class ActiveResult(model, labels_used, history=<factory>, labeled_texts=<factory>, labeled_labels=<factory>)[source]
Bases:
objectThe actively-distilled student plus an audit trail of labels spent vs. quality reached each round.
- Parameters:
- model: TaskModel
- labels_used: int
- class AgentTrace(request, plan, reply='', conversation_id='')[source]
Bases:
objectOne request -> what the agent did: the ordered tool calls and the final text reply.
- request: str
- reply: str = ''
- conversation_id: str = ''
- class AgentTraces(traces=<factory>)[source]
Bases:
objectThe harvested corpus plus the teacher views the distillers consume.
- Parameters:
traces (list[AgentTrace])
- traces: list[AgentTrace]
- requests(*, min_steps=0)[source]
The request texts (optionally only those whose plan has at least
min_stepscalls).
- tool_specs()[source]
Infer ToolSpecs from observed usage: args = union of keys, required = keys in EVERY call.
- Return type:
list[ToolSpec]
- call_teacher()[source]
A
distill_tool_callerteacher: request -> the FIRST tool call the agent made (or no-op).- Return type:
- class CalibratedTaskModel(task, *, alpha=0.1, qhat=None, density_gate=None)[source]
Bases:
objectA
TaskModelplus a conformal threshold: predicts label sets and decides answer-vs-escalate.- calibrate(texts, teacher_labels)[source]
Set the conformal threshold from held-out
(texts, teacher_labels)for1 - alphaset coverage.
- predict_sets(texts)[source]
Conformal label set per input (the classes whose score clears the calibrated threshold).
- decide(text)[source]
Return the label if the input is a confident, in-distribution singleton, else
ESCALATE(None).
- escalation_rate(texts)[source]
Empirical
p_escalate– the fraction of inputs escalated (ambiguous set or, if gated, OOD).
- save(path)[source]
Persist the underlying model, the calibration (alpha, qhat), and any density gate in the artifact.
qhatcan legitimately be+inf(a small calibration set / tightalpha: too little data to admit any confident singleton, so every input escalates). That is a real, callable threshold, so it is persisted as the JSON-safe sentinel"inf"and reloads back tofloat('inf')– a loaded model stays callable instead of raising “call calibrate”.
- class CallableLLM(fn)[source]
Bases:
objectWrap a plain
fn(prompt) -> str(orfn(prompt, system)) as anLLM– local models and tests.- Parameters:
fn (Callable[..., str])
- class Cascade(model, teacher, *, cost=None)[source]
Bases:
objectServe
text -> labelcheaply: local model when confident, teacher otherwise; track spend, harvest labels.- Parameters:
model (CalibratedTaskModel)
teacher (Callable[..., Any])
cost (CostModel | None)
- harvested()[source]
The escalated
(texts, teacher_labels)– targeted training data to re-distill a cheaper model.
- realized_cost()[source]
Actual spend so far:
c_localper request plusc_frontierper escalation (requires a CostModel).- Return type:
- report()[source]
Realized economics: requests, escalation rate, spend, and savings vs serving everything on the frontier.
- class CascadeStats(n_requests=0, n_escalated=0, escalated_texts=<factory>, escalated_labels=<factory>)[source]
Bases:
objectRunning tally of how a cascade served traffic – the basis for realized cost and the harvest.
- Parameters:
- n_requests: int = 0
- n_escalated: int = 0
- property realized_escalation_rate: float
- class CostModel(c_frontier, c_local=0.0, c_label=0.0, train_cost=0.0)[source]
Bases:
objectUnit costs (any consistent currency).
c_localis the amortized local per-request cost (~0 on CPU).- c_frontier: float
- c_local: float = 0.0
- c_label: float = 0.0
- train_cost: float = 0.0
- class DensityGate(featurizer, density=None, log_threshold=None)[source]
Bases:
objectA generative density over featurized inputs with a calibrated out-of-distribution floor on
log p(x).The featurizer is any
transform(list) -> matrix:HashedNGramfor text, orHashedRecordfor dict/tuple records (so record models get the same OOD protection).- Parameters:
featurizer (Any)
density (Any)
log_threshold (float | None)
- fit(texts, *, n_components=4, alpha=0.02, max_its=60, min_covar=1e-3, seed=0)[source]
Fit a diagonal-Gaussian mixture to the features and set the OOD floor at the
alphadensity quantile.
- log_density(texts)[source]
log p(x)of each input under the fitted density (higher = more typical of training data).
- is_ood(text)[source]
True when the input is atypical:
log p(x)below the calibrated floor.
- class DesignModel(signature, n_constraints, n_fingerprint=0)[source]
Bases:
objectA probabilistic model of the design space itself: design point -> (quality, budget violations).
Every evaluated design is a row; GP surrogates fitted on the rows drive
propose()(the next design worth training, by feasibility-weighted expected improvement) andpredict()(mean, sd, and probability-of-fitting-the-device for untrained designs). It serializes, so what was learned designing students for one task warm-starts the next – the design knowledge is itself a model artifact. (Anddistill_designer()compresses it into a student – models all the way down, each level a real artifact.)- add(point, quality, violations, *, fingerprint=None, **tag)[source]
- propose(bounds, *, seed=None, n_candidates=256, prefilter=None, max_tries=8, fingerprint=None)[source]
The next design worth training: feasibility-weighted EI over everything seen so far.
prefiltercloses the designer loop: pass a design judge – typically the tiny student fromdistill_designer(), called asprefilter(point_tuple) -> label– and any proposal it labels"weak"is vetoed and re-drawn (fresh acquisition seed), up tomax_tries. The distilled design knowledge thus skips known-bad designs before a single training run is spent; if every retry is vetoed the last proposal is returned anyway (the judge advises, the surrogate decides).fingerprintconditions the proposal on the current task (see_fingerprint_bounds()); the returned point has design coords only.
- predict(points, *, fingerprint=None)[source]
For untrained designs: predicted quality (mean, sd) and P(fits the device).
pointscarry design coords only;fingerprint(required when the ledger is fingerprinted) selects which task’s slice the prediction conditions on.
- class DesignedModel(estimator, spec, source, note='')[source]
Bases:
objectThe model an LLM (or the fallback) designed: the estimator, the spec it built from, and the source.
- estimator: Any
- source: str
- note: str = ''
- class DeviceSpec(max_bytes=None, max_ops=None, torch_free=False)[source]
Bases:
objectA hard deployment budget.
Noneleaves an axis unconstrained.max_bytes: model size on flash/disk.max_ops: per-inference op budget (a latency proxy – calibrate ops/sec once per device to turn a latency target into this number).torch_free: the device cannot run torch, so only pure-mixle students qualify.- torch_free: bool = False
- classmethod for_latency(max_ms, ops_per_second, *, max_bytes=None, torch_free=False)[source]
A budget from a latency target:
max_ops = ops_per_second * max_ms / 1000.ops_per_secondmust come from a probe run on the target device for the student kind you deploy (measure_ops_per_second()measures it for a representative student) – throughput differs by orders of magnitude across devices and student kinds, so there is no honest built-in constant.
- violations(fp)[source]
Normalized constraint values, feasible when
<= 0(the form constrained BO consumes).
- class EdgeDistillResult(model, family, recipe, agreement, footprint, feasible, pareto, design, trials=<factory>)[source]
Bases:
objectOutcome of an edge search: the winning student (with measured footprint), whether it truly fits the device, the (bytes, agreement) Pareto front over everything trained, and the updated
DesignModelcarrying the accumulated design knowledge.- Parameters:
- model: TaskModel
- family: str
- agreement: float
- footprint: EdgeFootprint
- feasible: bool
- design: DesignModel
- class EdgeFootprint(bytes, ops, torch_free)[source]
Bases:
objectA student’s measured deployment cost: serialized
bytes, per-inferenceops(multiply- accumulates for an MLP; factor evaluations for a structured classifier), andtorch_free.- bytes: int
- ops: int
- torch_free: bool
- class EdgeSpace(families=('mlp', 'structured'), dim_choices=(64, 128, 256, 512), hidden_range=(4, 96), epochs_range=(40, 320), log10_lr_range=(-3.0, -1.0), bits_choices=(32, 8), ngram=3, components_range=(1, 4), bins_range=(2, 8), max_its_range=(10, 60), min_gain_range=(0.0, 5.0))[source]
Bases:
objectOne unit-cube design space over family (structure) and each family’s recipe (process).
Coordinate 0 selects the family; 1..4 decode family-specifically.
familiesdefaults to what the input kind and device allow: hashed-MLP students need torch; structured students need fixed-schema records. Decode is deterministic, so a design point is a reproducible recipe.- Parameters:
ngram (int)
- ngram: int = 3
- signature()[source]
Fingerprint of the space so persisted design knowledge is only reused where it applies.
- Return type:
- class ExtractionIO(vocab, fields, *, max_len=128)[source]
Bases:
objecttext -> {field: value}: tokenize, tag (BIO), decode spans back to substrings of the original text.- kind = 'extraction'
- predict_batch(module, texts)[source]
- predict_with_confidence(module, texts)[source]
Extract each record and a confidence in
[0, 1]: the min per-token tag probability over tagged tokens.A low confidence or a missing field is an explicit signal that the format may be unfamiliar and should be escalated. Returns
0.0when nothing was tagged.
- class ExtractorHarness(model, teacher, fields, required, holdout_f1, n_fallback=0, n_requests=0)[source]
Bases:
objectA distilled extractor in front of the parser it replaces: local extraction or teacher fallback.
- Parameters:
- model: Any
- holdout_f1: float
- n_fallback: int = 0
- n_requests: int = 0
- class MatcherHarness(solution, teacher)[source]
Bases:
objectA calibrated pair-matcher in front of the rule it replaces.
- solution: Solution
- property holdout_agreement: float
- class FieldChoice(path, kind, family, runner_up, gap_bits)[source]
Bases:
objectThe family chosen for one field, the runner-up, and how decisive the choice was (bits/obs).
- path: str
- kind: str
- family: str
- property confident: bool
Confident when the family is type-determined (no real contender) or clears the runner-up by a margin.
- class GenerativeTextIO(labels, vocab, log_prior)[source]
Bases:
objectAdapter over
{label: fitted p(tokens|label)}+ log-priors: exact posteriors andlog p(x).- kind = 'generative_text'
- logits_batch(model, raw_inputs)[source]
log P(tokens, label)per label – an(m, K)matrix (multinomial: sum of token logs).
- proba_batch(model, raw_inputs)[source]
The exact class posterior (softmax of log-joints; the shared evidence cancels).
- log_evidence(model, raw_inputs)[source]
Per-token
log p(x)(length-normalized) – the built-in typicality/OOD score.Raw document evidence scales with length (a short gibberish string would outrank a long in-domain one), so typicality is reported per token: mean log-probability under the full generative model.
- predict_batch(model, raw_inputs)[source]
- class HashedNGram(n=3, dim=256, seed=0)[source]
Bases:
objectMap a string to a fixed-width float vector by hashing its character n-grams into
dimbuckets.Deterministic and dependency-free (stdlib
hashlib), so it serializes as three numbers and rebuilds identically anywhere – no fitted vocabulary, no external tokenizer. Counts are L2-normalized per row.
- class HashedRecord(dim=256, seed=0)[source]
Bases:
objectMap a heterogeneous record (tuple or dict) to a fixed vector by the hashing trick – tabular tasks.
Each field is hashed by
key: a categorical/string/bool value contributes a 1 athash("key=value"); a numeric value contributes a boundedtanh(value)athash("num:key")(and its presence at a second bucket). Stateless and deterministic – no fitted encoder or vocabulary – so it serializes as two numbers and rebuilds identically. The shape of a “classify this record / route this ticket / flag this transaction” model.
- class LNSStructuredClassifierIO(field_keys, label_index, labels, step=1e-2)[source]
Bases:
StructuredClassifierIOThe structured classifier executed in the log-number system: integers above the leaf boundary.
A structured student’s per-label score is a sum of factor log-densities – in log-space that is products of probabilities, which is exactly what
LogNumberSystemruns on integers: each factor’s log-density is quantized once at the leaf boundary (k = round(logp / step)), then the per-label accumulation is integer ADDs, mixture components fold with the integerlogaddLUT, the classification is an integer argmax, and the posterior is the integer log-softmax ofmixle.engines.lns_nn– noexp/loganywhere above the leaves (oneexponly if you ask for linear-scale probabilities). The dequantized scores match the float classifier within the engine’s documented bound (~``1.5 * step`` per fold), sostepis a dial between integer-width and fidelity.Categorical factors are pre-quantized to integer tables at first use, so their leaves are pure integer lookups – on an all-discrete schema inference touches no floats at all. Continuous leaves evaluate in float and quantize at the boundary, the same contract as the engine’s
SumProductCircuit.- kind = 'lns_structured_classifier'
- int_logits_batch(model, raw_inputs)[source]
Per-label INTEGER log-joint scores
(m, K)– the whole combination is integer math.
- logits_batch(model, raw_inputs)[source]
Per-label log-joint
log P(features, label)as an(m, K)score matrix (the classifier logits).
- proba_batch(model, raw_inputs)[source]
Posterior via the INTEGER log-softmax (max + LUT); one exp at the very end for linear scale.
The LUT rounds each log-probability to ~``step``, so the raw
expsums to1 +/- K*step/2; the final float renormalization (free – we already left integer space for the exp) removes that systematic drift without touching the integer pipeline.
- predict_batch(model, raw_inputs)[source]
- class ModelRecommendation(estimator, fields, dependencies, warnings, profile=None)[source]
Bases:
objectA model shape recommended from data: estimator, per-field choices+confidence, dependencies, and notes.
- Parameters:
- estimator: Any
- fields: list[FieldChoice]
- profile: Any = None
- low_confidence_fields()[source]
Fields whose family choice is not yet decisive – where more data would most sharpen the model.
- Return type:
list[FieldChoice]
- fit(data, **kwargs)[source]
Fit the recommended estimator on
dataand return the model.
- class OpenAICompatLLM(base_url, model, *, api_key=None, temperature=0.0, max_tokens=512, timeout=60.0)[source]
Bases:
objectAn
LLMbacked by any OpenAI-compatible/v1/chat/completionsendpoint (stdlib HTTP only).- Parameters:
- class QuantizedClassifierIO(featurizer, labels)[source]
Bases:
_ClassifierIOThe classifier IO for quantized students: same featurize -> logits -> label contract, no torch.
- kind = 'quantized_classifier'
- logits_batch(model, raw_inputs)[source]
- class QuantizedMLP(layers, *, bits=8)[source]
Bases:
objectA quantized-weight MLP with a pure-numpy forward pass.
layersis[(W_int (out, in), scale fp32, bias fp32 (out,)), ...]with weights in the symmetricbitsrange (int8: [-127, 127]; int4: [-7, 7], stored nibble-packed on disk); the forward isx @ (W * s).T + bwith ReLU between layers – exactly the dequantized version of the trained torch stack, so its logits match torch-on-dequantized-weights to float tolerance.- nbytes()[source]
Deployable payload bytes: packed weights (1 B/weight at int8, 1/2 B at int4) + fp32 biases + one fp32 scale per layer.
- Return type:
- macs()[source]
Per-inference multiply-accumulates (integer x fp32 dequant multiplies count the same).
- Return type:
- class RecipeSpace(dim_choices=(128, 256, 512, 1024), hidden_range=(16, 128), epochs_range=(50, 400), log10_lr_range=(-3.0, -1.0), n=4)[source]
Bases:
objectThe tunable axes of a distillation recipe and how a unit-cube point decodes into concrete knobs.
- Parameters:
- n: int = 4
- cost(recipe)[source]
Relative training cost of a recipe in [0, 1] (params x steps, normalized by the space’s max).
- class RecordClassifierIO(featurizer, labels)[source]
Bases:
_ClassifierIOrecord -> label: hashed-record features into a small classifier (tuples/dicts of mixed fields).- kind = 'record_classifier'
- class RoutePlan(route, volume, per_request, total, savings_vs_frontier, p_escalate, break_even, options)[source]
Bases:
objectThe costed comparison of routes at a given volume, with the recommended choice and its savings.
- Parameters:
- route: str
- volume: int
- per_request: float
- total: float
- savings_vs_frontier: float
- p_escalate: float
- break_even: float
- class Router(tiers)[source]
Bases:
objectRoute each request to the cheapest tier whose calibrated model is confident; the last tier always answers.
- classmethod from_solutions(solutions, teacher, *, costs, names=None)[source]
Build from
Solutionobjects (cheapest-first) + the frontier callable.costshas one entry per solution plus one for the teacher (per-request).
- harvested()[source]
The frontier-answered
(inputs, labels)— targeted training data for the cheaper tiers.
- report()[source]
Per-tier traffic and REALIZED economics vs sending everything to the final tier.
- class Scorecard(task: 'str', n_test: 'int', end_to_end_accuracy: 'float', local_agreement: 'float', escalation_rate: 'float', student_p50_ms: 'float', student_p95_ms: 'float', teacher_p50_ms: 'float', artifact_bytes: 'int | None', student_cost_per_1k: 'float | None', teacher_cost_per_1k: 'float | None')[source]
Bases:
object- Parameters:
- task: str
- n_test: int
- end_to_end_accuracy: float
- local_agreement: float
- escalation_rate: float
- student_p50_ms: float
- student_p95_ms: float
- teacher_p50_ms: float
- class RouterStats(tiers: 'list[TierStats]' = <factory>, harvested_inputs: 'list[Any]' = <factory>, harvested_labels: 'list[Any]' = <factory>)[source]
Bases:
object- tiers: list[TierStats]
- property n_requests: int
- class RegressionSolution(net, featurizer, teacher, qhat, alpha, tol, holdout_mae, y_mean, y_scale, train_inputs=<factory>, train_ys=<factory>, cal_inputs=<factory>, cal_ys=<factory>, hidden=(64, ), epochs=300, lr=0.01, seed=0, n_requests=0, n_escalated=0, harvested_inputs=<factory>, harvested_ys=<factory>)[source]
Bases:
objectA calibrated numeric student in front of the routine it replaces.
- Parameters:
net (Any)
featurizer (Any)
qhat (float)
alpha (float)
tol (float)
holdout_mae (float)
y_mean (float)
y_scale (float)
train_inputs (list)
train_ys (list)
cal_inputs (list)
cal_ys (list)
hidden (tuple)
epochs (int)
lr (float)
seed (int)
n_requests (int)
n_escalated (int)
harvested_inputs (list)
harvested_ys (list)
- net: Any
- featurizer: Any
- qhat: float
- alpha: float
- tol: float
- holdout_mae: float
- y_mean: float
- y_scale: float
- train_inputs: list
- train_ys: list
- cal_inputs: list
- cal_ys: list
- hidden: tuple = (64,)
- epochs: int = 300
- lr: float = 0.01
- seed: int = 0
- n_requests: int = 0
- n_escalated: int = 0
- harvested_inputs: list
- harvested_ys: list
- interval(x)[source]
(yhat, lo, hi)with calibrated>= 1 - alphacoverage of the teacher’s answer.
- property answers_locally: bool
Whether the calibrated precision meets the tolerance at all (else everything escalates).
- save(path)[source]
Persist net (safetensors via the mixle.mlp builder) + featurizer + calibration;
load()restores.
- classmethod load(path, teacher, *, device='cpu')[source]
Reconstitute a serving RegressionSolution (no training/calibration data; improve() raises).
- class MultiLabelSolution(net, featurizer, labels, teacher, upper_absent, lower_present, alpha, holdout_set_agreement, train_inputs=<factory>, train_sets=<factory>, cal_inputs=<factory>, cal_sets=<factory>, hidden=(64, ), epochs=300, lr=0.01, seed=0, n_requests=0, n_escalated=0, harvested_inputs=<factory>, harvested_sets=<factory>)[source]
Bases:
objectA per-label-calibrated tagger in front of the routine it replaces.
- Parameters:
net (Any)
featurizer (Any)
upper_absent (ndarray)
lower_present (ndarray)
alpha (float)
holdout_set_agreement (float)
train_inputs (list)
train_sets (list)
cal_inputs (list)
cal_sets (list)
hidden (tuple)
epochs (int)
lr (float)
seed (int)
n_requests (int)
n_escalated (int)
harvested_inputs (list)
harvested_sets (list)
- net: Any
- featurizer: Any
- upper_absent: ndarray
- lower_present: ndarray
- alpha: float
- holdout_set_agreement: float
- train_inputs: list
- train_sets: list
- cal_inputs: list
- cal_sets: list
- hidden: tuple = (64,)
- epochs: int = 300
- lr: float = 0.01
- seed: int = 0
- n_requests: int = 0
- n_escalated: int = 0
- harvested_inputs: list
- harvested_sets: list
- try_local(x)[source]
The decided label set, or
Nonewhen any label is ambiguous (= must escalate).
- save(path)[source]
Persist net + featurizer + per-label bars;
load()restores a serving tagger.
- classmethod load(path, teacher, *, device='cpu')[source]
Reconstitute a serving MultiLabelSolution (no training/calibration data; improve() raises).
- class StructuredSolution(fields_cat, fields_num, teacher, n_requests=0, n_escalated=0, harvested_inputs=<factory>, harvested_outputs=<factory>)[source]
Bases:
objectPer-field calibrated students in front of the dict-valued routine they replace.
- Parameters:
- n_requests: int = 0
- n_escalated: int = 0
- harvested_inputs: list
- harvested_outputs: list
- try_local(x)[source]
The fully-decided output dict, or
Nonewhen ANY field is unsure (= must escalate).
- save(path)[source]
Persist every field’s sub-artifact under one directory;
load()restores the whole schema.
- classmethod load(path, teacher, *, device='cpu')[source]
Reconstitute a serving StructuredSolution (fields serve locally; escalation runs
teacher).
- class GenerativePlanner(lm, codec, tools, teacher, plan_agreement, max_new=160, constrained=True, conf_floor=None, lm_config=<factory>, n_requests=0, n_escalated=0, harvested=<factory>)[source]
Bases:
objectA plan-writing LM behind a parse-and-validate gate: only verified plans leave; the rest escalate.
- Parameters:
- lm: Any
- codec: _CharCodec
- plan_agreement: float
- max_new: int = 160
- constrained: bool = True
- lm_config: dict
- n_requests: int = 0
- n_escalated: int = 0
- try_plan(request)[source]
Generate, parse, validate (grammar + specs + copy-fidelity);
None= must escalate.With
constrained=True(default) the decode itself runs inside the plan grammar (mixle.task.constrained.constrained_plan_decode()): malformed text and copy-drifted values are unrepresentable, and the parse/validate below is a pure backstop.
- save(path)[source]
Persist the plan-writing LM (weights + builder config), codec, specs, and gates;
load()restores.
- class Planner(selector, extractors, tools, teacher, plan_agreement, max_steps=8, n_requests=0, n_escalated=0, harvested=<factory>)[source]
Bases:
objectA distilled decomposer: emit verified steps until STOP, or escalate the whole problem.
- Parameters:
- selector: Any
- plan_agreement: float
- max_steps: int = 8
- n_requests: int = 0
- n_escalated: int = 0
- try_plan(request, *, execute=None)[source]
The local decomposition alone: a complete verified plan, or
None(= must escalate).No teacher, no stats — this is what a server without the frontier can run.
- save(path)[source]
Persist selector + per-tool extractors + specs as one artifact directory;
load()restores.
- class Solution(cascade, teacher, kind, train_inputs, train_labels, cal_inputs, cal_labels, holdout_agreement, escalation_rate, promoted, target_agreement, distill_kw=<factory>, ood=None, seed=0, synthesized=0, gate_inputs=<factory>, edge=None)[source]
Bases:
objectA deployed task: a calibrated student in front of the teacher, plus the loop to improve it.
Call it like the original function.
promotedsays whether the student passed verification – when False the callable simply runs the teacher (an honest failure, never a silently bad model).- Parameters:
- cascade: Cascade
- kind: str
- train_inputs: list
- train_labels: list
- cal_inputs: list
- cal_labels: list
- holdout_agreement: float
- escalation_rate: float
- promoted: bool
- distill_kw: dict
- seed: int = 0
- synthesized: int = 0
- gate_inputs: list
- edge: Any = None
- report()[source]
What you would want on a dashboard: verification, live escalation, realized cost.
- Return type:
- improve()[source]
Re-distill with the harvested (escalated) labels; promote only if it verifies at least as well.
Returns True when a better student was promoted. The calibration slice is never trained on, so the conformal guarantee and the agreement comparison stay honest across rounds.
- Return type:
- health(recent_inputs=None, *, p_threshold=0.01)[source]
Is the calibration still holding on live traffic? The guarantee-watcher.
The conformal escalate-or-answer rate was calibrated under exchangeability; when the input distribution drifts, the live escalation rate moves away from the verified baseline — which is exactly the observable to alarm on. This compares the live rate against the baseline with an exact binomial test, and (when
recent_inputsare supplied and an OOD gate exists) also checks the gate’s out-of-distribution hit-rate against its design quantile.Returns a dict with
drifted(bool), the rates, and p-values. Honest caveat: a drift alarm means “the world changed, escalations (and cost) will rise, re-solve soon” — the SYSTEM stays correct throughout because unsure inputs still go to the teacher.
- save(path)[source]
Persist the calibrated student as a load-anywhere artifact, with its verification record.
Every deployed artifact carries how it was verified — held-out agreement with the teacher, the escalation rate, the conformal alpha, and how much of its training data was synthetic — so “is this model trustworthy” is answerable from the artifact alone.
- deploy(name, root='./mixle_data/registry')[source]
Save into the serving layout —
{root}/tasks/{name}— the directory the mixle-mlops/v1/tasksroutes serve from. Returns the artifact path.
- classmethod load(path, teacher, *, cost=None, device='cpu')[source]
Reconstitute a serving Solution from a saved artifact — the deploy path for a fresh process.
The loaded Solution answers locally / escalates to
teacherand harvests labels exactly like the original. It carries no training or calibration data, soimprove()raises — collect the harvested pairs and re-solve(real + harvested inputs) to train the next round.
- class StructuredClassifierIO(field_keys, label_index, labels)[source]
Bases:
objectrecord -> labelthrough a structured probabilistic model instead of a neural net.The model is a fitted joint over
(field_1, ..., field_m, label)– aDependencyTreeDistribution(or mixture) discovered bymixle.inference.structure.learn_structure(). Classification is the generative ruleargmax_label P(features, label): score each candidate label and pick the best. Becausesoftmax_label log P(features, label) = P(label | features)exactly (the feature evidence is a shared constant across labels),proba_batch()returns the true posterior – not a softmax over arbitrary logits – so conformal calibration (mixle.task.calibrate) and the density gate operate on a real probability.The student is interpretable (
model.edges()shows the discovered dependencies), kilobytes on disk, and round-trips through the json artifact path. It assumes a fixed schema: every record exposes the same fields (field_keysfor dicts, positional for tuples) – the variable set a Bayesian network is defined over.- kind = 'structured_classifier'
- logits_batch(model, raw_inputs)[source]
Per-label log-joint
log P(features, label)as an(m, K)score matrix (the classifier logits).
- proba_batch(model, raw_inputs)[source]
The exact posterior
P(label | features)– softmax of the per-label log-joints (shared evidence cancels).
- predict_batch(model, raw_inputs)[source]
- class TaskManifest(payload, builder=None, config=<factory>, task='', io=<factory>, meta=<factory>, schema_version='1', created_at='')[source]
Bases:
objectThe self-describing header of a task artifact: enough to rebuild and call the model, plus provenance.
- Parameters:
- payload: str
- task: str = ''
- schema_version: str = '1'
- created_at: str = ''
- class TaskModel(model, adapter, *, builder=None, config=None, payload='torch', task='', meta=None)[source]
Bases:
objectA fitted small model plus its I/O adapter, callable as
task(raw) -> resultand saveable to a directory.- Parameters:
- save(path)[source]
Persist as a task artifact: the model payload plus the adapter’s
iospec and metadata.
- class ToolCaller(selector, extractors, tools, teacher, selection_agreement, n_requests=0, n_escalated=0, harvested=<factory>)[source]
Bases:
objectA distilled function-caller: emit a call only when selection AND arguments are trustworthy.
- Parameters:
- selector: Solution
- selection_agreement: float
- n_requests: int = 0
- n_escalated: int = 0
- try_local(request)[source]
The local decision alone: a trustworthy call / no-op, or
None(= must escalate).No teacher, no stats — this is what a server without the frontier can run.
- save(path)[source]
Persist selector + per-tool extractors + specs as one artifact directory;
load()restores.
- class ToolSpec(name, args, required=None)[source]
Bases:
objectOne callable tool: its name and the argument fields to extract from the request text.
- name: str
- class TextClassifierIO(featurizer, labels)[source]
Bases:
_ClassifierIOstr -> label: hashed character n-gram features into a small classifier.- kind = 'text_classifier'
- class TuneResult(model, recipe, agreement, score, cost, history=None)[source]
Bases:
objectThe outcome of a recipe search: the winning model, its recipe and scores, and the full BO history.
- Parameters:
- model: TaskModel
- agreement: float
- score: float
- cost: float
- history: Any = None
- acquisition_scores(student, texts, method='margin')[source]
Informativeness of each unlabeled text under the student (higher = more worth labeling).
- active_distill(teacher, pool, *, budget, seed_size=20, rounds=5, acquisition='margin', labels=None, recipe=None, val_texts=None, seed=0)[source]
Distill from
poolunder a labelingbudget, querying the teacher only for the most informative items.Labels a
seed_sizerandom seed, then overroundsadds the top-scoring unlabeled examples (byacquisition) untilbudgetlabels are spent, refitting the student each round. Ifval_textsis given, the teacher labels it once and each round’s agreement on it is logged.
- adapter_from_spec(spec)[source]
Rebuild an adapter from its
iospec (thekindfield selects the factory).
- agreement(student, teacher_labels, texts)[source]
Fraction of
textswhere the student’s label matches the teacher’s – distillation fidelity.
- break_even_volume(cost, n_label, *, p_escalate=0.0)[source]
Requests after which a distilled route undercuts frontier-only (
infif it never does).Setup is amortized against the per-request saving
c_frontier - per_request(route). Withp_escalate=0this is the local-only break-even; pass the model’s escalation rate for the cascade break-even.
- cascade_cost_per_request(cost, p_escalate)[source]
Expected per-request cost of the cascade: always run local, escalate the
p_escalatefraction.
- design_model(data, llm, *, fallback=True, validate_rows=200)[source]
Ask
llmto design a model fordata; build, fit-validate, and fall back to the heuristic on failure.The LLM sees a compact
data_profile()and returns a JSON spec; the spec is built into a real estimator and fit on a sample to prove it works. Any failure (no LLM, bad JSON, off-allowlist family, fit error) yields the heuristicmixle.task.recommend.recommend_model()estimator whenfallbackis set.
- distill(teacher, texts, *, labels=None, n=3, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu')[source]
Label
textswithteacher, fit a small student to match, 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.
- distill_designer(design, *, quality_quantile=0.5, seed=0)[source]
Distill the design ledger into a tiny torch-free student that judges designs: point -> good/weak.
The
DesignModel’s rows are records (the design coordinates); a row is labeledgoodwhen it was feasible on the device and its quality reached the ledger’squality_quantile.distill_structured_from_labels()– the same machinery the design model tunes – compresses that knowledge into a kilobyte Bayesian-network student usable as a zero-cost pre-filter for future searches. Teacher trains student; a model designs the students; the designer is distilled into a student: each level of the tower is a real artifact.
- distill_extractor(teacher, texts, fields, *, max_vocab=5000, d_model=64, hidden=64, epochs=60, lr=5e-3, max_len=128, seed=0, device='cpu', task='')[source]
Distill a teacher’s extractions into a tiny sequence tagger; return
model(text) -> {field: value}.
- distill_planner(teacher, requests, tools, *, holdout=0.2, seed=0, max_steps=8, selector_kw=None, extractor_kw=None)[source]
Distill the teacher’s multi-step plans into next-step students (see module docstring).
Plan-level verification is measured on held-out requests the students never trained on: a plan agrees when every step’s tool and required arguments match the teacher’s plan exactly, in order.
- distill_tool_caller(teacher, requests, tools, *, seed=0, selector_kw=None, extractor_kw=None)[source]
Distill the teacher’s function-calling into a tiny selector + per-tool argument extractors.
- Parameters:
teacher (Callable[[str], dict]) –
teacher(request) -> {"tool": name-or-None, "args": {field: value}}— the frontier LLM / agent / rule currently doing the calling. It labels everything; it remains the fallback.requests (Sequence[str]) – example request texts covering the tools.
tools (Sequence[ToolSpec]) – the tool specs (names + argument fields;
requireddefaults to all).extractor_kw (dict | None) – knobs forwarded to
solve()anddistill_extractor().seed (int)
selector_kw (dict | None)
extractor_kw
- Return type:
ToolCaller
- distill_for_edge(teacher, train_data, val_data, device, *, labels=None, train_labels=None, val_labels=None, space=None, design=None, designer=None, n_init=4, n_iter=6, screen_fidelity=0.3, promote=2, seed=0, task='')[source]
Search structure x training-process for the best student that fits
device.The teacher labels
train_data/val_dataonce (cached) – or passtrain_labels/val_labelswhen the labels already exist (a harvested dataset, an upstreamsolvesplit) and the teacher is then never called (it may beNone). Candidates proposed by theDesignModelare trained atscreen_fidelity(cheap), scored by held-out agreement, and measured (footprint()); the toppromotefeasible screens are re-trained at full fidelity and the best feasible one wins (ties -> smaller). Pass a previous search’sdesign(same space + device shape) to warm-start: the surrogate already knows which regions blow the budget. Passdesigner(the tiny judge fromdistill_designer()) to veto known-weak proposals before any training is spent. If nothing fits the device, the least-infeasible student is returned withfeasible=False– inspectresult.paretofor the real trade-off frontier.
- footprint(student)[source]
Measure a student’s deployment cost. Bytes are real (fp32 weights, int8 arrays for a quantized student, or serialized JSON for a structured one); ops are the closed-form per-inference count for the student’s kind.
- Parameters:
student (TaskModel)
- Return type:
EdgeFootprint
- 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_text_generative(teacher, texts, *, labels=None, pseudo_count=0.5, min_count=2, task='')[source]
Distill a teacher into the generative text student (the teacher labels; see module docstring).
- distill_text_generative_from_labels(texts, teacher_labels, *, labels=None, pseudo_count=1.0, min_count=2, task='')[source]
Fit the per-class token models from already-labeled texts (the teacher-free training core).
- distill_records(teacher, records, *, labels=None, dim=256, hidden=(64,), epochs=200, lr=1e-2, seed=0, task='', device='cpu')[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_structured(teacher, records, *, labels=None, n_components=1, min_gain=0.0, n_bins=4, max_its=30, seed=0, task='')[source]
Distill a teacher into a tiny 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.
- extraction_f1(model, gold, texts)[source]
Micro-averaged field-level F1: a field counts as correct when the extracted value exactly matches gold.
- harvest_agent_traces(directory=None)[source]
Read every stored mixle-agent conversation and return the trace corpus (skips unreadable files).
- parse_conversation(doc)[source]
Split one stored conversation into traces: user request -> assistant tool calls until the next user turn.
- get_arrays_builder(name)[source]
Look up a registered arrays builder, triggering native self-registration on first call.
- get_builder(name)[source]
Look up a registered builder, triggering native-builder self-registration on first call.
- llm_extractor(llm, fields, *, instruction=None, system=None)[source]
Turn an LLM into a field-extraction teacher
texts -> [{field: value}]formixle.task.extract.distill_extractor().Each text is extracted into a JSON object over
fields(values must be verbatim substrings so they align to token spans during distillation). The returned callable has the batched-teacher shape the extractor expects.
- llm_labeler(llm, labels, *, instruction=None, system=None)[source]
Turn an LLM into a label-constrained teacher
texts -> [label]for distillation / active labeling.Each item is classified into
labelsby a constrained prompt; the reply is mapped back withpick_label(). The returned callable has the batched-teacher shape the rest ofmixle.taskexpects.
- load_harvested(path)[source]
Read the
harvested.jsonla serving endpoint accumulates into(inputs, answers).Two line formats are understood:
{"input": ..., "label": ...}(the mixle-mlops/v1/tasks/{name}/feedbackclassification format — labels are str-coerced) and{"input": ..., "answer": ...}(the/v1/solutions/{name}/feedbackformat for every solve shape — the answer keeps its shape: a number for regression, a list of labels for multilabel, a dict for structured). Input JSON lists coerce back to tuples — the record shape the solve trained on — so the pairs feed straight intosolve*(..., prelabeled=load_harvested(p)).
- lns_classifier(student, *, step=1e-2)[source]
Re-execute a structured student in integer log-space (the LNS rung for structured students).
The fitted model is unchanged (same factors, same JSON artifact); what changes is how inference runs: factor log-densities are quantized once at the leaf boundary, and everything above – per-label accumulation, mixture folding, the argmax decision, the posterior’s log-softmax – is integer add/max/LUT arithmetic (
LNSStructuredClassifierIO).steptrades fidelity for integer width; the dequantized scores match the float classifier within ~``1.5 * step`` per fold. This is compute quantization (transcendental-free combination), not weight compression – pair it with the structured student’s already-tiny JSON payload.- Parameters:
student (TaskModel)
step (float)
- Return type:
TaskModel
- pick_label(text, labels)[source]
Map a free-text LLM reply to one of
labels(exact, then substring, else the first label).
- recommend_model(data, *, fit=False, **analyze_kwargs)[source]
Recommend a model shape for
data(and optionally fit it); seeModelRecommendation.analyze_kwargspass through tomixle.utils.automatic.analyze_structure()(sampling, pairwise budget, validation). Withfit=Truethe returned recommendation’sestimatoris also fit and the model is attached as.model.
- recommend_route(cost, *, volume, n_label, p_escalate, max_escalation=None)[source]
Pick the cheapest route over
volumerequests; honor an optional cap on tolerated escalation.local_onlyis treated as a cascade with no escalation only when its quality is acceptable to the caller – here it is offered whenevermax_escalationis not exceeded byp_escalate(the cascade already answers the easy cases locally and escalates the rest, so it dominates pure local-only on accuracy; local-only is kept as the floor cost when escalation is disallowed entirely,max_escalation == 0).
- replace_alerter(teacher, series, *, window=16, stride=1, **solve_kw)[source]
Replace a threshold/heuristic alert rule over a sliding window with a calibrated model.
teacher(window) -> label(e.g."alert"/"ok") labels every window of the historical series; the returnedSolutionis called with a window (the latestwindowsamples) and answers locally only when conformally confident and in-distribution — otherwise it runs the rule.
- replace_extractor(teacher, texts, fields, *, required=None, holdout=0.25, seed=0, **distill_kw)[source]
Replace a regex/parser scraper with a distilled token-level extractor + teacher fallback.
The teacher labels the training texts; a held-out slice measures field-level F1 against the teacher. At call time a prediction missing any
requiredfield (default: allfields) falls back to the teacher — the same never-silently-wrong shape assolve().
- replace_matcher(teacher, pairs, **solve_kw)[source]
Replace a record-matching/dedup rule with a calibrated model over encoded pairs.
teacher(a, b) -> label(e.g."match"/"no-match") labels the example pairs; each pair is encoded as one record (both sides plus numeric-difference and same-value features, which is where matchers earn their keep). Call the result with(a, b): confident pairs answer locally, everything else runs the rule.
- route_stack(solutions, teacher, *, costs)[source]
Convenience:
Router.from_solutions()with tiers sorted cheapest-first by cost.
- scorecard(student, teacher, test_inputs, *, student_cost=None, teacher_cost=None, task='task')[source]
Measure a deployed student against the teacher it replaces on held-out inputs (see module docstring).
- Parameters:
student (Any) – any solve shape —
Solution,RegressionSolution,MultiLabelSolution,StructuredSolution(or anything exposingcascade.model.decide) — the escalate-aware system under test.teacher (Any) – the callable being replaced; also the accuracy reference.
test_inputs (Any) – held-out inputs (the teacher is called once per input for the reference labels).
teacher_cost (float | None) – optional per-request costs for the $/1k rows. The blended student cost prices escalated requests at
teacher_cost.task (str) – a label for the table header.
student_cost (float | None)
teacher_cost
- Return type:
Scorecard
- sft_planner(teacher, requests, tools, *, holdout=0.2, seed=0, d_model=96, n_layer=3, n_head=4, block=192, epochs=30, lr=3e-3, device='cpu', constrained=True)[source]
Trace-SFT a small causal LM into a plan writer, verified on held-out requests.
Traces serialize as
request\n=> tool(k=v; ...) | ... \npairs;LM.fit_pairstrains with the prompt masked so only plan tokens carry loss; generation stops at newline. Held-out agreement is plan-level exact match (tools + required args, in order) on requests the LM never saw.
- spec_to_estimator(spec)[source]
Build a mixle estimator from an allowlisted spec dict (recursively); raise on anything off the allowlist.
- Specs:
{"family": "<name>"}– a scalar leaf (seeALLOWED_FAMILIES);{"type": "composite", "fields": [spec, ...]}– a tuple record of sub-models;{"type": "mixture", "k": K, "component": spec}– a K-component mixture of the component model.
- load_arrays(path)[source]
Rebuild a torch-free model from an arrays-payload artifact; return
(model, manifest).
- load_json(path)[source]
Rebuild a pure mixle distribution from a json-payload artifact; return
(model, manifest).
- load_module(path, *, device='cpu')[source]
Rebuild a torch module from its manifest alone and load weights; return
(module, manifest).
- quantize_mlp(student, *, bits=8, clip_percentile=None)[source]
Quantize a trained torch MLP student to an int8/int4, numpy-inference
TaskModel.Per-tensor symmetric weight quantization (
scale = max|W| / qmaxwithqmax127 for int8, 7 for int4); biases stay fp32 (they are a negligible byte fraction and quantizing them buys nothing). The returned student reuses the same featurizer and label list, reportspayload="arrays"(int4 weights nibble-packed on disk: two per byte), and – having no torch dependence at inference – qualifies fortorch_freedevices. LNS needs LUT matmul kernels (mixle.engines.lns) and is left explicitly unimplemented.clip_percentileguards heavy-tailed weights. Plain max-scaling lets one outlier set the whole layer’s scale: at int4 (qmax=7) a single weight 30x the rest quantizes everything else to 0, collapsing the layer. When set (e.g.99.9), the scale is derived from that percentile of|W|instead of the max, and weights above it saturate at+/-qmax– the bulk of the distribution keeps its resolution at the cost of clipping a few outliers. DefaultNonekeeps the exact max-scale behavior (bit-identical on well-behaved weights).
- read_manifest(path)[source]
Read just the manifest of an artifact directory (cheap: no weights loaded).
- Parameters:
path (str)
- Return type:
TaskManifest
- register_adapter(kind, from_spec)[source]
Register an adapter’s
from_specfactory underkindso a savedioblock can rebuild it.
- register_arrays_builder(name, builder)[source]
Register
builder(arrays: dict[str, ndarray], **config) -> modelfor arrays-payload artifacts.The arrays payload is for torch-free numeric students (e.g. an int8-quantized MLP): weights live in one
.npz, and the builder reconstructs the runnable model from them in a fresh process.
- register_builder(name, builder)[source]
Register
builderundernameso an artifact carryingbuilder=namecan reconstruct its module.builder(**config)must return a fresh (untrained)nn.Modulewhose parameter shapes match the saved weights. Re-registering the same name with the same callable is a no-op; a conflicting one raises.
- save_arrays(path, arrays, builder, config=None, *, task='', io=None, meta=None)[source]
Persist a dict of numpy arrays as an artifact directory (
arrays.npz); returnpath.
- save_json(path, model, *, task='', io=None, meta=None)[source]
Persist a pure (torch-free) mixle distribution via the safe serialization registry; return
path.
- save_module(path, module, builder, config, *, task='', io=None, meta=None)[source]
Persist a torch
moduleas an artifact directory and returnpath.builder/configmust reconstruct an architecturally identical module (get_builder(builder)(**config)); weights go throughsafetensors.torch.save_modelso tied parameters (e.g. the LM’s tied head) round-trip.
- solve(teacher, inputs, *, alpha=0.1, target_agreement=None, holdout=0.25, kind=None, ood=0.02, propose=None, propose_budget=8, synthesize=0, prelabeled=None, device=None, device_space=None, cost=None, seed=0, **distill_kw)[source]
Replace
teacher(the code currently doing the job) with a calibrated, self-improving model.- Parameters:
teacher (Callable[[...], Any]) – The callable performing the task today (per-item or batched). It labels the dataset and remains the fallback for inputs the student is not sure about.
inputs (Sequence[Any]) – Example inputs (text, or tuple/dict records) covering the task. The teacher labels them.
alpha (float) – Escalation honesty – answer locally only when a single label is conformally covered at
>= 1 - alpha; otherwise fall back to the teacher.target_agreement (float | None) – Optional gate. If the student’s held-out agreement with the teacher misses it, the returned Solution routes everything to the teacher (
promoted=False).holdout (float) – Fraction reserved for calibration + verification (never trained on).
kind (str | None) – Force the student path,
'text'or'record'; default sniffs the first input.ood (float | None) – Fit a
p(x)gate over the training inputs and escalate inputs whoselog p(x)falls below this quantile floor — so a wildly novel input escalates even when the softmax looks confident. On by default (0.02);Nonedisables.propose (str | None) –
"auto"searches the student recipe (dim/hidden/epochs/lr, Bayesian-optimized on a val slice carved from the training split) instead of using the defaults. Teacher-free — the labels are already computed, so candidates cost only student fits.propose_budget (int) – Total candidate recipes tried when
propose="auto".synthesize (int) – When example inputs are scarce, sample this many synthetic inputs from a generative model fit to the real training inputs (record inputs only) and have the teacher label them. Labels are always real (teacher-produced); the calibration slice and the OOD gate stay real-inputs-only, so the conformal guarantee and the p(x) floor reflect the true distribution.
prelabeled (tuple[Sequence[Any], Sequence[Any]] | None) – Already-teacher-labeled
(inputs, labels)pairs — typicallyload_harvested("harvested.jsonl")from a serving deployment — folded into the TRAINING split (and the OOD gate: they are real traffic) but never into calibration, which stays a fresh split ofinputs. This is the re-solve half of the serving loop.device (Any) – A
DeviceSpecmakes this “give me this capability on that device”: the student is found bydistill_for_edge()— a structure x precision x recipe search under the device’s hard byte/ops/torch-free budget (reusing the already-computed labels; the teacher is not re-called) — and the result’s footprint, Pareto front, and design ledger land onSolution.edge. If nothing fits the budget the Solution is demoted (everything routes to the teacher — an honest failure). Incompatible withpropose="auto"(the device search subsumes it). A plain string (e.g."cpu") keeps its old meaning: the torch training device.device_space (Any) – Optional
EdgeSpaceconstraining the device search (families, size ranges, precisions); default spans the standard space.cost (Any) – Optional
CostModelfor realized-savings reporting.seed (int) – Split + fit determinism.
**distill_kw (Any) – Student knobs forwarded to distillation (
dim,hidden,epochs,lr, …).student="generative"swaps the hashed-feature MLP for mixle’s generative student — per-class token models for text (mixle.task.generative_text) or the structure-learned joint for records (distill_structured_from_labels()): exact posteriors, no torch needed at inference, and a built-inlog p(x).
- Returns:
A
Solution– call it like the original function;report()/improve()/save().- Return type:
Solution
- solve_regression(teacher, inputs, *, tol, alpha=0.1, holdout=0.25, kind=None, hidden=(64,), epochs=300, lr=1e-2, dim=256, prelabeled=None, seed=0)[source]
Replace a numeric routine with a conformally-calibrated student (see module docstring).
- Parameters:
teacher (Callable[[...], Any]) – the numeric routine (
teacher(x) -> float); labels the dataset, remains the fallback.inputs (Sequence[Any]) – example inputs (text or dict/tuple records).
tol (float) – the caller’s precision requirement — answer locally only when the calibrated
qhat <= tol.alpha (float) – interval miscoverage level (
1 - alphacoverage of the teacher’s answer).prelabeled (tuple[Sequence[Any], Sequence[float]] | None) – already-teacher-labeled
(inputs, values)— typically harvested escalations from a serving deployment — folded into the TRAINING split only, never calibration (which stays a fresh split ofinputs, soqhatkeeps its finite-sample guarantee). The re-solve half of the serving loop.holdout (float)
kind (str | None)
epochs (int)
lr (float)
dim (int)
seed (int)
- Return type:
RegressionSolution
- solve_multilabel(teacher, inputs, *, alpha=0.1, holdout=0.25, kind=None, hidden=(64,), epochs=300, lr=1e-2, dim=256, prelabeled=None, seed=0)[source]
Replace a set-of-labels routine with a per-label-calibrated student (see module docstring).
prelabeled— already-teacher-labeled(inputs, label_sets), typically harvested escalations from a serving deployment — folds into the TRAINING split only, never calibration (which stays a fresh split ofinputs, so the per-label bars keep their finite-sample rank guarantee). Labels seen only inprelabeledstill enter the label space.
- solve_structured(teacher, inputs, *, tol=None, alpha=0.1, prelabeled=None, seed=0, **sub_kw)[source]
Replace a dict-valued routine with per-field calibrated students (see module docstring).
- Parameters:
teacher (Callable[[...], Any]) –
teacher(x) -> dictwith a consistent schema; called once per example input.inputs (Sequence[Any]) – example inputs (text or dict/tuple records).
tol (dict[str, float] | float | None) – the precision requirement for numeric fields — a scalar for all, or
{field: tol}. Required when the schema has numeric fields.alpha (float) – shared miscoverage level for every field’s calibration.
prelabeled (tuple[Sequence[Any], Sequence[dict]] | None) – already-teacher-labeled
(inputs, output_dicts)— typically harvested escalations from a serving deployment — fanned down into every field’s TRAINING split only, never calibration (each sub-solution’s guarantee stays a fresh split ofinputs). The schema stays authoritative from theinputspass; a pair missing a field is simply skipped for that field.**sub_kw (Any) – knobs forwarded to every sub-solve (
epochs,hidden,dim, …).seed (int)
**sub_kw
- Return type:
StructuredSolution
- measure_inference_seconds(student, inputs, *, repeats=5)[source]
Median measured wall-clock seconds per single-input inference for
studenton this host.Runs
student.batch(inputs)repeatstimes (after one untimed warm-up) and reports the median per-item time. Measured, not modeled – run it on the machine whose latency you care about (the deploy device, not the dev laptop) for a number that means anything there.
- measure_ops_per_second(student, inputs, *, repeats=5)[source]
Measured throughput (footprint ops / measured second) for this student kind on this host.
The calibration constant that turns a latency budget into
DeviceSpecmax_ops(DeviceSpec.for_latency()): probe once per (device, student kind), reuse across searches.
- task_fingerprint(data, labels)[source]
A fixed small vector describing which task this is: the coords cross-task warm start keys on.
(log10 #examples, #labels, #fields, fraction of categorical fields, normalized label entropy)– cheap invariants of the dataset, O(1)-scaled so the design surrogate’s default lengthscale treats similar tasks as informative neighbors and dissimilar ones as weakly coupled.
- tokenize(text)[source]
Split
textinto(token, start, end)triples: runs of digits, letters, or single punctuation.
- tune_recipe(teacher, train_texts, val_texts, *, labels=None, space=None, n_init=4, n_iter=8, cost_weight=0.0, seed=0, task='')[source]
Bayesian-optimize the distillation recipe; return the best re-distilled
TaskModel.Maximizes held-out
agreement(student, teacher, val_texts)minuscost_weight * relative_train_cost. Setcost_weight > 0to prefer the cheapest recipe that still matches the teacher.teacheris called once per candidate onval_texts(cached across the search) and once per candidate ontrain_texts.
Submodules¶
- mixle.task.active module
- mixle.task.artifact module
- mixle.task.calibrate module
- mixle.task.cascade module
- mixle.task.constrained module
- mixle.task.density module
- mixle.task.design module
- mixle.task.distill module
- mixle.task.distill_methods module
- mixle.task.economics module
- mixle.task.edge module
- mixle.task.extract module
- mixle.task.generative_text module
- mixle.task.harness module
- mixle.task.llm module
- mixle.task.model module
- mixle.task.multilabel module
- mixle.task.plan module
- mixle.task.quantize module
- mixle.task.recommend module
- mixle.task.regress module
- mixle.task.router module
- mixle.task.scorecard module
- mixle.task.sft_plan module
- mixle.task.solve module
- mixle.task.structured_out module
- mixle.task.toolcall module
- mixle.task.traces module
- mixle.task.tune module