TokenTrieModel is a high-throughput, adaptive unsupervised sequence prediction engine based on Variable Order Markov Models (VOMM) and Context Mixing, implemented over an unboxed Reverse Suffix Trie and accelerated via native Cython / C-level primitives.
Engineered for streaming sequential data, continuous edge learning, and high-frequency inference, TTM models arbitrary discrete token distributions (
- Mathematical Formulation & Problem Statement
- Core Architecture & Algorithmic Mechanics
- Architectural Comparison: TTM vs. Neural & Classical Baselines
- Empirical Benchmarks & Scientific Validation
- Installation & Build Requirements
- API Quickstart & Production Patterns
- Comprehensive Configuration Guide
- License & Citation
Let
Under causal autoregressive constraints, the predictive objective is to estimate the next-token conditional probability distribution:
conditioned strictly on the historical working memory:
to minimize cumulative online logarithmic cross-entropy loss without offline retraining:
Classical
-
High Bias (
$N \le 2$ ): Low-order chains are fundamentally blind to non-local temporal parity dependencies, failing on multi-symbol periodic trajectories and distant horizon tasks. -
Combinatorial Explosion (
$N \ge 5$ ): Full transition tables scale exponentially with state space complexity$\mathcal{O}(|\mathcal{V}|^N)$ . In an alphabet of size$|\mathcal{V}| = 10^4$ , a 4-gram table demands$10^{16}$ parameters, rendering dense representation intractable. - Sample Sparsity: In non-stationary environments, fixed-order contexts frequently encounter unobserved transitions, necessitating heuristic backoff cascades.
The Solution: Variable Order Markov Models (VOMM) adaptively prune context depth per-branch, allocating memory exclusively along observed trajectory paths and interpolating active horizons via Context Mixing.
[ Root: TokenTrieNode ] (Depth 0)
/ | \
'c' 'b' 'a' <- Suffix token x_{t-1}
/ \ |
'b' 'a' 'a' <- Suffix token x_{t-2}
/
'a' <- Suffix token x_{t-3}
|
[ Node: Counts = { Target_y : Weight } ]
Conventional prefix trees store contexts chronologically (
TTM stores preceding tokens in reverse chronological order:
During inference, a single sequential descent matches all valid suffix context orders
Rather than executing hard decision trees, TTM blends observations across all active context lengths valid_lengths). For each node along the matched reverse suffix path of length
Where:
-
$\text{Count}(c \to y)$ is the empirical transition frequency. -
$\gamma \in (0, 1]$ is the temporal exponential forgetting rate (decay). -
$\Delta t(c) = t_{\text{curr}} - t_{\text{last}}(c)$ is the elapsed timeline offset. -
$\mathcal{B}(\mathcal{V})$ is the Dynamic Vocabulary Entropy Base:
(configured via alphabet_autoscale=True).
This logarithmic scaling factor ensures that longer, more specific context matches exponentially dominate shorter, ambiguous fallbacks while gracefully preserving predictive mass.
To prevent numerical underflow and precision collapse across disparate context lengths, log-potentials are accumulated via a pairwise LogSumExp reduction implemented directly in Cython over libc.math (via c_log1p and c_exp):
The aggregate log-score for candidate token
Normalized probability distributions under temperature scaling
In non-stationary streaming distributions, models with infinite static memory suffer from severe hysteresis. TTM implements Lazy Exponential Decay:
- Transition counts are stored as static floats during active updates.
- Weight degradation (
$w = w_0 \cdot \gamma^{\Delta t}$ ) is deferred until a node is explicitly traversed. - Mathematical evaluation is accelerated via an
$O(1)$ precomputed integer power cache (_power_cache) and integer logarithm cache (_int_log_cache) bounded bycache_size. -
Skip-Decay Accelerator: When
$\gamma = 1.0$ ordecay=None, timeline delta tracking and floating-point power routines are completely bypassed (skip_decay=True), achieving maximum native execution speeds for stationary tasks.
If the working context min_depth):
-
katz_backoff: Gracefully falls back to global unigram counts, with individual token frequencies independently decayed against their dedicated timeline tracking timestamps (unigram_last_update). -
uniform: Allocates equal mass:$P(y) = \frac{1}{|\mathcal{V}|}$ .
For environments with sensor noise, typos, or omitted tokens, TTM implements breadth-first search (masked_mode in {'linear', 'squared'}) bounded by max_beams.
linear: Explores wildcards exclusively at the suffix boundary (Phase 0), locking into strict path matching (Phase 1) upon the first structural token hit.squared: Explores branching wildcard substitutions across internal positions, scoring alignments by effective matching length.
| Architectural Dimension | TokenTrieModel (TTM) | Transformers (LLMs) | Recurrent NNs (GRU/LSTM) | Classical |
|---|---|---|---|---|
| Learning Paradigm | Unsupervised / Online | Self-Supervised (Pre-train) | Supervised / BPTT | Unsupervised / Counting |
| Online Adaptation | Requires Fine-Tuning / LoRA | Backprop through time |
|
|
| Cold-Start Delay | Zero (Step 1 Ready) | Heavy (Pre-training required) | High (Requires epochs) | Zero |
| Inference Latency |
|
|||
| Memory Footprint | Sparse |
Gigabytes / Terabytes (VRAM) | Fixed Hidden State Size | Exponential $\mathcal{O}( |
| Interpretability | 100% Deterministic Counts | Black-box latent weights | Black-box hidden vectors | Transparent |
| Surgical Control | Inject / Delete branches | None (Prone to hallucinations) | None | Full |
| Hardware Target | Single CPU Core / Edge MCU | High-end GPU Clusters | Edge / Server GPU / CPU | CPU RAM |
To evaluate real-world sequential utility, TTM was benchmarked on an on-device T9 Mobile Autocomplete Engine trained on clean literary prose (Tolstoy, Dostoevsky) utilizing subword BPE tokenization.
The model preserves preceding completed words as atomic history tokens while actively typed character prefixes are compressed via BPE and prefixed with a collision-free marker:
High-speed keystroke querying is achieved by terminating linear probability scans early over pre-sorted log-logits (return_log_scores=True), dropping query latency from
================================================================================
T9 TEST SET EVALUATION REPORT
================================================================================
Training Corpus (80% Split) : 159,174 Sentences (15.2 MB / 2.85M words)
Training Throughput : 230.38 sentences / second
Total Active Trie Nodes : 19,422,451 nodes
Tracked Vocabulary Cardinality : 46,644 tokens
--------------------------------------------------------------------------------
Held-Out Evaluation Split (20%) : 1,000 Sentences (59,815 Keystroke Steps)
Top-1 Autocomplete Accuracy (@1) : 48.87%
Top-2 Suggestion Hit-Rate (@2) : 58.72%
Top-3 Suggestion Hit-Rate (@3) : 63.53%
Top-5 Suggestion Hit-Rate (@5) : 68.79%
Mean Reciprocal Rank (MRR@5) : 0.5660
Keystroke Savings Rate (KSR %) : 60.58%
Incompleteness-Weighted Efficiency : 30.31%
================================================================================
-
Top-$K$ Accuracy (
$\text{Acc}@K$ ): Percentage of keystrokes where target word$w_j \in \text{Top-}K(\mathcal{H}_j)$ . -
Keystroke Savings Rate (
$\text{KSR}%$ ): Physical key presses eliminated by prompt acceptance:
-
Incompleteness-Weighted Efficiency: Credits early-word predictions (
$i \ll L$ ):
All synthetic benchmarks are reproducible via examples/basic_tests.ipynb under strict zero-leakage online evaluation:
| Experiment | Generative Rule & Task | Theoretical Bound | Observed TTM Metric | Architectural Insight |
|---|---|---|---|---|
| 1. Discretized Sine Wave |
|
|
|
Disambiguates phase transitions without state space explosion. |
| 2. Pattern Drift ( |
|
Last error: |
Exponential decay reduces adaptation latency by |
|
| 3. Stochastic Bernoulli |
|
Bayes ceiling: |
|
Posterior probability converges to |
| 4. Non-Local Lag Parity |
|
Blind ( |
|
Resolves non-local parity with |
Benchmarked on AMD64 (Zen 3 Architecture, CPython 3.11.3, Windows 10) using nanosecond monotonic timing (time.perf_counter_ns):
| Primitive Operation | Throughput (ops/sec) | Mean Latency ( |
Median |
Tail |
Tail |
|---|---|---|---|---|---|
Ingestion (update) |
|||||
Inference (predict) |
|||||
Logits Scan (predict_proba) |
| Context Depth ( |
Static Throughput (kOps/s) | Decaying Throughput (kOps/s) | Decay Penalty ( |
Static |
Static |
Total Trie Nodes |
|---|---|---|---|---|---|---|
| 2 | ||||||
| 4 | ||||||
| 8 | ||||||
| 16 |
Systems Takeaway: At shallow depths (
$N \le 4$ ), tree traversal is so fast ($1.5,\mu s$ ) that floating-point math incurs measurable overhead. At operational depths ($N \ge 8$ ), tree descent dominates, rendering timeline decay math virtually zero-cost ($0.4%$ overhead).
TTM compiles directly into a native C-extension via Cython and requires a standard C99 compiler (GCC, Clang, or MSVC).
# Clone the repository
git clone https://github.com/Icold21/token-trie.git
cd token-trie
# Option A: Core Engine Only
pip install -e .
# Option B: Full Development & Benchmark Suite (Jupyter, Matplotlib, Tiktoken)
pip install -e .[full]pytest -vfrom tokentrie import TokenTrieModel
# Initialize model with maximum horizon of 5 tokens and moderate decay
model = TokenTrieModel(max_depth=5, decay=0.98)
stream = ["login", "view_cart", "checkout", "login", "view_cart", "checkout"]
for token in stream:
# 1. Query prediction prior to observation (Zero Data-Leakage)
predicted_next = model.predict(temperature=0.0) # Greedy argmax
print(f"Observed: {token:<12} | Predicted Next: {predicted_next}")
# 2. Ingest actual ground-truth token (O(1) amortized update)
model.update(token)# Extract raw, unnormalized Cython log-logits (pre-sorted descending)
log_logits = model.predict_proba(return_log_scores=True)
# Temperature-scaled probabilistic inference
stochastic_token = model.predict(temperature=0.8)
# Nucleus Sampling (Top-p: limits candidates to top 90% cumulative mass)
nucleus_token = model.predict(top_p=0.90)
# Top-K Rank Filtering
top_k_token = model.predict(top_k=3)
# Typo-tolerant inference via Masked Beam Search
resilient_token = model.predict(masked_mode="linear")Explicitly inject deterministic business logic, overwrite rules, or prune subtrees:
# Surgically inject or overwrite explicit contextual rules
model.set_branches([
(["auth", "failure", "retry"], {"lockout": 100.0, "captcha": 10.0})
])
# Sever a contextual branch and ALL its descendant subtrees permanently
model.delete_branches([
["auth", "failure", "retry"]
])
# Dynamically reconfigure horizons without cold-starting
model.reconfigure({"max_depth": 3, "decay": 1.0})Merge distributed models across heterogeneous edge timelines, depths, and decay rates:
global_server = TokenTrieModel(max_depth=3, decay=0.9)
edge_client = TokenTrieModel(max_depth=8, decay=0.999).fit(["deep", "edge", "pattern"])
# Host automatically upgrades depth bounds and mathematically projects timelines
global_server.merge(edge_client)| Parameter | Type | Default | Valid Range | Algorithmic Description |
|---|---|---|---|---|
max_depth |
int |
10 |
[1, inf) |
Maximum context horizon (Markov order) tracked in the Reverse Suffix Trie. |
min_depth |
int |
1 |
[1, max_depth] |
Minimum context length required before activating associative transitions. |
depth_list |
Optional[List[int]] |
None |
Subsets of positive integers | Tracks sparse context horizons explicitly (e.g., [2, 5, 8]) without allocating intermediate nodes. |
decay |
Optional[float] |
0.99 |
[0.0, 1.0] |
Exponential forgetting coefficient (1.0 or None to activate fast-path. |
alphabet_autoscale |
bool |
True |
{True, False} |
Dynamically calibrates entropy scaling base: $\ln \max(2, |
fallback_mode |
str |
'katz_backoff' |
{'katz_backoff', 'uniform'} |
Smoothing policy when encountering unobserved contexts. |
pruning_mode |
str |
'fixed' |
{'fixed', 'dynamic'} |
Garbage collection strategy: interval-based ('fixed') vs. node density ('dynamic'). |
pruning_step |
int |
1000 |
[1, inf) |
Step interval or target baseline for triggering tree sweeps. |
pruning_threshold |
float |
1e-6 |
[0.0, inf) |
Minimum transition weight below which nodes/counts are physically purged. |
max_beams |
int |
1000 |
[1, inf) |
Maximum queue iterations during masked beam search traversal. |
cache_size |
int |
4096 |
[1, inf) |
Capacity limit for LRU power and integer logarithm math caches. |
This project is licensed under the MIT License β see the LICENSE file for details.
@software{kholodilo2026tokentrie,
author = {Ivan Kholodilo},
title = {TokenTrieModel: High-Performance Adaptive Variable Order Markov Models via Reverse Suffix Tries},
year = {2026},
publisher = {GitHub},
url = {https://github.com/Icold21/token-trie}
}