mixle.task.calibrate module¶
CalibratedTaskModel wraps a task model in conformal answer sets.
A distilled student classifies by argmax over a softmax, but the softmax value
alone is not a coverage guarantee. Conformal prediction adds the serving
contract: on a held-out calibration set it learns a score threshold
(mixle.inference.conformal.conformal_label_threshold()) such that the
prediction set covers the true label with probability >= 1 - alpha under
the usual exchangeability assumption AND the condition that the underlying
model’s behavior is unchanged since calibration – the threshold ranks the
calibration-time model’s scores, so an in-place retrain/update voids the
statement exactly like distribution shift does, and just as silently
(STAT-RR22-08/RR23-09). The density gate mitigates shift; drifted traffic or a
changed model calls for recalibration.
The decision rule the cascade and the cost model consume:
singleton set -> answer locally. NOTE: the
1 - alphaguarantee is MARGINAL – over the whole population, the set contains the truth with probability>= 1 - alpha. It is NOT a conditional guarantee on the answered slice: error among singleton answers can be far higher (an adversarial review measured 9% marginal miscoverage alongside 47% answered-slice error atalpha=0.10). Measure answered-slice agreement per deployment (report()does) rather than reading it offalpha;empty or multi-label set -> escalate to the expensive teacher/frontier (genuinely ambiguous).
When the answered slice itself needs a risk guarantee, calibrate it directly:
CalibratedTaskModel.calibrate_selective() certifies thresholds from a PRE-SPECIFIED grid
(1001 evenly spaced values, fixed in code, never derived from the sample) with an exact
Clopper-Pearson binomial test per grid point at Bonferroni level delta / 1001, and serves at
the loosest certified threshold. That is Learn-Then-Test risk control with explicit
multiple-testing correction: with probability at least 1 - delta over an i.i.d. calibration
draw, the error rate among the answers the model actually gives is at most alpha. It exists
because the marginal guarantee above is NOT that statement – the adversarial statistical review
measured 9% marginal miscoverage alongside 47.4% answered-slice error on a population built to
split them.
escalation_rate is the empirical p_escalate used by the cost model.
Conformal coverage is marginal, and a softmax still cannot see true OOD; a generative-density gate
(mixle.task.density) covers that residual. Calibration persists in the artifact, so a loaded model decides
identically in a fresh process.
- selective_risk_threshold(top_probabilities, correct, *, alpha, delta=0.05, min_answered=10)[source]
Choose a confidence threshold whose ANSWERED-SLICE error is controlled, not just marginal.
Learn-Then-Test risk control with explicit multiple-testing correction (Angelopoulos et al., arXiv:2110.01052): every candidate threshold in the pre-specified grid
_SELECTIVE_GRIDis tested against the calibration sample with an exact Clopper-Pearson binomial upper bound on its answered-slice error rate, each test at Bonferroni leveldelta / len(grid). By the union bound, with probability at least1 - deltaover the calibration draw, EVERY threshold that passes its test simultaneously has true answered-slice error at mostalpha– which is what licenses returning the loosest certified threshold after seeing all the results. ReturnsNonewhen no grid threshold with at leastmin_answeredanswered rows certifies: “this model cannot guarantee that risk; escalate everything”.Guarantee, stated exactly: if calibration rows are drawn i.i.d. from the deployment distribution, then with probability at least
1 - deltaover the calibration draw, the deployment error rate among rows answered at the returned threshold (answer iff top-class probability>= tau) is at mostalpha. The conditional-Binomial step needs i.i.d. sampling, not just exchangeability. The correction’s price is conservatism: certifying a zero-error slice needs aboutlog(delta/1001)/log(1-alpha)answered rows (~94 atalpha=0.10, delta=0.05, versus ~29 uncorrected), andtauis quantized to 0.001.
- class CalibratedTaskModel(task, *, alpha=0.1, qhat=None, tau=None, density_gate=None)[source]
Bases:
objectA
TaskModelplus a conformal threshold: predicts label sets and decides answer-vs-escalate.THE THRESHOLD IS BOUND TO THE PREDICTOR THAT PRODUCED THE CALIBRATION SCORES (STAT-RR22-08).
qhatranks nonconformity scores computed by the contained task model at calibration time; every coverage/selective-risk statement is conditional on that model’s behavior remaining unchanged at serving. Mutating the contained model in place (retraining its raw weights, swapping adapter state) silently voids the guarantee – an exact-wheel probe that mutated the contained model flipped prediction sets from correct to wrong with coverage 1.0 -> 0.0 whileqhatsat unchanged – and no runtime check here can detect an in-place mutation. Every library flow that changes the model (improve()and friends) recalibrates in the same operation; if you touch the model yourself, callcalibrate(...)again before serving.- Parameters:
- 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).
Impossible structured evidence stays an empty prediction set so the calibrated serving contract escalates it; malformed adapter probabilities raise (see
_proba()).
- predict_set(text)[source]
Return the conformal label set for one input.
- calibrate_selective(texts, teacher_labels, *, delta=0.05, min_answered=10)[source]
Calibrate the ANSWERED-SLICE risk gate (see
selective_risk_threshold()).Runs after
calibrate()(both gates then apply) or instead of it (serving answers the argmax label whenever the top-class probability clearstau), and applies the same fail-closed input validation ascalibrate(). When no threshold can control the risk,taubecomesinfand everything escalates – an honest refusal, never a silent downgrade to the marginal-only contract.
- decide(text)[source]
Return the label if the input is a confident, in-distribution singleton, else
ESCALATE(None).
- batch_decide(texts)[source]
Return local labels or
ESCALATEfor a batch of inputs.
- escalation_rate(texts)[source]
Empirical
p_escalate– the fraction of inputs escalated (ambiguous set or, if gated, OOD).
- save(path)[source]
Persist the model, the full calibration (alpha, qhat, tau), and any density gate in the artifact.
qhatandtaucan each legitimately be+inf(qhat: too little calibration data to admit any confident singleton; tau:calibrate_selectivecould not control the risk). Those are real, callable thresholds, so both persist as the JSON-safe sentinel"inf"and reload back tofloat('inf'). The persistence contract is decision identity INCLUDING abstentions: the re-review’s STAT-R1 caughttaubeing dropped here, which silently downgraded a selectively calibrated artifact to the marginal-only rule and answered a row it had abstained on.