How to use from the
Use from the
MLX library
# Download the model from the Hub
pip install huggingface_hub[hf_xet]

huggingface-cli download --local-dir morph-hrr thebasedcapital/morph-hrr

morph-hrr

A compositional morpheme tokenizer built on Holographic Reduced Representations (HRR), for Apple MLX.

Each word becomes one fixed-width dense vector by binding its morphemes (prefix โŠ— root โŠ— suffix) into a single "holistic" superposition. Because the binding is circular convolution with unitary role vectors, you can algebraically pull a morpheme back out: unbind(word_vec, prefix_role) recovers the prefix. Words that share morphology land near each other in vector space, and an out-of-vocabulary word built from its pieces still neighbors its root family.

What this is โ€” and isn't

It is: an input representation / embedding layer for HRR-native or experimental models. It emits dense vectors, one per word, and exposes the HRR algebra (bind, unbind, bundle, make_unitary) behind them.

It is not: a HuggingFace textโ†”ID tokenizer. It does not produce token IDs, has no vocabulary, and will not drop into transformers. Think of it as an alternative to a learned embedding table โ€” one whose vectors are compositional by construction rather than arbitrary.

It is not: a way to make a pretrained Qwen/Gemma smaller or faster. HRR input is a different representation than what pretrained weights expect; you cannot swap it into an existing model without retraining from scratch. (See Scope & honesty below.)

Install

pip install morph-hrr        # Apple Silicon (mlx is the only dependency)

Development:

git clone <repo> && cd morph-hrr
pip install -e ".[test]"
pytest -q

Quickstart

from morph_hrr import MorphemeTokenizer, unbind, cosine_similarity

tok = MorphemeTokenizer(dim=2048)        # deterministic given seed

# A word is one fixed-width vector, composed from its morphemes by role.
v = tok.word_vector("unhappy")           # mx.array, shape (2048,)
print(tok.segment("unhappy"))            # ('un', 'happy', '')

# Composition is algebraic: recover the prefix filler by unbinding its role.
recovered = unbind(v, tok.prefix_role)
print(cosine_similarity(recovered, tok.bytes_vector("un")))   # ~0.6 (vs ~0 control)

# Shared morphology => shared neighborhood.
print(cosine_similarity(tok.word_vector("unhappy"),
                        tok.word_vector("happy")))            # > 0.2 (vs ~0 unrelated)

# Encode a sentence: one float16 vector per word.
mat = tok.encode("the quick brown fox")   # mx.array, shape (4, 2048), float16

The math (one paragraph)

bind(a, b) is circular convolution, computed in the Fourier domain as real(IFFT(FFT(a) * FFT(b))). unbind(bind(a,b), b) is the convolution inverse, real(IFFT(FFT(bound) * conj(FFT(b)))). A unitary vector has all FFT magnitudes equal to 1, so binding with it is a perfect, lossless rotation โ€” unbinding recovers the original to >0.99 cosine. A word vector bundles three roleโŠ—filler pairs โ€” prefix_role โŠ— bytes(prefix), root_role โŠ— bytes(root), suffix_role โŠ— bytes(suffix) โ€” into one normalized superposition; unbinding a role pulls its filler back out of the superposition (the other two act as noise, which is why longer dims recover more cleanly).

Compositionality demo (regression-tested, dim=2048)

Property HRR cosine Random control Test
Prefix recovery (unbind(unhappy, prefix_role) โ‰ˆ bytes("un")) > 0.50 โ‰ˆ 0 test_prefix_recovery_beats_control
Shared-root clustering (unhappy ~ happy) > 0.20 โ‰ˆ 0 test_shared_root_clusters
Shared-suffix clustering (running ~ walking) > 0.15 โ‰ˆ 0 test_shared_suffix_clusters
OOV root family (unbind(unkind, root_role) โ‰ˆ bytes("kind")) > 0.50 โ‰ˆ 0 test_oov_root_family
Role vectors near-orthogonal < 0.10 โ€” test_roles_are_near_orthogonal

Each HRR measurement is paired against a random-vector control of the same dimension, asserting the structured signal is meaningfully stronger than noise.

Public API

Name What
MorphemeTokenizer(dim=2048, seed=0) Map text โ†’ HRR morpheme vectors
.segment(word) (prefix, root, suffix)
.word_vector(word) / .bytes_vector(text) Holistic / byte-fold word vector
.encode(text) / .iter_vectors(text) Stacked (n, dim) float16 / lazy yield
.prefix_role / .root_role / .suffix_role Exposed unitary role vectors (for unbind)
bind, unbind, bundle, normalize, make_unitary, cosine_similarity, update_context HRR primitives
segment, PREFIXES, SUFFIXES Standalone morphological segmentation

HolographicMorphemeTokenizer is kept as a backwards-compatible alias for MorphemeTokenizer.

Segmentation: deliberately simple

morphemes.segment is dependency-free, longest-match affix stripping over curated prefix/suffix lists, with a minimum-root guard. It is imperfect by design: it does not undo consonant doubling (running โ†’ runn + ing, not run + ing) and cannot tell a real root from a suffixable tail (preorder โ†’ pre + ord + er). No dictionary, no learned model, no nltk. This keeps the package lightweight; better segmentation is future work and is orthogonal to the HRR representation itself.

Scope & honesty

  • mlx-only. Apple Silicon target audience; a numpy/JAX backend is a documented future option, not this release.
  • Representation, not a drop-in tokenizer. No token IDs, no HF integration.
  • Can't retrofit pretrained models. Swapping HRR input into a real model throws away its pretrained weights โ€” you must train from scratch. On consumer hardware (e.g. 16 GB) that means small research-scale models, not deployable ones. The value of this package is the compositional input representation and the HRR algebra, demonstrated on small models.
  • v0.1 ships the tokenizer + primitives + tests. A demo Space, a trained reference model, and a portable backend are future work.

License

MIT. See LICENSE.

Cite / priority

If you build on this representation in published work, please cite this repository. The compositional HRR morpheme representation (roleโŠ—filler binding of prefix/root/suffix via circular convolution, with unitary roles enabling algebraic morpheme manipulation) is, to our knowledge, novel as a tokenization scheme; we'd appreciate attribution.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support