Skip to content

feat(ds4v): dflash vision serving runtime with bounded IQ85 conversion - #722

Open
marcelormendes wants to merge 85 commits into
Luce-Org:mainfrom
marcelormendes:ds4v/quant85
Open

feat(ds4v): dflash vision serving runtime with bounded IQ85 conversion#722
marcelormendes wants to merge 85 commits into
Luce-Org:mainfrom
marcelormendes:ds4v/quant85

Conversation

@marcelormendes

@marcelormendes marcelormendes commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

DeepSeek V4 Flash Vision serving on the Strix Halo + 7900 XT pair, plus a bounded IQ85 converter for the abliterated parent. 83 commits, 135 files, +14651/−59.

Vision serving

  • Bounded image prompts integrated into the HIP serving path (03edb38), with image policy, transport, preprocess and prompt-ownership units and a CPU composition proof.
  • Standalone mmproj exporter (export_ds4v_mmproj.py) verified lossless: 267 tensors, 932786176 payload bytes compared against the parent by an independent reader.

Serving memory, prefill and decode

  • Release bulk prefill arenas before hybrid decode; trim cached GPU pools before bulk heterogeneous prefill; stage HIP dense uploads through bounded host scratch.
  • Reclaim copied mmap source pages and release the copied model file cache during hybrid GPU loading; pageout and loader staging fixes.
  • Bound the paired decode attention cache to the current shape; trim returned pool blocks between long prefill chunks; acknowledge every HC worker job generation.

Text correctness

  • Widen BF16 norm vectors at the affine boundary (fixes the GPU binary broadcast assertion seen at first chat).
  • Scope the biased-linear-rounding workaround to GPU backends; CPU outputs stay byte-identical to 4bf7270.

Tooling

  • server/tools/ds4v_vision/ probes and contracts, ds4v_preprocess_probe, and --recipe iq85 in ds4_mix_converter: IQ2_XXS gate/up, IQ2_XS down, Q8_0 for dense text matrices, vision/aligner/router/indexer/norms/biases preserved, reading the original safetensors rather than a previously quantized GGUF. New test_ds4_iq_converter.

Verification status — gates unchanged, nothing here is a quality claim

  • Text chat: PASS with the narrow BF16 norm fix (7071946, binary c32e5ae3); short decode 15.9/16.4/17.4 t/s.
  • Vision: features remain below the fixed 0.9995 cosine gate — native corn 0.99822935, first native HIP run 0.9859 (exit 3). Tower A is the experimental base; the numerical verdict is still ISSUES and runtime integration stays blocked.
  • IQ85 candidate: conversion completed and verified structurally (83,619,648,416 bytes, SHA256 954433dc…), but the frozen quality gate failed (12/16 content, 5/16 strict) and median decode was 20.1 t/s against a 35 t/s target. No candidate was installed; the original service was restored.
  • Cached speculative attention: preserved ring-row views used construction-time offsets while write indices advanced; the gather-based fix produced 22/22 identical visible replies across cache2/cache4 versus 19/22 before.

Full receipts: artifacts/ds4v-quant85/README.md, docs/ds4v-continuation-status.md, decisions-ds4v-continuation.tsv.

Notes

Binary trial evidence (requests, responses, journals) is retained outside the repository. The converter path is experimental and, per the evidence above, does not yet meet the target quality or speed.

Review in cubic


Upstream sync

upstream/main (2f0eff05) is merged into the branch (6d762d8e) so the PR applies cleanly again. Conflict resolutions:

  • ggml: both extension op sets kept (the four DS4V vision ops plus GGML_OP_DS4_MOE_COMBINE); GGML_OP_COUNT 105 → 110 in the enum and in both ggml.c tables.
  • Hybrid budget: compute_ds4_hybrid_budget_info now takes both with_vision and paged; it charges paged KV on the primary target and still reserves the vision scratch allowance via vision::remaining_expert_budget.
  • Attention: build_mla_attention_lane_core takes upstream's prepared lane and out_attn_context alongside the image span view; the contiguous wrapper forwards image spans so existing callers keep working.
  • Snapshot: upstream moved the helpers to deepseek4_snapshot.cpp; this branch's inline copies were byte-identical to the merge base, so they were dropped and deepseek4_release_image_scratch was kept.

Local checks on macOS with clang (C++17, HIP headers stubbed — Apple has no HIP): ggml.c compiles clean and the op enum plus both tables contain 110 entries; deepseek4_graph.cpp, deepseek4_backend.cpp, deepseek4_snapshot.cpp, deepseek4_paged_cache.cpp, the image units and test_deepseek4_unit.cpp all pass -fsyntax-only. No link or GPU-run verification was possible here. Upstream CI runs for this head are in action_required (maintainer approval pending), so the CUDA build has not executed yet.

CPU-only tool turning abliterated Vision-Exp safetensors into
ROCmFPX MIX GGUF. Down experts to qtype 105 with embedded P4MIXv1
codebooks. Gate and up experts to qtype 106 with a split GUMIXs1
sidecar. Vision, aligner, image and bias_vl tensors pass through
losslessly. Calibration needs an imatrix file or explicit
absmax-only. Includes block codec roundtrip plus layout plus
rejection unit test.
…evidence

Adds the operator handoff for the DeepSeek V4 Flash Vision work: the
continuation status authority, the DS4V vision plan it supersedes, the
four decision logs for the DS4V-1/2/3 and continuation passes, and the
IQ85 candidate evidence summary describing conversion output, trials
and the unmet quality/speed gates.

No code changes.
Reconciles the vision image-prompt work with upstream's paged-serving
refactor. Conflict resolutions:

- ggml: keep both extension op sets (four DS4V vision ops plus
  GGML_OP_DS4_MOE_COMBINE); GGML_OP_COUNT 105 -> 110 in the enum and both
  ggml.c tables.
- deepseek4 budget: compute_ds4_hybrid_budget_info now takes both
  with_vision and paged, charges paged KV on the primary target and still
  reserves the vision scratch allowance through
  vision::remaining_expert_budget.
- attention: build_mla_attention_lane_core takes upstream's prepared lane
  and out_attn_context alongside the image span view; the contiguous
  wrapper forwards image spans so HEAD callers keep working.
