mixle.enumeration.seek_index module¶
A persistent count-budget enumeration index: precompute once, then unrank/count/slice many times.
The one-shot drivers (count_budget_index(),
count_dp_seek(), the AutoregressiveEnumerable convenience
methods) rebuild the structural count DP on every query – fine for a single lookup, wasteful for the
common pattern of many queries against one model (seek a thousand ranks, sweep thresholds, page through the
support). For a transformer LM every rebuild re-walks the whole live prefix tree in Python even when the
forward passes are memoized.
SeekIndex is the reusable precomputation structure:
built once – the fine count histogram and its structural unranker are computed at a depth (bit budget) and kept;
queried many times –
unrank/slice/iter_from/count/threshold/rank_bracketall read the stored tables (a query costs an O(log #bins) bisect plus one structural unrank walk, never a DP rebuild);deepened in place – a query past the built depth triggers one rebuild at a geometrically deeper budget (models that memoize their evaluations, e.g. the autoregressive adapter’s forward cache, make the re-walk much cheaper than the first build).
Approximation contract: identical to the underlying count DP – the bin assignment is quantized (ordering
is exact up to the fine-bucket width) and, for the tropical Mixture/HMM indices, counts are the structural
upper bound documented on those families. With count_mode='float' the counts themselves are float64
(exact below 2**53, ~1e-16 relative error per operation beyond); every unranked value still carries its
exact log_density.
- class SeekIndex(model, *, bin_width_bits=1.0, oversample=8, count_mode='exact', max_depth_bits=4096.0)[source]
Bases:
objectBuild a model’s count-budget index once and answer many enumeration queries against it.
modelis anything implementing the count-index contract – every mixle distribution with aquantized_count_index(Composite/Sequence/Markov exactly; Mixture/HMM as the documented tropical bound) andAutoregressiveEnumerable(so LLMs plug in).Queries auto-deepen: asking for a rank (or a log-prob threshold) beyond the built depth rebuilds the DP at a geometrically larger budget, reusing whatever the model itself memoizes.
max_depth_bitscaps the deepening; past it, queries raiseIndexErrorfor out-of-range ranks.- Parameters:
- property built_bits: float
The depth (bit budget) the index is currently built to (0 before the first build).
- property truncated: bool
True when values beyond the built depth exist (deepening can still grow the index).
- property builds: int
How many times the structural DP has been (re)built – the cost a persistent index amortizes.
- property dropped_upper: float
Certified upper bound on in-budget values excluded by an approximation knob (e.g.
branch_cap).0.0 for exhaustive indices. The true in-budget count lies in
[len(self), len(self) + dropped_upper]; deepening does not recover these (that is what distinguishes it fromtruncated).
- ensure_bits(depth_bits)[source]
Make the index cover at least
depth_bitsof information (build or deepen if needed).- Parameters:
depth_bits (float)
- Return type:
SeekIndex
- ensure_count(n)[source]
Make the index hold at least
nvalues (geometric deepening from the current depth).Every rebuild at least doubles the built depth, so an ascending sequence of queries costs O(log) rebuilds total and the final (deepest) build dominates the work – the amortization a persistent index exists for.
- Parameters:
n (int)
- Return type:
SeekIndex
- unrank(i)[source]
The
i-th most probable value (0-based, quantized order) and its exact log-probability.
- slice(start, k)[source]
Up to
kvalues starting at rankstart(one deepen at most, then table reads).
- iter_from(start=0)[source]
Iterate values from rank
startthrough the end of the built index (no auto-deepen).
- count(min_log_prob)[source]
How many values have
log_density >= min_log_prob– read off the fine histogram.Exact-carrier families return an
int;count_mode='float'(or a float-carrying model like the deep-budget autoregressive fast path) returns a float with the documented relative error. Mixture/HMM counts are the structural (tropical) upper bound those families document.
- threshold(rank)[source]
Log-probability of the
rank-th most probable value (the top-rankboundary).
- rank_bracket(value)[source]
A
[lo, hi]bracket onvalue’s quantized rank, from its structural fine bucket.locounts every value in strictly shallower buckets;hiadds the rest of the value’s own bucket. For Mixture/HMM the bucket is the documented tropical projection, so the bracket carries that projection’s semantics (see the family docstrings).