Skip to main content

trigram-llm 🧠

A fast, production-ready Python library for next-word prediction and sentence completion, powered by a hand-written C engine using a Prefix Trie, DJB2 HashMap, and Stupid Backoff smoothing.

Sub-millisecond predictions · Zero dependencies · Pure ctypes · Thread-safe


Features

Feature Description
train_from_text(text) Train from any Python string
train_from_file(path) Train from a text file (incremental)
train_from_list(words) Train from a pre-tokenised word list
predict_next(w1, w2) Greedy single-word prediction (< 1ms)
predict_top_n(w1, w2, n, temperature) Top-N predictions with probabilities
complete_sentence(prompt, num_words, beam_width) Beam search sentence generation
greedy_generate(prompt, num_words) Fastest sentence completion
perplexity(text) Evaluate model quality on held-out text
vocabulary() Returns all known words as a Python set
get_stats() Dict with trigram count, vocab size, etc.
save(path) / TrigramModel.load(path) Binary model persistence
reset() Clear model and retrain from scratch
"the quick" in model Check if a bigram context was seen
len(model) Total number of stored trigrams
Thread-safe All predictions guarded by a threading.Lock
Context manager with TrigramModel.load(path) as m:

Installation

Prerequisites

  • Python 3.8+
  • GCC (macOS: xcode-select --install, Ubuntu: sudo apt install gcc)

Install (one command)

cd /path/to/Trigrams
pip install -e .

This compiles the C engine into trigram/_trigram_c.dylib (or .so on Linux) and installs the package in editable mode.


Quickstart

from trigram import TrigramModel

# 1. Create and train
model = TrigramModel()
model.train_from_text("""
    The quick brown fox jumps over the lazy dog.
    The quick brown fox was nimble and swift.
    The lazy dog slept peacefully under the old oak tree.
""")

# 2. Predict next word (greedy)
word = model.predict_next("the", "quick")
print(word)  # → "brown"

# 3. Top-N predictions with probabilities
preds = model.predict_top_n("the", "quick", n=3, temperature=1.0)
# [{"word": "brown", "probability": 0.75, "count": 2},
#  {"word": "red",   "probability": 0.25, "count": 1}]

# 4. Sentence completion (beam search)
completions = model.complete_sentence("the quick", num_words=4, beam_width=3)
# [{"sentence": "the quick brown fox jumps", "probability": 0.012}, ...]

# 5. Greedy generation (fastest)
sentence = model.greedy_generate("the quick", num_words=3)
# "the quick brown fox"

# 6. Evaluate quality
ppl = model.perplexity("the quick brown fox")
print(f"Perplexity: {ppl:.2f}")

# 7. Inspect model
print(len(model))          # → total trigrams
print("the quick" in model)  # → True
print(model.vocabulary())  # → {"the", "quick", "brown", ...}
print(model.get_stats())   # → {"total_trigrams": 7, "unique_first_words": 3, ...}

Training from a File

model = TrigramModel()
model.train_from_file("path/to/my_corpus.txt")

# Incremental training — add more data later
model.train_from_file("path/to/more_data.txt")

Saving and Loading Models

# Save
model.save("my_model.bin")

# Load (class method)
model2 = TrigramModel.load("my_model.bin")

# Context manager (auto-frees on exit)
with TrigramModel.load("my_model.bin") as m:
    print(m.predict_next("the", "quick"))

Temperature Sampling

The temperature parameter controls how creative predictions are:

# Deterministic — always picks the most common word
model.predict_top_n("the", "quick", temperature=0.1)

# Standard probability distribution
model.predict_top_n("the", "quick", temperature=1.0)

# More diverse / creative
model.predict_top_n("the", "quick", temperature=2.0)

Advanced Usage

Train from a word list (custom tokenisation)

import nltk
tokens = nltk.word_tokenize("The quick brown fox")
tokens = [t.lower() for t in tokens if t.isalpha()]

model = TrigramModel()
model.train_from_list(tokens)

Thread-safe batch prediction

import threading

def worker(model, results, idx):
    results[idx] = model.predict_top_n("the", "quick", n=5)

model = TrigramModel.load("model.bin")
results = [None] * 10
threads = [threading.Thread(target=worker, args=(model, results, i)) for i in range(10)]
for t in threads: t.start()
for t in threads: t.join()

Check if a context exists before predicting

if "the quick" in model:
    result = model.predict_next("the", "quick")

API Reference

TrigramModel()

Creates a new empty model.

train_from_text(text: str) → int

Train on a raw text string. Returns trigrams inserted.

train_from_file(path) → int

Train from a text file. Returns trigrams inserted.

train_from_list(words: list) → int

Train from a pre-tokenised word list. Returns trigrams inserted.

predict_next(w1, w2) → str | None

Return the single most-likely next word or None.

predict_top_n(w1, w2, n=5, temperature=1.0) → list[dict]

Return up to N predictions sorted by probability descending. Each dict: {"word": str, "probability": float, "count": int}.

complete_sentence(prompt, num_words=5, beam_width=3) → list[dict]

Generate sentence completions via beam search. Each dict: {"sentence": str, "probability": float}.

greedy_generate(prompt, num_words=5) → str

Fastest sentence completion using greedy decoding.

perplexity(text) → float

Compute per-token perplexity on held-out text. Lower = better.

vocabulary() → set[str]

All words seen in the first-word position of training trigrams.

get_stats() → dict

{"total_trigrams": int, "unique_first_words": int, "vocabulary_size": int}.

save(path) → None

Save model to binary file. Compatible with the C CLI tool.

TrigramModel.load(path) → TrigramModel (classmethod)

Load a pre-trained binary model. Supports context manager protocol.

reset() → None

Clear all training data.

len(model) → int

Total stored trigrams.

"w1 w2" in model / ("w1", "w2") in model → bool

Check if a bigram context exists.

repr(model)

TrigramModel(trigrams=11,062,203, vocab=97,277)


Performance

Operation Latency
Single word prediction < 1ms
Top-5 predictions 1–2ms
Beam search (5 words, width 3) 5–10ms
Training (1M words) ~30s

Running Tests

pip install pytest
pytest tests/ -v

Project Structure

Trigrams/
├── trigram/                  # Python library
│   ├── __init__.py
│   ├── _lib.py               # ctypes bindings
│   ├── model.py              # TrigramModel class
│   ├── utils.py              # Text preprocessing
│   └── _trigram_c.dylib      # Compiled C engine (auto-generated)
├── trigram_llm/
│   ├── src/                  # C source files
│   └── include/              # C headers
├── tests/                    # pytest test suite
├── setup.py                  # Build script
└── pyproject.toml

License

MIT License — feel free to use, modify, and distribute.

Metadata

Release files for trigram-llm 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for trigram-llm 0.1.0
File Size Uploaded Provenance Actions
trigram_llm-0.1.0.tar.gz 55.0 kB Without provenance Details for trigram_llm-0.1.0.tar.gz

Release files / trigram_llm-0.1.0.tar.gz

Download URL trigram_llm-0.1.0.tar.gz
Size 55.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6e5da04f2cfc928b2681e719fe6180e914fab96c3a13f6b29a18c63a2729a518
BLAKE2b-256 checksum
How to use checksums
d7f456a31465332dba005e77771ae98adc8da48784594d74b2fe389ba2bfbfbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Security for trigram-llm 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page