Core AI model zoo

Diffusion LLMs (dLLM) on Core AI — port notes

A masked diffusion LLM is not autoregressive. Instead of writing one token left-to-right with a KV cache, it runs a bidirectional forward over a fixed-length canvas of [MASK] tokens and unmasks the most-confident positions in parallel, repeating until the canvas resolves. Ported here as LLaDA-8B (base GSAI-ML/LLaDA-8B-Instruct, distilled d3LLM/d3LLM_LLaDA).

Shape of the port

  1. Backbone overlay (conversion/dllm/llada.py) — a fixed-shape, exportable LLaMA-dense 8B, but:
    • bidirectional SDPA (is_causal=False, no mask) — the whole point; the LLaDALlamaBlock name is misleading.
    • no KV cache — every denoising step is a full forward over the whole canvas S.
    • RoPE θ=500000 (baked), RMSNorm weight*x (not Gemma’s 1+w), MHA 32×128 (no GQA), no qk-norm, SwiGLU intermediate 12288 (config mlp_hidden_size; activation_type="silu" so ff_proj and up_proj are each full-width — NOT half), lm_head ff_out (weight_tying False).
    • Gated cos≈1.0 vs the official LLaDAModelLM (gate_llada_torch.py), per-layer + logits.
  2. Decode loop (generate_llada.py) — the host side: semi-AR blocks; each step unmask the masked positions with lowest entropy (always ≥1, plus any below threshold). Token-exact vs the official generate at temperature 0 (gate_llada_decode.py).
  3. Export (export_llada.py) — one static bundle main(input_ids[1,S] int32) → logits[1,S,vocab], bidirectional, no KV. VoxCPM2 idiom (externalize-drop SDPA+RoPE, export_to_coreai, quantize_pytorch_model). int4 per-block-32 body + int8 head ≈ 4.9 GB.
  4. Host — the same loop in Swift (apps/CoreAIChatMac LLaDAEngine): load the .aimodel, tokenize, run the denoising loop, stream the canvas. metadata.json carries the diffusion knobs (seq, block_size, threshold) so they retune without a recompile.

Lessons (the non-obvious ones)