Skip to content

fix(dsv41): align decode-sized replay position views - #31

Merged
bertholomus merged 1 commit into
bertholomus:deepseek-v41-zig-tp4from
mrsergiopascal:fix/replay-position-alignment
Oct 20, 2026
Merged

bertholomus merged 1 commit into
bertholomus:deepseek-v41-zig-tp4from
mrsergiopascal:fix/replay-position-alignment

Conversation

@mrsergiopascal

Copy link
Copy Markdown

Summary

Keep decode-sized replay position pointers aligned without changing their values. An odd replayCut offset currently leaves POS at 8 modulo 16; split sparse attention aliases its default RBASE/CBASE to POS, and the served aligned AOT variants correctly reject that launch with MissingTritonVariant.

Only when the cut view is unaligned and the surviving chunk has n <= tri.decode_rows, upload the exact surviving host_pos slice to the existing aligned ch.pos0, through the existing stream-ordered upload. Even cuts and larger chunks keep their original view. No kernel math, replay geometry, AOT captures, alignment matcher, deployment scripts or runtime settings change.

Target and duplicate check

Based on bertholomus/TensorFold:deepseek-v41-zig-tp4 at b65c8b92d2403dfdefccf15a3b23ba609a4553e2, the active TP4 engine branch. The affected family is absent from this fork's main and current ashhart main. Checked current source, fork issues/PRs and upstream replay/alignment reports: no equivalent repair found. The prompt-indexer VIS alignment repair (#4/#8) and generic safe AOT matching changes are different callsites/problems.

Regression and reproduction

  • python3 tools/dsv41-zig/test_replay_positions.py (Zig 0.17.0): 3/3 passed. The actual extracted replayCut is compiled, with GPU collaborators stubbed; exact positions, noncontiguous sentinels, host immutability, odd/even/large cuts and early returns are checked.
  • Running that same test against the unmodified base function: 2 failed, 1 passed, with expected 0, found 8 on position alignment.
  • Added opt-in, standard-library synthetic Responses reproducer and instructions in tools/dsv41-zig/replay_positions.md. It sizes with /tokenize, preserves identical first-request bytes for before/after, checks SSE completion, exact tool arguments and actual completed continuation. Its generated fixture objects were verified equal to the four previously GPU-qualified synthetic fixtures. The public helper's CLI/syntax were checked; no new GPU run was performed while preparing this PR.
  • zig fmt --check on the changed Zig file and git diff --check: passed.
  • python3 tools/zig/lean_check.py: 1615 inherited findings before and after; zero added (nonzero exit, not a clean full-tree claim).
  • zig build test test-golden -Dcpu=apple_m1: blocked on this macOS host, by missing Xcode Metal compiler and the pre-existing Linux-only c.SO.BUSY_POLL reference in dsv41/link.zig. No unrelated build/policy/CI edits made.
  • Independent read-only CLI code review completed before publication.

Earlier real TP4 before/after qualification

These results are from the recipe engine base 59402086381a42c74d53053443224eec2790b4c5 plus the four runs/2026-10-17-1017-tensorfold patches in tonyd2wild/DeepSeek-V4.1-Flash-vLLM-DGX-Spark, with/without this narrow fix. They do not claim GPU qualification of the newer PR base. Tested on four GB10 Sparks, DeepSeek-V4.1-Flash 1017, TP4, 2048-row chunks and 128-row replay window.

Rendered input tokens Baseline Identical first request after fix Candidate cached tokens
10353 MissingTritonVariant, zero output tokens completed + tool continuation 0
10363 MissingTritonVariant, zero output tokens completed + tool continuation 0
39039 MissingTritonVariant, zero output tokens completed + tool continuation 36864
123003 MissingTritonVariant, zero output tokens completed + tool continuation 120832

Neighbors 39038/39040 and 123002/123004 and prefix warmers also passed with exact tool arguments and ALIGNMENT_OK continuations. The failing launch has ring_size=144, n_idx=512 and POS/RBASE/CBASE all 8 modulo 16. Existing H16/H32 AOT records were inspected for the aligned requirement. Replay offsets are source-derived; prompt lengths, prefix resumption and completions were observed.

Only synthetic fixtures and four-Spark TP4 were tested. No TP2/other hardware qualification, benchmark, soak, private-workload replay, broad long-job stability or whole-model token-exactness claim. No raw prompts, private logs, infrastructure identifiers or deployment material are included.

@mrsergiopascal

Copy link
Copy Markdown
Author

Recipe heads-up for @tonyd2wild: this narrow engine PR addresses decode-sized long-context replay alignment in the runs/2026-10-17-1017-tensorfold recipe. Earlier four-Spark TP4 tests reproduced MissingTritonVariant at 10353/10363/39039/123003 rendered tokens and passed the identical requests after this repair, including tool continuations and cached-prefix cases. The PR includes synthetic reproduction instructions and explicitly distinguishes that pinned-build evidence from this newer branch. Linking here rather than opening a duplicate recipe issue; no recipe/runtime change is requested until engine review and qualification.

@bertholomus
bertholomus merged commit d9ce33c into bertholomus:deepseek-v41-zig-tp4 Oct 20, 2026
@bertholomus

Copy link
Copy Markdown
Owner

Merged, thank you @mrsergiopascal! A replay cut that leaves 1 to 15 rows at an odd offset now copies those rows' positions into the chunk's aligned buffer, and every other cut keeps the old view, so replies that worked before stay the same. Here the host tests, the server tests and an aarch64 + CUDA build pass, and your CPU test passes on the fix and fails on the old code, as you wrote. Thanks also for the clear notes and the reproducer!

bertholomus added a commit that referenced this pull request Oct 21, 2026
The four-node line that serves DeepSeek-V4.1-Flash-1017 on four GB10 nodes comes in as its own commits since v0.2.0
(22, six of them merges). This merge keeps the branch a fast-forward of its head with pull requests #30 and #31
(b8b115e).

Against v0.2.0:
- A replay cut uploads its rows' positions into the chunk's aligned buffer (a prompt resumed after a kept text prefix
  no longer stops with MissingTritonVariant).
- Kept prompt states: pull request #26 (@hashd1ve), a prefix two conversations share no longer stales the first one's
  kept states; prompts with lane images keep and resume their states, matched by the images' digests (after #28 by
  @hashd1ve), and a resumed prompt skips the vision tower for the images its kept state holds; a kept state the lanes
  would refuse is passed over for an earlier one.
- TENSORFOLD_PLAIN_SPECIALS: a sender's special-token text stays text, and a lane-vision engine's image placeholders
  stay its image tokens.
- Structured output (response_format json_object and json_schema) through libtfgrammar; TENSORFOLD_GRAMMAR_LIB names
  its file.
- tool_choice "required" and a named function write DeepSeek's DSML calls block, and a forced call's marker is always
  its token.
- The served sampler draws top_k off (0 and -1) and any top_k.
- The draft head's chains counted by depth for /metrics, with an optional stats line (TENSORFOLD_STATS_EVERY).
- Off unless set: TF_FILL_CHUNKS (#29 by @hashd1ve, on TP4: a prompt pass in pieces between the other streams'
  rounds) and TENSORFOLD_REPLY_IDS.

Both sides changed zig/src/families/dsv41/model.zig and prompt.zig. model.zig takes both: #30's neighbor gather beside
the served line's changes. prompt.zig keeps the served line's replayCut, which uploads every cut's surviving positions
into the chunk's own buffer; #31 uploads them for small odd cuts and keeps the view otherwise, and the positions are
the same. #31's CPU test follows the served replayCut (one upload for every cut) and passes on it, and
replay_positions.md says so; the v0.2.0 baseline still fails it as the document says. Every other file is one side's:
40 the served line's, 17 this branch's.

With TF_DS_NEIGHBOR_RDMA unset, #30 opens no neighbor gather and every exchange takes the path it took before. Rank
0's startup settings now carry the neighbor mode (48 bytes, 40 before), so every rank runs the same build.

Thanks @swbiggart for #30 and @mrsergiopascal for #31.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bertholomus added a commit that referenced this pull request Oct 21, 2026
…, forced tool calls, five contributions

The README's fork note adds what the branch serves since v0.3.0: kept prompt states for image turns too, a shared
4,194,304-position window, structured output and forced tool calls in DeepSeek's DSML. NOTICE lists the new files (the
prompt shield's, and the neighbor transport's document and receipts), every upstream file the branch changes against
1.0.12 (16 more since v0.2.0) and the contributions: Manrique's pull requests #26, #28 and #29, Scott Woolsey
Biggart's #30 and mrsergiopascal's #31. ATTRIBUTION.md adds them, the ideas taken from DeepSeek's DeepInfer and from
xgrammar's structural tags, and @den13501's report behind the stream keepalive. The family's section of
THIRD_PARTY_NOTICES.md names libtfgrammar in a deployment's kit.

The fork note also thanks the branch's contributors by name. ATTRIBUTION.md says that the EXL3 kernel code copied
from TensorFold's Python line was written before 0.6.0 and keeps its MIT notice (LICENSES/MIT.txt), and names the
co-authors the commits' trailers name.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants