Skip to content

feat(rai): move to ryzenai-corelib 0.29.2, add Qwen3.6-35B-A3B, run corelib's models behind one engine - #774

Draft
chizamd wants to merge 4 commits into
ROCm:mainfrom
chizamd:feature/dev01-update
Draft

chizamd wants to merge 4 commits into
ROCm:mainfrom
chizamd:feature/dev01-update

Conversation

@chizamd

@chizamd chizamd commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #748. Moves the rai backend from ryzenai-corelib 0.11 to 0.29.2, adds Qwen3.6-35B-A3B, runs Gemma 4 at 16k and Qwen3.5 at 32k, and has Qwen3, Qwen3.5, Gemma 4 and Qwen3.6 run as corelib's own models behind one shared engine.

Commits:

  1. corelib 0.26, Qwen3.6, Gemma 4 at 16k on the existing per-op engines.
  2. One engine for corelib's models. Qwen3, Qwen3.5 and Gemma 4 stop driving corelib op by op and run as ryzenai_corelib_model_*, like Qwen3.6. Phi-4 stays per-op.
  3. corelib 0.28. Qwen3.5's KV cache is paged up to 32768, and a later turn's prefill chunks start on 4096-row page boundaries.
  4. corelib 0.29.2. No ABI change; corelib speeds up Gemma 4's per-layer-embedding projection and runs Qwen3.6's in-page prefill chunks on the NPU.

Models

Tag How it runs Context Change
qwen3.6-moe-rai:35b-a3b corelib model default 4096, up to 262144 New. Qwen3.6-35B-A3B Q8_0, text only
gemma4-it-rai:e2b gemma4-it-rai:e4b corelib model default and max 16384 Was 4096; E4B is offered again
qwen3-rai:* corelib model 4096 Moved off the per-op engine
qwen3.5-rai:9b corelib model default 4096, up to 32768 Moved off the per-op engine; was capped at 4096
phi4-mini-it-rai:4b per-op (unchanged) 4096 Ported to the 0.26 ABI

What changes

corelib 0.29.2 (version pinned exactly)

  • Follows the 0.26 ABI (0.28 and 0.29 add nothing FastFlowLM has to meet): create_tensor_window takes strides, linear_attention_bf16 takes rows, and models are built with model_weights_create_path + model_create(name, weights, options).
  • Phi-4 writes its KV cache through a strided window [max_seq*head, head, 1], and opens its stream through corelib::OpenModelStream, which enables the model's kernel bundle before any kernel query (a new stream resolves no kernels on its own).

Packaging

  • corelib installs ryzenai_corelib plus one ryzenai_corelib_model_<name> library per model and loads them only from its own directory. A Windows rai build copies them beside flm.exe; home_install.sh copies them beside corelib on Linux.
  • RYZENAI_CORELIB_DD_ROOT / RYZENAI_CORELIB_KERNELS_ROOT are no longer needed, and the installer stops staging DynamicDispatch.

One engine: flm::rai::CorelibModel (include/rai/corelib_model.hpp, common/rai/corelib_model.cpp)

  • A causal_lm over a corelib model. Each model is a short ModelSpec naming what differs:
    • Continuation: where a multi-row pass may start past position 0 — anywhere (Qwen3.5, Qwen3.6), only at 0 (Qwen3, so a later prompt re-runs the conversation), or at 0 / a 4096-row page boundary (Gemma 4).
    • Rewind: kSeek for attention-only models (every pass states its position; rewind just moves it), kSnapshot for Qwen3.6 (model_state_save/restore, reused only if its history is a prefix of the current one), kReplay for Qwen3.5 (reset and replay).
  • Token ids and the context limit are checked before corelib is called. A failed forward, restore or reset poisons the engine.
  • Logits are fetched only for the row that gets sampled.

One backend: flm::rai::Factory(BackendSpec) (include/rai/corelib_model_backend.hpp)

  • Refuses preemption and a context outside the model's rule, reads the package's BOS/EOS ids (tokenizer_config.json + config.json, e.g. Gemma 4 → {1, 106}), and resolves the GGUF before the runtime or weights are touched. Image requests on rai return HTTP 400.

Page-aligned prefill chunks (AutoModel::_chunked_insert, model_backend.hpp)

  • New ModelBackend::aligns_prefill_chunks(), default false, so FastFlowLM's own engines are unaffected. The corelib-model backend returns true: a later turn's prompt is chunked on multiples of 4096 counted from position 0 instead of from the turn's start, so every chunk after the first starts on a page boundary and corelib runs it as whole pages on the NPU. Prompts carrying a multimodal payload keep the old chunking.

Removed

  • The per-op engines, GGUF readers, shape plans and host math of Qwen3, Qwen3.5 and Gemma 4; rai/gguf_file, rai/weight_cache, the Q8/RMSNorm parts of rai/host_ops, and 14 corelib entry points nothing calls.
  • No packed-weight cache on the corelib-model path: corelib packs weights on every load. Old <gguf stem>.rai-weights.bin/.json files can be deleted.

Shared

  • Sampler::sampler_topk_apply selects top-k with a k-entry heap in one pass instead of partial_sorting a vocab-sized array each token. Same ranking and lowest-id tie rule; checked against the old code on 63 inputs (vocab 1..248320, k = 1/2/20/40, heavy ties).

Docs: src/common/models/README.md gains a section on models corelib runs whole; docs/rai-setup-linux.md and the model pages cover 0.26 and the dropped weight cache.

Results

All on an aie_next NPU, Windows.

Unit tests (fake corelib): rai_model (new: 36 engine tests covering every Rewind/Continuation combination, poisoning and capacity, plus 14 backend tests), phi4_rai, gemma4_rai pass. The real-package tokenizer test was skipped.

This PR (corelib 0.29.2) vs before — "before" is the first commit's build on corelib 0.26: the per-op engines for Phi-4, Qwen3, Qwen3.5 and Gemma 4, and Qwen3.6 on corelib's model API. Both builds run interleaved, Gemma 4 twice each, with the NPU checked idle before and after every run. Long-prompt TTFT is the median of three ~1.1k-token prompts; decode is the median over three short prompts, 64 greedy tokens each.

Model Load, this PR vs before Long-prompt TTFT, this PR vs before Decode tok/s, this PR vs before Greedy text
gemma4-it-rai:e2b 8.1–11.4 s vs 3.3–4.2 s 0.64–0.68 vs 0.80–0.82 s 34.2–36.2 vs 37.1–38.0 1 of 3 prompts differs (known near-tie token)
gemma4-it-rai:e4b 11.2–16.4 s vs 3.4–3.6 s 1.02–1.06 vs 1.33–1.35 s 23.5–23.9 vs 23.6–24.2 identical
qwen3.6-moe-rai:35b-a3b 83.2 vs 84.4 s 1.45 vs 14.18 s 19.1 vs 20.4 identical
qwen3.5-rai:9b 22.5 vs 25.1 s 42.7 vs 49.3 s 19.0 vs 19.3 identical
qwen3-rai:0.6b 3.2 vs 1.8 s 0.24 vs 0.25 s 116.4 vs 121.8 identical
phi4-mini-it-rai:4b (per-op in both) 7.1 vs 3.4 s* 0.60 vs 0.60 s 43.9 vs 42.0 1 of 3 prompts differs

* This PR's Phi-4 run had no weight-cache directory set, so it packed on load; the "before" run loaded from its cache.

Loads are slower for Gemma 4 and Qwen3 because corelib packs the weights on every load and this path has no packed-weight cache.

Two-turn continuation at --ctx-len 16384: turn 1 is ~6.8k tokens carrying a passkey; turn 2 resends it with the reply and adds ~6.9k tokens, chunked on page boundaries (1395 / 4096 / 1414).

Model Turn 1 TTFT Turn 2 TTFT Passkey
qwen3.6-moe-rai:35b-a3b 6.4 s 7.5 s (14.3 s on corelib 0.28) correct
gemma4-it-rai:e2b 6.7 s 17.5 s correct

Measured on the second commit (corelib 0.26):

  • Switching e2b → qwen3 → qwen3.5 → e4b → phi4 → e2b in one flm serve process: every answer matches a fresh run, no errors.
  • Gemma 4 E2B at 16k: passkey recalled; a short prompt after a full paged cache matches a fresh run.

Long-context passkey recall (passkey at 45% depth, measured on the first commit):

Tag Context Prompt tokens Prefill Decode tok/s Answer
gemma4-it-rai:e2b 16384 11,329 13.5 s (838 tok/s) 28.9 correct
gemma4-it-rai:e4b 16384 11,329 13.4 s — correct
qwen3.6-moe-rai:35b-a3b 32768 23,714 932 s (25 tok/s) 19.7 correct

Gemma 4 on corelib's built-in model. On corelib 0.26 it was slower than the per-op engine (prefill ~1.5–2×, decode 24–29% slower), because of corelib's host per-layer-embedding projection. corelib 0.29 fixes that projection: prefill is now faster than the per-op engine, and decode is equal on E4B and ~5–8% lower on E2B. Loads stay slower, as above.

Not done yet

  • Rebuild and rerun the unit tests on top of current main (merge was clean; the merged tree has not been built)
  • Linux build of flm_rai and the home_install.sh --rai smoke test
  • Qwen3.5 at 32k and Qwen3.6 beyond 32k end to end

…ma 4 at 16k

Moves the `--rai` backend from ryzenai-corelib 0.11 to 0.26 and builds on
what the new corelib offers.

