d3LLM/d3LLM_LLaDA (distilled from
GSAI-ML/LLaDA-8B-Instruct, MIT) — the
zoo’s first diffusion LLM. The reply is not written left-to-right: a masked canvas
denoises in place, tokens committing in parallel, lowest-entropy first, semi-AR block by
block. One static bidirectional forward (input_ids[1,S] → logits[1,S,V], no KV cache);
the denoising loop is host code.
Bundle: 🤗 mlboydaisuke/LLaDA-8B-dLLM-CoreAI
— macOS (int4 per-block-32 body + int8 head, 4.9 GB, S=256 canvas). Mac-only today
(the canvas graph wants an AOT export before iPhone). Catalog id: llada-8b.
▶️ Run it (source) — the DiffuseChat runner (GUI + CLI, one app for every diffusion LM in the catalog):
git clone https://github.com/john-rocky/coreai-kit
open coreai-kit/Examples/DiffuseChat/DiffuseChat.xcodeproj
# → Run, then pick "LLaDA-8B (diffusion)" in the model picker
# agents / headless (macOS):
cd coreai-kit/Examples/DiffuseChat
swift run diffuse-cli --model llada-8b --prompt "What is the capital of France?"
💻 Build with it — complete; the glue is kit API, copy-paste runs:
import CoreAIKit
let dlm = try await KitDiffusionLM(catalog: "llada-8b")
let reply = try await dlm.reply(to: prompt)
// reply: the denoised answer — pass onStep: to watch the canvas fill in per forward
// (still-masked positions as ░), in parallel, not left-to-right
The take-home is Examples/DiffuseChat/Sources/QuickStart.swift
— this exact code as one typed function, no UI; the CLI is an argument shell over it, and
the GUI renders the same live canvas.
The canvas is fixed (S=256 ≈ 210 generated tokens) and the whole history must fit — no
KV cache. reply(messages:) takes role/content turns and drops the oldest first.
Pass onStep: nil if you only want the final text.
Integration checklist
https://github.com/john-rocky/coreai-kit → product CoreAIKitdownloadProgress callback)Distillation (d3LLM) commits ~8 tokens per forward; the entropy threshold trades step
count (NFE) against caution at constant ms/forward: 0.5 → NFE 19, 1.0 → NFE 11 ≈ 38–40
tok/s, 1.5 → NFE 8 ≈ 53 tok/s (≥ ~2.5 degrades). The shipped bundle’s metadata carries
the validated defaults; KitDiffusionLM reads them.
LLaDAModelLM: cos ≈ 1.0 per layer + logits
(conversion/dllm/gate_llada_torch.py).generate at temperature 0: matched
(conversion/dllm/gate_llada_decode.py). int8 is lossless; int4 per-block-32 diverges
in token choice occasionally but stays correct (see
knowledge/diffusion-llms-dllm.md — the “20/64
token match ≠ broken” lesson).S=256 fits ≈ 210 generated tokens and the whole history must fit in the canvas (no KV
cache): KitDiffusionLM drops oldest turns first, so short multi-turn works but long memory
does not. A delayed-KV-cache decode is the known next lever.
The kit’s DiffuseChat runner
(GUI + diffuse-cli, live ░-canvas view), or the zoo’s
CoreAIChatMac app (pick LLaDA-8B d3LLM, same denoising view).