Feature Extraction
MLX
English
hrr
vsa
holographic-reduced-representations
tokenizer
morphemes
compositional
Instructions to use thebasedcapital/morph-hrr with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use thebasedcapital/morph-hrr with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir morph-hrr thebasedcapital/morph-hrr
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
| """Holographic Reduced Representation (HRR) primitives on Apple MLX. | |
| Binding/unbinding are circular (de)convolution in the FFT domain (Plate, 1995). | |
| These are the building blocks the morpheme tokenizer uses to compose | |
| ``prefix (x) root (x) suffix`` into a single fixed-width "holistic" token vector. | |
| """ | |
| from __future__ import annotations | |
| import mlx.core as mx | |
| import numpy as np | |
| def normalize(x: mx.array, eps: float = 1e-6) -> mx.array: | |
| """L2-normalize along the last axis; upcast to float32 for stable math.""" | |
| x = x.astype(mx.float32) | |
| return x / mx.sqrt(mx.sum(x * x, axis=-1, keepdims=True) + eps) | |
| def _bind(a: mx.array, b: mx.array) -> mx.array: | |
| """Circular convolution: real(IFFT(FFT(a) * FFT(b))).""" | |
| return mx.real(mx.fft.ifft(mx.fft.fft(a.astype(mx.float32)) * mx.fft.fft(b.astype(mx.float32)))) | |
| def _unbind(bound: mx.array, key: mx.array) -> mx.array: | |
| """Circular correlation (approx inverse of bind): real(IFFT(FFT(bound) * conj(FFT(key)))).""" | |
| return mx.real( | |
| mx.fft.ifft(mx.fft.fft(bound.astype(mx.float32)) * mx.conj(mx.fft.fft(key.astype(mx.float32)))) | |
| ) | |
| # Compiled hot paths. | |
| bind = mx.compile(_bind) | |
| unbind = mx.compile(_unbind) | |
| def bundle(*vectors: mx.array) -> mx.array: | |
| """Superpose vectors by normalized sum (the VSA "add").""" | |
| if not vectors: | |
| raise ValueError("bundle requires at least one vector") | |
| return normalize(sum(v.astype(mx.float32) for v in vectors)) | |
| def cosine_similarity(a: mx.array, b: mx.array) -> mx.array: | |
| """Cosine similarity along the last axis (vectors are normalized first).""" | |
| return mx.sum(normalize(a) * normalize(b), axis=-1) | |
| def make_unitary(dim: int, seed: int = 0) -> mx.array: | |
| """Deterministic unitary vector: its FFT has all-ones magnitude, so binding with | |
| it is exactly invertible (unbind perfectly recovers the bound value).""" | |
| rng = np.random.default_rng(seed) | |
| spectrum = np.ones(dim, dtype=np.complex64) | |
| half = dim // 2 | |
| phases = rng.uniform(0, 2 * np.pi, max(0, half - 1)) | |
| spectrum[1:half] = np.exp(1j * phases) | |
| spectrum[half + 1 :] = np.conj(spectrum[1:half][::-1]) | |
| if dim % 2 == 0: | |
| spectrum[half] = 1.0 | |
| return mx.array(np.fft.ifft(spectrum).real.astype(np.float32)) | |
| def update_context(context: mx.array, token: mx.array, position_key: mx.array) -> mx.array: | |
| """Incrementally fold a token into a running context: normalize(context + token (x) pos).""" | |
| return normalize(context.astype(mx.float32) + bind(token, position_key)) | |