Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .agents/issue-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ rather than merged. `scripts/check-agent-record.py` gates both.
| [#1325](https://github.com/mudler/vllm.cpp/issues/1325) | `ENG-RECORD-ANCHOR-RATCHET` | `scripts/record-anchor-baseline.json` stores a `"total"` that no code reads. `load_record_anchor_baseline` in `scripts/check-agent-record.py` returns `{bucket: int(data["buckets"][bucket]) for bucket in RECORD_ANCHOR_BUCKETS}` with `RECORD_ANCHOR_BUCKETS = ("stale", "broken")`, and it is the file's only reader; `check_record_anchors` iterates those two buckets, and `write_record_anchor_baseline`'s refusal compares `result.total > sum(previous.values())` — the buckets, not the stored `total`. Measured at `af87251c5`: mutating `"total": 38` to `39` (a file whose total disagrees with `32 + 6`) leaves `check-agent-record.py` exit 0, tree restored byte-for-byte by sha256. So this row's own budget file carries the exact shape the row exists to name: a recorded figure no gate reads, sitting beside the figures that are read and presenting as if it were checked. `--write-baseline` compounds it by printing `-> 38`, which reads as the value it stored and is the one no later run consults. TWO candidate resolutions, deliberately not chosen here because choosing belongs to the fixing row: read it and assert `total == stale + broken` on load, or drop the field and derive it at read time, which is the shape AGENTS.md §Records prefers. Either is a semantic change to `check-agent-record.py` owing a spec and a red-before case in `tests/scripts/test_agent_record.py` `RecordAnchorRatchet`. Distinct from [#1287](https://github.com/mudler/vllm.cpp/issues/1287) and [#1270](https://github.com/mudler/vllm.cpp/issues/1270), neither of which reaches the unread field. Also under `## Owed` in [`record-anchor-ratchet.md`](specs/record-anchor-ratchet.md) | bug |
| [#1316](https://github.com/mudler/vllm.cpp/issues/1316) | — | `scripts/main-baseline.py` renders a scheduled run that executed ZERO jobs as `RED` with all 11 covered jobs `missing`, so `NEWEST BASELINE: RED at <sha>` names a tree the run never checked out. Measured at `origin/main` `250db75a2`: runs `32206456661` and `32140419182` both return `startedAt: null` for every job, because GitHub cancelled them while they were pending in the single `ci-schedule-refs/heads/main-mudler/vllm.cpp` group, whose queue holds one run ([#274](https://github.com/mudler/vllm.cpp/issues/274)). Fail-closed, and the `missing (expected, never ran)` line is accurate about the jobs; the defect is the verdict word, because a run that executed nothing is NOT RUN rather than RED, and the newest verdict should fall through to the newest run that actually ran. NOT fixed in flow: `test_an_expected_job_the_payload_never_mentions_is_red` and `test_a_narrowed_run_reports_red_and_names_what_never_ran` deliberately assert missing-is-red so a narrowed run cannot pass, and separating "narrowed" from "never started" changes what the verdict means, which owes its own spec, red-before evidence and a fresh reviewer. Owed under `## Owed` of [baseline-lane-eviction.md](specs/baseline-lane-eviction.md), which removes the only observed producer of a zero-job run | bug |
| [#1314](https://github.com/mudler/vllm.cpp/issues/1314) | `SPEC-DFLASH2` | **DFlash2 (`DFlash2DraftModel`) is unported**, and one config rule would run the published checkpoint wrong in silence. Upstream carries DFlash2 as a SECOND architecture beside DFlash rather than as a change to it ([vllm#52816](https://github.com/vllm-project/vllm/pull/52816), OPEN at head `19c9351904df4c63042671bc67a866ca48dc7d6f`, base `9842d701`, 755+/5-, 11 files, plus the stacked guard fix [vllm#52883](https://github.com/vllm-project/vllm/pull/52883)): DFlash1 gains two subclass seams and keeps every behaviour, and the new architecture adds a GROUPED DYNAMIC DEPTHWISE CONVOLUTION around each attention and each MLP sublayer plus a CANDIDATE SELECTOR that replaces the independent per-slot argmax with a scored path walk over the target head's top-K. Shapes taken from the published checkpoint rather than from the diff: `z-lab/Qwen3.8-27B-DFlash2`, safetensors header range-read 2026-08-19, 81 tensors -- DFlash1's set plus `layers.N.{attention,mlp}_conv.{base_kernel (2,2,5120), kernel_projection.weight (1280,5120)}` x5 and `candidate_selector.{hidden_projection.weight (256,5120), predecessor_codebook, successor_codebook}` at `(248320,256)` bf16 each, ~254 MB resident the DFlash1 lane never allocates; `conv_kernel_size 2`, `conv_group_size 16`, `selector_rank 256`, `selector_top_k 16`, `block_size 8`. **The silent one:** that config declares all five layers `sliding_attention` AND `is_causal false`, while our resolution mirrors the OLD upstream rule (causal iff SWA, unless `dflash_config.causal`, `include/vllm/model_executor/models/qwen3_dflash.h:22-24`), so every layer would run CAUSAL -- plausible tokens, a token gate against our own output sees nothing, and only ACCEPTANCE moves, which the lossless verify hides. Upstream changes `_dflash_layer_causal` to read `is_causal` first, in the same commit. Three further things are owed and none of them is silent: no route for the `DFlash2DraftModel` architecture string (the same classification code as the open `DSparkDraftModel` gap, [#1193](https://github.com/mudler/vllm.cpp/issues/1193)); no top-k that EMITS the surviving (id, value) pairs, where the decision is to extend the sort-free pivot-bracket threshold search already ported from the same FlashInfer approach at `src/vt/cuda/cuda_sample.cu:297-506` rather than port FlashInfer's 3380-line general radix kernel; and the path walk must run ON DEVICE from the first landing, because the identical sequential shape in DSpark shipped host-side and measured 28% of the 27B draft step ([#436](https://github.com/mudler/vllm.cpp/issues/436)) before `SampleSequentialDevice` moved it. Already reusable unchanged: `vt::DFlashBlockAttention`, the DFlash runner/rejection/GDN-rollback lane, and the loader's target-shared `embed_tokens`+`lm_head`, which is already what a DFlash2 checkpoint needs. BEYOND-PIN by developer decision 2026-08-19 (mirror the open PR now, reconcile if review moves it), in the same posture `SPEC-DSPARK-QWEN3-ROUTING` takes toward vllm#52197; the parity pin `555967922` does not carry the architecture and is NOT advanced. Gate arm is bf16 27B plus the GGUF drafter arm in the same wave, oracle = vLLM built at the PR head, acceptance measured SAME-TRAJECTORY because `SPEC-DFLASH` D8 spent a campaign on a divergent-trajectory confound that D9 refuted. Spec [dflash2-spec-decode.md](specs/dflash2-spec-decode.md) | feature |
| [#1332](https://github.com/mudler/vllm.cpp/issues/1332) | `BACKEND-ATTN-REGISTRY` | The attention-backend selector routes nothing, and a capability check is not a runnability check. `vllm::v1::SelectAttentionBackendName` (`src/vllm/v1/attention/registry.cpp`) mirrors vLLM's priority walk faithfully, and its result reaches only `attn_backend_names_`, a `VT_ATTN_SELECT_LOG` print and `CheckKvCacheShape` in `runner.cpp::GpuModelRunner::InitializeKvCache`; `dense_attn::AttnBlock` calls `vt::PagedAttention` unconditionally and the real arm choice is an env-flag + shape + dtype ladder in `src/vt/cuda/cuda_paged_attn.cu`. Deleting the whole selector would leave every emitted token identical, which is `.agents/reachability.md`'s "unselected branch" and "unpassed parameter" at once. Separately, measured on a GB10 (capability 12,1): vLLM selects `FLASH_ATTN` because `supports_compute_capability` is `capability >= (8,0)`, while the shipped FA2 binary carries `sm_80` SASS plus `compute_80` PTX alone, so every launch needs a driver JIT that fails with `cudaErrorUnsupportedPtxVersion` — `grep -rn get_arch_list vllm/` returns zero hits, so vLLM never asks what its own fatbins contain. We have written the same class of check: `src/vllm/platforms/cuda.cpp::CudaPlatform::supports_fa2_attention` returns true for every CUDA device while `CMakeLists.txt` defaults `VLLM_CPP_CUDA_ARCHITECTURES` to `121a` alone. The invariant: no backend may be declared valid on the strength of a property of the DEVICE alone; every predicate naming a compute capability must be paired with one naming the binary. M0 (reconcile) and M1 (the `validate_configuration` capability surface) land in [`attn-validate-configuration.md`](specs/attn-validate-configuration.md); the compiled-arch manifest, the launch probe, the dispatch wiring and the ABI override remain owed there under `## Owed` | bug |
| [#1333](https://github.com/mudler/vllm.cpp/issues/1333) | `BACKEND-ATTN-REGISTRY` | The non-MLA sm_100 attention priority row misses the `use_non_causal` guard the pin added. `include/vllm/platforms/cuda_attn_priority.h::AttnPriorityTable` keys rows on `(use_mla, major)` and cites `vllm/platforms/cuda.py:143-166` `@ pin e24d1b24`; at the tree pin `5559679229` that arm reads `if device_capability.major == 10 and not use_non_causal` (`cuda.py:148`) with `use_non_causal` added as a fifth `_get_backend_priorities` parameter (`cuda.py:88`), because SM100f's non-causal cutlass path — the one DFlash attention uses — is known-bad (`cuda.py:145-147`). No selected name changes in this tree today, since `FLASHINFER` is registered for no device and both orderings fall through to `FLASH_ATTN`; it becomes a real divergence the moment a FlashInfer backend registers, and it is already a divergence in the record because the header claims a faithful, complete port of that function. Found while reconciling the four `@ pin e24d1b24` header anchors under [#1332](https://github.com/mudler/vllm.cpp/issues/1332) M0 and fixed in the same flow, since `use_non_causal` is a field M1 adds to `AttnSelectorConfig` regardless. Spec [`attn-validate-configuration.md`](specs/attn-validate-configuration.md) | bug |
| [#1309](https://github.com/mudler/vllm.cpp/issues/1309) | `MUSIC3-DEPTH-DEVICE` | MiniMax-Music3's 0.646 B RVQ depth decoder is **48.4 % of a run** on `thor:gpu0` and is the last large stage still on the host, so a 0.646 B model costs **6.3x** the 8.6 B language model beside it on the same box. §11.4's last owed device row: the vocoder closed in §13, the DiT in §14, and §14.5 blocked this one on a dtype rather than on the work. **The dtype is settled in [§19.2](specs/minimax-music3.md): bf16 storage, f32 accumulation.** The oracle settles it by declaring nothing — `MiniMaxMusic3RVQDepthDecoder` takes no `dtype` parameter and contains no `torch.float32` literal and no `.float()` call (`diffusers` @ `c6da9936`, `models/transformers/minimax_music3_rvq_depth_decoder.py:101-125`); its one cast is the **down**-cast `:51` `.to(query.dtype)`; and `tools/oracle/music3_oracle.py:91-95,103-108` resolves `rvq_depth_decoder: torch.bfloat16` under both policies. `vt::MatmulBT` already carries exactly that contract (`include/vt/ops.h:1281-1283`), so §14.5's objection — that an **f32** `vt::MatmulBT` would drop the bf16 rounding every gated number was taken with — is answered by using the **bf16** one. A finding falls out that no gate here can see: the host arm keeps bf16-exact weights in `std::vector<float>`, so every golden, token gate and WAV hash passes while the path moves twice the oracle's bytes ([§19.2a](specs/minimax-music3.md)) | feature |
| [#1322](https://github.com/mudler/vllm.cpp/issues/1322) | `MUSIC3-DEPTH-DEVICE` | `vt` cannot express torch's **per-op bf16 rounding**, and no caller can build it. A bf16 torch module rounds at every op boundary; `vt::RmsNorm` keeps full f32 across the weight multiply (`include/vt/ops.h` says so) where `normalization.py:600-606` casts back to the weight dtype first, and `vt::SiluAndMul` computes `silu(g)*u` wholly in f32 where `F.silu(gate)` produces a **bf16 tensor** that is then multiplied. MEASURED on MiniMax-Music3's depth decoder ([#1309](https://github.com/mudler/vllm.cpp/issues/1309), spec §19.4a): the device arm reads worst **110 bf16 ULP** / mean **2.095** against the host reference, and collapsing those two host roundings to the seam's shape takes it to worst 8 / mean 0.0596 and the composed stage to **ZERO — bit-identical**. So ~97 % of the deviation is rounding POLARITY inside two shared ops, not dtype, accumulator or reduction order. A call site cannot split them, because `vt` has no elementwise or row-broadcast multiply — `kMulScalar` takes a scalar and `kMulColVecF32` is an f32 in-place column scale. Closing it needs either a `vt::Mul` with `vt::Add`'s two operand shapes or rounding-faithful modes on the two ops, with CPU and CUDA providers; #1309 records the measurement and stops. A token gate cannot see any of this | bug |
| [#1351](https://github.com/mudler/vllm.cpp/issues/1351) | `MUSIC3-DEPTH-DEVICE` | `scripts/check-fusion-consistency.py` Check 2 is satisfied by a **COMMENT**: it runs `_MERGED_GEMM_SEAM` over `path.read_text()` with no comment stripping, so a model TU that merely *mentions* `MlpGateUpMethod` in prose is exempt from the check forever. Measured on `minimax_music3_depth_device.cpp` ([#1309](https://github.com/mudler/vllm.cpp/issues/1309), spec §19.7): replacing the `layers::UnquantizedMlpGateUpMethod` call with an inline hand-rolled `vt::MatmulBT` + `vt::SiluAndMul` path while leaving the two comment mentions gives `uses_merged_gemm_seam = True` and the checker returns **rc=0 green**, with the numbers bit-identical so no other gate sees it; stripping comments flips it to `False`. The only comment-aware helper in the file, `allowlisted_names`, strips `#` comments from the allowlist FILE rather than from the scanned source. NOT a defect: `MlpGateUp[A-Za-z]*Method` matching a renamed `MlpGateUpXX` is deliberate, to cover `UnquantizedMlpGateUpGeluMethod`. Fixing it is a semantic checker change — spec, red-before test, green-after evidence — and must not be done by widening the regex; stripping comments also moves the site count, so a fixture must pin both numbers | bug |
Expand Down
Loading
Loading