Skip to content

feat(BACKEND-ROCM-F16-WEIGHTS): retain F16 dense weights on ROCm - #3095

Open
VikashLoomba wants to merge 16 commits into
mudler:mainfrom
VikashLoomba:row/BACKEND-ROCM-F16-WEIGHTS
Open

feat(BACKEND-ROCM-F16-WEIGHTS): retain F16 dense weights on ROCm#3095
VikashLoomba wants to merge 16 commits into
mudler:mainfrom
VikashLoomba:row/BACKEND-ROCM-F16-WEIGHTS

Conversation

@VikashLoomba

@VikashLoomba VikashLoomba commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Row

BACKEND-ROCM-F16-WEIGHTS. Refs #3092. Refs #3106.

What changed

ROCm retains supported dense and embedding GGUF weights in F16 storage. Each retained operand carries its resolved value dtype, so BF16 model arithmetic rounds the file values before multiplication or gathering. Ordinary NN/BT multiplication and both embedding ID widths reach native ROCm providers. Queue and graph ownership release transient conversion scratch without retaining a permanent converted weight copy.

The default Qwen3.5 dense registry supplies the value dtype and rejects incompatible explicit model dtypes. Other loaders and stacked experts preserve expansion. This change integrates the reviewed full-attention consumer prerequisite from #3101 and its runner regression correction under #3098. It is independent of #2782 and changes no CI configuration.

Before starting

  • The gap was verified at 6db4bef906859e864c82523c01107473f7dcca29 against the code, tests, issues, pull requests, and owning records.
  • One pull request carries specification 4486d24f07ce197155fa2b37c1ff590cdbe290e7 before implementation. The scratch-lifetime amendment also precedes its product changes.
  • The canonical child inventory and evidence are in .agents/specs/rocm-f16-weights.md. The child remains ACTIVE; the parent lifecycle does not change.
  • The design follows pinned vLLM e126687a9a and GGUF plugin d4c1f0d082 through parameter creation, destination-dtype conversion, and native dispatch.

Evidence

CPU ownership and metadata tests, physical gfx1100 primitive and lifetime tests, graph dedup, and two-device controls pass. The new registry control passes 4 cases and 107 assertions. The complete CPU operand-contract suite passes 6 cases and 240 assertions. Guard-deletion mutations fail the new registry, embedding-provider, and NN-compute assertions; the unchanged controls pass. Scoped restoration covers absent, empty, and nonempty environment values and both provider states.

The unchanged full-attention runner fixture now passes 18 assertions through successful execution, attention-cache writes, sampling, and request feedback. All 41 CPU runner cases pass with 1,914 assertions. Restoring unconditional dense GDN validation fails at the original refusal. The committed #3098 amendment precedes this test-only repair.

ctest --test-dir build-repair-cpu --output-on-failure -j 1 passes 703 cases, skips 12, and retains the single #3102 baseline failure out of 716. The operator runs the complete HIP suite under the GPU mutex with both devices visible, provider statistics enabled, and graph dedup disabled: 692 pass, 12 skip, and 20 fail out of 724. Every one of the 19 baseline failures matches the pristine diagnostic and assertion summary exactly. The remaining failure is #3106. The added public full-attention completion target passes.

bash scripts/agent-preflight.sh --staged exits zero with every executed check passing and 678 translation units compiled. Its five argument-dependent skips are qualified by an explicit passing CPU ISA audit, passing PR #3095 classification, and inapplicable ARM/CUDA/Triton artifacts. Exact-range style, trailer, classification, Now, and diff checks pass on 9cf2bc9505fc377dd5ef707b15c1122e6f09c60d.

The spec records exact commands, source and binary hashes, skips, and baseline comparisons. Root verifies all 4,157 source files and 1,006 declared HIP inputs before and after the full run. The operator's full preflight on 9cf2bc9505fc377dd5ef707b15c1122e6f09c60d also passed, including all 678 affected translation units. Fresh scoped review passed the three F16 guards, the prerequisite integration, and the runner regression. A separate implementer corrected the paged-attention source citation. Fresh record review passed on 4137b96369467e925bfdf0738e5bad013c89b58f. All 7,274 other tracked files retain their tested bytes and modes. The operator verified the one-line delta and reran the applicable record, anchor, compilation-scope, and exact-range gates before publishing that commit.

Repair round (heads 15d8e1682 and 6607faea2)

The committed spec and fix complete native unfused attention. Fresh review of 15d8e1682 returned PASS with no findings: four CPU guard mutations redden both model modes (default and explicitly unfused), and the operator's six GPU mutation gates each redden its guarantee on gfx1100: G1 unregisters the split and reproduces the recorded pre-fix refusal at the production regression (57 of 58, 10,457 assertions, vt: no kernel for op AttnGateSplit), G2 swaps the per-head query/gate layout, G3 replaces the nearest-even BF16 narrowing, G4 makes the gate widening lossy, G5 modifies the input, and G6 removes the current-device binding. Pristine rebuilt-head reruns of the five receipt gates exit zero. The operator receipts, the review report, and the mutation logs are retained with the row evidence, and the full preflight at 6607faea2 exits zero with the argument-dependent skips separately recorded.

Speed claims

This pull request makes no speed, latency, memory-ratio, or invocation-parity claim. The capacity-four materialized-oracle subcase matches all 256 generated IDs across both repeats. Matching rocprofv3 artifacts capture both executing paths, but native BF16-to-F32 outputs and atomics policy differ from the primary BF16-to-BF16 path.

Honest gaps

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Codex:gpt-6-astra [Codex CLI]

ROCm expands F16 GGUF weights because its ordinary GEMM and embedding
providers reject their storage type. Define the default loader path and
model-dtype rounding contract before implementation under mudler#3092.

The spec requires explicit operand metadata, production reachability,
exact-token comparison, paired dtype traces, and measured scratch memory.
The per-row issue and inventory avoid a shared parent-matrix edit.
Implementation and GPU measurements remain pending on this row.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
The default Qwen3.5 registry currently expands F16 embedding weights on ROCm. Pin the production admission regression and the exact model token workloads before changing that behavior for mudler#3092.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
A full-attention Qwen3.5 model loads but fails completion because the
shared forward validates unused recurrent metadata against zero slots.
Define the consumer checks, existing input-builder reuse, public red,
pinned oracle workload, and mutation gates before implementation.

This specification on row/ENG-QWEN35-FULL-ATTN-STATE tracks mudler#3098.
Implementation and runtime verification remain pending. This commit
changes no product code and makes no performance claim.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Codex:gpt-6-astra [Codex CLI]
…aph owners

The initial scratch pool bounds each queue but retains destroyed queues
until process exit. Extend mudler#3092 to the existing ROCm lifecycle hooks so
repeated engine creation can release scratch without invalidating active
graphs. The operator approved this scoped backend extension before its
product edits. Require lifecycle red, both graph APIs, and dedup handles.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
Retain eligible Qwen3.5 embedding and projection storage for mudler#3092 while
preserving each weight's resolved BF16 or F32 values. Carry that metadata
through shared residency and tensor views, and route conversion through
the native ROCm GEMM and gather providers. Scratch follows queue and graph
ownership so repeated engines release allocations without breaking replay.

The ported primitive fixtures, ownership mutations, two-device checks,
and repeated capacity-four model requests pass. Full CPU and HIP suites
retain independently reproduced baseline failures under mudler#3070, mudler#3102,
and mudler#3105. The explicit full-attention-only head gate awaits mudler#3098 on
ENG-QWEN35-FULL-ATTN-STATE. The preserved D1/P128 and identical-GGUF primary
gates remain open under mudler#2773 and this row. No performance result or
invocation-parity result is accepted, and the row remains ACTIVE.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
The retained-F16 explicit-head fixture needs the reviewed mudler#3098 consumer
checks before it can enter the full-attention forward. Apply prerequisite
6a7bcb7 while preserving this branch's
F16 weight metadata. The Qwen27, Qwen35, graph, and registry CPU suites pass.
The unchanged HIP fixture now reaches a missing native AttnGateSplit provider.
The row retains that failure and makes no complete-forward or speed claim.

Refs mudler#3092, mudler#3098

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
…ssion

The full-attention-only runner test still expects the former forward-side
GDN refusal. Specify its successful execution and state checks before
correcting the test. Keep fixture geometry and runner topology unchanged.

Refs mudler#3098

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
The reviewed consumer checks make the full-attention runner fixture succeed,
so its old exception expectation now fails. Require completed execution,
changed attention state, a valid sampled token, and request feedback.
Preserve the existing fixture and keep GDN state absent.

The focused case passes 18 assertions. All 41 CPU runner cases pass with
1914 assertions. Restoring unconditional dense GDN validation fails the
corrected case at the original refusal. Product bytes remain unchanged.

Refs mudler#3098

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
Fresh review could remove three production guards without failing their
existing tests. Enter incompatible dtypes through the model registry, enter
marked embedding weights through a provider that cannot consume them, and
exercise both ordinary NN and BT compute overrides outside graph capture.

Each targeted guard mutation now fails its intended assertions. The fixed
CPU and physical gfx1100 controls pass. Scoped state restoration preserves
original environment values and provider enablement across the cases.

The integrated runner correction removes its obsolete refusal expectation.
The full CPU suite retains only the baseline token-anchor failure under
mudler#3102. The unchanged explicit-head HIP fixture reaches the separately owned
missing AttnGateSplit provider under mudler#3106. Keep the row active and retain
all oracle and performance limitations in its records.

Refs mudler#3092, mudler#3098, mudler#3106

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
The F16 fixture enters FullAttnBlockPaged through the registered forward.
Correct its AttnGateSplit citation to identify the call that actually fails.
The fixture, implementation, gate results, and issue ownership stay unchanged.

This repairs F16-REPAIR-REVIEW-4 under mudler#3092 on
row/BACKEND-ROCM-F16-WEIGHTS-citation-repair. F16-G3 still fails under
mudler#3106. The primary oracle qualifications and performance gates stay open.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:gpt-6-astra [Codex]
The retained-F16 production fixture reaches an absent ROCm split provider.
Its next rotation call rejects the loader's existing zero-width value.
Specify native split coverage and the measured identity adaptation before
implementation. Preserve the fixture and shared primitive validation.

The operator measured default primitive identity in both dtypes and retained
the explicit HIP launch failures. These measurements do not establish an
upstream model configuration or an alternative GGUF default. Issue mudler#3106
owns the complete production repair under its dedicated child row.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Codex:gpt-6-astra [Codex CLI]
The completed forward exposes equal-width projections in the old observer. Bind the head witness to returned device logits and its physical weight before repairing mudler#3112. Product and test implementation edits remain unstaged.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Codex:gpt-6-astra [Codex]
The dense GGUF head widens its BF16 GEMM output before returning logits. Extend the mudler#3112 witness through that actual native cast so its pointer checks describe the executing chain.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Codex:gpt-6-astra [Codex]
The retained F16 registered forward stops at an unregistered ROCm split. Add the native per-head copy for every F32/BF16 pair and skip only zero-width model rotation after normalization. Preserve shared validation and all fixture bytes.

The completed forward exposes an equal-width observer collision. Bind its exact head witness through the actual native BF16 cast and completed outer GEMM, preserving the exact-one assertion for both tied modes. This repairs mudler#3106 and mudler#3112.

The operator focused gate passes all 58 GGUF cases and 10970 assertions, plus native split, both devices, 64-bit offsets, and model controls. CPU focused gates pass and the full CPU suite retains only the proven mudler#3102 baseline failure. Full HIP CTest, final preflight, and independent review remain pending at this review head. The row remains ACTIVE and makes no performance claim.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Codex:gpt-6-astra [Codex]
Fresh review returned PASS with no findings, the six operator GPU mutation
gates each redden their guarantee at 15d8e16, and the pristine rebuilt-head
reruns of the five receipt gates exit zero. Refs mudler#3106.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:deepseek-v4-flash [DeepSeek Harness]
@VikashLoomba

Copy link
Copy Markdown
Contributor Author

CI triage — so the red checks can be read at a glance.

Four of the five red checks here are red in the same way on origin/main at 8df67640d, in main's own run 34538060205:

Check Failure Main evidence
sanitize-cpu (address,undefined) test_dots3_note_vision, test_dots3_note_audio, test_openai_api_server_dots3_mm_forward job 103074166410 fails the same three tests
sanitize-cpu (thread) test_gemma4_moe_fp8_native_arm_guard job 103074166517 fails the same test (its number is 162 there and 163 here because this branch adds one test)
windows-msvc-cpu test_openai_api_server.exe exits -1073740791 (0xC0000409) at localiser cases 58/59/61 job 103074166371 is the same crash and exit code
windows-msvc-vulkan the same crash and exit code job 103074166311

The fifth, build-test-cpu, is a wall-clock flake in a path this diff never calls:

tests/vt/test_cpu_threadpool.cpp:610: MESSAGE: empty-op dispatch: 2 threads 0.421 us, 5 threads 42.75 us, ratio 101.544
ERROR: CHECK( ratio < 100.0 ) is NOT correct!

