ExamplesΒΆ
Runnable examples live in examples/. They are plain Python scripts, so the
fastest way to learn a workflow is to run the script under the same environment
you use for tests.
For a shorter, receipt-focused index of the newer applied adapter and multimodal-pretraining workflows, see Example Gallery.
Start with the base-install examples. Move to Torch, task, or real-data workflows only after the core distribution and inference path is clear.
Examples are documentation assets, not release gates by themselves. When an example backs a public claim, record its execution status in Example Execution Manifest and note any skipped optional dependency.
Recommended First RunsΒΆ
Script |
What it demonstrates |
Needs |
|---|---|---|
|
The two front-door entry points, |
Base install |
|
Scalar continuous and discrete families. |
Base install |
|
Records, tuples, sequences, optional fields, and transforms. |
Base install |
|
Mixtures, HMMs, LDA, and latent-variable models. |
Base install |
|
Automatic estimator selection for mixed Python records. |
Base install |
|
Low-rank, sparse, Kronecker, duration, terminal, and input-output HMMs. |
Base install |
|
Provenance, registry, serving, drift, and checkpoints. |
Base install |
Run them directly:
python examples/quickstart_example.py
python examples/gallery_univariate_example.py
python examples/gallery_combinators_example.py
python examples/gallery_structured_example.py
python examples/auto_example.py
python examples/structured_hmm_example.py
python examples/production_example.py
Choose by WorkflowΒΆ
Workflow |
Start with |
Related guides |
|---|---|---|
Heterogeneous records |
|
|
Capability introspection |
|
|
Correlated continuous columns (copulas and vines) |
|
|
Combinatorial scheduling (max-weight closure, time-phased MILP) |
|
|
Symbolic export (LaTeX / SymPy / Sage) |
|
|
Mixtures and latent state models |
|
HMMs and Latent Structure, Latent, Bayesian, and Nonparametric Families |
Mixture compression and projection |
|
|
Distribution family discovery |
|
|
Graphs, rankings, trees, and sets |
|
|
Temporal and point processes |
|
|
Probabilistic programming |
|
|
Model comparison (WAIC / LOO / compare) |
|
|
Exact support traversal |
|
|
Scaling and engines |
|
|
Neural or representation workflows |
|
|
Local reasoning ecosystem |
|
|
Scientific inverse problems |
|
|
LLM/task replacement |
|
Task Distillation, Task Serving, Routing, and Edge Deployment |
Extraction and agent-style task behavior |
|
Task Serving, Routing, and Edge Deployment, Agentic Task Distillation |
Real DataΒΆ
The repository deliberately carries no direct dataset usage: no example fetches, embeds, or pins an external dataset, and every script here runs on synthetic data it generates itself. Demonstrations against real public datasets live in notebooks outside this repository, where a dataset download is an explicit, interactive act rather than repository behavior.
Dependency NotesΒΆ
Most examples use only the base package dependencies. Examples that train
neural students, neural leaves, representation models, or neural-density
teachers generally need mixle[torch].
pip install -e .
pip install -e ".[torch]"
pip install -e ".[scientist]"
pip install -e ".[examples]"
Use mixle[all] only when you deliberately want the full runtime-feature surface.
For most examples, a smaller extra is easier to debug.
Execution StandardΒΆ
When adding or updating an example:
keep it runnable from the repository root;
print a compact result that confirms the intended behavior;
avoid private data, external credentials, and hidden services;
mark optional dependencies in this page or in the script header;
keep long benchmarks outside the documentation example set;
update Example Execution Manifest when the example is part of release evidence.
Examples that require downloaded datasets or large local weights should degrade clearly when those resources are missing.
Complete InventoryΒΆ
Script |
Category |
Purpose |
|---|---|---|
|
Automatic inference |
Infer an estimator shape for mixed Python records. |
|
Enumeration |
Exact count, rank, and unrank over an autoregressive modelβs sequence space without enumerating it. |
|
Calibrated reporting |
Volumes to claims to a calibrated report: every sentence in the output carries its own receipt. |
|
Capability layer |
What an object can actually do, not what class it is. |
|
Dependence structure |
Copula and vine dependence-structure fitting, including the joint tails a Gaussian-copula assumption would miss. |
|
Cross-modal inference |
Fit a heterogeneous Bayesian network over categorical, image-vector, signal-vector, and continuous fields. |
|
Design of experiments |
Latin hypercube designs, Bayesian optimization, and sensitivity. |
|
Engines |
Compare NumPy and Torch engine paths across workloads with explicit tolerances. |
|
Enumeration |
Exact top-k support traversal. |
|
Enumeration |
Broader ranking, seek, and structured-support examples. |
|
Extension |
Show where new families and backends attach. |
|
Reasoning ecosystem |
Ontology-constrained graph facts, KG completion, and cited KG-RAG. |
|
Scientific inference |
Bayesian inverse problem with coverage-oriented uncertainty checks. |
|
Reasoning ecosystem |
Support triage over substrate, skills, pool-style jobs, monitoring, and grounded answering. |
|
Local reasoning ecosystem |
End-to-end tour of substrate, creation, simulation, skills, reasoning, telemetry, and governance surfaces. |
|
Frontier family lifecycle |
Checkpoint, size ladder, quantized artifacts, edge student, and served cascade with cost/quality receipts at every stage (illustrative, synthetic data). |
|
Distribution gallery |
Composite, record, sequence, optional, and transformed families. |
|
Distribution gallery |
Circular and spherical directional families. |
|
Distribution gallery |
Graph and tree distributions. |
|
Distribution gallery |
Vector and matrix families. |
|
Distribution gallery |
Temporal and point-process families. |
|
Distribution gallery |
Ranking and permutation families. |
|
Distribution gallery |
Mixtures, HMMs, LDA, and latent models. |
|
Distribution gallery |
Scalar continuous and discrete families. |
|
Scientific inference |
Sense, simulate, invert, report: the full inference loop on a toy geoscience story. |
|
Validation |
Correctness checks across heterogeneous components. |
|
Representation |
Segmenters, embeddings, and shared heterogeneous encoders. |
|
Latent models |
Association models with hidden structure. |
|
Latent models |
Hierarchical mixture variants. |
|
Latent models |
Joint mixture variants. |
|
Task workflow |
Expert-label economics: the |
|
Latent models |
Latent families beyond the first HMM path. |
|
Latent models |
HMMs with longer history. |
|
Projection/compression |
Compare closed-form Gaussian-mixture reduction with sample-and-refit projection. |
|
PPL |
Rank fitted models by out-of-sample predictive accuracy ( |
|
Neural leaf |
LLaVA-style stage-1 on toy volumes: a thin trainable projection between a frozen encoder and a frozen toy LM. |
|
Neural leaf |
peft LoRA through the GradLeaf bridge with a real HuggingFace checkpoint. |
|
Projection/compression |
Project a trained neural density onto a structured Gaussian-mixture student and measure size, latency, and likelihood tradeoffs. |
|
PPL |
|
|
Combinatorial optimization |
Precedence-constrained scheduling: maximum-weight closure and time-phased MILP scheduling. |
|
Production |
Provenance, registry, serving, drift, and checkpoints. |
|
Entry points |
The two front-door entry points: |
|
Reasoning ecosystem |
Evidence acquisition over retrieve, compute, simulate, and delegate actions with abstention. |
|
Parallelism |
Same |
|
Latent models |
Partially labeled mixture fitting. |
|
Neural leaf |
Mixture of language-model experts with one shared embedding. |
|
Verification workflow |
Stress-check claims and examples against explicit evidence. |
|
Applied models |
Dependency and structure learning before modeling. |
|
HMMs |
Structured transition variants and duration behavior. |
|
Structured models |
Structured emissions and leaves. |
|
Symbolic export |
Closed-form log-densities exported as LaTeX, SymPy, or (optionally) Sage. |
|
Task workflow |
Cascade cost accounting, harvesting, and retraining. |
|
Task workflow |
Distill a slow teacher into a local callable artifact. |
|
Task workflow |
Distill LLM field extraction into a local sequence tagger. |
|
Task workflow |
LLM teacher, active labeling, local student, and calibrated cascade. |
|
Verification workflow |
Trust receipts on a VLM: three subsystems composed around a frozen 3-D encoder. |
|
End-to-end workflow |
Replace a ticket router and invoice extractor with calibrated models. |
Benchmark and distributed-stress harnesses that were previously under
examples/ have been moved to gitignored benchmark areas. The tracked
examples page now focuses on scripts designed to be read and run as
documentation.
Representative SourceΒΆ
Structured HMMs:
"""Composable / structured HMMs β a tour of mixle.stats.latent.structured_hmm.
A standard HMM is a dense K x K transition + per-state emissions. mixle factors the transition behind a
small TransitionOperator interface (forward: alpha @ A, backward: A @ v, plus an expected-mass M-step), so
rich structure plugs into ONE forward-backward / EM: low-rank transitions, block / factorial (Kronecker)
combinators, sparse (left-to-right) transitions, sticky / Dirichlet priors. On top sit decoding (Viterbi /
posterior), enumeration (top-k / rank / nucleus over sequences), terminal (absorbing) states, an
input-output HMM, an explicit-duration HMM (HSMM) with segment decoding, forgetting-based parallel
Baum-Welch, and a JAX fast path.
Run: ``python examples/structured_hmm_example.py``
"""
from __future__ import annotations
import numpy as np
import mixle.stats as S
from mixle.inference import optimize
from mixle.stats.latent.structured_hmm import (
DenseTransition,
ExplicitDurationHMM,
InputOutputHMM,
KroneckerTransition,
LowRankTransition,
SparseTransition,
StructuredHMM,
_row_normalize,
left_to_right_edges,
sticky_transition,
)
def gaussians(centers, sd=1.0):
return [S.GaussianDistribution(float(c), sd) for c in centers]
def low_rank():
rng = np.random.RandomState(0)
k, r = 8, 2
gen = StructuredHMM(
gaussians(range(0, 4 * k, 4)),
np.ones(k) / k,
LowRankTransition(_row_normalize(rng.rand(k, r)), _row_normalize(rng.rand(r, k))),
)
seqs = [gen.sampler(seed=s).sample(50) for s in range(60)]
# STAT-RR17-05: the init is displaced FAR enough that a no-op "fit" cannot pass -- offsets
# of 1.5-2.0 against a recovery bound of 0.5 mean the printed "recovered" is earned by the
# optimizer, not planted by the initialization (the old Uniform(-1,1) init with an error<1
# oracle passed a fitter that returned its input unchanged).
truth = [4.0 * i for i in range(k)]
# RESTARTS, and 150 iterations rather than 40. A single displaced start reaches a merged-state
# optimum on roughly one seed in three -- fit error 4.05 at RandomState(1), 1.59 at (200) -- and
# the example then crashed on its own recovery assertion (P10-F04). More iterations do not fix
# that (seed 1 is still at 2.4 after 400); a different start does, and keeping the restart with
# the best likelihood is how a caller picks between them without looking at the truth.
init_error, best, best_objective = 0.0, None, -np.inf
for _restart in range(3):
offsets = [rng.uniform(1.5, 2.0) * rng.choice([-1.0, 1.0]) for _ in range(k)]
init = StructuredHMM(
gaussians([4 * i + offsets[i] for i in range(k)]),
np.ones(k) / k,
LowRankTransition(_row_normalize(rng.rand(k, r)), _row_normalize(rng.rand(r, k))),
)
init_error = max(init_error, max(abs(m - t) for m, t in zip(sorted(e.mu for e in init.emissions), truth)))
candidate = optimize(seqs, init.estimator(), prev_estimate=init, max_its=150, delta=None, out=None)
objective = float(np.sum(candidate.seq_log_density(candidate.dist_to_encoder().seq_encode(seqs))))
if objective > best_objective:
best_objective, best = objective, candidate
fit_error = max(abs(m - t) for m, t in zip(sorted(e.mu for e in best.emissions), truth))
if not (fit_error < 0.5 < init_error):
raise RuntimeError(
f"recovery NOT demonstrated: fit error {fit_error:.2f} must be < 0.5 while the "
f"init error {init_error:.2f} stays above it (a no-op fitter fails this)"
)
print(
f"1. Low-rank HMM (K={k}, rank={r}): transition params {2 * k * r} vs dense {k * k}; "
f"means recovered to max error {fit_error:.2f} from an init error of {init_error:.2f} "
f"(best of 3 restarts by likelihood)"
)
def factorial():
rng = np.random.RandomState(0)
a1, a2 = _row_normalize(rng.rand(3, 3)), _row_normalize(rng.rand(4, 4))
kt = KroneckerTransition(DenseTransition(a1), DenseTransition(a2))
print(
f"2. Factorial (Kronecker) HMM: state=(s1,s2), {kt.n_states}=3x4 joint states, A=A1(x)A2 "
f"(forward O(K1 K2 (K1+K2)) not O((K1K2)^2))"
)
def sticky_and_sparse():
sp = SparseTransition(5, left_to_right_edges(5, skip=1))
a = sp.as_matrix()
st = sticky_transition(np.full((3, 3), 1 / 3), kappa=10.0)
print(
f"3. Sparse left-to-right (5 states): lower-triangle zero={np.allclose(np.tril(a, -1), 0)}; "
f"sticky prior biases self-transitions (segmentation)"
)
def decode_and_enumerate():
a = np.array([[0.92, 0.08], [0.08, 0.92]])
cat = [S.CategoricalDistribution({0: 0.8, 1: 0.2}), S.CategoricalDistribution({0: 0.2, 1: 0.8})]
hmm = StructuredHMM(cat, [0.5, 0.5], DenseTransition(a), len_dist=S.CategoricalDistribution({2: 0.5, 3: 0.5}))
en = hmm.enumerator()
print(
f"4. Decoding + enumeration: Viterbi works for any operator; top-3 most-probable sequences "
f"{[seq for seq, _ in en.top_k(3)]}, nucleus(0.9) covers {en.nucleus_size(0.9).covered_mass:.2f}"
)
def terminal():
a = _row_normalize(np.array([[0.6, 0.3, 0.1], [0.2, 0.6, 0.2], [0, 0, 1.0]]))
hmm = StructuredHMM(gaussians([-3, 0, 3]), [0.7, 0.3, 0.0], DenseTransition(a), terminal_states={2})
lengths = [len(hmm.sampler(seed=s).sample(50)) for s in range(20)]
print(
f"5. Terminal (absorbing) states: state 2 stops the sequence -> variable lengths "
f"{min(lengths)}..{max(lengths)} (length is a stopping time)"
)
def hsmm():
d = 6
dur = np.zeros((2, d))
dur[0, 3] = 1.0
dur[1, 1] = 1.0
gen = ExplicitDurationHMM(gaussians([-6, 6], 0.4), [1.0, 0.0], np.array([[0, 1.0], [1.0, 0]]), dur, d)
rng = np.random.RandomState(0)
true = [0] * 4 + [1] * 2 + [0] * 4 + [1] * 2
seq = [float(rng.normal([-6, 6][s], 0.4)) for s in true]
segs = gen.viterbi_segments(seq)
print(
f"6. Explicit-duration HMM (HSMM): non-geometric durations; decoded segments "
f"{[(s, dd) for s, _, dd in segs]} (state, duration)"
)
def iohmm():
a0, a1 = np.array([[0.95, 0.05], [0.05, 0.95]]), np.array([[0.05, 0.95], [0.95, 0.05]])
io = InputOutputHMM(gaussians([-5, 5], 0.5), [0.5, 0.5], [DenseTransition(a0), DenseTransition(a1)])
print(
"7. Input-output HMM: an exogenous input selects the transition each step (input 0=sticky, "
"1=flip) -- a controlled Markov model"
)
def main():
print("# Composable / structured HMMs in mixle\n")
low_rank()
factorial()
sticky_and_sparse()
decode_and_enumerate()
terminal()
hsmm()
iohmm()
print(
"\nAll of these share one TransitionOperator interface: the operator's structure makes FITTING "
"cheaper (O(K r) low-rank, O(edges) sparse, factorial Kronecker), while as_matrix() feeds decoding "
"and enumeration. Forgetting-parallel Baum-Welch (fit_chunked) and a JAX fast path "
"(jit_forward_loglik) round out the toolkit."
)
if __name__ == "__main__":
main()
Active LLM distillation and cascade:
"""LLM teacher + active labeling: spend a FIXED label budget on the least-certain examples, then serve locally.
The two differentiators in one run:
* the teacher is an **LLM** (here a local ``CallableLLM``; swap in ``OpenAICompatLLM(base_url, model)``
to use Ollama / vLLM / a hosted endpoint unchanged);
* **active labeling** (DoE applied to the labeling decision) queries that LLM for the examples
the current student is least sure about (margin acquisition). The comparison below is a SAME-TRAINING-BUDGET one -- both policies spend
exactly the same number of paid training calls (the shared evaluation labels are paid too, and
counted) -- and the measured quantity is held-out agreement with this synthetic deterministic
teacher, decided by the EXACT paired test on the discordant pairs. (A labels-to-target
curve -- how many calls each policy needs to REACH a fixed quality -- is a different experiment;
the EIG/BALD curve in ``label_economics_demo.py`` is the acquisition-level version of it.)
Then the distilled student is wrapped in a calibrated cascade and the realized savings are reported.
Scope: the LABELING-BUDGET side of the mixle.task loop. ``task_distill_example.py`` is the plain
distill/save/reload entry point and ``task_cascade_economics_example.py`` prices the serving side;
``label_economics_demo.py`` explores the acquisition-level EIG/BALD side (its receipt is a
PAIRED per-seed win/tie/loss record with an exact sign test, the same conclusion discipline as
the comparison here).
Run: ``python examples/task_llm_active_example.py`` (needs ``pip install "mixle[torch]"``).
"""
from __future__ import annotations
import numpy as np
from mixle.task import (
CalibratedTaskModel,
CallableLLM,
Cascade,
CostModel,
active_distill,
llm_labeler,
)
SPAM = ["free", "winner", "prize", "buy", "cheap", "offer", "click", "loan", "casino"]
HAM = ["meeting", "lunch", "project", "report", "schedule", "team", "review", "invoice"]
FILLER = ["the", "a", "today", "please", "thanks", "we", "you", "and", "to"]
def pool(seed, n_per_class=300):
r = np.random.RandomState(seed)
out = []
for words in (SPAM, HAM):
for _ in range(n_per_class):
toks = list(r.choice(words, size=2)) + list(r.choice(FILLER, size=r.randint(3, 8)))
r.shuffle(toks)
out.append(" ".join(toks))
r.shuffle(out)
return out
def exact_paired_pvalue(first_only: int, second_only: int) -> float:
"""Exact two-sided paired (McNemar) p-value from the two discordant-pair counts.
Under the null of equal policies, each discordant pair favors either side with probability
one half, so the p-value is the two-sided binomial tail at 0.5 over the discordances. This
is the example's CONCLUSION RULE: it stays valid at any discordance count, including the
tiny ones where a Wald interval on the paired mean is unreliable.
"""
n = first_only + second_only
if n == 0:
return 1.0
k = max(first_only, second_only)
from math import comb
tail = sum(comb(n, i) for i in range(k, n + 1)) / 2.0**n
return float(min(1.0, 2.0 * tail))
def local_llm(prompt, system=None):
"""Deterministic local teacher with the same callable shape as an LLM endpoint."""
text = prompt.split("Text:", 1)[-1].lower()
return "spam" if any(w in text.split() for w in SPAM) else "ham"
def main() -> None:
# the teacher is an LLM, constrained to the label set
teacher = llm_labeler(CallableLLM(local_llm), ["spam", "ham"], instruction="Classify the email as spam or ham.")
recipe = {"n": 4, "dim": 512, "hidden": [64], "epochs": 200, "lr": 1e-2}
p, val = pool(1), pool(seed=900)[:300]
truth = teacher(val) # 300 evaluation labels: PAID teacher calls, shared by both policies
budget = 60
print(f"training-label budget: {budget} LLM calls per policy (out of {len(p)} unlabeled)")
print(f"shared evaluation labels: {len(val)} LLM calls (paid; score both students, train neither)")
print(f"teacher calls for this comparison: {2 * budget + len(val)} (2 x {budget} training + {len(val)} evaluation)")
active = active_distill(teacher, p, budget=budget, seed_size=20, rounds=4, acquisition="margin", recipe=recipe)
rand = active_distill(teacher, p, budget=budget, seed_size=20, rounds=4, acquisition="random", recipe=recipe)
# The ESTIMAND, stated before the numbers: each realized student's agreement with the
# deterministic teacher over the synthetic pool() population, compared at the SAME
# training-label budget, conditional on the two fitted students. Both students predict the
# SAME 300 fresh validation rows. The decision rule is the EXACT paired (McNemar) test on
# the discordant pairs -- a normal-approximation interval is unreliable exactly where this
# comparison lives (an external review measured a Wald gate declaring superiority at four
# discordant pairs, where the exact two-sided p-value is 0.125). "Agreement", not
# "accuracy": the teacher is the reference, and the data are synthetic.
active_hits = np.asarray([a == b for a, b in zip(active.model.batch(val), truth)], dtype=np.float64)
random_hits = np.asarray([a == b for a, b in zip(rand.model.batch(val), truth)], dtype=np.float64)
active_only = int(np.sum((active_hits == 1.0) & (random_hits == 0.0)))
random_only = int(np.sum((random_hits == 1.0) & (active_hits == 0.0)))
p_exact = exact_paired_pvalue(active_only, random_only)
print(f" active labeling : {active_hits.mean():.3f} held-out teacher agreement ({active.labels_used} labels)")
print(f" random labeling : {random_hits.mean():.3f} held-out teacher agreement ({rand.labels_used} labels)")
print(
f" discordant pairs: {active_only} active-only vs {random_only} random-only; "
f"exact paired two-sided p = {p_exact:.3f}"
)
if p_exact < 0.05 and active_only > random_only:
# STAT-RR21-02: the two-sided p-value is symmetric -- with 0 active-only vs 10
# random-only discordances it is 0.002, and gating on p alone announced an active WIN
# while every discordance favored random. The claim needs significance AND direction.
print(" -> active labeling beats random AT THE SAME TRAINING BUDGET on this population")
print(" (exact paired evidence at the 5% level, in the active direction)")
elif p_exact < 0.05 and random_only > active_only:
print(" -> RANDOM labeling beat active on this run (exact paired evidence at the 5% level):")
print(" the discordances favor random; do not read this as an active win")
else:
print(" -> the exact paired evidence is INCONCLUSIVE at the 5% level on this run: too few")
print(" disagreements to distinguish the policies; no superiority claim is made")
print("\nwrap the active student in a calibrated cascade and serve")
cal = pool(seed=2)
cal_labels = teacher(cal) # calibration labels are PAID teacher calls too, and counted below
model = CalibratedTaskModel(active.model, alpha=0.1).calibrate(cal, cal_labels)
total_pre_serving = 2 * 60 + 300 + len(cal)
print(f" calibration bought {len(cal)} more teacher labels")
print(
f" ALL-IN teacher calls before serving: {total_pre_serving} "
f"(120 training + 300 evaluation + {len(cal)} calibration)"
)
casc = Cascade(model, teacher, cost=CostModel(c_frontier=0.01, c_local=0.00001))
casc.serve(pool(seed=901))
rep = casc.report()
setup_cost = total_pre_serving * 0.01
print(f" served {rep['n_requests']} requests, escalated {rep['realized_escalation_rate']:.1%} to the LLM")
print(
f" serving saved ${rep['savings_vs_frontier']:.2f} vs paying the LLM per request -- against "
f"${setup_cost:.2f} of setup labels ({total_pre_serving} calls); setup amortizes only past that volume"
)
if __name__ == "__main__":
main()