mixle.models package¶
Applied models – richer, domain-specialized families that plug into the same contract as mixle.stats.
Where mixle.stats holds the elementary distributions (a Gaussian, a Poisson, a categorical), this package
holds the models that are more than one elementary density: a neural network, a Gaussian process, a random
forest, a knowledge graph, a grammar, a decision process, a causal skeleton. Each is exposed through the same
five-piece Distribution/Estimator/Accumulator/Sampler/Encoder contract (or, for the
supervised/decision/causal ones, a small task-appropriate surface), so it composes with the stats core – a
neural leaf drops into a CompositeDistribution, a GP into a mixture, and so on.
The right mental model is a small catalog of applied model families (mixle/models/README.md maps every
module to one):
neural & deep – neural nets, transformers/LMs, embeddings, and their training utilities;
non-parametric – Gaussian processes and random forests as
p(y | x)leaves;relational / structured – knowledge graphs, random graphs, grammars;
latent-variable – Bayesian-nonparametric mixtures (Dirichlet process);
decision & control – partially observable Markov decision processes;
causal discovery – constraint-based structure learning.
(The imports below stay alphabetical – the ruff import sorter enforces that – so use the families above, not import order, as the map.)
These surfaces vary in maturity (see the Project status table in the top-level README); treat them as specialist adapters composable with the stable stats spine, not as the spine itself.
- class LM(vocab, *, d_model=256, n_layer=6, n_head=8, block=128, device='cpu', embedding=None)[source]
Bases:
objectA causal-Transformer language model with a small declarative surface:
fit/generate/nll.- Parameters:
- to_dict()[source]
Serialize the hyperparameters + trained weights so the LM survives a process boundary.
The token embedding may be tied across LMs (
embedding=);from_dictrebuilds an untied module and loads the savedstate_dictinto it, so a round-tripped LM is standalone (any external tie is dropped).- Return type:
- classmethod from_dict(payload)[source]
Rebuild an LM from
to_dict()output (fresh module, saved weights loaded in).- Parameters:
payload (dict)
- Return type:
LM
- save(path)[source]
Persist the LM’s inference artifact to
pathviatorch.save: architecture config (vocab/d_model/n_layer/n_head/block) + learned weights, nothing else.This is not a training checkpoint. It deliberately does not store the optimizer, LR scheduler, step count, RNG state, data-loader position, or gradient-scaler state, so
load()returns a model ready for scoring and generation, not one you can resume training from without loss of state. For resumable training use the checkpoint path inmixle.utils.parallel.fault_tolerant_training/mixle.utils.parallel.dcp_checkpoint, which stores model + optimizer + data-loader position.- Parameters:
path (str)
- Return type:
None
- classmethod load(path)[source]
Load an LM inference artifact written by
save()(config + weights).Returns a model ready for scoring/generation; this is not a training-resume checkpoint (see
save()), so optimizer/step/RNG/data-loader state is not restored.Loaded with
weights_only=True:to_dict()’s payload is plain config scalars plus a tensorstate_dict, never an arbitrary object graph, so this does not execute code from the file (unlike a full-module pickle – seemixle.models._neural_serialfor that case).- Parameters:
path (str)
- Return type:
LM
- fit(token_ids, *, epochs=1, batch_size=64, lr=3e-3, distributed=False, precision='fp32', shuffle=True, dense=False, seed=0, log=None, tp_size=1, pp_size=1, cp_size=1, dp_replicate=1, dp_shard=1, ep_size=1, etp_size=1, microbatches=1, gradient_accumulation_steps=1, distributed_backend='torch_native', optimizer=None, max_grad_norm=None, compile=False, checkpoint_path=None, resume=False)[source]
Small-scale reference pretraining (or continuation) on a token-id array.
Two paths, chosen by
dense:dense=False(default, unchanged): the streaming estimator; the corpus is never buffered. It scores one next-token target perblock-length window – the right shape for an unbounded stream, but only a fraction (~``1/block``) of the token supervision that packed dense teacher forcing extracts from the same tokens. A reference / continuation path for small-scale runs, not a frontier pretraining engine.dense=True: packed dense teacher forcing on a BOUNDED corpus. The token stream is cut into non-overlapping rows ofblock + 1tokens (a partial tail row is dropped; there is no padding, so no attention-mask or EOS special-casing is needed – document boundaries are whatever the ids encode). Every row consumesblock+1tokens but contributesblockshifted targets: the corpus’s first token and each cross-row transition are not supervised, and the partial tail is not consumed.last_fit_receiptreports those counts explicitly. Token ids stay integer end to end (no float conversion).seeddrives row shuffling andlog(epoch, mean_loss)reports per-epoch training loss, both as infit_pairs(). Withdistributed=Truethis objective is executed by the selected distributed-gradient backend.
Parallel sizes are executable contracts.
torch_nativesupports DDP/HSDP, FSDP2, MLP tensor parallelism, and CUDA context parallelism; unsupported combinations fail capability validation. Full TP/PP/CP/EP transformer and MoE training is exposed by themegatronbackend.- Parameters:
token_ids (Any)
epochs (int)
batch_size (int)
lr (float)
distributed (bool)
precision (str)
shuffle (bool)
dense (bool)
seed (int)
log (Any)
tp_size (int)
pp_size (int)
cp_size (int)
dp_replicate (int)
dp_shard (int)
ep_size (int)
etp_size (int)
microbatches (int)
gradient_accumulation_steps (int)
distributed_backend (str)
optimizer (Any)
max_grad_norm (float | None)
compile (bool)
checkpoint_path (str | None)
resume (bool)
- Return type:
LM
- fit_pairs(pairs, *, epochs=1, batch_size=32, lr=3e-3, mask_prompt=True, pad_id=0, seed=0, log=None)[source]
Supervised fine-tuning on
(prompt_ids, completion_ids)pairs with a dense per-position loss.The streaming
fitpath scores ONE next-token target per window (the right shape for an unbounded pretraining stream); for a pair corpus that wastes a factor ofblockin compute. Here every position of every pair contributes cross-entropy in a single forward, andmask_promptrestricts the loss to completion positions – the standard SFT objective. Sequences longer thanblockkeep the completion and drop the oldest prompt tokens; shorter ones are left-padded withpad_id(excluded from the loss). Include your end-of-sequence token in each completion sogenerate(stop_id=...)knows where to stop.
- generate(prompt_ids, n=200, *, temperature=1.0, greedy=False, seed=0, stop_id=None)[source]
Autoregressively extend
prompt_idsbyntokens (greedy, or temperature-sampled).stop_idends generation early when that token is produced (it is included in the return value, so callers can strip it – and its presence distinguishes ‘finished’ from ‘ran out of budget’).
- class LMFitReceipt(objective, input_tokens, consumed_tokens_per_epoch, supervised_tokens_per_epoch, discarded_cross_row_transitions_per_epoch, dropped_tail_tokens, epochs)[source]
Bases:
objectToken-accounting receipt for one packed dense corpus layout.
- class CategoricalEmbedding(num_categories, dim, *, name=None, device='cpu', dtype='float32', init_seed=0)[source]
Bases:
objectA lazily-built learned embedding of shape
(num_categories, dim); every consumer gets the same module.- Parameters:
- class EmbeddingSpec(num_categories, dim, device, dtype, init_seed)[source]
Bases:
objectImmutable construction contract for a shared embedding table.
- class CausalSkeleton(edges, separating_sets, variable_names, all_separating_sets=None)[source]
Bases:
objectUndirected skeleton plus separating sets from a PC-style search.
- Parameters:
- class CategoricalClassificationNeuralNetwork(module, engine=None, precision=None)[source]
Bases:
objectA Torch classifier wrapper optimized by summed categorical log likelihood.
The wrapped module must return one logits row per observation. Fitting is delegated to
optimize_torch_objectiveso classification examples get the same convergence diagnostics and best-state restoration as distribution objectives.- Parameters:
module (Any)
engine (Any | None)
precision (Any | None)
- parameters()[source]
Return trainable parameters of the wrapped classification module.
- logits_tensor(x)[source]
Return raw class logits for
xas a Torch tensor.
- log_likelihood(x, y)[source]
Return the summed categorical log likelihood for integer labels.
- fit(x, y, max_its=500, lr=0.01, optimizer='adam', tol=1.0e-7, out=None, print_iter=100, return_result=False, restore_best=True)[source]
Maximize the categorical classification log likelihood.
- predict_proba_tensor(x)[source]
Return class probabilities for
xas a Torch tensor.
- predict_proba(x)[source]
Return class probabilities for
xas a NumPy array.
- class ConditionalIndependenceResult(measure, statistic, p_value, independent, status, sample_size, degrees_of_freedom, method, reason=None)[source]
Bases:
objectResult from a conditional independence calculation.
- discrete_conditional_independence(data, x, y, given=(), alpha=0.05)[source]
Likelihood-ratio (G-test) conditional-independence test for categorical samples.
The statistic is
2 n I(X;Y|Z)and is compared with its chi-square null distribution. The asymptotic result is reported as inconclusive unless there are at least five observations per degree of freedom; callers that need sparse-table exactness should use a permutation test.
- DPOLeaf
alias of
DPOModel
- class ErdosRenyiGraphModel(p, directed=False, self_loops=False, name=None)[source]
Bases:
objectIndependent Bernoulli edge model for directed or undirected graphs.
- classmethod fit_mle(adjacency, directed=False, self_loops=False, pseudo_count=0.0, prior_p=0.5, name=None)[source]
Thin shim delegating to
fit_erdos_renyi_mle(kept for the classmethod-fit call API).
- log_likelihood(adjacency)[source]
Return the Bernoulli graph log likelihood.
- sample(num_nodes, seed=None)[source]
Draw one binary adjacency matrix.
- class GaussianProcessRegressor(lengthscale=1.0, amplitude=1.0, noise=0.1, mean=0.0, jitter=1.0e-6, kernel='rbf', engine=None, precision=None)[source]
Bases:
objectExact GP regression with a stationary kernel and Gaussian observation noise.
The kernel is RBF (squared-exponential) by default;
kernel="matern32"or"matern52"selects the Matern-3/2 or Matern-5/2 covariance, whose less smooth sample paths often fit physical responses better than the very smooth RBF.- Parameters:
- parameters()[source]
Return trainable raw kernel/noise parameters and the mean.
- property lengthscale: float
Return the fitted kernel lengthscale.
- property amplitude: float
Return the fitted kernel amplitude.
- property noise: float
Return the fitted Gaussian observation-noise standard deviation.
- kernel(x1, x2)[source]
Return the covariance matrix between two input arrays under the configured kernel.
- log_marginal_likelihood(x, y)[source]
Return the exact GP log marginal likelihood for training data.
- fit(x, y, max_its=500, lr=0.05, optimizer='adam', tol=1.0e-7, out=None, print_iter=100, return_result=False, restore_best=True)[source]
Maximize the GP log marginal likelihood and return
self.Returns the fitted model so
model = gp.fit(x, y)works like every otherModel.fitinmixle.models. Setreturn_result=Truefor the full objective diagnostics (anObjectiveFitResultcarrying the objective value, iteration count, and history).Compatibility note: before 0.8.0 the default return was the
(value, iterations)tuple; those live behindreturn_result=Truenow (result.value/result.iterations).
- predict(x_train, y_train, x_new, return_cov=False)[source]
Return posterior predictive mean, and optionally covariance.
- predict_monotone(x_train, y_train, x_new, increasing=True)[source]
Return the posterior-mean prediction projected to be monotone in scalar
x_new.Predicts the GP posterior mean at
x_newand projects it onto the monotone cone (non-decreasing ifincreasingelse non-increasing) by pool-adjacent-violators inx_neworder – the L2-closest monotone curve to the GP mean. Intended for scalar (1-D) inputs (e.g. monotone age-depth / dose-response fits); reduces topredict()when the posterior mean is already monotone.
- class SparseGaussianProcessRegressor(lengthscale=1.0, amplitude=1.0, noise=0.1, kernel='rbf', n_inducing=50, jitter=1e-8)[source]
Bases:
objectSparse GP regression with
minducing points (FITC).- Parameters:
lengthscale – initial kernel/noise hyperparameters (all positive and finite).
amplitude – initial kernel/noise hyperparameters (all positive and finite).
noise – initial kernel/noise hyperparameters (all positive and finite).
kernel –
'rbf','matern32'or'matern52'.n_inducing – number of inducing points (placed by k-means++ over unique training inputs at
fit).jitter – strictly positive diagonal stabilization for the inducing covariance.
- fit(x, y, *, optimize=True, seed=0, max_iter=100)[source]
Place inducing points and (optionally) fit hyperparameters by the FITC marginal likelihood.
- predict(x_new, *, return_var=False)[source]
Posterior mean (and optionally marginal variance) at
x_new. O(m^2) per query batch.
- class GaussianRegressionNeuralNetwork(module, noise=1.0, engine=None, precision=None)[source]
Bases:
objectA Torch module trained with a Gaussian regression log likelihood.
The wrapped module predicts the response mean and this helper learns a scalar observation noise alongside module weights. It uses the same generic Torch objective optimizer as the distribution objective helpers.
- Parameters:
module (Any)
noise (float)
engine (Any | None)
precision (Any | None)
- parameters()[source]
Return trainable module parameters plus the raw noise parameter.
- property noise: float
Return the fitted observation standard deviation.
- predict_tensor(x)[source]
Return module predictions as a Torch tensor on the configured engine.
- log_likelihood(x, y)[source]
Return the summed Gaussian regression log likelihood.
- fit(x, y, max_its=500, lr=0.01, optimizer='adam', tol=1.0e-7, out=None, print_iter=100, return_result=False, restore_best=True)[source]
Maximize the Gaussian regression log likelihood.
The default return shape is the historical
(value, iterations)tuple. Setreturn_result=Truefor the full objective diagnostics.
- class NeuralCategorical(module, m_steps=40, lr=0.01, name=None, batch_size=None, device='cpu', max_optimizer_steps=None, optimizer_state=None)[source]
Bases:
SequenceEncodableProbabilityDistributionp(y | x) = softmax(module(x))as a mixle leaf. Observation is the pair(x, y),yan int class.batch_size(None = full batch) makes the M-step minibatch SGD overm_stepspasses – needed to train a real conv net on a large image set;max_optimizer_stepsoptionally caps updates independently of batch size, anddevice(e.g."mps"/"cuda") runs them on the GPU.- Parameters:
- log_density(xy)[source]
Return
log p(y | x)for one feature/class observation pair.
- seq_log_density(enc)[source]
Return per-row categorical conditional log probabilities for encoded pairs.
- predict(x)[source]
Return maximum-probability class predictions for one or more inputs.
- sampler(seed=None)[source]
Return a conditional sampler over labels given features.
- Parameters:
seed (int | None)
- Return type:
NeuralCategoricalSampler
- estimator(pseudo_count=None)[source]
Return the generalized-EM estimator for weighted cross-entropy training.
- Parameters:
pseudo_count (float | None)
- Return type:
NeuralCategoricalEstimator
- dist_to_encoder()[source]
Return the encoder for
(x, class)observation pairs.- Return type:
NeuralCategoricalEncoder
- to_dict()[source]
Serialize hyperparameters and module bytes for registry-based round trips.
- class NeuralConditionalDensity(module, *, m_steps=60, lr=5e-3, device='cpu', name=None)[source]
Bases:
SequenceEncodableProbabilityDistributionWrap a torch conditional-density
module(module.log_density(x, y) -> (n,)) as a mixle leaf.Observations are pairs
(x, y). The module must also exposesample_given(x) -> (n, d)to drawy.- log_density(xy)[source]
Return
log p(y | x)for one observation pair(x, y).
- seq_log_density(enc)[source]
Return per-row conditional log densities for encoded
(x, y)arrays.
- sampler(seed=None)[source]
Return a conditional sampler for drawing
ygivenx.- Parameters:
seed (int | None)
- Return type:
NeuralConditionalDensitySampler
- estimator(pseudo_count=None)[source]
Return the generalized-EM estimator for weighted conditional-density training.
- Parameters:
pseudo_count (float | None)
- Return type:
NeuralConditionalDensityEstimator
- dist_to_encoder()[source]
Return the encoder for
(x, y)observation pairs.- Return type:
NeuralConditionalDensityEncoder
- to_dict()[source]
Serialize hyperparameters and module bytes for registry-based round trips.
- class GradEstimator(module, *, m_steps=60, lr=5e-3, device=None, batch_size=None, max_optimizer_steps=None, precision='auto', name=None, loss=None, optimizer=None, lr_decay=None)[source]
Bases:
ParameterEstimatorM-step: responsibility-weighted MLE –
max sum_i w_i log p(x_i)by gradient ascent on the module (warm-started across EM iterations).loss/optimizerare the caller’s hooks; the optimizer only ever sees trainable parameters, so frozen submodules stay frozen and a fully frozen module makes the M-step a no-op (a fixed distribution).- Parameters:
- accumulator_factory()[source]
Return the accumulator factory used to collect this estimator’s sufficient statistics.
- Return type:
DataBufferAccumulatorFactory
- class GradLeaf(module, *, m_steps=60, lr=5e-3, device=None, batch_size=None, max_optimizer_steps=None, precision='auto', name=None, loss=None, optimizer=None, lr_decay=None)[source]
Bases:
SequenceEncodableProbabilityDistributionWrap a torch density
module(module.log_density(x) -> (n,)) as a composable mixleMeasured negative, so nobody re-derives it (2026-07-12, Apple M4, torch 2.12 CPU): wrapping the full-batch M-step loss in
torch.compileis a LOSS here – 0.93x at a 2x32 MLP / n=100k and 0.79x at 2x256 / n=200k, plus ~6s compile overhead per module – so there is deliberately nocompile=flag. Re-measure before adding one (a CUDA build or a much larger module could flip it); the probe script pattern lives in the introducing PR. distribution (see the module docstring).lossandoptimizerare the M-step hooks.- Parameters:
- log_density(x)[source]
Return the log-density or log-mass at a single observation.
- seq_log_density(x)[source]
Return vectorized log-density values for sequence-encoded observations.
- sampler(seed=None)[source]
Return a sampler for drawing observations from this distribution.
- Parameters:
seed (int | None)
- Return type:
GradLeafSampler
- estimator(pseudo_count=None)[source]
Return an estimator for fitting this distribution from data.
- Parameters:
pseudo_count (float | None)
- Return type:
GradEstimator
- dist_to_encoder()[source]
Return the data encoder used by this distribution for vectorized methods.
- Return type:
GradLeafEncoder
- class NeuralDensity(module, *, m_steps=60, lr=5e-3, device='cpu', precision='auto', name=None)[source]
Bases:
GradLeafWrap a torch density
module(module.log_density(x) -> (n,)) as a composable mixle distribution.A thin named subclass of
GradLeaf– the generic bridge owns the manufactured contract (buffer accumulator, array encoder, gradient M-step, sampler); this class owns only its name, its JSON payload, and its ready-module builders below.loss/optimizerhooks pass through (see the grad_leaf module docstring for the control story).- log_density(x)[source]
Return
log p(x)for one observation under the wrapped density module.
- seq_log_density(x)[source]
Return per-row log densities for encoded observations.
- sampler(seed=None)[source]
Return a sampler delegating to the wrapped module’s
samplemethod.- Parameters:
seed (int | None)
- Return type:
NeuralDensitySampler
- estimator(pseudo_count=None)[source]
Return the generalized-EM estimator for weighted neural-density training.
- Parameters:
pseudo_count (float | None)
- Return type:
NeuralDensityEstimator
- dist_to_encoder()[source]
Return the encoder for vectorized neural-density scoring and fitting.
- Return type:
NeuralDensityEncoder
- to_dict()[source]
Serialize hyperparameters and module bytes for registry-based round trips.
- class NeuralDensityEstimator(module, *, m_steps=60, lr=5e-3, device='cpu', precision='auto', name=None)[source]
Bases:
GradEstimatorM-step: responsibility-weighted MLE –
max sum_i w_i log p(x_i)by gradient ascent on the module (warm).- accumulator_factory()[source]
Return an accumulator factory for weighted neural-density batches.
- Return type:
DataBufferAccumulatorFactory
- class NeuralGaussian(module, noise=1.0, m_steps=40, lr=0.01, name=None, device=None)[source]
Bases:
SequenceEncodableProbabilityDistributionp(y | x) = N(y; module(x), noise^2 I)as a mixle leaf. Observation is the pair(x, y).- log_density(xy)[source]
Return
log p(y | x)for one encoded observation pair(x, y).
- seq_log_density(enc)[source]
Return per-row Gaussian conditional log densities for encoded
(x, y)arrays.
- classmethod compute_capabilities()[source]
Declare engine-ready scoring support for NumPy and Torch execution backends.
- backend_seq_log_density(enc, engine)[source]
Engine-neutral vectorized log-density for encoded
(x, y)pairs.
- sampler(seed=None)[source]
Return a conditional sampler for drawing
ygivenx.- Parameters:
seed (int | None)
- Return type:
NeuralGaussianSampler
- estimator(pseudo_count=None)[source]
Return the generalized-EM estimator for responsibility-weighted neural regression.
- Parameters:
pseudo_count (float | None)
- Return type:
NeuralGaussianEstimator
- dist_to_encoder()[source]
Return the encoder for batches of
(x, y)observation pairs.- Return type:
NeuralGaussianEncoder
- to_dict()[source]
Serialize hyperparameters and module bytes for registry-based round trips.
- class VAE(dim, *, latent=2, hidden=32, eval_samples=16, m_steps=120, lr=5e-3, device='cpu', name=None)[source]
Bases:
_NeuralFamilyA latent-variable
p(x)overR^dimvia a variational autoencoder.log_densityis a reproducible multi-sample estimate of the ELBO, with uncertainty available from the wrapped module’selbo_estimatemethod. It is not an exact log density. Seebuild_vae()for the full statement.
- class Flow(dim, *, hidden=32, layers=4, m_steps=80, lr=5e-3, device='cpu', name=None)[source]
Bases:
_NeuralFamilyAn exact
p(x)overR^dimvia a RealNVP coupling flow (invertible map to a standard-normal base).
- class MAF(dim, *, hidden=64, blocks=3, m_steps=80, lr=5e-3, device='cpu', name=None)[source]
Bases:
_NeuralFamilyAn exact
p(x)overR^dimvia a masked autoregressive flow (richer autoregressive dependence).
- class DiscreteAR(dim, cats, *, hidden=64, m_steps=100, lr=5e-3, device='cpu', name=None)[source]
Bases:
_NeuralFamilyAn exact, normalized
p(x)over discrete vectorsx in {0..cats-1}^dim(autoregressive, MADE-masked).
- class DPOModel(policy, ref, beta=0.1, m_steps=100, lr=1e-3, device='cpu')[source]
Bases:
SequenceEncodableProbabilityDistributionDPO over
(x, chosen, rejected)preference triples.policyis trained,refis frozen.- seq_log_density(enc)[source]
Return per-row DPO preference log likelihoods for encoded triples.
- log_density(xcr)[source]
Return the DPO log likelihood for one
(x, chosen, rejected)triple.
- prefers(x)[source]
The policy’s argmax action at
x– what the aligned policy now picks.
- sampler(seed=None)[source]
Return the sampler for the preference-scoring leaf.
- Parameters:
seed (int | None)
- Return type:
DPOModelSampler
- estimator(pseudo_count=None)[source]
Return the DPO estimator that trains the policy while keeping the reference fixed.
- Parameters:
pseudo_count (float | None)
- Return type:
DPOModelEstimator
- dist_to_encoder()[source]
Return the encoder for preference triples.
- Return type:
DPOEncoder
- to_dict()[source]
Serialize policy/reference modules and DPO hyperparameters.
- class EnergyModel(module, *, m_steps=200, lr=5e-3, noise_ratio=1, langevin_steps=40, langevin_step=0.05, device='cpu', name=None)[source]
Bases:
SequenceEncodableProbabilityDistributionlog p(x) ≈ -E(x) + cfor an energy module.The module exposes
energy(x) -> (n,)and a learned scalarlog_normwhose convention isc=-log Z. Approximately normalized (trained by NCE);log_densityreturns-E(x) + c. Composes like any leaf.- Parameters:
- log_density(x)[source]
Return the approximate normalized log density for one observation.
- seq_log_density(x)[source]
Return approximate normalized log densities for a batch of observations.
- sampler(seed=None)[source]
Return a Langevin sampler for the learned energy model.
- Parameters:
seed (int | None)
- Return type:
EnergyModelSampler
- estimator(pseudo_count=None)[source]
Return the NCE estimator used as the model’s M-step.
- Parameters:
pseudo_count (float | None)
- Return type:
EnergyModelEstimator
- dist_to_encoder()[source]
Return the encoder for vectorized energy-model scoring.
- Return type:
EnergyModelEncoder
- to_dict()[source]
Serialize hyperparameters and module bytes for registry-based round trips.
- class CoarseningMetrics(source_parameter_count, result_parameter_count, source_parameter_bytes, result_parameter_bytes, source_manifest_entries, result_manifest_entries, source_leaf_blocks, result_leaf_blocks, source_estimated_block_evaluations, result_estimated_block_evaluations, latency_seconds=None, latency_basis='unmeasured: no calibration input was supplied')[source]
Bases:
objectStructural measurements for the source and returned executable models.
estimated_block_evaluationscounts ordinary block-branch evaluations in one forward: a plain block costs one and the current numerical Taylor merge costs four. FLOPs and latency are deliberately not fabricated without shapes or calibration inputs.- Parameters:
source_parameter_count (int)
result_parameter_count (int)
source_parameter_bytes (int)
result_parameter_bytes (int)
source_manifest_entries (int)
result_manifest_entries (int)
source_leaf_blocks (int)
result_leaf_blocks (int)
source_estimated_block_evaluations (int)
result_estimated_block_evaluations (int)
latency_seconds (float | None)
latency_basis (str)
- class CoarsenResult(model, receipt_map=<factory>, accepted_pairs=<factory>, rejected_pairs=<factory>, depth_only_kl=0.0, total_kl=0.0, budget=inf, trust_region=inf, within_budget=True, structure_receipts=<factory>, artifact_digest=None, metrics=None)[source]
Bases:
objectOutput of
coarsen(): the new (shallower) model, the full per-scale receipt map, and the bookkeeping needed to see exactly which merges were accepted vs. rejected and why.structure_receiptsis the third move’s own receipt list – see_narrow_block_mlp2()– kept OUT ofreceipt_mapdeliberately:receipt_mapvalues areScaleReceipt(closed-form KL against a Gaussian law, consumed as-is by hybrid’ssurrogate_closure_error-keyed stage ranking inmixle.models.compress), while structure- projection’s own receipt is aProjectionReceipt(a Sigma-weighted reconstruction error, not a KL) – mixing the two dataclasses into one dict would silently break that attribute lookup. Thefinal_artifactscale receipt is authoritative for the returned model: its end-to-end law,total_kl, and digest are computed after every accepted structure projection.
- class ProjectionReceipt(name, mode, sigma_weighted_error, accepted=True, final_kl_divergence=None, artifact_digest=None)[source]
Bases:
objectReceipt for a
structure_project()call – reports G2’s own Sigma-weighted reconstruction error directly (there is no Gaussian law on either side of a weight-space projection, so this is not a KL divergence; it is the SAMEsigma_weighted_errorobjective G2’s solvers themselves minimize).
- class ScaleReceipt(name, teacher_law, student_law, kl_divergence, surrogate_closure_error, accepted=True, divergence_basis='full_rank_gaussian', regularized_kl_divergence=None, assumptions=(), sensitivity=<factory>, scope='local_candidate', artifact_digest=None)[source]
Bases:
objectOne per-scale receipt: the CLOSED-FORM teacher/student divergence at this coarsening step, plus (separately) G1’s own closure-error signal for how much the Gaussian-surrogate assumption itself is trusted at this point in the network (
nanwhere no G1 block closure applies, e.g. width-merge, which never runs a realBlockforward and so has nothing for G1’s Monte-Carlo closure check to compare against).
- class CompressedModel(model, method, receipt, non_sampling_receipts=<factory>, hybrid_selected_stages=<factory>, hybrid_sample_indices=<factory>)[source]
Bases:
objectUnified result: the compressed module plus the receipt explaining which method produced it, and (when the chosen/underlying path touched
non_sampling) the raw per-stageScaleReceiptmap that path’s closure-error signal came from.
- class CompressionReceipt(method, auto, quality, sample_count, selection_training_sample_count=0, selection_evaluation_sample_count=0, quality_basis='unmeasured', candidates=<factory>, notes='')[source]
Bases:
objectExplains why
methodwas used: its own measured numbers, plus – for auto-pick – the same real numbers for every OTHER method considered and rejected. Mirrorsmixle.models.unified_quantizer.QuantizationReceipt.- Parameters:
- property total_selection_sample_count: int
All real training plus evaluation examples consumed to make an automatic choice.
- class MethodCandidate(method, quality, sample_count, evaluation_sample_count, reward)[source]
Bases:
objectReal, measured numbers for one method family considered for one
compress()call – the raw material everyCompressionReceipt(chosen or rejected) is built from, mirroringmixle.models.unified_quantizer.MethodCandidate.
- class EvalReport(checkpoint_id, tasks, seed, metadata=<factory>)[source]
Bases:
objectThe per-rung receipt: every task’s score for one checkpoint, JSON-serializable via
report().
- class RegressionFlag(task, checkpoint_id, checkpoint_index, current_score, reference_score, reference_checkpoint_id, reference_index, relative_delta, threshold)[source]
Bases:
objectOne metric that regressed beyond
thresholdrelative to its best-so-far value in the sequence.
- class RegressionReport(flags, n_checkpoints, threshold, reference)[source]
Bases:
objectThe regression-tracking receipt over an ordered sequence of
EvalReport.
- class TaskResult(name, score, higher_is_better, n_examples, details=<factory>, succeeded=True, error=None)[source]
Bases:
objectOne capability-axis score: a name, a scalar, and which direction is “better” for regression math.
- class CompressedAdam(*_args, **_kwargs)[source]
Bases:
objectPlaceholder for the torch-only optimizer; constructing it reports the missing dependency.
- Parameters:
_args (Any)
_kwargs (Any)
- class CompressedMomentEncoding(method, shape, g4_encoding=None, int8_codes=None, int8_scales=None, int8_block_size=2048, dense_values=None, source_dtype='<f4', schema_version=1, requested_method='auto', fallback_reason=None)[source]
Bases:
objectStorage format for ONE moment tensor (
morv), compressed by exactly one of the three available methods – only the fields formethodare populated, mirroringSortedProfileEncoding’s single-active-branch convention.- Parameters:
- method
"g4"(sorted-profile,mixle.models.sorted_profile_quantizer),"int8"(blockwise quantization), or"dense"(fallback – neither compressed representation was trustworthy for this tensor).- Type:
- g4_encoding
Populated iff
method == "g4".- Type:
mixle.models.sorted_profile_quantizer.SortedProfileEncoding | None
- int8_codes / int8_scales / int8_block_size
Populated iff
method == "int8".
- dense_values
Populated iff
method == "dense".- Type:
numpy.ndarray | None
- nbytes()[source]
Measured storage footprint, in bytes – delegates to G4’s own receipt-carrying
nbytes()for the G4 branch; computes int8/dense directly.- Return type:
- to_tensor_state()[source]
Return a portable tensor tree with no custom Python objects or NumPy arrays.
- class CompressedOptimizerState(shape, method='auto', *, state_dtype=None, **compress_kwargs)[source]
Bases:
objectAdam-style
m/vmoment storage for ONE parameter tensor, held COMPRESSED between optimizer steps (rather than as two dense fp32 buffers).setcompresses;getdecompresses back to plain tensors for the optimizer math to use.v(Adam’s second moment, an EMA of squared gradients) is stored as its COMPRESSED SQUARE ROOT rather than compressed directly. This is a real, load-bearing design choice, not cosmetic:vroutinely spans many orders of magnitude within one parameter tensor (a few large-gradient elements next to many near-zero ones), which is exactly the dynamic range that defeats both compression paths – linear int8 quantization sets one block-wide scale from the block’s max, so any element more than ~127x smaller than that max quantizes to LITERALLY zero; G4’s Gaussian tail fit is symmetric and can reconstruct small true values as slightly negative. Either failure, fed straight into Adam’s1/(sqrt(v_hat) + eps)denominator, produces a step blown up by orders of magnitude (empirically confirmed: an early version of this module, compressingvdirectly with int8, diverged to a >100x loss spike within ~5 steps on the tiny transformer this module’s own test suite trains).sqrt(v)roughly halves the dynamic range in log-space (Adam’s own second-moment buffer already tracks squared gradients FOR this reason –sqrt(v)is the RMS gradient-magnitude scale, the quantity Adam’s update actually normalizes by), and squaring the reconstructed value back onget()is a nonnegative projection for free – it can never reconstruct a negativev, closing the negative-v/NaN failure mode without a separate clamp needing to paper over it (a defensiveclamp_min(0.0)is still applied as a last line of defense inCompressedAdam, since callers ofCompressedOptimizerStatedirectly should not have to know this internal detail to stay safe).- nbytes()[source]
Total measured compressed footprint of both moment buffers, in bytes.
- Return type:
- class Fp8CastResult(tensor, used_fp8, reason, max_abs, underflow_fraction)[source]
Bases:
objectReceipt of one
fp8_cast_with_guard()call – never silently swallowed.- tensor
The output tensor – either the fp8-cast tensor (
used_fp8=True) or thefallback_dtypecast (used_fp8=False).- Type:
Any
- used_fp8
Whether the fp8 cast was accepted.
- Type:
- reason
Human-readable reason for the decision (acceptance or the specific guard that fired).
- Type:
- max_abs
The input tensor’s max absolute value (0.0 for an empty tensor) – the statistic the overflow guard checks.
- Type:
- underflow_fraction
Fraction of the input’s nonzero values that flushed to exactly zero under the fp8 round-trip – the statistic the underflow guard checks.
0.0when the overflow guard fired first (the round-trip was never attempted).- Type:
- class RecomputeDecision(block_index, should_recompute, estimated_cost, estimated_benefit, activation_bytes, recompute_flops, rationale)[source]
Bases:
objectThe cost/benefit tradeoff and chosen action for ONE block’s activation-recompute policy – mirrors D6’s
RespecializationDecisionshape: a flat, inspectable dataclass carrying both the raw estimates and the derived decision, not just a boolean.- Parameters:
- property net_benefit: float
estimated_benefit - estimated_cost– positive iff recomputing this block is worth it.
- class SelectiveRecomputePolicy(memory_value_per_byte=_DEFAULT_MEMORY_VALUE_PER_BYTE, flop_cost_per_unit=_DEFAULT_FLOP_COST_PER_UNIT)[source]
Bases:
objectPer-block, cost-model-driven activation-checkpointing decision – extends
mixle.models.transformer.CausalLM’s previously all-or-nothinggradient_checkpointingbool flag (see that module’sforward, which now also accepts a per-block list) to a PER-BLOCK decision.A block is recommended for recompute when the value of the memory freed (its stored- activation footprint, valued at
memory_value_per_byte) exceeds the cost of the extra compute spent recomputing it (its recompute FLOPs, valued atflop_cost_per_unit) – the same cost-vs-benefit tradeoff SHAPE as D6’s compile economics, applied to this different decision (recompute-vs-store, not eager-vs-compiled).- decide_model(lm, batch, seq_len, dtype_bytes=4)[source]
Decide per-block recompute for every block of a
CausalLM(mixle.models.transformer.build_causal_lm), bound to its actual block manifest.Linear recompute cost is measured from every block’s real parameter count, so edited, widened, coarsened, or otherwise heterogeneous blocks can receive different decisions.
- apply_to_model(lm, batch, seq_len, dtype_bytes=4)[source]
Compute the per-block decisions and set them directly as
lm.gradient_checkpointing(a per-block bool list – seemixle.models.transformer.CausalLM.forward, which accepts either a single bool for all blocks or a per-block list).
- GaussianLaw
alias of
MultivariateGaussianDistribution
- class GeluCovarianceReceipt(correction_frobenius, min_eigenvalue_before, min_eigenvalue_after, iterations, marginal_variance_max_error)[source]
Bases:
objectMeasured correction applied to keep linearized GELU correlations PSD at exact marginal variances.
- class LayerMoments(index, name, law, closure_error, diagnostics=<factory>)[source]
Bases:
objectOne layer’s propagated law plus its locally-computed closure-error receipt.
- class NeuralOptimizerPlan(routes, sign_stable=None)[source]
Bases:
objectInspectable non-Adam-first routes for a Torch module.
- class NeuralOptimizerRoute(name, family, reason, shape)[source]
Bases:
objectOne named parameter’s executable update family and selection reason.
- class RoutedNeuralOptimizer(groups, defaults, plan, *, precondition_frequency, muon_backend, muon_steps, fisher_provider, projection_provider)[source]
Bases:
objectCheckpointable mixed-family optimizer with one validated route per trainable parameter.
- class EMATeacher(model, decay=0.999)[source]
Bases:
objectAn exponential-moving-average copy of a model’s own weights: the standard mean-teacher/BYOL/DINO self-distillation teacher.
update(student_model)appliesteacher = decay * teacher + (1 - decay) * studentto every tensor in the teacher’sstate_dict(parameters AND buffers, so e.g. non-trainable statistics stay consistent too) – called once per training step, AFTER the optimizer step, so the teacher always tracks a temporally-smoothed trailing average of the student. The teacher is a real, independent, forward-passable module (forward/predict), held in eval mode with gradients disabled: it is a read-only distillation TARGET, never itself directly optimized.- Parameters:
model (Any)
decay (float)
- update(student_model)[source]
One EMA step: pull every teacher tensor toward the student’s current value.
CausalLMtieshead.weighttotok.weight(weight tying), so severalstate_dict()keys alias the SAME underlying storage – updating each key naively would apply the EMA formula to that storage more than once per step (a double update).seendedupes by storage identity (data_ptr()) so every real tensor is updated exactly once, however many names alias it.- Parameters:
student_model (Any)
- Return type:
None
- forward(x)[source]
Run
xthrough the EMA-teacher weights (eval mode, no grad).
- class TrainStats(ce_loss=<factory>, stochastic_depth_loss=<factory>, ema_consistency_loss=<factory>, total_loss=<factory>)[source]
Bases:
objectPer-step telemetry from
train_with_self_distillation()– cross-entropy, stochastic-depth consistency, and EMA-teacher consistency losses, kept separately so a caller can see which pressure is doing what (and the combined total actually optimized).
- class FeatureMapDensity(feature_name, inner, name=None, *, feature_version=None, feature_digest=None, feature_dim=None)[source]
Bases:
SequenceEncodableProbabilityDistributionp(feature_fn(x))for a registered, deterministicfeature_fnand inner distribution.- Parameters:
- density(x)[source]
Return the induced feature-space density at raw item
x.
- log_density(x)[source]
Return
log p(feature_fn(x))under the inner distribution.
- seq_log_density(x)[source]
Return inner log densities for an already-featurized batch.
- sampler(seed=None)[source]
Raw-item sampling is undefined because the feature map has no inverse.
- Parameters:
seed (int | None)
- Return type:
DistributionSampler
- feature_sampler(seed=None)[source]
Return the sampler of the explicitly separate inner feature-space distribution.
- Parameters:
seed (int | None)
- Return type:
DistributionSampler
- estimator(pseudo_count=None)[source]
Return an estimator that fits the inner estimator on registered features.
- Parameters:
pseudo_count (float | None)
- Return type:
FeatureMapEstimator
- dist_to_encoder()[source]
Return the encoder that maps raw items to feature vectors.
- Return type:
FeatureMapEncoder
- class FeatureMapEstimator(feature_name, inner, name=None, *, feature_version=None, feature_digest=None, feature_dim=None)[source]
Bases:
ParameterEstimatorFits
inneronfeature_fn(x)for raw itemsx– the estimator side ofFeatureMapDensity.- Parameters:
- accumulator_factory()[source]
Return an accumulator factory that feature-maps raw inputs before inner accumulation.
- Return type:
FeatureMapAccumulatorFactory
- feature_fn(name, *, version=None, digest=None, feature_dim=None)[source]
Resolve a feature function and optionally verify its complete pinned identity.
- register_feature_fn(name, fn, *, version, feature_dim)[source]
Register one immutable, versioned raw-item feature transform.
Repeating the exact registration is idempotent. Reusing
(name, version)for different code or output schema raises; callers must publish a new version instead.
- class StreamingTransformer(module, device='cpu', *, lr=3.0e-3, optimizer_state=None)[source]
Bases:
SequenceEncodableProbabilityDistributionWraps a live, persistently-trained module.
seq_log_density= next-tokenlog p(eval/telemetry).- classmethod from_config(vocab, *, d_model=128, n_layer=4, n_head=4, block=64, embedding=None, device='cpu')[source]
Build the leaf from hyperparameters (no hand-built torch module) – the declarative estimator surface.
embeddingoptionally ties a sharedCategoricalEmbeddingacross leaves.
- log_density(xy)[source]
Return the next-token log probability for one
(context, token)pair.
- predict(x)[source]
Return argmax next-token predictions for one or more contexts.
- sampler(seed=None)[source]
Return the sampler for the conditional next-token model.
- Parameters:
seed (int | None)
- Return type:
StreamingTransformerSampler
- seq_log_density(enc)[source]
Return per-row next-token log probabilities for encoded context/token pairs.
- estimator(pseudo_count=None)[source]
Return the streaming estimator that trains the live module in accumulator updates.
- Parameters:
pseudo_count (float | None)
- Return type:
StreamingTransformerEstimator
- dist_to_encoder()[source]
Return the encoder for context/token training pairs.
- Return type:
StreamingTokenEncoder
- to_dict()[source]
Serialize the module bytes and device for registry-based round trips.
- NeuralLeaf
alias of
NeuralGaussian
- SoftmaxNeuralLeaf
alias of
NeuralCategorical
- StreamingTransformerLeaf
alias of
StreamingTransformer
- class TrainingSearchResult(recipe, loss, history=None, seed=None)[source]
Bases:
objectThe outcome of a multi-fidelity training search: the best recipe, its full-budget loss, and the history.
The result OWNS what it reports (MXR-080-1890). It used to store the caller’s
recipemapping andhistorycontainer by reference and validate nothing, so:recipe = {"d_model": 64} res = TrainingSearchResult(recipe=recipe, loss=1.0, history=trace) recipe["d_model"] = 999 # the recorded winning recipe silently became a different one
rewrote a decision that had already been recorded, and
lossacceptednanor the string"not a number"as a search outcome.__post_init__now copies both containers withdetach_receipt_container()and checks that the fields are the kind of thing the search actually produces.seedrecords the search’s common-random-numbers seed, so the reported loss is attributable to a reproducible run rather than to one unlabelled draw.Deliberately NOT checked, and why:
The numeric contents of ``history``.
detach_receipt_containercopies containers but passes elements through by identity, so theX/Yblocks a search accumulates stay the same arrays rather than being duplicated – they are the optimizer’s own freshly built output, nobody else holds them, and copying every evaluation block would add a real cost to a result that is often only glanced at. A holder can still edit those arrays in place; this defends against the caller who kept a reference, which is the aliasing defect that was reproduced.That ``recipe`` decodes to ``history[“x”]``. Inside
tune_training()both come from the same optimizer result, so the check would be tautological; for a directly constructed result there is no space to decode against.
- class TrainingSpace(d_model_choices=(64, 128, 256, 512), n_layer_range=(2, 12), log10_lr_range=(-4.0, -2.0), batch_choices=(16, 32, 64, 128))[source]
Bases:
objectThe tunable axes of an LM training recipe and how a unit-cube point decodes into concrete knobs.
- Parameters:
- bounds()[source]
Return unit-cube bounds for the DOE optimizer.
- class TransformerLMEstimator(vocab, *, d_model=128, n_layer=4, n_head=4, block=64, embedding=None, lr=3e-3, device='cpu')[source]
Bases:
StreamingTransformerEstimatorA Transformer language model as a fit-ready estimator:
TransformerLMEstimator(vocab, d_model=..., ...).The clean, declarative surface – no hand-built torch module, no
Leaf(...).estimator()two-step. Drops intoMixtureEstimator/CompositeEstimatorlike any other*Estimator.embeddingoptionally ties a sharedCategoricalEmbedding(e.g. one word embedding across a mixture’s experts).TransformerLMEstimator(V, embedding=emb)andStreamingTransformer.from_config(V, embedding=emb).estimator()build the same thing.
- build_causal_lm(vocab, d_model=128, n_layer=3, n_head=4, block=64, embedding=None, gradient_checkpointing=False)[source]
Build a causal decoder-only Transformer LM (token+pos embeddings, pre-norm blocks, weight-tied head).
embeddingoptionally injects a shared tokennn.Embedding(vocab x d_model) to use in place of a fresh one – so several language models can tie the same word embedding and train it jointly (the weight-tied head follows it). Its shape must match(vocab, d_model).gradient_checkpointing=Truerecomputes block activations during backward instead of storing them – identical gradients (pinned by test) for a large activation-memory cut on deep stacks or long blocks. The flag is a plain module attribute, so it can also be toggled on an existing model – including to a per-block list/tuple of bools (one pern_layer) rather than a single all-or-nothing bool, for F6’s cost-model-driven selective policy (mixle.models.memory_efficient_training.SelectiveRecomputePolicy).
- coarsen(model, budget, trust_region, input_law, n_mc=64, seed=0)[source]
The iterated coarsening operator
R: walkmodel.blockspairwise, attempting adepth_merge()at each adjacent pair. A merge is ACCEPTED only if BOTH hold:TRUST REGION – its own LOCAL closed-form KL (
receipt.kl_divergence) is at mosttrust_region;BUDGET – accepting it would not push the ACCUMULATED KL (summed over all accepted merges so far) past
budget.
A rejected (or budget-exhausted) pair is left UNMERGED – both original blocks are kept, and the running law is propagated through them individually (via G1’s own per-layer laws, reusing
_block_branch()plus the outer residual add) so later merge attempts still see the correct running law regardless of whether earlier pairs were merged. This makes the whole pass data-free: the running “receipt map” is built entirely from propagated LAWS, never real data.Returns a
CoarsenResultwrapping a new, real, forward-passableCoarsenedLM(so a caller can still measure REAL per-layer error against the original model by literally running both models on sampled token sequences – seemixle/tests/coarsening_test.py).
- compress(model, method='auto', *, calibration_data=None, eval_data=None, sample_budget=None, input_law=None, budget=5.0, trust_region=5.0, n_mc=64, seed=0, kd_epochs=200, kd_lr=1e-2, hybrid_sample_fraction=0.01, hybrid_max_stages=1, hybrid_epochs=40, hybrid_lr=5e-4, target_n_layer=None)[source]
The single compression entry point (roadmap J1): dispatches to one of the three method families, or lets a
UCB1CompressionReceipt-carrying picker choose (method="auto", default).- Parameters:
model (Any) – a real
mixle.models.transformer.CausalLM(or a coarsened one).method (str) –
"auto"(default),"sampling_kd","non_sampling", or"hybrid".calibration_data (Any) – integer token-context tensor/array
(N, L)– required for"sampling_kd","hybrid", and"auto"(the two methods that touch real data).eval_data (Any) – held-out integer token-context tensor/array used to MEASURE quality (teacher-agreement against
model). Required and memory/value-independent fromcalibration_dataformethod="auto". Explicit methods may omit it, in which case quality is unmeasured rather than fabricated from training data.sample_budget (int | None) – an explicit cap (absolute count) on how many REAL calibration samples
"hybrid"/"auto"’s hybrid arm may use; ifNone,hybrid_sample_fractionoflen(calibration_data)is used instead.input_law (MultivariateGaussianDistribution | None) – the data-free input law for G1’s propagation; defaults to
_default_input_law()(the model’s own token-embedding statistics).budget (float) – forwarded to
mixle.models.coarsening.coarsen().trust_region (float) – forwarded to
mixle.models.coarsening.coarsen().n_mc (int) – forwarded to
mixle.models.coarsening.coarsen().kd_epochs (int) – forwarded to the fresh, from-scratch
sampling_kdstudent’s full training loop.kd_lr (float) – forwarded to the fresh, from-scratch
sampling_kdstudent’s full training loop.hybrid_sample_fraction (float) – fraction of
calibration_datahybrid may use whensample_budgetis not given (default 1%, matching the acceptance criterion).hybrid_max_stages (int) – how many worst-closure-error stages hybrid fine-tunes (default 1).
hybrid_epochs (int) – forwarded to hybrid’s own micro-calibration fine-tune loop – deliberately separate from
kd_epochs/kd_lr: hybrid fine-tunes ALREADY-good non_sampling weights on a HANDFUL of real samples (a light nudge), a completely different regime from training a fresh architecture from scratch on the full calibration set, and reusing the same hyperparameters for both badly overfits hybrid’s tiny sample budget in practice.hybrid_lr (float) – forwarded to hybrid’s own micro-calibration fine-tune loop – deliberately separate from
kd_epochs/kd_lr: hybrid fine-tunes ALREADY-good non_sampling weights on a HANDFUL of real samples (a light nudge), a completely different regime from training a fresh architecture from scratch on the full calibration set, and reusing the same hyperparameters for both badly overfits hybrid’s tiny sample budget in practice.target_n_layer (int | None) – depth of the fresh
sampling_kdstudent; defaults tocoarsen’s own natural 2x depth cut (max(1, model.n_layer // 2)) so all three methods are compared at a MATCHED compression ratio.seed (int)
- Returns:
CompressedModel
- Return type:
CompressedModel
- depth_merge(block_a, block_b, input_law, n_mc=64, seed=0)[source]
Fold two adjacent
Blocks into one via the second-order Taylor composition documented at module level.Returns
(merged_block, receipt)wheremerged_blockis a real, forward-passableMergedBlockandreceiptis aScaleReceiptwhoseteacher_law/student_laware the EXACT-per-G1 sequential composition (block_athenblock_b, propagated exactly asmixle.models.moment_propagation.propagate_moments()would) vs. the second-order MERGED composition, both Gaussian, sokl_divergenceis the closed-formgaussian_kl()between them – the receipt for this individual (local) merge step, i.e. what a caller’s TRUST REGION check compares against.
- experimental_width_merge_representation(target_width, input_law, temperature=0.1, n_iter=200)[source]
Reduce the residual-stream width from
d_modeltotarget_widthby pairing near-duplicate coordinates of the (Sigma-weighted) residual-stream covariance and merging/averaging them.sigma_weighted_permutation(G2) was checked first per the roadmap note (see the module docstring): it solvesmin_P tr((W - P @ target_profile) Sigma (W - P @ target_profile)^T)for a SQUARE permutationPmatching two SAME-shape objects (Wagainst a fixedtarget_profile) – the classic one-to-one “git re-basin” alignment. Width reduction needs a genuinely MANY-TO-FEW map (d_model -> target_width, generallytarget_width < d_modelso there is no permutation at all, square or otherwise), so it is not directly reusable here;_rectangular_sinkhorn()reuses the SAME log-domain Sinkhorn fixed-point idea for the rectangular marginals this problem actually has, rather than pulling in a separate heavy OT solver.Data-free: the only input is
input_law.covar(the propagated residual-stream covariance from G1), used to build a correlation-distance costcost[i, j] = Sigma[i,i] + Sigma[a_j,a_j] - 2*Sigma[i, a_j]between every source coordinateiandtarget_widthanchor coordinatesa_j(the highest-variance coordinates, chosen as informative anchors) –cost[i, j]is exactlyVar(x_i - x_{a_j}), so a near-zero cost means coordinateiis functionally redundant with anchora_jand should be merged into it. The resulting Sinkhorn plan, column-normalized into convex combinations, is the merge operator; its pseudo-inverse is the reconstruction (“unmerge”) map.This is explicitly a representation helper, not a model transformation: it does not rewire transformer weights, normalization, attention heads, or output heads and therefore does not return or claim a smaller executable model.
receipt.kl_divergencereports the true support result. It is infinite for a genuine rank reduction because the full-rank teacher assigns mass outside the rank-deficient round-trip support. For callers that explicitly assume isotropic downstream noise,regularized_kl_divergenceand the receipt’s sensitivity values report that separate surrogate.
- gaussian_kl(p, q)[source]
Closed-form
KL(p || q)for two multivariate Gaussians – the standard textbook formula:KL(p||q) = 0.5 * ( tr(Sigma_q^-1 Sigma_p) + (mu_q - mu_p)^T Sigma_q^-1 (mu_q - mu_p) - k + ln(det Sigma_q / det Sigma_p) )
computed ANALYTICALLY, not via Monte Carlo – both
p(the “teacher” law) andq(the “student” law) are alreadyMultivariateGaussianDistributionobjects, which cacheinv_covarandlog_detfrom a (self-healing) Cholesky factorization at construction time, so this reuses those cached quantities directly rather than re-deriving them. Clipped at 0 to absorb float round-off on (near-)identical laws (KL is exactly 0 there, mathematically).- Parameters:
p (MultivariateGaussianDistribution)
q (MultivariateGaussianDistribution)
- Return type:
- structure_project(weight, sigma, mode='low_rank', rank=None, pattern='2:4')[source]
Thin wrapper calling G2’s
mixle.models.sigma_weighted_projectionsolvers directly – NOT a reimplementation, per the roadmap’s build-vs-borrow note.mode="low_rank"callssigma_weighted_low_rank()(requiresrank);mode="block_sparse"callssigma_weighted_block_sparse()(usespattern, either the literal"2:4"or an explicit boolean mask, exactly as G2 documents).
- evaluate_checkpoint(model, *, checkpoint_id='checkpoint', seed=0, n_examples=256, metadata=None, eval_data=None)[source]
Run the full synthetic capability suite on
modeland return one structuredEvalReport.modelis a real (or toy)mixle.models.transformer.CausalLM– anything exposing.vocab,.block, and__call__(x) -> (batch, vocab)next-token logits works. This is the single entry point: no separate setup per task, no manual orchestration – the “one command per checkpoint” F10 asks for.
- markov_transition_matrix(vocab)[source]
The fixed order-1 Markov chain the perplexity task scores against.
Keyed only on
vocab(via a module-level constant seed), not on the caller’s sampleseed– the benchmark distribution is a fixed property of the eval suite (like a real held-out benchmark), while the per-callseedonly controls which samples from it are drawn for a given run. This is what lets a training loop legitimately learn this chain (it is a fixed, nameable distribution) while individual eval runs still draw fresh, unseen sequences from it.
- track_regression(reports, *, threshold=0.05, reference='best')[source]
Flag metrics that regressed by more than
threshold(relative) across a sequence of checkpoints.reportsis an ordered sequence – successive training rungs, or successive steps of a J2 compression ladder. For each task, each report (from the second onward) is compared against either the best score seen so far in the sequence (reference="best", the default – catches slow drift, not just one-step drops) or the immediately-prior report (reference="prior"– catches only step-to-step drops). A task is flagged when it moved worse than the reference by more thanthresholdas a fraction of the reference’s magnitude, direction-aware (a drop for accuracy-like metrics, a rise for perplexity-like metrics).
- choose_compression_method(tensor, *, min_size_for_g4=_DEFAULT_MIN_SIZE_FOR_G4, g4_top_k_fraction=_DEFAULT_G4_TOP_K_FRACTION, g4_gof_threshold=DEFAULT_GOF_THRESHOLD, tail_family=None)[source]
Goodness-of-fit-based per-tensor method picker (the “one level down” method-picker pattern I1 uses for its own picker –
mixle.task.banditis a reasonable fit for a LEARNED, reward- driven picker, but the choice here is cheaper and just as principled as a fixed rule: G4 already computes a real KS goodness-of-fit receipt as part of fitting, so reusing THAT receipt directly is simpler than bolting on a bandit that would need to learn what the receipt already tells us for free).Rule: for tensors at or above
min_size_for_g4(below which G4’s fixed per-tensor fitting overhead is not worth it), attempt a G4 fit; if it does not dense-fall-back on its own goodness-of-fit receipt, use G4 (the more accurate, more expensive path). Otherwise, use int8 (the cheap path) – callers should still checkcompress_moment()’s returnedmethodfor a possible further downgrade to"dense"if int8 itself proves untrustworthy for this specific tensor (see_DEFAULT_INT8_ADVERSARIAL_RELATIVE_ERROR).
- compress_moment(tensor, method='auto', *, min_size_for_g4=_DEFAULT_MIN_SIZE_FOR_G4, g4_top_k_fraction=_DEFAULT_G4_TOP_K_FRACTION, g4_gof_threshold=DEFAULT_GOF_THRESHOLD, int8_block_size=_DEFAULT_INT8_BLOCK_SIZE, int8_adversarial_relative_error=_DEFAULT_INT8_ADVERSARIAL_RELATIVE_ERROR, int8_flushed_fraction_threshold=_DEFAULT_INT8_FLUSHED_FRACTION_THRESHOLD, tail_family=None)[source]
Compress one Adam moment tensor (
morv) via G4, int8, or dense storage.- Parameters:
tensor (Any) – A torch tensor or numpy array (one Adam moment buffer, any shape).
method (str) –
"auto"(usechoose_compression_method()),"g4","int8", or"dense"to force a specific path. A forced"g4"/"int8"still honestly downgrades to"dense"if the chosen method’s own receipt (G4’s KS statistic, or int8’s reconstruction error) rejects the fit – this function never returns a silently bad compressed representation.min_size_for_g4 (int)
g4_top_k_fraction (float)
g4_gof_threshold (float)
int8_block_size (int)
int8_adversarial_relative_error (float)
int8_flushed_fraction_threshold (float)
tail_family (Any)
- Returns:
CompressedMomentEncoding
- Return type:
CompressedMomentEncoding
- decompress_moment(encoding)[source]
Invert a complete versioned compressed-moment payload.
- Parameters:
encoding (CompressedMomentEncoding)
- Return type:
- dequantize_int8_blockwise(codes, scales, block_size=_DEFAULT_INT8_BLOCK_SIZE)[source]
Invert
quantize_int8_blockwise(). Returns afloat32array the same length ascodes.
- estimate_block_activation_bytes(batch, seq_len, d_model, dtype_bytes=4)[source]
Estimate the memory footprint of ONE transformer block’s stored output activation (
mixle.models.transformer.Block’s output, shape(batch, seq_len, d_model)) – the memory that activation checkpointing (recomputing instead of storing) frees.
- estimate_block_recompute_flops(batch, seq_len, d_model)[source]
Estimate the FLOP cost of recomputing ONE transformer block’s forward pass, tied directly to
mixle.models.transformer.Block’s actual layer shapes:qkv(d -> 3d),proj(d -> d), and the two MLP linears (d -> 4d -> d) give3d^2 + d^2 + 4d^2 + 4d^2 = 12*d_model^2linear-layer parameters per block; the standard “2 FLOPs per parameter per token” forward-pass heuristic turns that into a FLOP estimate, plus the attention score/value matmuls (QK^Tandattn @ V, each~2*batch*seq_len^2*d_modelFLOPs) that scale withseq_len^2rather than with parameter count.
- estimate_recompute_benefit(activation_bytes, memory_value_per_byte=_DEFAULT_MEMORY_VALUE_PER_BYTE)[source]
The value of the memory freed by recomputing (rather than storing) one block’s activation.
- estimate_recompute_cost(recompute_flops, flop_cost_per_unit=_DEFAULT_FLOP_COST_PER_UNIT)[source]
The cost of the extra compute spent recomputing one block’s activation during backward.
- fp8_cast_with_guard(tensor, fp8_dtype='float8_e4m3fn', fallback_dtype=None, underflow_fraction_threshold=_DEFAULT_UNDERFLOW_FRACTION_THRESHOLD)[source]
Attempt an fp8 cast of
tensor, guarded against the two ways fp8 silently corrupts data.- Parameters:
tensor (Any) – A torch tensor (any float dtype).
fp8_dtype (str) –
"float8_e4m3fn"(higher precision, smaller range – the default, matching common fp8-training practice for weights/activations) or"float8_e5m2"(wider range, coarser precision).fallback_dtype (Any) – Dtype to fall back to when a guard fires. Defaults to
torch.bfloat16(the codebase’s existing wide-range training dtype, permixle.utils.parallel.torch_neural).underflow_fraction_threshold (float) – Maximum tolerable fraction of nonzero input values that are allowed to flush to exactly zero under the fp8 round-trip before the underflow guard fires.
- Returns:
always carries the real, computed guard statistics, whether or not the fp8 cast was ultimately accepted – consistent with this codebase’s receipt-over-silent- assumption convention (see
mixle.models.sorted_profile_quantizer’s goodness-of-fit receipt).- Return type:
Fp8CastResult
- quantize_int8_blockwise(flat, block_size=_DEFAULT_INT8_BLOCK_SIZE)[source]
Dynamic per-block symmetric int8 quantization (bitsandbytes-style 8-bit-Adam technique).
Each contiguous block of
block_sizeelements gets its own scale (absmax / 127), so one extreme value only degrades the resolution of ITS OWN block rather than the whole tensor.
- attention_law(law, qkv_weight, qkv_bias, proj_weight, proj_bias, n_head)[source]
Propagate a Gaussian law through one
mixle.models.transformer.CausalAttentionlayer.Modeling assumption: the key/value population attended over (across sequence positions) is treated as a single STATIONARY Gaussian – the same joint law as the query’s – rather than tracking per-position laws. This is the “R2 MGF” population-level approximation the roadmap specifies; it does not model the causal mask explicitly (a real causal mask makes early positions attend to a smaller, non-stationary population). That mismatch is a known limitation, checked directly against Monte Carlo softmax attention in
mixle/tests/moment_propagation_test.py(tightest for a roughly-stationary population, looser for strongly non-stationary / short sequences).Derivation¶
For jointly Gaussian
(K, V)(a key vector and its associated value vector from the SAME token) and a fixed queryq, the requested MGF identity isE[exp(q^T K / sqrt(d)) V] = exp(q^T mu_K/sqrt(d) + 0.5 q^T Sigma_KK q / d) * (mu_V + Sigma_VK q / sqrt(d))which is the standard “
E[Y e^{t^T X}] = M_X(t) (mu_Y + Sigma_YX t)” identity for jointly Gaussian(X, Y)witht = q / sqrt(d),X = K,Y = V. The attention DENOMINATOR (the softmax normalizer) is exactly the same MGF evaluated withVreplaced by the constant1:E[exp(q^T K / sqrt(d))] = exp(q^T mu_K/sqrt(d) + 0.5 q^T Sigma_KK q / d).Both share the identical exponential prefactor, so it CANCELS in the ratio:
softmax-attention-output(q) ~= E[exp(q^T K/sqrt(d)) V] / E[exp(q^T K/sqrt(d))] = mu_V + (Sigma_VK / sqrt(d)) q.This is a remarkably clean result: the MGF-approximated attention output, as a function of the query, is EXACTLY AFFINE in
q(no exponential term survives). Sinceqitself has a propagated Gaussian law (the marginal of the joint (Q, K, V) law after theqkvprojection), pushing that law through this affine map is exact (reusinglinear_law()’s formula) – there is no additional approximation beyond the population-stationarity assumption above and (for the covariance) the affine relation being evaluated with theSigma_VKestimated from the SAME joint law used for the mean.Per head, per token position,
y_h(q) = mu_{V,h} + (Sigma_{VK,h} / sqrt(d_head)) q_h. Stacking heads into a block-diagonal mapA(each head only reads its own query slice) and reusing the FULL (cross-head) query covariance from theqkvprojection gives the cross-head covariance of the output “for free” – cross-head correlation inQ(already present inSigma_QQ’s off-diagonal blocks) propagates throughA Sigma_QQ A^Teven thoughAitself only mixes within a head.
- gelu_law(law, *, return_receipt=False)[source]
Propagate a Gaussian law through elementwise
GELUusing the closed-form per-dimension moments in_gelu_scalar_moments().The per-dimension MEAN and VARIANCE are exact closed-form expressions (no Monte Carlo, no approximation of the GELU functional form). The OFF-diagonal output covariance –
Cov(GELU(x_i), GELU(x_j))fori != j– has no simple closed form (it needs the joint bivariate distribution of(x_i, x_j)through a nonlinearity) and is instead approximated by the standard delta-method / Price’s-theorem-style linearizationCov(y_i, y_j) ~= J_ii * J_jj * Cov(x_i, x_j)withJ_ii = d E[GELU(x_i)]/d mu_ithe EXACT mean-derivative from Stein’s lemma. The diagonal is then overwritten with the exact closed-form variance. Because that splice need not be PSD, correlations are projected to the PSD cone under a fixed-unit-diagonal constraint and then rescaled by the exact marginal standard deviations. This preserves the scalar variances while correcting only the approximate correlation structure.Set
return_receipt=Trueto receive aGeluCovarianceReceiptmeasuring the correction, pre/post minimum correlation eigenvalues, iteration count, and marginal-variance preservation error.
- iter_moments(model, input_law, n_mc=128, seq_len=16, seed=0, probe_batch_size=32)[source]
Yield layer-local Gaussian laws without retaining earlier receipts.
input_lawmodels the distribution of a token’s residual-stream vector ENTERING the block stack (i.e. after token + position embedding) – anN(mu, Sigma)overR^{d_model}.The iterator walks
model.blocksone at a time, then the finalmodel.lnandmodel.head. Closure probes execute in the target module’s device/dtype and evaluation mode, restore every submodule’s prior mode, and reduce batches of at mostprobe_batch_sizeonline.
- layernorm_law(law, weight, bias, eps=1e-5)[source]
Propagate a Gaussian law through
LayerNorm:y = weight * (x - m(x)) / sqrt(v(x) + eps) + bias, wherem(x) = mean_d(x)andv(x) = mean_d((x - m(x))^2)are the PER-SAMPLE (per-token) statistics LayerNorm computes over the feature axis – this is the nonlinear, data-dependent step in the block.Derivation (“re-anchoring”)¶
LayerNorm has no closed-form pushforward of a full law in general (
m(x)andv(x)are themselves random, nonlinear functions ofx). We use a first-order Taylor expansion around the CURRENT meanmu, i.e. anchor the (unknown, per-sample) normalization statistics at their EXPECTED values under the current law, not merely their values evaluated at the mean vector.m(x) = mean_d(x)is itself LINEAR inx, soE[m(x)] = mean_d(mu)exactly – no correction needed there. Butv(x) = mean_d((x - m(x))^2)is QUADRATIC inx, so evaluating it atmualone (v(mu) = mean((mu - m)^2)) drops a systematic bias term: writingP = I - (1/d) 11^Tfor the feature-centering projector (symmetric, idempotent),v(x) = (1/d) x^T P x, and the standard quadratic-form expectation identity givesE[v(x)] = v(mu) + (1/d) trace(P @ Sigma) = v(mu) + (1/d) (trace(Sigma) - (1/d) sum(Sigma)).The second term is the “spread of x around its own per-token mean” contribution that
v(mu)alone misses entirely; it is NOT a higher-order correction that can be dropped onceSigmais non-negligible relative tod– for smalld_model(e.g. an 8-wide toy model) it routinely dominatesv(mu), which without this correction makes the anchoredstd = sqrt(v(mu) + eps)far too small and blows the propagated mean/covariance up by an order of magnitude relative to the true LayerNorm output law. We therefore re-anchor at the BIAS-CORRECTEDv = E[v(x)]above (still a first-order/delta-method treatment of the covariance push-forward – only the anchor point forvis corrected, not the linearization itself). This is the LLM analogue of BatchNorm-based data-free-quantization (DFQ) calibration, which likewise re-derives cheap closed-form layer statistics (there, running mean/var; here, the expected LayerNorm mean/var under the CURRENT propagated law) without touching real data.The mean is propagated by evaluating the true (nonlinear) LayerNorm map at
mubut with the bias-correctedv:mu_out = weight * (mu - m) / sqrt(v + eps) + bias.The covariance is propagated via the JACOBIAN of LayerNorm evaluated at
muwith the same bias-correctedv(a standard, textbook LayerNorm-backward-style derivative applied at the corrected anchor):d(norm_i)/d(x_j) |_{x=mu} = (1/sqrt(v+eps)) * (delta_ij - 1/d - (mu_i - m)(mu_j - m) / (d*(v+eps)))J_ij = weight_i * d(norm_i)/d(x_j)Sigma_out ~= J Sigma J^T.Known failure modes (feeds the closure-error receipt)¶
Small ``d_model``:
m(x)andv(x)are averages over onlyd_modelfeatures, so their sample-to-sample fluctuation around their (now bias-corrected) expectation – which this delta-method approximation still ignores, since the Jacobian itself is frozen at the anchor – is large relative to their magnitude whend_modelis small. The approximation is progressively worse asd_modelshrinks, even after the mean-bias correction above.Heavy-tailed pre-norm activations: the first-order Taylor expansion is only locally valid; if the input law has high kurtosis / is far from Gaussian in practice (despite being MODELED as Gaussian here), the true per-sample
(m, v)can swing far from their Gaussian-law expectations, and the linearization degrades.A deep stack of blocks compounds both effects: even a small per-layer LayerNorm error can accumulate across
n_layerre-anchoring steps.
- linear_law(law, weight, bias=None)[source]
Exact Gaussian push-forward of
y = Wx + b.x ~ N(mu, Sigma) => y ~ N(W mu + b, W Sigma W^T)exactly – no approximation. Returns the new law together with the Jacobiandy/dx = W(used to chain residual cross-covariances).Note on
out.covarwhenweightmaps to MORE output dimensions thanlaw.covar’s rank (e.g. an expanding projection like theqkvweight inattention_law()):W Sigma W^Tis then mathematically rank-deficient (PSD, not PD), and the returned law – aMultivariateGaussianDistribution, which self-heals a non-PD covariance with a small trace-scaled diagonal jitter so it stays Cholesky-factorizable forlog_det/inv_covar/sampling, see_robust_cho_factorinmixle.stats.multivariate.multivariate_gaussian– may therefore differ from the exactW Sigma W^Tby that jitter (diagonal-only,~1e-10 * trace/n). This is NOT an error in the formula above – verified bit-exact whenever the output is genuinely PD (e.g. square invertibleweight); seemixle/tests/moment_propagation_test.py::LinearExactTestfor both regimes – it is the unavoidable cost of representing an exactly-singular covariance with a factorization that requires one.
- propagate_moments(model, input_law, n_mc=128, seq_len=16, seed=0, probe_batch_size=32)[source]
Materialize
iter_moments()into a list of per-layer full-covariance receipts.Unlike the iterator, this convenience API intentionally retains
O(depth × d_model²)returned law state. It remains useful when callers need random access to every layer; callers requiring depth-independent retained memory should consumeiter_moments().
- build_auto_optimizer(module, *, lr=1.0e-3, sign_stable=True, **kwargs)[source]
Plan and build the default non-Adam-first optimizer for
module.
- build_routed_optimizer(module, plan, *, lr=1.0e-3, betas=(0.9, 0.999), eps=1.0e-8, weight_decay=0.0, precondition_frequency=10, muon_backend='newton_schulz', muon_steps=7, fisher_provider=None, projection_provider=None)[source]
Build a Torch optimizer from stable or experimental structurally compatible routes.
- plan_neural_optimizer(module, *, matrix_min_elements=4_096, sign_stable=True)[source]
Plan update families from parameter role and shape without importing Torch at module import time.
- resolve_neural_optimizer(module, optimizer=None, *, lr=1.0e-3, sign_stable=True)[source]
Resolve automatic, named, planned, or callable neural optimizers with an audit receipt.
- shard_safe_neural_optimizer_plan(plan)[source]
Localize routes whose geometry is not invariant under parameter sharding.
Muon/Kronecker/natural-gradient directions require a global matrix. Applying them independently to rectangular shards is a different algorithm. Until a backend declares and executes the required gather/factor reductions, use momentum for those blocks and record the reason in the plan.
- Parameters:
plan (NeuralOptimizerPlan)
- Return type:
NeuralOptimizerPlan
- consistency_loss(student_output, teacher_output, mode='mse')[source]
The self-distillation consistency term between a student prediction and a teacher/target prediction on the SAME input –
mode="mse"(default, plain squared-error between logits, the mean-teacher convention) ormode="kl"(KL(teacher_softmax || student_log_softmax), the classic soft-target distillation loss).
- stochastic_depth_forward(model, x, drop_prob, generator=None, *, return_keep_mask=False)[source]
Run
modelonxtwice: once at full depth, once with each block independently dropped with probabilitydrop_prob(at least one block is always kept, so the partial pass never degenerates to the bare embedding/head). Returns(full_output, partial_output)– the pairtrain_with_self_distillation()feeds toconsistency_loss().At
drop_prob == 0both passes keep every block, so the two outputs are IDENTICAL (no dropout elsewhere inBlock) – the degenerate-case sanity check pinned inmixle/tests/self_distillation_test.py.
- train_with_self_distillation(model, data, steps, *, ema_decay=0.999, drop_prob=0.1, consistency_weight=1.0, ema_weight=None, stochastic_depth_weight=None, consistency_mode='mse', lr=3e-3, device='cpu', optimizer=None, seed=0, log=None)[source]
Train
model(aCausalLM, trained in place and also returned) forstepsnext-token cross-entropy steps, with EMA-teacher consistency and stochastic-depth consistency added as extra loss terms on top of the SAME per-step batch – both self-distillation pressures happen DURING training, not as a separate post-hoc pass.datayields(context, next_token)micro-batches shaped exactly likemixle.data.stream_token_source.stream_token_source()(context: (batch, block)float ids,next_token: (batch,)int ids).datamay be:a zero-arg CALLABLE returning a fresh iterator each time (e.g.
lambda: stream_token_source(ids, block=64, batch_size=32)) – restarted automatically whenever it runs dry beforestepsis reached, so training can outlast one epoch; ora plain iterable/iterator (e.g. a list of batches, or a single generator object) – consumed once, sized to yield at least
stepsbatches (a bare generator can’t be rewound).
Per step:
loss = cross_entropy(full_depth_logits, target) + stochastic_depth_weight * consistency(partial_depth_logits, full_depth_logits.detach()) + ema_weight * consistency(full_depth_logits, ema_teacher(context)), then one optimizer step, then one EMA-teacher update.ema_weight/stochastic_depth_weighteach default toconsistency_weightwhen unset.
- ewc(anchor, fisher, lam=1.0, floor=0.0)[source]
Bundle
(anchor, fisher, lambda)for.fit(..., ewc=...)(the EWC anti-forgetting penalty).flooradds a constant to every Fisher entry, so the penalty weights areF_i + floorand the penalty islambda * sum_i (F_i + floor) (theta_i - theta*_i)^2. It defaults to 0.0, which is EWC exactly as defined – and which, on its own, usually does not retain the old task, for a reason that is structural rather than a matter of tuninglam.The diagonal empirical Fisher is estimated from per-example gradients at the end of the previous stage. A stage that fit well leaves those gradients near zero, so almost every entry of
Fis near zero and the quadratic it defines is badly rank-deficient. Minimizing that penalty then does not hold the module neartheta*; it moves the module through the Fisher’s null space, where the penalty is cheap and the old task’s function is not preserved. Measured on a 4-feature 3-class pair of unrelated tasks (seeneural_ppl_test.test_cpt_ewc_retains_the_old_task), raisinglamfrom 10 to 8000 drives the Fisher-weighted drift down by four orders of magnitude, 3.6e-1 to 3.7e-5, while the raw distance from the anchor nearly doubles, 81 to 147, and retained accuracy on the old task stays flat around 0.21-0.24 against 0.19 for plain continuation. The penalty is satisfied; the capability it exists to protect is not. Pastlamof about 1e4 the quadratic is stiffer than the routed optimizer’s step size and the objective diverges instead.A small positive
floorcloses that null space – it is EWC plus L2-to-anchor, a Tikhonov regularization of the importance estimate rather than of the parameters. On the same task pairfloor=1e-3, lam=1e2retains 0.59-0.74 on the old task against 0.19-0.34 for plain continuation, at 0.62-0.66 on the new one: a real stability/plasticity trade rather than a satisfied constraint. Prefer a floor over a largelam; the floor buys retention wherelamalone only buys stiffness.
- extrapolate_learning_curve(steps, losses, *, at)[source]
Predict the loss at budget/step
atfrom a partial run’s(steps, losses)via a power-law fit.Fits
loss(t) = a + b * t^(-c)and evaluates it atatso a partial run can estimate the full-budget loss for early stopping. Invalid data, an underdetermined curve, or a failed/non-finite fit raises explicitly.
- fisher_diagonal(leaf, x, y, *, samples=512, device='cpu', seed=0)[source]
Diagonal empirical Fisher computed on an isolated evaluation-mode copy.
- lm_train_fn(token_ids, val_ids, *, vocab, block=64, max_epochs=3, device='cpu', seed=0, fidelities=None)[source]
Return a training callback
(recipe, budget) -> held-out nats/tokenforLM.budget in (0, 1]is a fraction of the FULL run’s training tokens (max_epochs * len(token_ids)), not a fraction of the epoch count.budget=1.0is unchanged –max_epochsepochs over the whole corpus – while a smaller budget shortens the corpus prefix as well as the epoch count, so distinct budgets buy distinct work. SeeLMFidelityfor the measurement that motivated this (MXR-080-1890).seedis the common-random-numbers seed shared by every run, which is what makes two recipes comparable; seeLMTrainFn.__call__().fidelitiesis optional and off by default. Pass the exact budget ladder the search will use and it is checked, before any training happens, for budgets that still resolve to identical work – the failure this finding is about. Token resolution runs out on a short corpus, so this can legitimately happen; it is reported rather than assumed away.
- snapshot(leaf_or_module)[source]
Detached clones of the module’s parameters – the anchor
theta*for an EWC penalty.- Parameters:
leaf_or_module (Any)
- Return type:
ParameterBundle
- tune_training(train, space=None, *, fidelities=(0.25, 1.0), costs=None, max_cost=20.0, n_init=None, seed=0)[source]
Run multi-fidelity BO over a training recipe.
train(recipe, budget)returns held-out loss, where lower is better.fidelitiesare the training-budget fractions the search may run at. Returns the recipe with the best full-budget loss and the full BO history.seedis recorded on the returned result (MXR-080-1890) so the reported loss is attributable to a reproducible search rather than to one unlabelled draw. Whether the objective is itself reproducible is the callback’s contract, not this function’s:lm_train_fn()supplies one that pins its own randomness, but an arbitrary caller-suppliedtrainis opaque here and is deliberately not second-guessed.
- apply_mup_init(model, *, base_width, base_std=0.02)[source]
Re-initialize
modelin place per the muP init rules, relative tobase_width.base_stdis the hidden-role init std tuned/measured atbase_width(the mixle default,0.02, matches common transformer practice and is a reasonable base-width value on its own).model.d_modelis read as the target width, sowidth_mult = model.d_model / base_width. LayerNorm weight/bias keep their identity init (1/0, unaffected by width, matching the"input"role’s no-rescale treatment); every other bias is zero-initialized (muP does not rescale bias init); every other weight matrix is drawnNormal(0, base_std * init_std_multiplier(role, width_mult)). Also turns on muP attention-logit scaling (enable_mup_attention()) on every block – the1/head_dimQK scaling is as much a part of “the model is parametrized under muP” as the init/lr rules above, and previously being left at the standard1/sqrt(head_dim)scale was an unintentional gap between what this module documented and what it actually configured.
- classify_causal_lm_params(model)[source]
Map every named parameter of a
mixle.models.transformer.CausalLMto its muP role.tok.weight/pos.weight(embeddings) ->"input"– fan-in is the fixed vocab / block length, notd_model.LayerNorm affine params (
blocks.*.ln1/ln2, top-levelln) ->"input"– no fan-in at all, muP leaves them at their standardTheta(1)scale/shift regardless of width.head.weight-> not a separate entry: it is the samenn.Parameterastok.weight(weight tying), somodel.named_parameters()already reports it once, under"tok.weight". See the module docstring for how the muP output role is instead applied at readout time.everything else (the attention qkv/proj and MLP
Linearweights/biases inside each block) ->"hidden"– fan-in scales linearly withd_model.
- init_std_multiplier(role, width_mult)[source]
Return the muP multiplier on init std for a parameter of
roleat the givenwidth_mult.width_mult = target_width / base_width. Multiply the BASE width’s tuned/measured init std by this factor to get the init std to use at the target width:"input"->1(fan-in fixed, e.g. vocab size – no rescale)"hidden"->width_mult ** -0.5(variance1/fan_in, standard, unchanged form)"output"->width_mult ** -1(variance1/fan_in**2– an extra1/width_mult)
- lr_multiplier(role, width_mult)[source]
Return the muP multiplier on learning rate for a parameter of
roleat the givenwidth_mult.width_mult = target_width / base_width. Multiply the BASE width’s tuned lr by this factor to get the transferred lr to use at the target width:"input"->1(constant lr – the muP “don’t touch it” role)"hidden"->width_mult ** -1(the headline muP rule: lr shrinks as the model widens)"output"->width_mult ** -1(same shrink as hidden, for Adam)
- mup_param_groups(model, *, base_width, lr)[source]
Build torch optimizer param groups implementing muP’s per-role lr scaling for
model.lris the BASE (hidden-role) learning rate – the one hyperparameter tuned once, cheaply, atbase_width.model.d_modelis read as the target width. Returns a list of{"params": [...], "lr": ..., "mup_role": ...}dicts suitable fortorch.optim.Adam(groups); the"input"group’s lr is unscaled, the"hidden"/"output"groups getlr * lr_multiplier(role, width_mult)– i.e. passing the same tunedlrat any target width reproduces exactly whattransfer_lr()predicts for that role.transfer_lris the formula; this is the mechanism that applies it to a live model + optimizer.
- output_forward_multiplier(width_mult)[source]
Return the muP readout multiplier (the “c” of abc-parametrization) applied to output-role logits.
Multiply the raw
headoutput by this factor so the readout’s output scale stays width-independent at init, even though (due to weight tying, see the module docstring)head.weightitself is parametrized under the"input"rule rather than a separate"output"init/lr rule.
- transfer_init_std(base_std, base_width, target_width, *, role='hidden')[source]
Rescale
base_std(tuned/measured atbase_width) to the muP init std attarget_width.
- transfer_lr(base_lr, base_width, target_width, *, role='hidden')[source]
Rescale
base_lr(tuned atbase_width) to the muP-predicted optimum attarget_width.This is the deliverable that “collapses the ladder’s tuning bill”: tune
role="hidden"lr once, cheaply, at a smallbase_width, then call this to predict the optimal lr at any largertarget_widthwith (ideally) no further search. Defaults torole="hidden"– the dominant parameter group (attention + MLP) and the one muP’s headline lr-transfer guarantee is about.
- stream_fit(module, token_source, *, lr=3e-3, device='cpu', report_every=200, log=None)[source]
Train one persistent-optimizer step per streamed micro-batch without buffering the corpus.
- class GrammarLearningResult(model, history, validation_history=None)[source]
Bases:
FitResult[HeterogeneousPCFGDistribution]Fitted PCFG plus training and optional validation log-likelihood history.
- class HamiltonianNet(dim, hidden=(64, 64), *, separable=True)[source]
Bases:
objectLearns a scalar
H(q, p)and exposes the symplectic-gradient dynamics it implies.dimis the dimension ofq(and ofp, always equal);hiddensizes the network computingH. By default the network is masked into independentV(q)andT(p)branches whose scalar outputs are summed, making the supported leapfrog premise structural rather than advisory. Setseparable=Falseonly when learning a general Hamiltonian that will be integrated by another method.module(the underlyingtorch.nn.Module) is exposed directly for training with an ordinary optimizer loop against derivative-matching data.- hamiltonian(q, p)[source]
H(q, p), shape(...,)– squeezes the module’s scalar output dimension.
- time_derivative(q, p)[source]
(dq/dt, dp/dt) = (dH/dp, -dH/dq)via autograd – the symplectic gradient ofhamiltonian.q/pmust be leaf tensors (requires_grad_(True)) or already part of an active graph; the returned derivatives carry gradients back throughself.module’s parameters, so this composes into a training loop that fits derivative-matching data end to end.
- class HardEMResult(model, history, validation_history=None)[source]
Bases:
FitResult[StochasticBlockGraphModel]Result from hard-EM fitting of a stochastic block model.
- class KnowledgeGraphFitResult(model, history, validation_history=None)[source]
Bases:
FitResult[TransEKnowledgeGraphModel]Result from TransE margin fitting.
- class PartiallyObservableMarkovDecisionProcessFilterResult(beliefs, log_likelihood, predictive_observation_probs, possible=True, impossible_at=None)[source]
Bases:
objectBelief trajectories, log likelihood, and predictive observation terms.
- class PartiallyObservableMarkovDecisionProcessFitResult(model, history, validation_history=None)[source]
Bases:
FitResult[PartiallyObservableMarkovDecisionProcessModel]Baum-Welch style fit result for known-action PartiallyObservableMarkovDecisionProcess sequences.
- class PartiallyObservableMarkovDecisionProcessModel(transition, observation, initial_belief=None, rewards=None, name=None)[source]
Bases:
objectFinite-state PartiallyObservableMarkovDecisionProcess with action-conditioned transitions and observations.
transition[a, i, j]is P(S_t=j | S_{t-1}=i, A_t=a).observation[a, j, o]is P(O_t=o | S_t=j, A_t=a).- Parameters:
transition (Any)
observation (Any)
initial_belief (Any | None)
rewards (Any | None)
name (str | None)
- belief_update(belief, action, observation)[source]
Update a belief after taking
actionand seeingobservation.
- filter(actions, observations, initial_belief=None)[source]
Run the forward filter and return posterior beliefs and log likelihood.
- sequence_log_likelihood(actions, observations, initial_belief=None)[source]
Return log P(observations | actions, model).
- forward_backward(actions, observations, initial_belief=None)[source]
Return state marginals, transition marginals, and sequence log likelihood.
- predict_observation(belief, action)[source]
Return P(O_t | belief, action) before observing O_t.
- expected_reward(belief, action)[source]
Return E[R | belief, action] when rewards were supplied.
- class PartiallyDirectedGraph(directed_edges, undirected_edges, variable_names)[source]
Bases:
objectPartially directed graph after collider orientation.
- class PCFGParseNode(label, span, log_prob, rule_index, rule_type, children=(), value=None)[source]
Bases:
objectNode in a Viterbi parse tree.
- Parameters:
- class PINNRegression(module, residual_fn, domain, *, problem, noise=1.0, residual_weight=1.0, n_collocation=64, m_steps=40, lr=0.01, seed=0, name=None, device=None, constraint_receipt=None)[source]
Bases:
NeuralGaussianNeuralGaussianplus a PDE/ODE-residual penalty evaluated on sampled collocation points.domainis a(low, high)pair of per-dimension box bounds for collocation sampling;residual_fncomputes the physics residual (see module docstring);residual_weightscales the penalty relative to the data-fit NLL;n_collocationis how many collocation points are drawn fresh every M-step.- Parameters:
- estimator(pseudo_count=None)[source]
Return the estimator that combines weighted data fit with residual collocation penalties.
- Parameters:
pseudo_count (float | None)
- Return type:
PINNRegressionEstimator
- dist_to_encoder()[source]
Return the neural-Gaussian encoder for
(x, y)observation pairs.- Return type:
NeuralGaussianEncoder
- to_dict()[source]
Serialize the module, residual function reference, domain, and PINN hyperparameters.
- class PINNRegressionEstimator(module, residual_fn, domain, *, problem, noise=1.0, residual_weight=1.0, n_collocation=64, m_steps=40, lr=0.01, seed=0, name=None, device=None)[source]
Bases:
NeuralGaussianEstimatorEM estimator for
PINNRegression: the M-step adds a residual penalty on fresh collocation points to the same weighted-NLL gradient descentNeuralGaussianEstimatorruns.Collocation sampling is deterministic given
seed(a privatenumpy.random.RandomState, advanced once per M-step) – refitting with the same seed draws the same collocation batches.- Parameters:
- accumulator_factory()[source]
Return the neural-Gaussian accumulator factory for weighted observation pairs.
- Return type:
NeuralGaussianAccumulatorFactory
- class PINNProblemSpec(equation, coordinates, fields, residual_components, constraints, identifiability_conditions, constraint_enforcement, completeness_basis)[source]
Bases:
objectExplicit mathematical and enforcement schema for a PINN fit.
- Parameters:
- class PINNConstraintReceipt(status, equation, constraint_enforcement, constraints, identifiability_conditions, completeness_basis, labeled_constraints, residual_loss_initial, residual_loss_final)[source]
Bases:
objectDurable declaration and measured outcome of a constraint-aware PINN fit.
- Parameters:
- class QATWrapper(*args, **kwargs)[source]
Bases:
objectTorch-absent stand-in: keeps
QATWrapperalways importable (mixle.modelsimports it unconditionally, matching every other torch-optional model in this package – seeGaussianProcessRegressor), raising only when actually constructed, since it must subclassnn.Moduleto be real andnndoes not exist here.- Parameters:
args (Any)
kwargs (Any)
- apply_qat(model, *, bits=4, clip_percentile=None, reconfigure=False)[source]
Replace every
nn.Linearundermodelin place with aQATWrapper, so the whole model trains quantization-aware (straight-through int4 fake-quant on every Linear weight, every forward call). Mirrorsmixle.experimental.program.lora’s wrapping pattern: walknamed_children, swapLinearleaves, recurse into everything else. Weight-tied layers (e.g.CausalLM.headsharingtok.weight) wrap cleanly – only the wrapped module’sforwardchanges, the underlyingnn.Parameter(and anything else pointing at it) is untouched. Returnsmodel(mutated in place) for chaining.
- fake_quantize(x, *, bits=4, clip_percentile=None)[source]
Straight-through fake-quantize
xtobits(int4 or int8, permixle.task.quantize._QMAX): forward returns the real quantize->dequantize round trip, backward passes the gradient through unchanged (STE).
- fake_quantize_int4(x, *, clip_percentile=None)[source]
fake_quantize(x, bits=4)– the int4 case this roadmap item targets.
- set_fake_quant_enabled(model, enabled)[source]
Toggle every
QATWrapperundermodelon/off in place.enabled=Falseruns the model at its real fp32 weights (e.g. to check that QAT training didn’t wreck full-precision quality);enabled=True(the default afterapply_qat()) restores the fake-quant forward. Returnsmodelfor chaining.
- class PoissonRegressionNeuralNetwork(module, engine=None, precision=None)[source]
Bases:
objectA Torch count-regression wrapper optimized by Poisson log likelihood.
The wrapped module predicts log rates. Observed counts must be non-negative and match the module output shape after one-dimensional inputs are promoted to column vectors.
- Parameters:
module (Any)
engine (Any | None)
precision (Any | None)
- parameters()[source]
Return trainable parameters of the wrapped log-rate module.
- log_rate_tensor(x)[source]
Return predicted log rates as a Torch tensor.
- log_likelihood(x, y)[source]
Return the summed Poisson count log likelihood.
- fit(x, y, max_its=500, lr=0.01, optimizer='adam', tol=1.0e-7, out=None, print_iter=100, return_result=False, restore_best=True)[source]
Maximize the Poisson count log likelihood.
- predict_rate_tensor(x)[source]
Return predicted Poisson rates as a Torch tensor.
- predict_rate(x)[source]
Return predicted Poisson rates as a NumPy array.
- class RandomForestConditional(forest, task, sigma=None, n_features=None, name=None, keys=None, forest_spec=None)[source]
Bases:
SequenceEncodableProbabilityDistributionFitted random forest viewed as a conditional distribution p(y | x).
Observations are (x, y) pairs: x is a feature vector and y is a class label (classification) or a real target (regression). seq_log_density returns log p(y | x) – predict_log_proba for classification, a Gaussian residual density with scale sigma for regression.
- Parameters:
- density(x)[source]
Return
p(y | x)for one feature/target pair.
- log_density(x)[source]
Return
log p(y | x)for one feature/target pair.
- seq_log_density(x)[source]
Return per-row conditional log densities for encoded
(X, y)data.
- sample_y(x, rng)[source]
Draw target values from the fitted conditional forest at feature rows
x.- Parameters:
x (Any)
rng (RandomState)
- Return type:
- sampler(seed=None)[source]
Return a conditional sampler for drawing targets given features.
- Parameters:
seed (int | None)
- Return type:
RandomForestConditionalSampler
- estimator(pseudo_count=None)[source]
Return an estimator preserving the fitted model’s complete specification.
- Parameters:
pseudo_count (float | None)
- Return type:
RandomForestEstimator
- dist_to_encoder()[source]
Return the encoder for feature/target observation pairs.
- Return type:
RandomForestEncoder
- class RandomForestEstimator(task=None, n_estimators=100, max_depth=None, min_samples_split=2, min_samples_leaf=1, max_features='auto', random_state=None, min_sigma=1.0e-3, name=None, keys=None, n_features=None)[source]
Bases:
ParameterEstimatorEstimator that fits a native (numpy) random forest as a conditional leaf.
task is explicitly ‘classification’ or ‘regression’; target dtype is never used to guess semantics. The forest hyperparameters (n_estimators, max_depth, min_samples_split, min_samples_leaf, max_features, random_state) are passed straight to the native ensemble. estimate() trains in one pass on the accumulated weighted data; there is no EM iteration, so drive it with optimize(max_its=1) or call the seq_encode / accumulate / estimate path directly.
- Parameters:
- accumulator_factory()[source]
Return an accumulator factory for weighted feature/target buffers.
- Return type:
RandomForestAccumulatorFactory
- class StochasticBlockGraphModel(block_probs, block_assignments, directed=False, self_loops=False, name=None)[source]
Bases:
objectBernoulli stochastic block model with fixed node assignments.
- Parameters:
- classmethod fit_mle(adjacency, block_assignments, num_blocks=None, directed=False, self_loops=False, pseudo_count=0.0, prior_p=0.5, name=None)[source]
Thin shim delegating to
fit_stochastic_block_mle(kept for the classmethod-fit call API).
- log_likelihood(adjacency)[source]
Return the Bernoulli SBM log likelihood.
- sample(seed=None)[source]
Draw one graph from the block model.
- class TransEKnowledgeGraphModel(entity_embeddings, relation_embeddings, entity_names=None, relation_names=None, name=None)[source]
Bases:
objectDependency-free TransE model with a NumPy margin objective.
- Parameters:
entity_embeddings (Any)
relation_embeddings (Any)
entity_names (Sequence[Any] | None)
relation_names (Sequence[Any] | None)
name (str | None)
- classmethod random(num_entities, num_relations, embedding_dim=16, seed=None, scale=0.01, entity_names=None, relation_names=None, name=None)[source]
Create a randomly initialized model.
- distance_triples(triples)[source]
Return squared TransE distances ||h + r - t||^2.
- score_triples(triples)[source]
Return TransE scores; higher is more plausible.
- margin_loss(positive_triples, negative_triples, margin=1.0)[source]
Return the pairwise TransE ranking loss.
- negative_sample(triples, seed=None, corrupt='tail', *, known_triples=None)[source]
Produce filtered corruptions that are not any supplied known true triple.
- fit_margin(positive_triples, negative_triples=None, margin=1.0, lr=0.01, max_its=100, seed=None, normalize_entities=True)[source]
Fit embeddings with simple stochastic subgradient descent.
- class TruncatedDirichletProcessMixtureFitResult(model, responsibilities, history, objective_name='truncated_dp_elbo')[source]
Bases:
objectFitted truncated DPM plus variational responsibilities and history.
- class TruncatedDirichletProcessMixtureModel(components, alpha=1.0, gamma=None, weights=None, name=None)[source]
Bases:
objectTruncated stick-breaking mixture over existing mixle component models.
- Parameters:
- property expected_log_weights: ndarray
Return E_q[log pi_k] under the variational stick posteriors.
- component_log_density(x)[source]
Return component log densities for one observation.
- log_density(x)[source]
Return the finite-truncation mixture log density for one observation.
- density(x)[source]
Return the finite-truncation mixture density for one observation.
- responsibilities(data, expected=True)[source]
Return posterior component probabilities for observations.
- effective_components(threshold=0.01)[source]
Count components with posterior mean stick weight above
threshold.
- baum_welch_pomdp(sequences, num_states, num_actions, num_observations, initial_model=None, max_its=50, tol=1.0e-8, pseudo_count=1.0e-3, seed=None)[source]
Fit a known-action finite PartiallyObservableMarkovDecisionProcess by Baum-Welch/EM.
- Parameters:
- Return type:
PartiallyObservableMarkovDecisionProcessFitResult
- discrete_conditional_mutual_information(data, x, y, given=())[source]
Estimate I(X;Y | Z) from categorical samples using empirical counts.
- expected_log_stick_weights(gamma)[source]
Return E_q[log pi_k] for truncated Beta stick posteriors.
- fit_erdos_renyi_mle(adjacency, directed=False, self_loops=False, pseudo_count=0.0, prior_p=0.5, name=None)[source]
Conjugate-Bernoulli MLE of the edge probability (module-level estimation, not a classmethod-fit).
- fit_stochastic_block_mle(adjacency, block_assignments, num_blocks=None, directed=False, self_loops=False, pseudo_count=0.0, prior_p=0.5, name=None)[source]
Conjugate-Bernoulli MLE of block edge probabilities for fixed assignments (module-level estimation).
- fit_truncated_dpm(data, initial_components, component_estimator, alpha=1.0, max_its=50, tol=1.0e-8, sort_components=True, name=None)[source]
Fit a truncated DP mixture by coordinate-ascent variational updates.
The component M-steps are delegated to ordinary
mixle.statsestimators. Components are point-estimated parameters;historyis the complete truncated-stick ELBO over assignments and Beta sticks conditional on those point estimates (expected likelihood + assignment entropy - stick KL).- Parameters:
- Return type:
TruncatedDirichletProcessMixtureFitResult
- fit_induced_pcfg(data, terminal_estimators, max_nonterminals, initial_model=None, vdata=None, max_its=10, init_p=1.0, seed=None, terminal_rule_mass=0.5, rule_pseudo_count=1.0e-3, prune_threshold=0.0, min_rule_prob=0.0, start='S', name=None)[source]
Fit an induced heterogeneous PCFG and track train/validation likelihoods.
- Parameters:
terminal_estimators (Sequence[ParameterEstimator])
max_nonterminals (int)
initial_model (HeterogeneousPCFGDistribution | None)
max_its (int)
init_p (float)
seed (int | None)
terminal_rule_mass (float)
rule_pseudo_count (float | None)
prune_threshold (float)
min_rule_prob (float)
start (Any)
name (str | None)
- Return type:
GrammarLearningResult
- gaussian_conditional_independence(data, x, y, given=(), alpha=0.05, ridge=1.0e-10)[source]
Fisher-z Gaussian conditional independence test.
- gaussian_partial_correlation(data, x, y, given=(), ridge=1.0e-10)[source]
Return partial correlation rho_xy.given for continuous data.
- grammar_rule_table(model)[source]
Return a flat, inspectable rule table for learned PCFGs.
- hard_em_stochastic_block_model(adjacency, num_blocks, max_its=20, restarts=1, seed=None, directed=False, self_loops=False, pseudo_count=1.0, prior_p=0.5)[source]
Classification/hard-EM fit for a stochastic block model.
- leapfrog_rollout(net, q0, p0, dt, n_steps)[source]
Leapfrog integration of
net’s learned (or untrained) Hamiltonian flow.Returns
(qs, ps), each shaped(n_steps + 1, *q0.shape)– the trajectory including the initial state. This scheme is available only whennet.is_separableis true. A symplectic integrator is the right numerical counterpart to a conservative continuous-time system: unlike a generic (e.g. Euler) integrator, its energy error stays bounded and oscillates rather than drifting monotonically over long rollouts.
- learn_pc_skeleton(data, variable_names=None, alpha=0.05, max_cond_set=2, method='gaussian')[source]
Learn a PC-style undirected skeleton from conditional independences.
- build_autoregressive_categorical(dim, n_categories, *, hidden=64)[source]
An autoregressive neural density over discrete vectors
x in {0..C-1}^dim– exact, normalizedp(x).The continuous flows/VAE above model
R^d; heterogeneous data is also categorical. This factorizesp(x) = prod_i p(x_i | x_{<i})with a MADE-masked network whose per-coordinate softmax is each conditional, so the density is exactly normalized (sums to 1 over the finite space) and can be compared directly with count/categorical families.log_densitysums the picked log-softmax logits;samplefills the vector one coordinate at a time. Another ready module forNeuralDensity; the adapter is unchanged.
- build_contrastive_projection(d_x, d_y, *, encoder_x=None, encoder_y=None, proj_dim=None, hidden=64, freeze_encoders=True, temperature=0.07)[source]
Build a contrastive projection/ranker between two embedding spaces.
This is the stage-1 multimodal pattern – frozen encoder -> trainable projection -> frozen encoder – stated with no domain nouns.
encoder_x/encoder_yare any torch module mapping a raw item to ad_x/d_yembedding; both default tonn.Identity(), sox/ymay already BE the embeddings (pass precomputed vectors straight in, no backbone required). Encoders are frozen by default (freeze_encoders=True): their parameters getrequires_grad_(False)and the module is pinned ineval()regardless of the outertrain()/eval()calls the M-step makes, so no dropout/batchnorm noise leaks into a “frozen” backbone and no gradient ever reaches it. The only trainable piece is a small projection head per side (d_x/d_y->hidden->proj_dim, defaultproj_dim = min(d_x, d_y)) mapping BOTH embeddings into one shared, L2-normalized space – the CLIP design (two projections into a shared space), not a single asymmetricx -> yregression – so the same leaf answers “which y matches this x” and “which x matches this y”.contrastive_lossis a symmetric weighted InfoNCE objective over a complete paired batch. Anchor weights and the two candidate/negative measures are explicit and independently validated, so responsibilities are never applied only after cross-row negative contributions have already been formed.score_pairsandsimilarity_matrixare batch-independent retrieval surfaces.This object intentionally has no
log_densityorsample_givenmethod: a contrastive batch objective is not a normalized per-observation probability distribution and cannot be composed into mixture/HMM EM.
- build_conditional_autoregressive_categorical(x_dim, y_dim, n_categories, *, hidden=64)[source]
An autoregressive categorical conditioned on
x: exactp(y | x)over discretey in {0..C-1}^y_dim.The conditional sibling of
build_autoregressive_categorical()and the discrete counterpart tobuild_conditional_flow(). It factorizesp(y | x) = prod_i p(y_i | y_{<i}, x)with a MADE-masked net overyinto whichxis injected unmasked (degree 0, so every coordinate may depend onx). Each per-coordinate softmax is exactly a conditional, so the density is exactly normalized and comparable to other exact discrete conditional leaves. Exposeslog_density(x, y)andsample_given(x)– the contract aNeuralConditionalDensityadapts.
- build_conditional_flow(x_dim, y_dim, *, hidden=32, layers=4)[source]
A conditional coupling flow: an exact
p(y | x)whose transform ofyis conditioned onx.The exact-density counterpart to
build_mdn(). Each affine-coupling layer’s shift/scale networks take both the passed-throughycoordinates andx, so the whole invertibley-transform bends with the input – capturing within-``y`` dependence (e.g.y2a nonlinear function ofy1) that a single-GaussianNeuralGaussian(isotropic mean-only) cannot, while keeping an exact log-density rather than a bound. Needsy_dim >= 2for the coupling to be non-trivial. Exposeslog_density(x, y)andsample_given(x)– the contract aNeuralConditionalDensityadapts.
- build_convex_energy_net(dim, *, hidden=64, layers=3)[source]
An input-convex MLP energy
E(x): R^dim -> R, convex inxBY CONSTRUCTION – ready to wrap in anEnergyModelexactly likebuild_energy_net(). A convex energy gives Langevin sampling (EnergyModelSampler) a unimodal target with no spurious local minima to get stuck in, and gives any consumer of the fitted energy a certified-convex scalar-valued potential (e.g. a verified optimum for a downstreammixle.doesearch over-E(x)). See_convex_energy_net_class()for the construction.
- build_coupling_flow(dim, *, hidden=32, layers=4)[source]
A RealNVP coupling flow over
R^dimwith an exactlog_density(x)andsample(n)– ready to wrap.Alternating affine-coupling layers map data to a standard-normal base;
log_densityis the base log-prob plus the log-determinant of the (triangular) Jacobian. A minimal, correct instance of the density module aNeuralDensityadapts – swap in any other module with the same two methods.
- build_energy_net(dim, *, hidden=64, layers=3)[source]
An MLP energy
E(x): R^dim -> Rplus a learned scalar normalization offset.Lower energy = higher unnormalized density.
log_normuses the-log Zconvention, so the pairedEnergyModelscores-E(x) + log_norm. Swap in any module exposingenergy(x) -> (n,), a scalarlog_normparameter, and adimattribute.
- build_maf(dim, *, hidden=64, blocks=3)[source]
A masked autoregressive flow over
R^dim– an exact density that factorizesp(x)by the chain rule, eachp(x_i | x_{<i})an affine map with autoregressive (MADE-masked) mean and log-scale.Unlike the coupling flow it conditions every coordinate on all earlier ones (a richer autoregressive dependence), and unlike the VAE its
log_densityis exact. It can therefore be compared directly with a Gaussian, a flow, or another exact-density leaf. Sampling is the sequential inverse (one coordinate at a time). Another ready module forNeuralDensity; the adapter is unchanged.
- build_mdn(x_dim, y_dim, *, k=5, hidden=32, layers=2)[source]
A mixture density network:
p(y | x) = sum_k pi_k(x) N(y; mu_k(x), diag sigma_k(x)^2)– ready to wrap.A shared MLP body maps
xto three heads – mixing logits, component means, and (log) component scales – so the entire conditional law is a function ofx: multimodal (severalmu_k) and heteroscedastic (input-dependentsigma_k). Exposeslog_density(x, y)(a log-sum-exp over components) andsample_given(x)(pick a component bypi, then a Gaussian), the contract aNeuralConditionalDensityadapts.
- build_product_energy_net(experts)[source]
Combine expert energy modules multiplicatively: one module with
energy(x) = sum_k experts[k].energy(x).A product of experts,
p(x) ∝ prod_k p_k(x)– a conjunction (each expert a soft constraint, the product their intersection), as opposed to a mixture’s disjunction. This is the ENERGY-BASED, arbitrary-density complement tomixle.ops.product_of_experts(), which pools tractable families (Categorical, Gaussian) in closed form but deliberately raises on the general continuous case because the product normalizer is then intractable. That intractable normalizer is exactly what the energy stack already handles: wrap the result here in anEnergyModelto fit the sharedlog_normby NCE and sample by Langevin, no new machinery.Each expert must expose
energy(x) -> (n,)and adimattribute (e.g. anybuild_energy_net()/build_convex_energy_net()module, all sharing one input dim), and stays individually inspectable via the built module’s.experts/.expert_energies(x). Fit it in one line:model = EnergyModel(build_product_energy_net([expert_a, expert_b]), m_steps=250)
- build_projection_leaf(d_x, d_y, *, encoder_x=None, encoder_y=None, proj_dim=None, hidden=64, freeze_encoders=True, temperature=0.07)[source]
Compatibility spelling for
build_contrastive_projection(); the result is not a distribution leaf.
- build_vae(dim, *, latent=2, hidden=32, eval_samples=16)[source]
Build a variational autoencoder over
R^dim.An amortized encoder
q(z | x)and a decoderp(x | z)(diagonal-Gaussian, learned observation scale) are trained by the ELBO with the reparameterization trick. This is a different family from a flow: structure is represented through a low-dimensional latent rather than an invertible map, while the sameNeuralDensityadapter can still use it because it exposes the same two methods.At evaluation,
log_density(x)returns a deterministic Monte Carlo estimate of the ELBO usingeval_samplesfixed local draws fromq(z | x).elbo_estimate(x)returns that estimate together with its Monte Carlo standard error. It is an estimate of a lower bound, not an exact log density and not itself guaranteed to remain belowlog p(x)at finite sample count. Compare VAE leaves with other bounded leaves whenever possible. Training uses fresh reparameterized samples for an unbiased gradient.
- make_deep_set(element_dim, phi_hidden, latent_dim, rho_hidden, output_dim=1, *, pooling='mean')[source]
A Deep Sets network (Zaheer et al. 2017): invariant to any permutation of the set axis, by construction.
Input shape
(..., set_size, element_dim): a per-element MLPphi(shared weights, applied identically to every element –torch.nn.Linearalready broadcasts over all leading dims, so reusingmake_mlp()forphigives exactly that) maps each element to alatent_dimcode; a permutation-invariant pool (pooling="mean"/"sum"/"max", taken over the set axis) aggregates the codes into one order-independent summary; a second MLPrhomaps the summary to the output. Becausephiis applied identically per element and the pool is a symmetric function, the output is exactly unchanged by any permutation of the set axis – true for any weights, trained or not, unlike e.g. training on many random orderings and hoping the network learns invariance.The returned module is a plain
torch.nn.Module, trainable with any ordinary Torch optimizer loop over(set_size, element_dim)-shaped inputs. Note:NeuralGaussian’s accumulator flattens each observation to a 1-D feature vector (reshape(n, -1)) before the M-step, which destroys the set axis this module needs – so it is not a drop-in wrapper for set-shaped data asmake_mlp()/make_monotonic_mlp()are for flat feature vectors. Use this module directly with a custom training loop (or through a wrapper that preserves the set axis) for a fixed set size.
- make_mlp(input_dim, hidden_dims, output_dim=1, activation='tanh')[source]
Create a simple fully connected Torch MLP.
- make_monotonic_mlp(input_dim, hidden_dims, output_dim=1, *, increasing=True)[source]
A fully connected Torch MLP that is monotonic in every input dimension jointly, BY CONSTRUCTION.
Each layer’s weight matrix is reparameterized through
softplusbefore use, so every weight is strictly non-negative; composed with the (smooth, strictly increasing)Softplusactivation, a non-negative-weight affine map followed by an increasing activation is itself increasing, and that property is closed under composition – so the whole network is provably non-decreasing in every input coordinate, with no penalty term and no post-hoc check needed.increasing=Falsenegates the output, giving a network non-increasing in every coordinate instead.This is a hard architectural constraint (unlike
PINNRegression’s soft residual penalty): the guarantee holds at every point in input space, not just where training data landed. Drops into the same wrappers asmake_mlp()–NeuralGaussianfor regression,NeuralCategoricalfor classification – no other changes needed. Only jointly monotonic in ALL inputs; a network monotonic in some coordinates and free in others needs a two-path (monotonic + unconstrained) variant, not built here.
- mean_stick_weights(gamma)[source]
Return E_q[pi_k] under independent Beta stick posteriors.
- orient_v_structures(skeleton)[source]
Build a deterministic, conflict-checked CPDAG from skeleton and separating evidence.
- Parameters:
skeleton (CausalSkeleton)
- Return type:
PartiallyDirectedGraph
- pcfg_log_likelihood(model, data)[source]
Return total PCFG log likelihood on raw sequences.
- sample_crp_assignments(num_obs, alpha, seed=None)[source]
Sample Chinese-restaurant-process assignments and table counts.
- stick_breaking_weights(stick_fractions, residual=True)[source]
Convert stick fractions into mixture weights.
When
residualis true, the returned vector has one extra final entry containing the remaining stick mass. This is the usual finite truncation.
- viterbi_parse(model, sequence)[source]
Return the maximum-probability CKY parse under a heterogeneous PCFG.
Submodules¶
- mixle.models.coarsening module
- mixle.models.compress module
- mixle.models.continual module
- mixle.models.dependence module
- mixle.models.dirichlet_process_mixture module
- mixle.models.dpo_leaf module
- mixle.models.embedding module
- mixle.models.energy module
- mixle.models.eval_harness module
- mixle.models.feature_map module
- mixle.models.gaussian_process module
- mixle.models.grad_leaf module
- mixle.models.grammar module
- mixle.models.hamiltonian module
- mixle.models.knowledge_graph module
- mixle.models.language_model module
- mixle.models.memory_efficient_training module
- mixle.models.mixture_density module
- mixle.models.moe module
- mixle.models.moment_propagation module
- mixle.models.mup module
- mixle.models.neural module
- mixle.models.neural_density module
- mixle.models.neural_families module
- mixle.models.neural_leaf module
- mixle.models.optimizer_routing module
- mixle.models.partially_observable_markov_decision_process module
- mixle.models.pinn module
- mixle.models.qat module
- mixle.models.quotient module
- mixle.models.random_forest module
- mixle.models.random_graph module
- mixle.models.self_distillation module
- mixle.models.sigma_weighted_projection module
- mixle.models.softmax_leaf module
- mixle.models.sorted_profile_quantizer module
- mixle.models.sparse_gaussian_process module
- mixle.models.sparsity_2_4 module
- mixle.models.streaming_transformer_leaf module
- mixle.models.train_search module
- mixle.models.transformer module
- mixle.models.unified_quantizer module