- snapshot: upstream moved the snapshot helpers into deepseek4_snapshot.cpp
  (HEAD's inline copies were byte-identical to the merge base), so the
  duplicated definitions were dropped and release_image_scratch was kept.

@cubic-dev-ai cubic-dev-ai 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.

38 issues found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="server/tools/ds4v_image_prepare/verify.py">

<violation number="1" location="server/tools/ds4v_image_prepare/verify.py:27">
P1: Running this verifier with Python optimization (`-O` or `PYTHONOPTIMIZE`) removes the hash, count, and probe-status checks, allowing invalid fixtures or a failing probe to produce a `PASS` verdict. Replace these assertions with explicit exceptions or return-code checks.</violation>

<violation number="2" location="server/tools/ds4v_image_prepare/verify.py:30">
P2: If the native probe hangs, this wrapper waits forever instead of failing the qualification. Add a bounded timeout and convert `TimeoutExpired` into a nonzero verification result.</violation>

<violation number="3" location="server/tools/ds4v_image_prepare/verify.py:34">
P2: When a rerun fails after an earlier success, the old `verdict.json` remains `PASS` and can be mistaken for the current result. Remove or invalidate the existing verdict before validation, then publish the success artifact only after all checks pass.</violation>
</file>

<file name="server/tools/ds4v_image_prompt/verify_fixtures.py">

<violation number="1" location="server/tools/ds4v_image_prompt/verify_fixtures.py:20">
P1: When this verifier runs with `python -O` or `-OO`, Python removes the hash, count, and probe-status assertions, so invalid fixtures or a failing probe can still produce `PASS`. Replace these assertions with explicit exceptions or return-code checks.</violation>

<violation number="2" location="server/tools/ds4v_image_prompt/verify_fixtures.py:27">
P2: On a fresh checkout, the documented verification reaches this line and fails because the output parent directory does not exist. Create `a.output.parent` before writing the verdict.</violation>
</file>

<file name="server/tools/ds4v_vision/compare.py">

<violation number="1" location="server/tools/ds4v_vision/compare.py:22">
P1: When the reference manifest is empty or omits one required image, this loop skips that case and the comparator still exits 0. Validate the expected `corn` and `carrots` image set before iterating.</violation>

<violation number="2" location="server/tools/ds4v_vision/compare.py:25">
P2: When this verifier runs with Python optimization enabled, the fixture hashes and shape check disappear because they are `assert` statements. Replace these gate validations with explicit failure checks so an invalid reference cannot return a successful qualification.</violation>
</file>

<file name="server/CMakeLists.txt">

<violation number="1" location="server/CMakeLists.txt:383">
P2: On Windows, the default build enters this branch and fails compiling `ds4_mix_converter` because its source is POSIX-only. Gate this target on non-Windows or port the converter to the Win32 file APIs.</violation>
</file>

<file name="server/tools/ds4v_image_policy/verify_fixtures.py">

<violation number="1" location="server/tools/ds4v_image_policy/verify_fixtures.py:16">
P2: This verifier is only manually invoked, so routing or raw-mask regressions can ship while the configured CTest and CI suites remain green. Register it with the existing test framework or add a CI job that stages its required fixtures and model.</violation>

<violation number="2" location="server/tools/ds4v_image_policy/verify_fixtures.py:28">
P2: When this verifier runs with `python -O`, it skips all source, fixture, routing, and mask validation yet can still write `verdict: PASS`. Replace verification assertions with explicit exceptions, or reject optimized mode before running the checks.</violation>
</file>

<file name="server/tools/ds4v_vision/linear_source.cpp">

<violation number="1" location="server/tools/ds4v_vision/linear_source.cpp:75">
P2: On HIP, this assertion requires the unbiased lane to dispatch the fused vision operation, producing two fused nodes and two Lt launches. Keep the unbiased lane on the ordinary product/cast path and assert one fused operation and one launch for the biased lane.</violation>
</file>

<file name="server/tools/ds4_bf16_affine/CMakeLists.txt">

<violation number="1" location="server/tools/ds4_bf16_affine/CMakeLists.txt:7">
P2: `ggml/src/libggml-cpu.so.0` is the wrong path, so the EXISTS check always fails and the build aborts with FATAL_ERROR before it ever links. ggml-cpu is defined in the `ggml/src/ggml-cpu` subdirectory, so its built library lives at `${GGML_BUILD}/ggml/src/ggml-cpu/libggml-cpu.so.0` (ggml-base is at `ggml/src/` and ggml-hip at `ggml/src/ggml-hip/`, which are correct). Change the ggml-cpu entry to `ggml/src/ggml-cpu/libggml-cpu.so.0`.</violation>
</file>

<file name="server/tools/ds4v_image_integration/test.cpp">

<violation number="1" location="server/tools/ds4v_image_integration/test.cpp:216">
P2: This integration test is not part of the repository’s normal build or CI test gate, so regressions in these invariants can ship with every standard `ctest` run still passing. Add the coverage to the established server test target, or explicitly wire this standalone project into CI.</violation>
</file>

<file name="server/tools/ds4v_image_assembly/test.cpp">

<violation number="1" location="server/tools/ds4v_image_assembly/test.cpp:23">
P2: This coverage is absent from the normal `DFLASH27B_TESTS`/`test_server_unit` CTest run because this file creates a separate executable. Move these cases into the existing unit-test framework so standard server CI executes them.</violation>
</file>

<file name="server/tools/ds4v_vision/reference_math.py">

<violation number="1" location="server/tools/ds4v_vision/reference_math.py:58">
P2: When `OUTPUT_DIR` aliases `NATIVE`, the script overwrites each native tensor before reading it, so `native_vs_math` reports an artificial exact match. Read both inputs before writing outputs, or reject overlapping directories.</violation>

<violation number="2" location="server/tools/ds4v_vision/reference_math.py:59">
P2: If a reference fixture is stale or corrupted, this script accepts it as the baseline because it validates only source hashes. Verify each patch and reference file against the manifest before loading them, as `compare.py` does.</violation>
</file>

<file name="server/tools/ds4_mix_converter/ds4_mix_converter.cpp">

<violation number="1" location="server/tools/ds4_mix_converter/ds4_mix_converter.cpp:626">
P2: `--validate-input-only` cannot validate a source directory unless the caller also supplies an unused imatrix or `--absmax-only`. Exempt this mode from the mutually-exclusive calibration requirement for the non-IQ85 recipe.</violation>

<violation number="2" location="server/tools/ds4_mix_converter/ds4_mix_converter.cpp:903">
P2: When a global embedding or output weight is FP8, the converter fails on its companion `.scale` tensor after successfully pairing it in `mapped_source_spec`. Skip global FP8 scale entries during enumeration, as the layer path already does.</violation>
</file>

<file name="server/tools/ds4v_image_prompt/test.cpp">

<violation number="1" location="server/tools/ds4v_image_prompt/test.cpp:19">
P2: This test never runs in the repository’s normal `server` build or CTest suite, so regressions in `prepare_image_prompt` can ship while CI remains green. Integrate these cases with the existing server unit-test target and registration, or explicitly wire this target into the parent build rather than relying on a separately configured tool project.

(Based on your team's feedback about integrating new tests with the existing framework.)</violation>
</file>

<file name="server/tools/ds4v_vision/loader_tests.py">

<violation number="1" location="server/tools/ds4v_vision/loader_tests.py:25">
P2: The malformed-loader suite is not part of the normal CTest run, so CI can pass without executing these 16 rejection checks. Register this harness with CTest or move the cases into the existing test suite.</violation>
</file>

<file name="server/tools/ds4v_image_prompt/fixtures.cpp">

<violation number="1" location="server/tools/ds4v_image_prompt/fixtures.cpp:46">
P2: The added source-fixture coverage is not run by CTest, so layout regressions can ship while the registered suite remains green. Integrate these cases into the registered test target or register this executable conditionally with its fixture directory.

(Based on your team's feedback about extending tests through the existing test framework).</violation>
</file>

<file name="server/tools/ds4v_preprocess_probe/generate_reference_fixtures.py">

<violation number="1" location="server/tools/ds4v_preprocess_probe/generate_reference_fixtures.py:78">
P2: When `--output` names an existing directory, this recursively deletes the entire directory, including files unrelated to these fixtures. Refuse non-empty output paths or delete only files created by this generator.</violation>

<violation number="2" location="server/tools/ds4v_preprocess_probe/generate_reference_fixtures.py:135">
P2: When Python runs with `-O`, this assertion and the other assertions in `main()` disappear, so the generator can emit fixtures without checking source and rebuilt tensors match. Replace validation assertions with explicit exceptions that remain active in optimized runs.</violation>
</file>

<file name="server/tools/ds4_mix_converter/CMakeLists.txt">

<violation number="1" location="server/tools/ds4_mix_converter/CMakeLists.txt:17">
P2: When the build host has no network access, configuration fails even if `nlohmann_json` is already installed because this file never checks for a system package. Prefer `find_package(nlohmann_json CONFIG QUIET)` and retain the pinned FetchContent block only as a fallback.</violation>

<violation number="2" location="server/tools/ds4_mix_converter/CMakeLists.txt:45">
P2: The new fitter and IQ tests are invisible to the repository’s standard test command because this separate CMake project is not part of the parent test registration. Move these cases into the existing CppUnit suite or wire their targets into the parent CTest discovery so CI runs them.</violation>
</file>

<file name="server/tools/ds4_mix_converter/prove_iq85.py">

<violation number="1" location="server/tools/ds4_mix_converter/prove_iq85.py:44">
P2: When shard payloads or config/tokenizer files change without changing the index, this manifest still claims the same source. Record checksums for every source file consumed by the converter, or write a complete source checksum manifest.</violation>

<violation number="2" location="server/tools/ds4_mix_converter/prove_iq85.py:63">
P2: When a lane exceeds `--timeout`, the manifest omits its exit status and duration, and the wrapper exits with Python's generic failure status. Catch `TimeoutExpired`, record `exit_code=124`, save the lane, and terminate with status 124.</violation>
</file>

<file name="server/tools/ds4v_vision/reference_stages.py">

<violation number="1" location="server/tools/ds4v_vision/reference_stages.py:30">
P2: When this tool runs with Python optimization enabled, the source-integrity and fixture-reproduction checks disappear, so it can produce stage metrics from an unverified parent implementation. Replace these assertions with explicit conditional checks that raise an exception.</violation>
</file>

<file name="server/tools/ds4v_image_input/test.cpp">

<violation number="1" location="server/tools/ds4v_image_input/test.cpp:19">
P2: Adding `main()` here creates a second image-input test executable outside the server’s normal CppUnit/CTest suite. Move these cases into `test_server_unit` and remove the standalone runner so the coverage is discovered and maintained with the existing suite.

(Based on your team's feedback about extending tests through the existing test framework.) [2bd18e9d-595d-43f5-9a23-697c6928cbc2]</violation>
</file>

<file name="server/src/deepseek4/deepseek4_image_policy.h">

<violation number="1" location="server/src/deepseek4/deepseek4_image_policy.h:26">
P2: The interval comment gives `image_end` inclusive semantics, but `raw_key_visible` and the production caller use an exclusive end. Document the range as `[IMAGE_START, IMAGE_END)` so callers do not pass an inclusive endpoint and lose the final image key.</violation>
</file>

<file name="server/tools/ds4v_vision/probe.cpp">

<violation number="1" location="server/tools/ds4v_vision/probe.cpp:71">
P2: When a probe is rerun with an existing output directory, this silently overwrites qualification artifacts and can leave stale stage snapshots mixed with the new run. Require a fresh output directory, matching the other vision qualification tools, before writing any files.</violation>
</file>

<file name="server/tools/ds4v_vision/linear_rounding.cpp">

<violation number="1" location="server/tools/ds4v_vision/linear_rounding.cpp:49">
P2: `ds4v_linear_rounding` is never run by CTest, so this self-contained rounding regression check can silently regress. Register it with CTest or fold its case into `ds4v_linear_contract`.

(Based on your team's feedback about extending tests through the existing test framework.)</violation>
</file>

<file name="decisions-ds4v-continuation.tsv">

<violation number="1" location="decisions-ds4v-continuation.tsv:21">
P2: Spaces are stripped between words and numbers throughout this decision log, so factual records are hard to read and ambiguous: 'All129 tensors', 'complete2filemanifestpublishedbeforeexit0', 'staybyteidentical', 'nowpass but featuresstillfail', 'Implementation scopedPASS; targettowerexit3', 'test PID exited;8016not touched', 'PID3396669gone/KFDempty'. The PR frames this TSV as the record for future gating iterations, so restore the intended spacing so PID values, tensor counts, and exit codes are unambiguous.</violation>
</file>

<file name="server/tools/ds4v_image_prepare/compose.cpp">

<violation number="1" location="server/tools/ds4v_image_prepare/compose.cpp:46">
P2: When a custom Jinja template preserves the marker count but reorders or relocates markers, this check passes. `prepare_image_prompt` then pairs extraction-order images with rendered-order markers, attaching pixels to the wrong prompt position. Preserve per-image identity through rendering or reject templates whose marker sequence changes.</violation>
</file>

<file name="server/tools/ds4v_vision/norm_contract.cpp">

<violation number="1" location="server/tools/ds4v_vision/norm_contract.cpp:17">
P2: When core dumps are enabled, each intentionally aborted child can write a dump, so this test may create ten core files and exhaust CI disk or leave large artifacts. Disable core dumps in the child before exercising rejected inputs, as `attention_contract.cpp` does.</violation>
</file>

<file name="server/tools/ds4v_vision/linear_contract.cpp">

<violation number="1" location="server/tools/ds4v_vision/linear_contract.cpp:13">
P2: Each invalid-input child can emit a core dump, and this test launches 21 such aborting children. Disable core dumps in the child before constructing invalid tensors, as `attention_contract.cpp` does.</violation>
</file>

<file name="server/deps/llama.cpp/ggml/rocmfpx/rocmfpx.c">

<violation number="1" location="server/deps/llama.cpp/ggml/rocmfpx/rocmfpx.c:1357">
P2: When a finite input is large enough for `delta * delta` to overflow, every candidate scores `INFINITY` and the MIX encoder rejects the row. Accumulate or clamp each error term before comparing candidates so finite inputs follow the format's saturation behavior.</violation>
</file>

<file name="docs/ds4v-uncensored-vision-plan.md">

<violation number="1" location="docs/ds4v-uncensored-vision-plan.md:3">
P2: The plan's deliverable is a model explicitly designed to comply with harmful requests, and Appendix C's only mitigation is 'keep them local and never serve them publicly,' yet DS4V-3's verification exercises the model through a persistent OpenAI-compatible /v1/chat/completions endpoint and the broader PR wires serving-runtime integration for it. Nothing in the plan enforces the 'never serve publicly' constraint, so a misconfigured deployment would expose the uncensored model. Make the public-exposure restriction an explicit, checked gate (e.g., bind to loopback / auth required, and a lane that asserts it) rather than a prose note.</violation>
</file>

Tip: cubic used a learning from your PR history. Let your coding agent read cubic learnings directly with the cubic MCP.

Re-trigger cubic

verified={}
for name,sha in expected.items():
if name.split('/')[0] in ('corn','carrots'):
assert digest(a.fixtures/name)==sha,name

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.

P1: Running this verifier with Python optimization (-O or PYTHONOPTIMIZE) removes the hash, count, and probe-status checks, allowing invalid fixtures or a failing probe to produce a PASS verdict. Replace these assertions with explicit exceptions or return-code checks.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tools/ds4v_image_prepare/verify.py, line 27:

<comment>Running this verifier with Python optimization (`-O` or `PYTHONOPTIMIZE`) removes the hash, count, and probe-status checks, allowing invalid fixtures or a failing probe to produce a `PASS` verdict. Replace these assertions with explicit exceptions or return-code checks.</comment>

<file context>
@@ -0,0 +1,36 @@
+verified={}
+for name,sha in expected.items():
+    if name.split('/')[0] in ('corn','carrots'):
+        assert digest(a.fixtures/name)==sha,name
+        verified[name]=sha
+assert len(verified)==28
</file context>

if name.split('/')[0] not in ('corn','carrots'):
continue
actual=hashlib.sha256((a.fixtures/name).read_bytes()).hexdigest()
assert actual==digest,name

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.

P1: When this verifier runs with python -O or -OO, Python removes the hash, count, and probe-status assertions, so invalid fixtures or a failing probe can still produce PASS. Replace these assertions with explicit exceptions or return-code checks.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tools/ds4v_image_prompt/verify_fixtures.py, line 20:

<comment>When this verifier runs with `python -O` or `-OO`, Python removes the hash, count, and probe-status assertions, so invalid fixtures or a failing probe can still produce `PASS`. Replace these assertions with explicit exceptions or return-code checks.</comment>

<file context>
@@ -0,0 +1,29 @@
+    if name.split('/')[0] not in ('corn','carrots'):
+        continue
+    actual=hashlib.sha256((a.fixtures/name).read_bytes()).hexdigest()
+    assert actual==digest,name
+    verified[name]=digest
+assert len(verified)==28
</file context>

manifest = json.loads((a.reference / 'manifest.json').read_text())
results = {}
passed = True
for label, entry in manifest['images'].items():

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.

P1: When the reference manifest is empty or omits one required image, this loop skips that case and the comparator still exits 0. Validate the expected corn and carrots image set before iterating.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tools/ds4v_vision/compare.py, line 22:

<comment>When the reference manifest is empty or omits one required image, this loop skips that case and the comparator still exits 0. Validate the expected `corn` and `carrots` image set before iterating.</comment>

<file context>
@@ -0,0 +1,45 @@
+manifest = json.loads((a.reference / 'manifest.json').read_text())
+results = {}
+passed = True
+for label, entry in manifest['images'].items():
+    results[label] = {}
+    patches = entry['patches']
</file context>

Comment thread server/CMakeLists.txt

option(DFLASH27B_DS4_MIX_CONVERTER
"Build the CPU-only DeepSeek-V4 safetensors to MIX GGUF converter" ON)
if(DFLASH27B_DS4_MIX_CONVERTER)

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.

P2: On Windows, the default build enters this branch and fails compiling ds4_mix_converter because its source is POSIX-only. Gate this target on non-Windows or port the converter to the Win32 file APIs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/CMakeLists.txt, line 383:

<comment>On Windows, the default build enters this branch and fails compiling `ds4_mix_converter` because its source is POSIX-only. Gate this target on non-Windows or port the converter to the Win32 file APIs.</comment>

<file context>
@@ -377,6 +377,22 @@ if(DFLASH27B_MIXED_GGML_SHARED)
+
+option(DFLASH27B_DS4_MIX_CONVERTER
+    "Build the CPU-only DeepSeek-V4 safetensors to MIX GGUF converter" ON)
+if(DFLASH27B_DS4_MIX_CONVERTER)
+    add_executable(ds4_mix_converter
+        tools/ds4_mix_converter/ds4_mix_converter.cpp)
</file context>
Suggested change
if(DFLASH27B_DS4_MIX_CONVERTER)
if(DFLASH27B_DS4_MIX_CONVERTER AND NOT WIN32)

print(run.stdout,end='')
print(run.stderr,end='')
assert run.returncode==0,run.returncode
a.output.write_text(json.dumps({'verdict':'PASS','verified_source_fixture_hashes':verified,

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.

P2: On a fresh checkout, the documented verification reaches this line and fails because the output parent directory does not exist. Create a.output.parent before writing the verdict.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tools/ds4v_image_prompt/verify_fixtures.py, line 27:

<comment>On a fresh checkout, the documented verification reaches this line and fails because the output parent directory does not exist. Create `a.output.parent` before writing the verdict.</comment>

<file context>
@@ -0,0 +1,29 @@
+print(run.stdout,end='')
+print(run.stderr,end='')
+assert run.returncode==0,run.returncode
+a.output.write_text(json.dumps({'verdict':'PASS','verified_source_fixture_hashes':verified,
+    'single_image_cases':10,'ordered_pair_cases':2,'decoder_calls':0,'tower_calls':0,
+    'scope':'Unintegrated prompt preparation using accepted source RGB core layouts and BF16 patch fixtures'},indent=2)+'\n')
</file context>

? render_chat_template(chat,ChatFormat::DEEPSEEK4,true,false,tools)
: render_chat_template_jinja(jinja,chat,"","",true,false,tools);
auto tokens=tokenizer.encode(rendered);
if (std::count(tokens.begin(),tokens.end(),129264)!=static_cast<ptrdiff_t>(encoded.size()))

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.

P2: When a custom Jinja template preserves the marker count but reorders or relocates markers, this check passes. prepare_image_prompt then pairs extraction-order images with rendered-order markers, attaching pixels to the wrong prompt position. Preserve per-image identity through rendering or reject templates whose marker sequence changes.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tools/ds4v_image_prepare/compose.cpp, line 46:

<comment>When a custom Jinja template preserves the marker count but reorders or relocates markers, this check passes. `prepare_image_prompt` then pairs extraction-order images with rendered-order markers, attaching pixels to the wrong prompt position. Preserve per-image identity through rendering or reject templates whose marker sequence changes.</comment>

<file context>
@@ -0,0 +1,67 @@
+            ? render_chat_template(chat,ChatFormat::DEEPSEEK4,true,false,tools)
+            : render_chat_template_jinja(jinja,chat,"","",true,false,tools);
+        auto tokens=tokenizer.encode(rendered);
+        if (std::count(tokens.begin(),tokens.end(),129264)!=static_cast<ptrdiff_t>(encoded.size()))
+            return fail("cardinality: final image marker count differs from image count");
+        Composition result;
</file context>

GGML_OP_RMS_NORM_VISION_F32==106 && GGML_OP_SOFT_MAX_VISION_F32==107 && GGML_OP_MUL_MAT_VISION_AV_F32==108 && GGML_OP_COUNT==109,"operation ABI changed");
static void rejected(int mode) {
const pid_t pid=fork(); check(pid>=0,"fork failed");
if(pid==0) {

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.

P2: When core dumps are enabled, each intentionally aborted child can write a dump, so this test may create ten core files and exhaust CI disk or leave large artifacts. Disable core dumps in the child before exercising rejected inputs, as attention_contract.cpp does.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tools/ds4v_vision/norm_contract.cpp, line 17:

<comment>When core dumps are enabled, each intentionally aborted child can write a dump, so this test may create ten core files and exhaust CI disk or leave large artifacts. Disable core dumps in the child before exercising rejected inputs, as `attention_contract.cpp` does.</comment>

<file context>
@@ -0,0 +1,63 @@
+              GGML_OP_RMS_NORM_VISION_F32==106 && GGML_OP_SOFT_MAX_VISION_F32==107 && GGML_OP_MUL_MAT_VISION_AV_F32==108 && GGML_OP_COUNT==109,"operation ABI changed");
+static void rejected(int mode) {
+    const pid_t pid=fork(); check(pid>=0,"fork failed");
+    if(pid==0) {
+        auto c=ggml_init({1024*1024,nullptr,true});
+        auto x=ggml_new_tensor_2d(c,mode==1?GGML_TYPE_BF16:GGML_TYPE_F32,mode==2?512:1024,mode==3?15:16);
</file context>

static_assert(GGML_OP_PAGED_ATTN==104 && GGML_OP_MUL_MAT_BIAS_BF16==105 && GGML_OP_RMS_NORM_VISION_F32==106 && GGML_OP_SOFT_MAX_VISION_F32==107 && GGML_OP_MUL_MAT_VISION_AV_F32==108 && GGML_OP_COUNT==109,"operation ABI changed");
static void rejected(int mode,bool with_bias=true) {
pid_t pid=fork(); check(pid>=0,"fork failed");
if(pid==0) {

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.

P2: Each invalid-input child can emit a core dump, and this test launches 21 such aborting children. Disable core dumps in the child before constructing invalid tensors, as attention_contract.cpp does.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tools/ds4v_vision/linear_contract.cpp, line 13:

<comment>Each invalid-input child can emit a core dump, and this test launches 21 such aborting children. Disable core dumps in the child before constructing invalid tensors, as `attention_contract.cpp` does.</comment>

<file context>
@@ -0,0 +1,68 @@
+static_assert(GGML_OP_PAGED_ATTN==104 && GGML_OP_MUL_MAT_BIAS_BF16==105 && GGML_OP_RMS_NORM_VISION_F32==106 && GGML_OP_SOFT_MAX_VISION_F32==107 && GGML_OP_MUL_MAT_VISION_AV_F32==108 && GGML_OP_COUNT==109,"operation ABI changed");
+static void rejected(int mode,bool with_bias=true) {
+    pid_t pid=fork(); check(pid>=0,"fork failed");
+    if(pid==0) {
+        auto c=ggml_init({1024*1024,nullptr,true});
+        auto w=ggml_new_tensor_2d(c,mode==0?GGML_TYPE_F32:GGML_TYPE_BF16,64,32);
</file context>

}
weight = imatrix[i];
}
error += weight * delta * delta;

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.

P2: When a finite input is large enough for delta * delta to overflow, every candidate scores INFINITY and the MIX encoder rejects the row. Accumulate or clamp each error term before comparing candidates so finite inputs follow the format's saturation behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/deps/llama.cpp/ggml/rocmfpx/rocmfpx.c, line 1357:

<comment>When a finite input is large enough for `delta * delta` to overflow, every candidate scores `INFINITY` and the MIX encoder rejects the row. Accumulate or clamp each error term before comparing candidates so finite inputs follow the format's saturation behavior.</comment>

<file context>
@@ -1292,3 +1292,248 @@ bool rocmfpx_validate_row_data_fp8(const void * data, size_t nbytes) {
+            }
+            weight = imatrix[i];
+        }
+        error += weight * delta * delta;
+        if (error > best) {
+            break;
</file context>
Suggested change
error += weight * delta * delta;
const float term = weight == 0.0f ? 0.0f : weight * delta * delta;
error = isfinite(term) && error <= FLT_MAX - term
? error + term : FLT_MAX;

@@ -0,0 +1,242 @@
# DS4V uncensored vision GGUF for Strix Halo plus 7900XT plan

Build an uncensored DeepSeek V4 Flash Vision GGUF that runs on the operator pair.

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.

P2: The plan's deliverable is a model explicitly designed to comply with harmful requests, and Appendix C's only mitigation is 'keep them local and never serve them publicly,' yet DS4V-3's verification exercises the model through a persistent OpenAI-compatible /v1/chat/completions endpoint and the broader PR wires serving-runtime integration for it. Nothing in the plan enforces the 'never serve publicly' constraint, so a misconfigured deployment would expose the uncensored model. Make the public-exposure restriction an explicit, checked gate (e.g., bind to loopback / auth required, and a lane that asserts it) rather than a prose note.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/ds4v-uncensored-vision-plan.md, line 3:

<comment>The plan's deliverable is a model explicitly designed to comply with harmful requests, and Appendix C's only mitigation is 'keep them local and never serve them publicly,' yet DS4V-3's verification exercises the model through a persistent OpenAI-compatible /v1/chat/completions endpoint and the broader PR wires serving-runtime integration for it. Nothing in the plan enforces the 'never serve publicly' constraint, so a misconfigured deployment would expose the uncensored model. Make the public-exposure restriction an explicit, checked gate (e.g., bind to loopback / auth required, and a lane that asserts it) rather than a prose note.</comment>

<file context>
@@ -0,0 +1,242 @@
+# DS4V uncensored vision GGUF for Strix Halo plus 7900XT plan
+
+Build an uncensored DeepSeek V4 Flash Vision GGUF that runs on the operator pair.
+Start from the OrcaRouter abliterated parent with vision intact.
+Quant with the prometheusAIR imatrix recipe for a 128 GiB plus 24 GiB budget.
</file context>

@marcelormendes

Copy link
Copy Markdown
Contributor Author

Handoff: where this branch actually stands

Posting this so nobody has to reconstruct the state of the work from the diff. Short version: the serving/text path is proven, the vision path is not qualified, and the smaller-model experiment failed its quality and speed gates and was not installed. Nothing here should be read as a claim that vision works end to end.

Intent

Bring DS4V (DeepSeek V4 Flash Vision, abliterated parent) image input into the dflash HIP serving path on the Strix Halo + 7900 XT pair, with the memory/prefill behaviour needed to hold a long context alongside vision, plus a bounded converter for a smaller (80-85 GB) variant of the same model.

What is in the diff

Area Where Notes
Image serving integration server/src/deepseek4/deepseek4_image_*.{h,cpp}, deepseek4_backend.*, deepseek4_graph.cpp image spans, policy, admission, assembly, prompt ownership, image scratch release
Serving memory / prefill server/src/deepseek4/*, server/src/common/* prefill arena release, GPU pool trimming, staged dense uploads, mmap pageout reclaim, loader fadvise, paired decode attention cache bound, HC worker job-generation ack
Text correctness server/src/deepseek4/deepseek4_backend.cpp, ggml BF16 path BF16 norm vectors widened at the affine boundary; biased-linear-rounding workaround scoped to GPU backends
Standalone vision tooling server/tools/ds4v_vision/*, server/tools/ds4v_preprocess_probe/*, server/tools/export_ds4v_mmproj.py probes, contracts, lossless mmproj exporter
Converter server/tools/ds4_mix_converter/*, server/test/test_ds4_iq_converter.cpp --recipe iq85 (IQ2_XXS gate/up, IQ2_XS down, Q8_0 dense), reads original safetensors
ggml extensions server/deps/llama.cpp/ggml/** four HIP-only DS4V vision ops + upstream GGML_OP_DS4_MOE_COMBINE; GGML_OP_COUNT 105 -> 110
Evidence docs/ds4v-continuation-status.md, docs/ds4v-uncensored-vision-plan.md, decisions-ds4v-{1,2,3,continuation}.tsv, artifacts/ds4v-quant85/README.md operator handoff, per-pass decision logs, candidate evidence summary

Verified

  • Text chat passes at 7071946 with binary c32e5ae3: all six requests succeed, exact-math and triplicate 145-token replies reproduce with speculative decoding on. Short decode 15.9 / 16.4 / 17.4 t/s.
  • Standalone projector export is lossless: 267 tensors compared against the parent by an independent reader, 932786176 payload bytes, mmproj 932805568 bytes, SHA256 58eb6b63243df2db21261ced5568b385b04991f38d45d39b781309497abd4b1c.
  • Parallel MIX conversion is accepted for load: 129 expert tensors, internal structural/sidecar/raw-byte verification, GGUF 58086fcd, GUMIX 954110a5, first 64 MiB byte-identical to the serial candidate (f13168d5...).
  • Image units are CPU-qualified: policy parity, transport red/green, preprocessing composition through the real renderer/tokenizer, prompt ownership.
  • Cached speculative attention divergence fixed: preserved ring-row views used construction-time offsets while write indices advanced; the gather-based fix produces 22/22 identical visible replies across cache2/cache4 versus 19/22 before. This is visible-text agreement, not token-ID parity.
  • Merge with upstream/main (2f0eff05) resolved in 6d762d8e: op tables 105 -> 110, hybrid budget takes both with_vision and paged, build_mla_attention_lane_core takes the prepared lane and out_attn_context plus the image span view, and the duplicated inline snapshot helpers were dropped in favour of deepseek4_snapshot.cpp (the branch copies were byte-identical to the merge base).

Not verified / not passing

  • Vision features fail the frozen 0.9995 cosine gate. CPU corn 0.99822935 (ISSUES retained); first native HIP run on the 7900XT: corn 0.985939, carrots 0.993884, both embedding comparisons now pass while features fail, exit 3. Peak scratch measured 891424512 bytes at the maximum permitted 3366 patches; all three probe processes completed with finite outputs and corn repeated byte-identically.
  • Native drift against original-source HIP is unresolved. The sensitive-block diagnostic found no semantic or BF16-boundary discrepancy for corn blocks 12/31, and a single-thread original-source control reproduced the two-thread reference bitwise. A prospective same-7900XT original-source reference policy was adopted, the reference was frozen after exact repeat stability, and the corrected candidate qualification was never executed.
  • The 80-85 GB candidate is rejected. Conversion completed (83,619,648,416 bytes, SHA256 954433dcb2e64ce6082f4ea8c1478428198fd81b6e7ec0729e9eefa3d56f8497, converter afa56b0a60e7f883091ed669f8bad01439f9789fa7835184f736563075f84533), header and tensor verification passed, but the frozen quality gate failed: 12/16 content and 5/16 strict against a 15/16 and 7/16 baseline, with python-copy and nested-json wrong and python-slice answering inside an unrequested Markdown fence. Median decode was 20.1 t/s against the 35 t/s target; batched and cache-slot variants reached 14.0-16.8 t/s. A second variant restoring BF16 embedding/output matrices (84,612,519,168 bytes, SHA256 99a2260c862e270fa654a1f1e75fad88ec824c58963a2c30135ba91edaf9bb2b) showed no quality or speed benefit. No candidate was installed.
  • Cache-eviction, SSE, 8K/32K/64K/124K and daily-service acceptance stages never ran for the candidate; the functional quality gate stopped each trial first. The fixed cache sequence 2K-4K-8K-16K-2K, the validator wrapper and the config generator have CPU tests only.
  • No link-stage or GPU verification of the merge. The conflict resolution was syntax-checked locally on macOS with clang C++17 (HIP headers stubbed, since Apple has no HIP): ggml.c compiles clean with the op enum and both tables at 110 entries, and deepseek4_graph.cpp, deepseek4_backend.cpp, deepseek4_snapshot.cpp, deepseek4_paged_cache.cpp, the image units and test_deepseek4_unit.cpp all pass -fsyntax-only. Nothing was built with HIP or CUDA and nothing was run.

Blockers

  1. CI has not run. The workflow runs for 6d762d8e are all action_required pending maintainer approval (CI #34456464789, Speed Profile #34456464764, Docker prebuilds #34456464762). Until they run, no build has validated this branch anywhere.
  2. The vision numerical gate is not met, and it is the gate that blocks runtime integration; the branch deliberately keeps it visible and failing rather than relaxing the threshold.
  3. The qualification harness is not in the repo. The component-only HIP window, the daily guard, the admission/acceptance wrappers and the TTM recovery helper live as operator scripts on the host (~/ds4v-work/image-integration/*), referenced only from docs/ds4v-continuation-status.md; harness SHA256 152af330bb37f77f8e6f9c795ae46c12f787e8587c42fc210aeb671b205296d5 for the component window. Say the word and I will upstream them as a follow-up PR.
  4. Per-trial binary evidence (~425 MB) is not in the repo. HTTP requests/responses, SSE captures, journals and per-run JSON live on my machine under artifacts/**. Available on request.
  5. This PR mixes two reviewable units: the serving/vision runtime work and the experimental IQ85 converter. Happy to split them if that is easier to review.

Unresolved questions for you

  • Is the same-device original-source HIP reference the right basis for the vision gates, or should the gate follow the CPU reference?
  • For the smaller-model line: is a 35 t/s short-chat target with retained image input still the requirement, or should quality be prioritised over the 80-85 GB ceiling?

@marcelormendes

Copy link
Copy Markdown
Contributor Author

@davide221 — tagging you since you reviewed #604. This is where I stopped on bringing DS4V vision input into the dflash HIP serving path; details are in the handoff comment above.

Headline: the text path passes (7071946, binary c32e5ae3, 15.9/16.4/17.4 t/s short decode), vision does not — features still fail the fixed 0.9995 cosine gate on CPU (corn 0.99822935) and on the 7900XT (corn 0.985939, carrots 0.993884, exit 3), and the 80-85 GB IQ85 candidate failed its frozen quality gate (12/16 content, 5/16 strict against 15/16, 7/16 baseline) and reached 20.1 t/s against a 35 t/s target, so no candidate was installed.

Also in the PR: ds4_mix_converter --recipe iq85 and a merge of upstream/main (2f0eff05) into the branch (6d762d8e) so it applies cleanly.

The CI runs for this head are sitting in action_required — approving them would give this branch its first real build. Two things I can do on request: split the runtime work from the converter, and upstream the operator-side qualification harness (component-only HIP window, daily guard, acceptance wrappers) that currently only exists on my host.

@marcelormendes

Copy link
Copy Markdown
Contributor Author

Refinement to the vision numbers above

The handoff comment quotes the first native HIP run; the scoped fix moved those numbers, so here is the current state of the tower gate:

  • First native HIP run (runtime 4bf7270): corn feature cosine 0.985939, carrots 0.993884, embeddings also below gate, harness exit 3.
  • After the scoped biased-linear-rounding fix (be8b0f1, biases promoted to F32 operands on GPU backends only): embeddings now pass against the frozen same-GPU original-source reference — corn 0.999525047, carrots 0.999721786. Features still fail: corn cosine 0.999063593 against the fixed 0.9995 minimum, maxabs 0.947265625; carrots cosine 0.999538399 passes but maxabs 0.26416015625 exceeds its tolerance. Harness exit 3 preserved, corn repeat byte-identical, all outputs finite.
  • CPU portability is a separate retained failure: original CPU corn feature cosine 0.99822935, ISSUES.
  • Three-way comparison (artifacts/ds4v-step2/source-rocm-reference/hip-supervision-confirmed/three-way.json): the corrected original-source corn HIP forward also fails the unchanged CPU gate (cosine 0.997729789, maxabs 2.73828125), and native HIP fails against source HIP (features 0.991196939, embeddings 0.994697537). So CPU/GPU portability does not explain the native discrepancy.

Status of the image path itself, to avoid reading the above as "images do not run":

  • 03edb38 ("integrate bounded image prompts into HIP serving") is in the diff and is an ancestor of the runtime used for the candidate trials; docs/ds4v-image-serving.md documents the request contract (base64 JPEG/PNG data URLs in user content), the required two-device HIP sparse-prefill configuration, the paths that explicitly do not support images (layer splitting, remote expert IPC, all-on-secondary, dense prefill, concurrent scheduling, upstream forwarding), and the /props capability flag.
  • In the candidate trials every one of the 18 functional cases passed, including image ordering and follow-ups, and image decode throughput was measured — but that is the request path, not numerical vision fidelity.
  • That document also states that private paired-model HTTP qualification is still pending, and the continuation status says no production HTTP/backend vision wiring or image-chat acceptance is claimed at the point where the tower gate was last run.

So: an image request can be submitted and answered in this runtime, but the vision tower does not meet its numerical contract and image-chat acceptance is not claimed.

Adds harness/qualification/deepseek4/ds4v-vision/ so the DS4V vision
numerical gate can be reproduced without rebuilding the measurement
setup: the component-only and runtime qualification harnesses, the
per-component qualification scripts with their review notes, the adopted
same-GPU reference policy, the original-source reference tooling and
environment receipts (constraints, libtorch/MIOpen linkage, script
hashes), the frozen three-way comparison, and the native-hip-first and
native-hip-scoped run summaries.

Documents the current gate values, the open question of whether the
target is the frozen same-GPU source or the absolute 0.9995 threshold,
the next experiments, and the known gaps (reference images and guard
journals are not included). Text only, about 0.5 MB.
@marcelormendes

Copy link
Copy Markdown
Contributor Author

Reproduction kit added (c6030da7)

The comments above describe the state, but they did not let anyone measure it. That gap is now closed:

harness/qualification/deepseek4/ds4v-vision/ — 76 files, ~0.6 MB, text only.

  • Harness: hip-qualification.sh (component-only window), runtime-qualification.sh, and the per-component qualifiers for linear, attention, norm, unbiased, LT, LT-concurrent and LT-retry, each with its review note where one exists. Read hip-qualification-README.md first — they carry host paths and their own idle/port/KFD/memory guards.
  • Policy and contracts: target-hip-qualification-policy.md (+ review), component-window-review.md, how-source.md, how-backend.md, native-tower-brief.md, native-tower-rubric.md.
  • Reference: source-rocm-reference/constraints.txt, cpu-runtime-info.py, freeze-source-reference.py, compare-corn-three-way.py, the control reports, hip-supervision-confirmed/three-way.json, and the environment receipts that pin the reference build (libtorch HIP linkage, MIOpen packages, frozen script hashes).
  • Results: native-hip-first/ (corn 0.985939, carrots 0.993884, exit 3) and native-hip-scoped/ (embeddings 0.999525047 / 0.999721786 pass; corn cosine 0.999063593, maxabs 0.947265625; carrots cosine 0.999538399, maxabs 0.26416015625).
  • Kit README: how to reproduce (pin the reference environment, freeze same-GPU source outputs, run the guarded component window, compare with thresholds unchanged), the current numbers, and the next experiments.

One decision I cannot make for you

The adopted policy keeps every numeric threshold unchanged, but the original-source corn HIP forward itself fails the CPU feature gate (0.997729789, maxabs 2.73828125), and native HIP fails against source HIP (features 0.991196939). So "match the frozen same-GPU source" and "pass 0.9995" are different targets, and the residual corn deviation sits between them. Without an owner decision on which one is the target, the tower cannot be declared qualified either way.

Still not in the repo

  • The two source images (corn.jpeg, carrots.jpeg). The frozen reference outputs are tied to them; they were deleted from the reference host and can be recovered from base64 payloads in the trial captures, or provided on request.
  • Guard journals, per-run guard.json snapshots and HTTP captures (~425 MB).
  • No production image-chat acceptance has been run against this tower state.

@cubic-dev-ai cubic-dev-ai 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.

1 existing issue remains and 40 new issues found across 198 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="harness/qualification/deepseek4/ds4v-vision/hip-qualification.sh">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/hip-qualification.sh:19">
P1: The harness gates HIP output against the CPU fixtures instead of the frozen same-GPU source reference. Point `reference` at `~/ds4v-work/source-rocm210-reference/source-hip-reference` and pin its `677b5ef0...` manifest; retain the CPU manifest only for a separate portability comparison.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/hip-qualification.sh:109">
P2: On interruption or timeout, `stop_owned()` writes incomplete process timing evidence because it reaps the child with `Popen.wait()` instead of recording `wait4` usage and elapsed time. Capture resource usage while reaping the killed child so failed runs retain the documented diagnostics.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/hip-lt-concurrent-qualification.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-concurrent-qualification.py:57">
P1: If SIGTERM or SIGINT arrives between `Popen` and handler installation, the parent exits without reaping the guard, leaving its GPU child active. Install or block the handlers before spawning the guard, then restore them after cleanup.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-concurrent-qualification.py:82">
P1: The adapter hash is only recorded, so a modified qualification script can change the acceptance logic while every external artifact pin still passes. Require the configured reviewed adapter hash to equal `digest(__file__)` before using the configuration.</violation>

<violation number="3" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-concurrent-qualification.py:154">
P2: When two lane policies share a `run_name`, the later lane overwrites the earlier lane’s guard evidence and the qualification is no longer independently auditable. Require all resolved lane output directories to be distinct before launching any lane.</violation>

<violation number="4" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-concurrent-qualification.py:165">
P2: A malformed guard report can bypass the proof check because both fields are tested by truthiness. Require `result['pass'] is True` and `result['device_proof_verified'] is True`.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/hip-lt-retry-qualification.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-retry-qualification.py:81">
P1: The config and guard hashes are not anchored to a reviewed value, so a modified guard can fabricate lane reports and bypass this numerical qualification. Verify the config and guard/policy artifacts against a trusted release receipt or hard-coded approved digests, rather than accepting a digest supplied alongside the config.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-retry-qualification.py:162">
P1: When two lane policies use the same `run_name`, their executions share `out` and the later copies cannot represent independent lanes. Reject duplicate output directories before launching any lane.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/compare-corn-three-way.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/compare-corn-three-way.py:17">
P2: When this comparison runs with Python optimization enabled, its input-identity and hash checks are skipped and mismatched tensors can be reported as if they were the pinned run. Use explicit exceptions instead of `assert` for these runtime checks.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/compare-corn-three-way.py:20">
P1: When `source/report.json` or its output files are replaced, this check still accepts the replacement because the report supplies both the output path and its expected hash. The three-way result can therefore compare native output against a substituted source tensor instead of the frozen reference; pin the two frozen source output hashes (or verify a pinned source manifest/report digest) before reading the source files.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/mmproj-byte-proof.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/mmproj-byte-proof.py:15">
P1: When this proof runs under an optimized Python interpreter, every validation is removed but the script still writes a PASS manifest. Replace validation `assert` statements with explicit exceptions, or reject optimized execution before producing evidence.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/hip-unbiased-qualification.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/hip-unbiased-qualification.py:58">
P2: If SIGTERM or SIGINT arrives immediately after spawning a guard, the default handler bypasses cleanup and leaves the guard potentially running a GPU lane. Install or block the parent handlers before spawning the guard, then restore them after cleanup.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/hip-unbiased-qualification.py:172">
P1: When two lane policies share `run_name`, sequential runs overwrite the same output files, so native/repeat comparisons can use the wrong lane and falsely pass. Reject duplicate lane output directories before launching.</violation>
</file>

<file name="server/deps/llama.cpp/ggml/src/ggml.c">

<violation number="1" location="server/deps/llama.cpp/ggml/src/ggml.c:1203">
P1: These entries shift the pre-existing `GGML_OP_DS4_MOE_COMBINE` ordinal, breaking the operation ABI for old graph or protocol encodings. Append the new operations after `DS4_MOE_COMBINE` and update the enum and parallel name tables together.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/freeze-source-reference.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/freeze-source-reference.py:15">
P1: When this script is invoked with `python -O`, Python removes every validation `assert`, so arbitrary or mismatched artifacts can be copied into the canonical reference without any checks. Reject optimized execution and use explicit exceptions for the integrity checks.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/freeze-source-reference.py:57">
P2: If a source run used stale or mismatched patches, this freeze would still accept its outputs because it checks only the manifest hash. Compare `report['patch_sha256']` with the original image patch hash before copying.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/hip-lt-qualification.sh">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-qualification.sh:81">
P2: `--component-only` always fails this check, so the documented standalone qualification can never reach `idle_window()` or produce evidence. Remove this guard or remove the mode from the usage and documentation.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-qualification.sh:92">
P2: The prerequisite validates only a text-proof directory and three `text_*` verdicts; it never reads or hashes the required source-linear acceptance. Require an immutable linear receipt tied to `source_sha` before launching these lanes.</violation>

<violation number="3" location="harness/qualification/deepseek4/ds4v-vision/hip-lt-qualification.sh:196">
P2: This only checks that the `libggml-hip` soname appears in `ldd`; it never compares the resolved path with the pinned files, so a different GGML or ROCm library can qualify. Validate every effective soname path against its pinned path before running the probe.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/runtime-qualification.sh">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/runtime-qualification.sh:8">
P2: This qualification can validate stale or modified external binaries and fixtures instead of the PR runtime. Pin and verify the probe, source commit, comparator, projector, and reference manifest before recording qualification evidence.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/runtime-qualification.sh:47">
P2: When this qualification runs with Python optimization enabled, its finite, shape, and byte-identity gates disappear while the verdict still records PASS. Use explicit exceptions for these checks and run the comparator with a non-optimized isolated interpreter.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/reference-fixtures.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/reference-fixtures.py:17">
P2: This limits only intra-op parallelism and leaves inter-op scheduling at its default, so fixture generation can oversubscribe CPUs and differ from the controlled two-thread reference. Set both Torch thread pools to two before importing the model.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/reference-fixtures.py:26">
P2: When `output` contains a prior run, an interrupted regeneration can leave manifest hashes paired with changed or partial files. Require a fresh output directory or stage the complete fixture set before publishing it.</violation>

<violation number="3" location="harness/qualification/deepseek4/ds4v-vision/reference-fixtures.py:38">
P2: When `--encode` uses a different or corrupted model shard, this manifest still looks valid because it does not bind the loaded weights. Hash the index and every loaded shard before publishing encoded fixtures.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/hip-linear-qualification.sh">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/hip-linear-qualification.sh:183">
P2: The harness can qualify with an alternate GGML library: this check does not prove that the probe loaded the pinned files, and the later hash is diagnostic only. Require each resolved GGML SONAME to match its pinned `ggml_build` path before launching the GPU lanes.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/capture-comparator-runtime.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/capture-comparator-runtime.py:7">
P2: Importing NumPy before disabling bytecode writes can modify the reference environment and contradict the read-only inventory. Set `sys.dont_write_bytecode = True` before importing NumPy.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/capture-comparator-runtime.py:9">
P2: With `python -O`, this assertion is removed, so the script can inventory a non-isolated NumPy installation and emit pins for it. Raise an explicit exception when `sys.flags.isolated` is false.</violation>

<violation number="3" location="harness/qualification/deepseek4/ds4v-vision/capture-comparator-runtime.py:11">
P2: The manifest omits the Python standard-library files used by `compare.py`, so changing `/usr/lib/python3.12` without changing the executable can pass the runtime pin. Add the standard-library tree and its extension modules to `files`.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/hip-attention-qualification.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/hip-attention-qualification.py:65">
P2: When SIGINT or SIGTERM interrupts a lane, the broad exception handler converts it into exit 3. Catch `InterruptedError` separately and return `128 + signal` after cleanup.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/hip-attention-qualification.py:69">
P2: If the external guard hangs, `guarded_run` waits forever because `child.wait()` has no deadline. Add a bounded supervisor timeout and guaranteed cleanup of the guard and its owned worker.</violation>
</file>

<file name="server/src/common/backend_factory.cpp">

<violation number="1" location="server/src/common/backend_factory.cpp:221">
P2: When `--mmproj` is used without sparse prefill and in-process distinct local HIP expert owners, this gate accepts the launch but `DeepSeek4Backend::load_model()` immediately rejects it. Validate the complete DS4V placement contract during factory admission, or centralize that validation so invalid image launches fail before backend construction with the correct reason.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/hip-norm-qualification.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/hip-norm-qualification.py:62">
P2: The guard inherits the caller's dynamic-loader and GPU/runtime environment, so pinned binaries do not guarantee the qualified process is the one being tested. Launch it with the same fixed clean environment used by the qualification harness, removing inherited loader, device-mask, and GGML/DS4/DFLASH variables.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/hip-norm-qualification.py:69">
P2: A hung supervisor can wedge the qualification indefinitely and prevent the final report. Bound each lane wait and use the existing termination/reaping path when the timeout expires.</violation>

<violation number="3" location="harness/qualification/deepseek4/ds4v-vision/hip-norm-qualification.py:210">
P2: Preflight failures occur before the exception handler, so a stale or missing prerequisite produces a traceback and no `summary.json`. Wrap preflight and evidence creation in the same reporting failure path so every qualification failure emits structured evidence.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/patch-bias-diagnostic.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/patch-bias-diagnostic.py:40">
P2: This diagnostic does not perform the exact dyadic calculation its description promises, so it cannot establish tie-rounding behavior independently of Torch's CPU kernels. Implement an exact reference calculation or remove the claim before using this report to explain native differences.</violation>

<violation number="2" location="harness/qualification/deepseek4/ds4v-vision/patch-bias-diagnostic.py:47">
P2: If a reference patch file is stale or corrupted, this script consumes it without checking the manifest hash and can misattribute differences to rounding. Verify `meta['sha256']` before loading the patch.</violation>

<violation number="3" location="harness/qualification/deepseek4/ds4v-vision/patch-bias-diagnostic.py:56">
P2: When native output already matches the CPU reference, `np.flatnonzero(mismatch)[0]` raises `IndexError`, so the diagnostic cannot emit its success report. Record first-difference fields as null when `mismatch` is empty.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/cpu-runtime-info.py">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/cpu-runtime-info.py:11">
P2: Running this receipt with `python -O` or `PYTHONOPTIMIZE` strips the environment and provenance guards, allowing mismatched device masks, MIOpen, or Torch versions to be reported as valid. Replace these validation assertions with explicit checks that raise errors.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/hip-control-initial-failure.md">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/hip-control-initial-failure.md:17">
P2: This sentence is stale after the corrected follow-up landed: the repository now contains completed source-HIP/CPU and native-HIP/source-HIP comparisons. Describe the unavailability as applying to this initial attempt and link `hip-control-report.md` so readers do not mistake the initial failure for the final status.</violation>
</file>

<file name="harness/qualification/deepseek4/ds4v-vision/target-hip-qualification-policy-review.md">

<violation number="1" location="harness/qualification/deepseek4/ds4v-vision/target-hip-qualification-policy-review.md:36">
P2: The review calls fixture breadth the main scientific limitation, but the frozen source-HIP reference already fails the unchanged CPU feature gate. State that matching it cannot rule out a shared backend defect.</violation>
</file>

Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.

Re-trigger cubic

root = home / 'lucebox-ds4v-runtime'
build = Path('/tmp/ds4v-runtime-hip-build')
binary = build / 'ds4v_vision_probe'
reference = home / 'lucebox-ds4v-mix-fix/artifacts/vision-reference'

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.

P1: The harness gates HIP output against the CPU fixtures instead of the frozen same-GPU source reference. Point reference at ~/ds4v-work/source-rocm210-reference/source-hip-reference and pin its 677b5ef0... manifest; retain the CPU manifest only for a separate portability comparison.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/hip-qualification.sh, line 19:

<comment>The harness gates HIP output against the CPU fixtures instead of the frozen same-GPU source reference. Point `reference` at `~/ds4v-work/source-rocm210-reference/source-hip-reference` and pin its `677b5ef0...` manifest; retain the CPU manifest only for a separate portability comparison.</comment>

<file context>
@@ -0,0 +1,226 @@
+root = home / 'lucebox-ds4v-runtime'
+build = Path('/tmp/ds4v-runtime-hip-build')
+binary = build / 'ds4v_vision_probe'
+reference = home / 'lucebox-ds4v-mix-fix/artifacts/vision-reference'
+mmproj = home / 'ds4v-work/ds4v-mmproj.gguf'
+compare = root / 'server/tools/ds4v_vision/compare.py'
</file context>

args = parser.parse_args()
require(sys.flags.isolated and args.parent_radeon_window_released, 'explicit numerical release required')
require(digest(args.config) == args.config_sha, 'config changed')
cfg = json.loads(args.config.read_text())

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.

P1: The adapter hash is only recorded, so a modified qualification script can change the acceptance logic while every external artifact pin still passes. Require the configured reviewed adapter hash to equal digest(__file__) before using the configuration.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/hip-lt-concurrent-qualification.py, line 82:

<comment>The adapter hash is only recorded, so a modified qualification script can change the acceptance logic while every external artifact pin still passes. Require the configured reviewed adapter hash to equal `digest(__file__)` before using the configuration.</comment>

<file context>
@@ -0,0 +1,230 @@
+    args = parser.parse_args()
+    require(sys.flags.isolated and args.parent_radeon_window_released, 'explicit numerical release required')
+    require(digest(args.config) == args.config_sha, 'config changed')
+    cfg = json.loads(args.config.read_text())
+    linear_path = Path(cfg['linear_receipt']['path'])
+    require(digest(linear_path) == cfg['linear_receipt']['sha256'], 'linear acceptance receipt changed')
</file context>

parser.add_argument('--parent-radeon-window-released', action='store_true')
args = parser.parse_args()
require(sys.flags.isolated and args.parent_radeon_window_released, 'explicit numerical release required')
require(digest(args.config) == args.config_sha, 'config changed')

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.

P1: The config and guard hashes are not anchored to a reviewed value, so a modified guard can fabricate lane reports and bypass this numerical qualification. Verify the config and guard/policy artifacts against a trusted release receipt or hard-coded approved digests, rather than accepting a digest supplied alongside the config.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/hip-lt-retry-qualification.py, line 81:

<comment>The config and guard hashes are not anchored to a reviewed value, so a modified guard can fabricate lane reports and bypass this numerical qualification. Verify the config and guard/policy artifacts against a trusted release receipt or hard-coded approved digests, rather than accepting a digest supplied alongside the config.</comment>

<file context>
@@ -0,0 +1,243 @@
+    parser.add_argument('--parent-radeon-window-released', action='store_true')
+    args = parser.parse_args()
+    require(sys.flags.isolated and args.parent_radeon_window_released, 'explicit numerical release required')
+    require(digest(args.config) == args.config_sha, 'config changed')
+    cfg = json.loads(args.config.read_text())
+    require(cfg.get('adapter_sha256') == digest(__file__), 'qualification adapter changed')
</file context>

assert sha(manifest_bytes) == '38d12f30b9a10ed2f0e99bf4d40a07357ab5e8c4880151c58cb90414e4a53f4f'
manifest = json.loads(manifest_bytes)
source_report = json.loads((source/'report.json').read_text())
assert source_report['script_sha256'] == 'cd34fd3df07963bea9014ccc6f405ec95400a7b8b70e4233fe5d3ead7dc9468c'

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.

P1: When source/report.json or its output files are replaced, this check still accepts the replacement because the report supplies both the output path and its expected hash. The three-way result can therefore compare native output against a substituted source tensor instead of the frozen reference; pin the two frozen source output hashes (or verify a pinned source manifest/report digest) before reading the source files.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/source-rocm-reference/compare-corn-three-way.py, line 20:

<comment>When `source/report.json` or its output files are replaced, this check still accepts the replacement because the report supplies both the output path and its expected hash. The three-way result can therefore compare native output against a substituted source tensor instead of the frozen reference; pin the two frozen source output hashes (or verify a pinned source manifest/report digest) before reading the source files.</comment>

<file context>
@@ -0,0 +1,55 @@
+assert sha(manifest_bytes) == '38d12f30b9a10ed2f0e99bf4d40a07357ab5e8c4880151c58cb90414e4a53f4f'
+manifest = json.loads(manifest_bytes)
+source_report = json.loads((source/'report.json').read_text())
+assert source_report['script_sha256'] == 'cd34fd3df07963bea9014ccc6f405ec95400a7b8b70e4233fe5d3ead7dc9468c'
+assert source_report['device']['name'] == 'Radeon RX 7900 XT'
+assert source_report['device']['gcn_arch'].split(':')[0] == 'gfx1100'
</file context>

str(out / f'{label}-embeddings.f32'): ((h+2)//3)*((w+2)//3)*4096*4}
require(set(p['required_outputs']) == set(sizes), 'wrong output contract')
require(all(p['required_outputs'][k]['bytes'] == v for k, v in sizes.items()), 'wrong output dimensions')
policies.append((p, out, label))

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.

P1: When two lane policies use the same run_name, their executions share out and the later copies cannot represent independent lanes. Reject duplicate output directories before launching any lane.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/hip-lt-retry-qualification.py, line 162:

<comment>When two lane policies use the same `run_name`, their executions share `out` and the later copies cannot represent independent lanes. Reject duplicate output directories before launching any lane.</comment>

<file context>
@@ -0,0 +1,243 @@
+                 str(out / f'{label}-embeddings.f32'): ((h+2)//3)*((w+2)//3)*4096*4}
+        require(set(p['required_outputs']) == set(sizes), 'wrong output contract')
+        require(all(p['required_outputs'][k]['bytes'] == v for k, v in sizes.items()), 'wrong output dimensions')
+        policies.append((p, out, label))
+    evidence = Path(cfg['evidence'])
+    require(evidence.is_absolute() and not evidence.exists(), 'fresh evidence required')
</file context>

a.output.mkdir(parents=True,exist_ok=True)
for label in ('corn','carrots'):
meta=manifest['images'][label]['patches']
patches=torch.from_numpy(np.fromfile(a.reference/meta['file'],np.float32).reshape(meta['shape'])).to(torch.bfloat16)

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.

P2: If a reference patch file is stale or corrupted, this script consumes it without checking the manifest hash and can misattribute differences to rounding. Verify meta['sha256'] before loading the patch.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/patch-bias-diagnostic.py, line 47:

<comment>If a reference patch file is stale or corrupted, this script consumes it without checking the manifest hash and can misattribute differences to rounding. Verify `meta['sha256']` before loading the patch.</comment>

<file context>
@@ -0,0 +1,58 @@
+a.output.mkdir(parents=True,exist_ok=True)
+for label in ('corn','carrots'):
+    meta=manifest['images'][label]['patches']
+    patches=torch.from_numpy(np.fromfile(a.reference/meta['file'],np.float32).reshape(meta['shape'])).to(torch.bfloat16)
+    with torch.inference_mode():
+        fused=module(patches)
</file context>

child = subprocess.Popen(command, stdout=log, stderr=subprocess.STDOUT)
previous = {}
def interrupted(signum, frame):
raise InterruptedError(f'qualification interrupted: {signum}')

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.

P2: When SIGINT or SIGTERM interrupts a lane, the broad exception handler converts it into exit 3. Catch InterruptedError separately and return 128 + signal after cleanup.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/hip-attention-qualification.py, line 65:

<comment>When SIGINT or SIGTERM interrupts a lane, the broad exception handler converts it into exit 3. Catch `InterruptedError` separately and return `128 + signal` after cleanup.</comment>

<file context>
@@ -0,0 +1,314 @@
+    child = subprocess.Popen(command, stdout=log, stderr=subprocess.STDOUT)
+    previous = {}
+    def interrupted(signum, frame):
+        raise InterruptedError(f'qualification interrupted: {signum}')
+    try:
+        for signum in (signal.SIGTERM, signal.SIGINT):
</file context>

import torch
from safetensors import safe_open

torch.set_num_threads(2)

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.

P2: This limits only intra-op parallelism and leaves inter-op scheduling at its default, so fixture generation can oversubscribe CPUs and differ from the controlled two-thread reference. Set both Torch thread pools to two before importing the model.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/reference-fixtures.py, line 17:

<comment>This limits only intra-op parallelism and leaves inter-op scheduling at its default, so fixture generation can oversubscribe CPUs and differ from the controlled two-thread reference. Set both Torch thread pools to two before importing the model.</comment>

<file context>
@@ -0,0 +1,65 @@
+import torch
+from safetensors import safe_open
+
+torch.set_num_threads(2)
+torch.set_default_dtype(torch.bfloat16)
+sys.path.insert(0, str(args.source / 'inference'))
</file context>
Suggested change
torch.set_num_threads(2)
torch.set_num_threads(2)
torch.set_num_interop_threads(2)

Comment on lines +36 to +39
Those separate gates remain required. The main residual scientific limitation is
fixture breadth: two images establish the selected deployment gate, not general
cross-image or cross-backend equivalence. No tolerance, source implementation or
reference backend may be changed after seeing corrected candidate results.

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.

P2: The review calls fixture breadth the main scientific limitation, but the frozen source-HIP reference already fails the unchanged CPU feature gate. State that matching it cannot rule out a shared backend defect.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/target-hip-qualification-policy-review.md, line 36:

<comment>The review calls fixture breadth the main scientific limitation, but the frozen source-HIP reference already fails the unchanged CPU feature gate. State that matching it cannot rule out a shared backend defect.</comment>

<file context>
@@ -0,0 +1,42 @@
+Any PASS is limited to the native tower on the recorded 7900 XT/software tuple.
+It does not qualify CPU numerics, gfx1151, other accelerators, decoder behavior,
+HTTP image input, image-dependent answers, isolation, resource limits or cleanup.
+Those separate gates remain required. The main residual scientific limitation is
+fixture breadth: two images establish the selected deployment gate, not general
+cross-image or cross-backend equivalence. No tolerance, source implementation or
</file context>
Suggested change
Those separate gates remain required. The main residual scientific limitation is
fixture breadth: two images establish the selected deployment gate, not general
cross-image or cross-backend equivalence. No tolerance, source implementation or
reference backend may be changed after seeing corrected candidate results.
Those separate gates remain required. Scientific limitations include the source-HIP
reference's unchanged CPU feature failure, so matching it cannot rule out a shared
backend defect, and fixture breadth: two images establish the selected deployment
gate, not general cross-image or cross-backend equivalence. No tolerance, source implementation or
reference backend may be changed after seeing corrected candidate results.

import pathlib
import subprocess
import sys
import numpy

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.

P2: Importing NumPy before disabling bytecode writes can modify the reference environment and contradict the read-only inventory. Set sys.dont_write_bytecode = True before importing NumPy.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At harness/qualification/deepseek4/ds4v-vision/capture-comparator-runtime.py, line 7:

<comment>Importing NumPy before disabling bytecode writes can modify the reference environment and contradict the read-only inventory. Set `sys.dont_write_bytecode = True` before importing NumPy.</comment>

<file context>
@@ -0,0 +1,27 @@
+import pathlib
+import subprocess
+import sys
+import numpy
+
+assert sys.flags.isolated
</file context>
Suggested change
import numpy
sys.dont_write_bytecode = True
import numpy

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