The arms 2 and 5 show the runner reported 4 cores. That case's own comment calibrates its 100x threshold on a 20-core box, where the arms are 10 and 21 and the recorded defect signature is an over arm of 2999-5996 us against 18-20 us fixed; the 42.75 us measured here is roughly 70x below the defect the case exists to catch, and the fitted arm's 0.421 us is about 4x below the 1.68 us that comment calibrates against. The measured path is Threadpool::Run with an empty body, which this branch never reaches: it changes attention and embedding gating in src/vt/ops.cpp. Tracked for the owning row as #3130. A re-run of the job should clear it.

pr-size passes on this pull request. mergeStateStatus is UNSTABLE because of the four pre-existing checks above.

… it never carried

`OwnedTensor::ViewOn` was introduced here to carry `weight_value_dtype` onto the
resident view, which is what the F16 work needs. It also copied `repacked`,
`q8_0_aligned` and `elem_kn_repacked`, and both `ResidentWeight` bodies were
switched onto it. That changed behaviour well outside this row.

The two arms deliberately own DIFFERENT marker sets. The CPU-alias arm aliases
host bytes and restores `repacked` and `elem_kn_repacked` only; the staging arm
uploads bytes verbatim and returns no markers at all. `q8_0_aligned` reached
neither, and `expert_stream_seam.h` records why: copying it "would change the CPU
lane's bytes rather than preserve them". `tests/vllm/models/test_qwen4_exp_inject_residency.cpp`
states the same invariant. Both comments became false the moment ViewOn copied
all three, and the shared helper in `dense_attn_block.h` is included by roughly
twenty-five model files, so the change reached DeepSeek-V4, Gemma, GLM and dots3
as well as CUDA, where `cuda_quant_dot.cu` selects a different physical Q8_0
decode on `b.q8_0_aligned`.

Nothing in the spec, the body or any commit message mentioned it, and no test
covers it, so it reads as accidental rather than intended. This restores main's
behaviour exactly: ViewOn carries `weight_value_dtype` alone, and each arm sets
its own markers explicitly. The second resident helper keeps returning the view
unchanged, which also matches main, where it returns `MakeTensor` with none.

If the propagation is actually wanted, it is its own row with its own red-first
test on the DSV4/CUDA `q8_0_aligned` path, not a silent rider on an F16 change.

Refs mudler#3092.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5-1m [claude-code]
localai-org-maint-bot added a commit that referenced this pull request Sep 11, 2026
…radicts the canonical record (#3144)

`GATE-PR-BODY-TRAILERS`. Refs ISSUE-LOCAL-01M298Q7PPM145DQA5C30GRYJA.

## What changed

`squash_merge_commit_message = PR_BODY` makes a pull request body the
landed
commit message, so `Closes #N` in a body closes the GitHub mirror the
moment the
squash lands. Local files under `.agents/issues` are the issue
authority, and
nothing checked that the branch also carries `ISSUE-GH-N.md` reading
`State: CLOSED`. The two authorities diverge at the merge, and the
authoritative
half is the one left reading OPEN.

`scripts/agent-pr-body.py` now refuses such a body. It already fetches
the live
body and already runs before a merge, which is exactly when this
matters.

## Why here, and why only closing keywords

`check-agent-record.py` cannot catch it: it is offline and never sees a
body,
and `check_canonical_issue_references` silently `continue`s on an
unresolvable
bare `#N`. Making that strict was the obvious repair and is the wrong
one.
Measured over four open pull requests, bare citations lacking a local
record run
6 of 7, 4 of 4, 8 of 8 and 10 of 11 — so failing them would fire the
gate on
ordinary work, which AGENTS.md names as the defect rather than the
discipline.
The rule therefore keys on the closing keyword alone.

## Evidence

Red before: a body closing an issue with no record exits 1 naming the
missing
path. Green after: a bare `Refs #N` still exits 0. Both are committed as
cases
in `tests/scripts/test_agent_pr_body.py` (suite: 21 passed, 16
subtests), and
the spec's `## Tests` table is updated because that table is compared
with the
loaded suite rather than sampled.

Found live on four pull requests in one review pass: #3101 carried a
closing keyword for #3098, whose
record read OPEN; #3095 did the same for #3092 while that row's own gate
table reads
FAILING; #3096 carries five closing keywords against four OPEN records
and one
issue with no local record at all; #3097 likewise for #3093, against a
spec saying the
row is not ready to land. On its first live run against #3095 it also
caught a closing keyword for #3106, which the human review pass and I
had both missed — that record
reads OPEN and its Resolution says it stays open until the reviewed
production
repair lands.

The spec's `Kind` line is amended in the same change, because it claimed
this
row edits no checker rule and now it does.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5-1m [claude-code]

Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
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.

2 participants