corelib 0.26 (pinned exactly):
- Follow the ABI changes: `create_tensor_window` takes strides,
  `linear_attention_bf16` takes rows, and models are built with
  `model_weights_create_path` + `model_create`.
- A 3-D matmul output that writes the KV cache is a strided window
  `[max_seq*head, head, 1]` (Phi-4, Qwen3, Qwen3.5 V writes; Gemma 4 E4B
  staging window).
- Per-op engines open their stream through `corelib::OpenModelStream`,
  which enables the model's kernel bundle before any kernel query.
- corelib's per-model libraries are copied beside `flm.exe` on Windows
  and beside corelib by `home_install.sh` on Linux. Nothing needs
  `RYZENAI_CORELIB_DD_ROOT` or `RYZENAI_CORELIB_KERNELS_ROOT` any more.

Qwen3.6-35B-A3B (new `qwen3.6-moe-rai:35b-a3b`, text only):
- Runs on corelib's model API; context up to 262144 in 4096-row pages,
  a prompt is a single `model_forward`, and checkpoint/restore use
  corelib state snapshots.
- Fetch logits only for the row that gets sampled.

Gemma 4:
- Context of 1..4096 on flat attention, or a multiple of 4096 up to 16384
  on corelib paged attention; the aie_next catalog entries default to
  16384. A paged continuation starts from its own page.
- `gemma4-it-rai:e4b` is offered again.

Shared:
- `Sampler::sampler_topk_apply` selects top-k with a k-entry heap in one
  pass (same ranking and tie rule).

Tests: new `src/test/qwen36_rai`, and the Gemma 4, Phi-4 and Qwen3 rai
tests and fake corelib follow the 0.26 ABI and the 16k paged context.

Co-authored-by: Cursor <cursoragent@cursor.com>
chizamd and others added 3 commits October 11, 2026 03:59
Qwen3, Qwen3.5 and Gemma 4 on the `rai` backend stop driving corelib op
by op and run as corelib's own models (`ryzenai_corelib_model_*`), the
way Qwen3.6 already does. All four share one engine and one backend; each
model is a short spec. Phi-4 is unchanged (corelib's `phi4mini` takes
ONNX only, and FastFlowLM ships a GGUF).

- `flm::rai::CorelibModel` (`rai/corelib_model`): a `causal_lm` over a
  corelib model, generalized from the Qwen3.6 engine. `ModelSpec` states
  where a multi-row pass may start (`Continuation`: anywhere, only at 0,
  or at 0 / a 4096-row page boundary) and how to rewind (`Rewind`: seek,
  state snapshot, or reset and replay). Token ids and the context limit
  are checked before corelib is called; a failed forward, restore or
  reset poisons the engine.
- `flm::rai::Factory(BackendSpec)` (`rai/corelib_model_backend`): refuses
  preemption and a context outside the model's rule, reads the package's
  BOS/EOS ids, and resolves the GGUF before the runtime or weights are
  touched.
- Removed: the per-op engines, GGUF readers, shape plans and host math of
  Qwen3, Qwen3.5 and Gemma 4; `rai/gguf_file`, `rai/weight_cache`, the
  Q8/RMSNorm parts of `rai/host_ops`, and 14 unused corelib entry points.
  corelib packs the weights on every load; old
  `<gguf stem>.rai-weights.bin/.json` files can be deleted.
- Tests: new `src/test/rai_model` (engine and backend against the fake
  corelib; the Qwen3.6 tests move here). Gemma 4's registry, catalog and
  server-gate tests move to `test_gemma4_registry.cpp`; the op-level
  Gemma 4 and Qwen3 suites are gone.

Gemma 4 is slower on corelib 0.26's built-in model than on the per-op
engine (prefill ~1.5-2x, decode 24-29% slower, slower loads). The cause
is in corelib's host per-layer-embedding projection and serial weight
packing; FastFlowLM picks up the fix with a corelib version bump.

Co-authored-by: Cursor <cursoragent@cursor.com>
…efill chunks to pages

corelib 0.28 pages Qwen3.5's KV cache up to 32768 and runs Qwen3.6's prefill past page 0 in whole-page passes. A later turn's prompt is now chunked on multiples of 4096 counted from position 0, so its chunks start on page boundaries.

Co-authored-by: Cursor <cursoragent@cursor.com>
No ABI change FastFlowLM meets. 0.29 speeds up Gemma 4's per-layer-embedding projection and runs Qwen3.6's prefill chunks inside a page on the NPU.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chizamd chizamd changed the title feat(rai): move to ryzenai-corelib 0.26, add Qwen3.6-35B-A3B, run Gemma 4 at 16k feat(rai): move to ryzenai-corelib 0.29.2, add Qwen3.6-35B-A3B, run corelib's models behind one engine Oct 12, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant