Text Generation
MLX
English
German
next-concept-modeling
apple-silicon
diffusion-lm
research-code
negative-results
Instructions to use Red-fuchs/ncm-modular with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use Red-fuchs/ncm-modular with MLX:
# Make sure mlx-lm is installed # pip install --upgrade mlx-lm # if on a CUDA device, also pip install mlx[cuda] # Generate text with mlx-lm from mlx_lm import load, generate model, tokenizer = load("Red-fuchs/ncm-modular") prompt = "Once upon a time in" text = generate(model, tokenizer, prompt=prompt, verbose=True) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- MLX LM
How to use Red-fuchs/ncm-modular with MLX LM:
Generate or start a chat session
# Install MLX LM uv tool install mlx-lm # Generate some text mlx_lm.generate --model "Red-fuchs/ncm-modular" --prompt "Once upon a time"
- Atomic Chat
Download src/ncm_modular/ar_mlx.py from Red-fuchs/ncm-modular: direct link, hf CLI and curl.
- Browser
- Download file 5.53 kB
-
https://huggingface.co/Red-fuchs/ncm-modular/resolve/main/src/ncm_modular/ar_mlx.py
- Command line
-
hf download hf://Red-fuchs/ncm-modular/src/ncm_modular/ar_mlx.py
-
curl -L -o ar_mlx.py https://huggingface.co/Red-fuchs/ncm-modular/resolve/main/src/ncm_modular/ar_mlx.py
5.53 kB
| """Baselines (MLX): AR prefix-LM decoder (same 8L/512d/8H as NCM gen, KV cache) + intent classifier encoder.""" | |
| import os, sys, math | |
| sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) | |
| import numpy as np, mlx.core as mx | |
| from mlx import nn | |
| from ncm_mlx.official.model import rope_tables, _rotate, LN_EPS | |
| class CAttn(nn.Module): | |
| def __init__(self, D, H): | |
| super().__init__(); self.H, self.hd = H, D // H | |
| self.qkv = nn.Linear(D, 3 * D); self.proj = nn.Linear(D, D) | |
| self.q_norm = nn.RMSNorm(self.hd, eps=LN_EPS); self.k_norm = nn.RMSNorm(self.hd, eps=LN_EPS) | |
| def __call__(self, x, mask, rope, cache=None): | |
| B, T, C = x.shape | |
| q, k, v = (t.reshape(B, T, self.H, self.hd).transpose(0, 2, 1, 3) for t in mx.split(self.qkv(x), 3, -1)) | |
| q, k = self.q_norm(q), self.k_norm(k) | |
| q, k = _rotate(q, *rope), _rotate(k, *rope) | |
| if cache is not None: | |
| if cache[0] is not None: k = mx.concatenate([cache[0], k], 2); v = mx.concatenate([cache[1], v], 2) | |
| cache[0], cache[1] = k, v | |
| y = mx.fast.scaled_dot_product_attention(q, k, v, scale=self.hd ** -0.5, mask=mask) | |
| return self.proj(y.transpose(0, 2, 1, 3).reshape(B, T, C)) | |
| class CBlock(nn.Module): | |
| def __init__(self, D, H): | |
| super().__init__() | |
| self.ln1 = nn.LayerNorm(D, eps=LN_EPS); self.attn = CAttn(D, H); self.ln2 = nn.LayerNorm(D, eps=LN_EPS) | |
| self.fc = nn.Linear(D, 4 * D); self.out = nn.Linear(4 * D, D) | |
| def __call__(self, x, mask, rope, cache=None): | |
| x = x + self.attn(self.ln1(x), mask, rope, cache) | |
| return x + self.out(nn.gelu(self.fc(self.ln2(x)))) | |
| class ARGen(nn.Module): | |
| """prefix (frozen codec token emb -> in_proj, bidirectional, pad-masked) + target tokens (compact vocab, causal).""" | |
| def __init__(self, tok_table, V, P=48, T=48, D=512, H=8, nl=8, pad_id=151643, drop=0.1): | |
| super().__init__() | |
| self.P, self.T, self.V, self.pad_id, self.D = P, T, V, pad_id, D | |
| self._tok = tok_table | |
| self.in_proj = nn.Linear(tok_table.shape[1], D) | |
| self.emb = nn.Embedding(V, D) # target tokens; 0 = BOS; head tied | |
| self.blocks = [CBlock(D, H) for _ in range(nl)] | |
| self.ln_f = nn.LayerNorm(D, eps=LN_EPS); self.drop = nn.Dropout(drop) | |
| self._rope = rope_tables(np.arange(P + T), D // H, 10000.0) | |
| rows = np.arange(P + T)[:, None]; cols = np.arange(P + T)[None, :] | |
| self._base = mx.array(np.where(rows < P, cols < P, (cols < P) | (cols <= rows)))[None, None] | |
| def logits(self, h): return h @ self.emb.weight.T | |
| def __call__(self, ptoks, tin): | |
| """tin: (B,T') input tokens (BOS + target[:-1]) -> logits (B,T',V)""" | |
| B, Tn = tin.shape | |
| keep = ptoks != self.pad_id | |
| h = mx.concatenate([self.drop(self.in_proj(self._tok[ptoks])), self.drop(self.emb(tin))], 1) | |
| S = self.P + Tn | |
| kk = mx.concatenate([keep, mx.ones((B, Tn), dtype=mx.bool_)], 1) | |
| mask = self._base[:, :, :S, :S] & kk[:, None, None, :] | |
| rope = (self._rope[0][:S], self._rope[1][:S]) | |
| for b in self.blocks: h = b(h, mask, rope) | |
| return self.logits(self.ln_f(h)[:, self.P:]) | |
| def generate(self, ptoks, eos_c, maxlen=None): | |
| """greedy with KV cache; returns list of compact-id lists; NFE = steps run.""" | |
| B = ptoks.shape[0]; maxlen = maxlen or self.T | |
| keep = ptoks != self.pad_id | |
| caches = [[None, None] for _ in self.blocks] | |
| # prefill: prefix (bidirectional) + BOS | |
| h = mx.concatenate([self.in_proj(self._tok[ptoks]), self.emb(mx.zeros((B, 1), dtype=mx.int32))], 1) | |
| S = self.P + 1 | |
| kk = mx.concatenate([keep, mx.ones((B, 1), dtype=mx.bool_)], 1) | |
| mask = self._base[:, :, :S, :S] & kk[:, None, None, :] | |
| rope = (self._rope[0][:S], self._rope[1][:S]) | |
| for b, c in zip(self.blocks, caches): h = b(h, mask, rope, c) | |
| out = []; done = mx.zeros((B,), dtype=mx.bool_); nfe = 1 | |
| nxt = mx.argmax(self.logits(self.ln_f(h)[:, -1]), -1) | |
| for i in range(maxlen): | |
| out.append(nxt); done = done | (nxt == eos_c) | |
| if i == maxlen - 1 or bool(done.all().item()): break | |
| pos = self.P + 1 + i | |
| h = self.emb(nxt[:, None]); rope = (self._rope[0][pos:pos + 1], self._rope[1][pos:pos + 1]) | |
| kk = mx.concatenate([keep, mx.ones((B, 1 + i + 1), dtype=mx.bool_)], 1) | |
| mask = kk[:, None, None, :] | |
| for b, c in zip(self.blocks, caches): h = b(h, mask, rope, c) | |
| nxt = mx.argmax(self.logits(self.ln_f(h)[:, -1]), -1); nfe += 1 | |
| return mx.stack(out, 1), nfe | |
| class IntentCls(nn.Module): | |
| def __init__(self, tok_table, n_cls, P=48, D=256, H=4, nl=4, pad_id=151643, drop=0.1): | |
| super().__init__() | |
| self.P, self.pad_id, self._tok = P, pad_id, tok_table | |
| self.in_proj = nn.Linear(tok_table.shape[1], D) | |
| self.pos = nn.Embedding(P, D) | |
| self.blocks = [CBlock(D, H) for _ in range(nl)] | |
| self.ln_f = nn.LayerNorm(D, eps=LN_EPS); self.drop = nn.Dropout(drop); self.head = nn.Linear(D, n_cls) | |
| self._rope = rope_tables(np.arange(P), D // H, 10000.0) | |
| def __call__(self, ptoks): | |
| keep = ptoks != self.pad_id | |
| h = self.drop(self.in_proj(self._tok[ptoks]) + self.pos.weight[None]) | |
| mask = keep[:, None, None, :] | |
| for b in self.blocks: h = b(h, mask, self._rope) | |
| h = self.ln_f(h); m = keep[..., None].astype(h.dtype) | |
| return self.head((h * m).sum(1) / m.sum(1)) | |