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/eval_all.py from Red-fuchs/ncm-modular: direct link, hf CLI and curl.
- Browser
- Download file 4.61 kB
-
https://huggingface.co/Red-fuchs/ncm-modular/resolve/main/src/ncm_modular/eval_all.py
- Command line
-
hf download hf://Red-fuchs/ncm-modular/src/ncm_modular/eval_all.py
-
curl -L -o eval_all.py https://huggingface.co/Red-fuchs/ncm-modular/resolve/main/src/ncm_modular/eval_all.py
4.61 kB
| """Test-set metrics + latency for NCM generator, AR baseline, intent classifier.""" | |
| import os, sys, json, time, argparse | |
| sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) | |
| from paths import WORK | |
| os.environ.setdefault("MFMT", "C") | |
| import numpy as np, mlx.core as mx | |
| from transformers import AutoTokenizer | |
| from gen_mlx import * | |
| from ar_mlx import * | |
| from massive_eval import score | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--ncm", default=WORK+"/ncm_pilot"); ap.add_argument("--ar", default=WORK+"/ar_pilot"); ap.add_argument("--cls", default=WORK+"/cls_pilot") | |
| ap.add_argument("--split", default="test"); ap.add_argument("--out", default=WORK+"/massive_de/results.json"); ap.add_argument("--P", type=int, default=40) | |
| ap.add_argument("--nreq", type=int, default=200) | |
| a = ap.parse_args() | |
| EOS, PAD = 151645, 151643 | |
| tok = AutoTokenizer.from_pretrained(WORK+"/tok/Qwen3-0.6B"); fc = FrozenCodec() | |
| D = [json.loads(l) for l in open(f"{WORK}/massive_de/{a.split}.jsonl")] | |
| def pad(ids, n): ids = ids[:n]; return ids + [PAD] * (n - len(ids)) | |
| PT = np.array([pad(tok.encode(d["prefix"])[:a.P - 1] + [EOS], a.P) for d in D], np.int32) | |
| def cut(r): | |
| r = list(r); r = r[:r.index(EOS)] if EOS in r else r | |
| return tok.decode([t for t in r if t != PAD], skip_special_tokens=True) | |
| def lat(fn, bs, n): | |
| ts = [] | |
| rng = np.random.RandomState(0) | |
| for i in range(n + 3): | |
| idx = rng.randint(0, len(D), bs); t = time.perf_counter(); fn(mx.array(PT[idx])); ts.append((time.perf_counter() - t) * 1000) | |
| ts = np.array(ts[3:]); return dict(p50=float(np.percentile(ts, 50)), p95=float(np.percentile(ts, 95)), mean=float(ts.mean())) | |
| res = {} | |
| # ---- NCM | |
| cfg = json.load(open(f"{a.ncm}/ckpt.json"))["args"] | |
| master = Gen(fc, cfg["P"], cfg["D"], cfg["H"], cfg["nl"], PAD, drop=0.0); master.load_weights(f"{a.ncm}/best.safetensors") | |
| g = Gen(fc, cfg["P"], cfg["D"], cfg["H"], cfg["nl"], PAD, drop=0.0).set_compute(mx.float16) | |
| from mlx.utils import tree_map | |
| g.update(tree_map(lambda t: t.astype(mx.float16), master.parameters())); g.eval(); mx.eval(g.parameters()) | |
| def ncm_gen(p): t, _ = generate(g, fc, p); mx.eval(t); return t | |
| preds = [] | |
| for i in range(0, len(D), 64): preds += [cut(r) for r in ncm_gen(mx.array(PT[i:i + 64])).tolist()] | |
| r = score(preds, D); r["NFE"] = g.K; r["params_M"] = count_params(master) / 1e6 | |
| r["lat_b1_ms"] = lat(ncm_gen, 1, a.nreq); r["lat_b16_ms"] = lat(ncm_gen, 16, max(a.nreq // 5, 20)); res["ncm"] = r | |
| res["ncm_codec_ceiling_exact"] = None | |
| json.dump({"preds_ncm": preds[:50]}, open(a.out.replace(".json", "_samples_ncm.json"), "w"), ensure_ascii=False, indent=1) | |
| print("NCM", r, flush=True) | |
| # ---- AR | |
| if os.path.exists(f"{a.ar}/model.safetensors"): | |
| voc = json.load(open(f"{a.ar}/vocab.json")); ck = json.load(open(f"{a.ar}/ckpt.json")); inv_v = {i + 3: t for i, t in enumerate(voc["vocab"])} | |
| m = ARGen(fc.tok, ck["V"], ck["args"]["P"], ck["args"]["T"], pad_id=PAD, drop=0.0); m.load_weights(f"{a.ar}/best.safetensors") | |
| m.set_dtype(mx.float16); m.eval(); mx.eval(m.parameters()) | |
| nfe = [] | |
| def ar_gen(p): o, n = m.generate(p, 1); mx.eval(o); nfe.append(n); return o | |
| def dec(row): | |
| row = row[:row.index(1)] if 1 in row else row | |
| return tok.decode([inv_v[c] for c in row if c in inv_v], skip_special_tokens=True) | |
| preds = [] | |
| for i in range(0, len(D), 64): preds += [dec(r) for r in ar_gen(mx.array(PT[i:i + 64])).tolist()] | |
| r = score(preds, D); r["NFE_mean_b64"] = float(np.mean(nfe)); r["params_M"] = count_params(m) / 1e6 | |
| nfe.clear(); r["lat_b1_ms"] = lat(ar_gen, 1, a.nreq); r["NFE_mean_b1"] = float(np.mean(nfe)); nfe.clear() | |
| r["lat_b16_ms"] = lat(ar_gen, 16, max(a.nreq // 5, 20)); r["NFE_mean_b16"] = float(np.mean(nfe)); res["ar"] = r | |
| json.dump({"preds_ar": preds[:50]}, open(a.out.replace(".json", "_samples_ar.json"), "w"), ensure_ascii=False, indent=1) | |
| print("AR", r, flush=True) | |
| # ---- classifier | |
| if os.path.exists(f"{a.cls}/model.safetensors"): | |
| ints = json.load(open(f"{a.cls}/vocab.json"))["ints"] | |
| m = IntentCls(fc.tok, len(ints), a.P, pad_id=PAD, drop=0.0); m.load_weights(f"{a.cls}/best.safetensors"); m.set_dtype(mx.float16); m.eval() | |
| def cl(p): o = mx.argmax(m(p), -1); mx.eval(o); return o | |
| hit = 0 | |
| for i in range(0, len(D), 256): hit += sum(ints[j] == d["intent"] for j, d in zip(cl(mx.array(PT[i:i + 256])).tolist(), D[i:i + 256])) | |
| res["cls"] = dict(intent_acc=hit / len(D), params_M=count_params(m) / 1e6, NFE=1, lat_b1_ms=lat(cl, 1, a.nreq), lat_b16_ms=lat(cl, 16, max(a.nreq // 5, 20))) | |
| print("CLS", res["cls"], flush=True) | |
| json.dump(res, open(a.out, "w"), indent=1) | |