Skip to content

qwen38: drafted-plan headroom counts the stage card's reserves - #793

Merged
juliankang4 merged 1 commit into
midagedev:mainfrom
juliankang4:dgx-spark-fix-786-qwen3-8
Oct 24, 2026
Merged

juliankang4 merged 1 commit into
midagedev:mainfrom
juliankang4:dgx-spark-fix-786-qwen3-8

Conversation

@juliankang4

Copy link
Copy Markdown
Collaborator

이 PR은 드래프트 계획의 카드 headroom 계산에서 카드의 이름 붙은 reserve가 빠지던 문제를 고칩니다.

What and why

plan_mtp_with and plan_mtp_with_slots in crates/model/src/arch/qwen35moe/place.rs added up the target card's terms from a hand-written list. The list left out the card's named reserves, so on a card that has one (for example the activation forms reserve) the drafted plan's headroom read too high.

Both functions now take the total as the card's own byte count plus the draft's reserve, so the bound and the headroom count the same terms. The sum uses checked_add. A total past u64 returns PlacementError::CardBytesPastU64 with the card's name, where a saturating sum would have produced a plan that looked valid and had no headroom.

The gate in gate_qwen4exp_mtp.rs checked the planner's identity as MtpPlan::headroom = T.headroom + T.reserves - R. The planner now computes T.headroom - R, so the gate's identity and its comment say that.

Release notes: Fixed: The drafted plan's headroom on a card with named reserves no longer reads too high.

Code shape

  • No second copy. The two planner functions share the card's byte count instead of two hand-written term lists.
  • Model code holds only architecture facts. No per-model branch, flag or method was added.
  • Dead code is gone. The two term lists are removed; nothing new is left unused.
  • No silent failure. A sum past u64 is a named error.
  • Comments state what is true now.
  • No relaxed gate. The gate's identity changed to match the planner, and no band or tolerance moved.
  • cargo fmt was applied. cargo clippy was not run for this PR.

Duplication found or removed: the two eight-term sums in plan_mtp_with and plan_mtp_with_slots are removed (crates/model/src/arch/qwen35moe/place.rs).

What I ran

cargo test -p bloomery-model --lib qwen35moe::place

Result: rc 0.

The new test a_draft_reserve_past_u64_is_refused_by_name gives the card u64::MAX usable bytes and a named reserve of u64::MAX minus the target's other terms, for one slot and for two. Without the fix it failed at "1 slots" with rc 101. With the fix it passes.

The new test drafted_headroom_counts_the_stage_cards_reserves gives the card a named reserve and checks, for one and two slots, that the drafted headroom equals the card's usable bytes minus the target's terms minus the draft's reserve. It is part of the run above.

Not run: the full t0 tier.

GPU evidence

The gate binary changed (the identity expression and its comment), so I ran its fixture tier on a GB10 card:

nvidia-smi
BLOOMERY_BOX_LOCAL=1 BLOOMERY_TIER=fixture just gate-gpu-qwen4exp-mtp
| NVIDIA-SMI 595.84                 Driver Version: 595.84         CUDA Version: 13.3     |
|   0  NVIDIA GB10                    On  |
clauses: 28 ran, 4 left to the real tier
gpu-gate.sh: gate_qwen4exp_mtp ... (exit 0)

The gate exited 0. The four clauses left to the real tier did not run in this fixture run.

What I ran into

This does not block review. The four clauses above need the real tier, which I did not run. A maintainer needs to run it on a card.

Hardware (if the change is for a machine)

One DGX Spark (NVIDIA GB10, driver 595.84, CUDA 13.3), fixture tier only. The unit tests are host-only and open no card.

AI help

AI 코딩 에이전트가 코드를 작성한 후 설명을 썼고, 테스트를 마쳤습니다. diff 리뷰와 PR 초안 리뷰는 제가 직접 했습니다.

plan_mtp_with and plan_mtp_with_slots summed the target card's terms without its named reserves, so the single-card headroom ran high by the activation-forms reserve on an integrated card. The sum is CardTotals::bytes plus the draft's reserve, and the gate's identity is T.headroom - R.
@github-actions github-actions Bot added gpu The card engine: crates/gpu*, crates/app model The CPU engine and model files: crates/model, models, hf, gguf, tokenizer, jinja needs-gpu Changes code a card must check, and carries no gate run on a card labels Oct 24, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: CLEAN: Both drafted planners count named reserves and check the addition for overflow.

Non-blocking

⚠ Complete the GPU witness: crates/gpu-gates/src/bin/gate_qwen4exp_mtp.rs:6183. The fixture run deferred (pg), so it did not execute this changed assertion. Supply real-tier output with both commit hashes and the model identity. Use a card with nonzero named reserves to exercise the changed equation.

Checked

  • Duplicates: the 2 new tests exercise named-reserve headroom and addition overflow. Dryer reported no pairs in crates/model. Both planners reuse CardTotals::bytes().
  • Complexity: crapper reported no changed function crossing its thresholds. The production changes add checked arithmetic without new branches.
  • Silent failure: both additions return CardBytesPastU64 with the card name on overflow. Tiered plans retain their existing reserve accounting.
  • Tests: static mutation review only; tests were not executed here. Omitting reserves at crates/model/src/arch/qwen35moe/place.rs:848 or its multi-slot counterpart fails the headroom assertion. Replacing checked_add at line 849 or its counterpart with saturation fails the overflow assertion. Both tests cover 1 and 2 slots. Flipping the gate equality makes fit false when (pg) runs.
  • Gates: the identity includes named reserves through the target card's headroom. No band, tolerance, threshold or clause was removed or relaxed.
  • Escape catalog: C1–C4 do not match. The diff changes placement and gate code, with no decode or prefill work added.

Notes

Dryer excluded crates/gpu-gates; the changed assertion was checked manually.

Card check: needs-gpu. This pull request changes crates/gpu-gates/src/bin/gate_qwen4exp_mtp.rs and carries no gate run on a card (CONTRIBUTING's evidence list); a maintainer adds gpu-verified after one.

🔨 Shingler, bloomery's review bot: approves a clean pull request and requests changes on a must-fix (how it works)

@juliankang4

Copy link
Copy Markdown
Collaborator Author

The review is done and the contribution check passed, so I'm merging this.

@juliankang4
juliankang4 merged commit f485b64 into midagedev:main Oct 24, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gpu The card engine: crates/gpu*, crates/app model The CPU engine and model files: crates/model, models, hf, gguf, tokenizer, jinja needs-gpu Changes code a card must check, and carries no gate run on a card

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant