Skip to content

[Engine] Diagnostic: fixed-config CUDA split A/A matches early state but varies per-verify timing and later path #4069

Closed

Description

@oscarlius

Summary

On a four-stage native CUDA Qwen3.8-Flash-Next setup, two controlled A/A requests produced identical output and identical valid state at three early checkpoints, but showed large differences in individual verify-call durations and a later difference in the recorded speculative execution path.

This is a bounded diagnostic observation, not a confirmed correctness bug, a root-cause claim, or a performance result. Only two generation requests were executed. We stopped before the planned 8192-chunk and MTP-off comparisons.

Related: #3976. This report uses the ordinary chunk-major path; it does not test or validate the layer-major branch proposed there.

Tested configuration and scope

  • Test date: 2026-10-25.
  • Baseline source: 5c8dd322528cc84f68f461ad54a506b9da8fa8d4, with local diagnostic instrumentation in native generation/state export and a service configuration override. This is not a reproduction on current upstream main or v0.2.4.2.
  • Diagnostic executable SHA-256: bb472f0af8145c18c1b324f4056e8319ac8dedd8f364b018c2c135f963f2a1d9. Both arms used this same executable.
  • Model: Qwen3.8-Flash-Next, GSQ-RCO-IQ3_S weights; Q2_0 MTP sidecar enabled in both arms. Model/profile/reserve settings were held fixed.
  • Four CUDA stages, layer split 12,24,36; configured parallel slots: 16, with one diagnostic request at a time.
  • --prefill 2048 --pcie-frac 0.55 --spec 4 --kv int8 --expert-cache auto; observed PCIe fraction was 0.55 on all four stages. Requested --spec 4 is not a claim that every effective verify window has T=4; the recorded verify maximum was 8.
  • Same 130,658-token six-needle retrieval input, seed 20261018, and max_new=32768.
  • Each arm started a fresh candidate engine; conversation-cache reuse was zero. OS page cache was not cleared, and "cold" here means conversation-cache-cold.
  • Effective configuration and the exported initial logical expert-residency maps matched. These maps are logical host-side records, not independent physical GPU-memory readbacks.

The raw prompt, weights and full state exports are not attached. This is therefore a diagnostic summary, not a self-contained public reproducer.

Early state and output checks

Checkpoint A1 vs A2
Before first verify All exported valid float-state items: NRMSE=0; integer/quantized K/V identical
After first verify, before commit Same state result; full first-token logits NRMSE=0, KL=0, top-1 identical
After first commit completed All exported valid float-state items: NRMSE=0; integer/quantized K/V identical

There were 93 / 94 / 93 comparison items at the respective checkpoints, covering all four stage sessions. Unused paged tails were excluded. Existing acceptance thresholds were kept at NRMSE <= 2e-4 and logits KL <= 1e-5; no tolerance was relaxed.

The actual boundary matters: before first verify, p=130657 and T=1. After verify, valid main K/V extends to 130658 while the recurrent checkpoint remains at 130657; after commit, both reach 130658. Draft K/V at that commit checkpoint precedes the subsequent MTP write. We did not compare invalid/speculative rows as if they were committed state.

Both requests returned exactly the same correct six-needle JSON, 231 output tokens, and a natural stop. These checks establish equality at the exported early checkpoints; they do not establish equality of all later hidden states.

Timing and execution-path observations

Timings below are monotonic host-side intervals around the instrumented native calls, not individual CUDA-kernel timings.

Observation A1 A2
First verify, p=130657, T=1 21.994 ms 168.190 ms
Second verify, p=130658, T=4 619.830 ms 28.163 ms
Total verify-call time 1477.145 ms 1426.180 ms
prompt_end to DONE, subtracting three state-export intervals 1808.038 ms 1836.321 ms
Verify-window count 53 55
Draft offered / accepted, response totals 212 / 179 210 / 177

The first 26 windows matched in the recorded execution fields (p, T, T_mtp, merged, from_sfx, chain_n). Thus the second-window difference of 591.667 ms compares the same recorded position, T and draft source; it does not prove identical kernel launches or scheduling.

The first recorded path difference occurred at zero-based window 26, p=130769:

  • A1: T=6, T_mtp=6, from_sfx=true, merged=false, chain_n=0.
  • A2: T=4, T_mtp=4, from_sfx=false, merged=false, chain_n=0.

Windows after that point should not be paired mechanically by index. A2 also had a 395.988 ms T=2 verify interval at its own zero-based window 45; we do not treat it as a matched A1 event.

Stop decision and measurement limitations

The aggregate timing gate would pass: aggregate intervals were close despite the per-window changes. On observing the per-window timing/path differences, we stopped the campaign under the predeclared "unstable A/A => stop attribution" rule. The request ledger contained only A1 and A2; no 8192 arm or MTP-off arm was sent. Subsequent work was offline analysis of those two requests.

  • Neither request had OOM, host swap or a resource-guard failure. Minimum sampled free GPU memory was 1604 / 1600 MiB; peak sampled temperatures were 59 / 63 C; host available memory remained above 100 GiB.
  • Per-GPU sampling intervals had a median of about 100.4 ms and maximum of about 111.6 ms. All four GPUs were observed at PCIe Gen4 x16. Across 25 samples spanning the slow A1 T=4 interval, sampled SM clocks were 2520 MHz. This does not exclude shorter events, scheduling, synchronization or initialization effects.
  • CPU/expert counters cover only the primary drive, not all stages; zero counters cannot establish absence of CPU/cache work elsewhere.
  • First-kernel/CUDA-graph capture counters were unavailable and recorded as unknown. We do not have a complete kernel-launch trace.
  • State export, CUDA synchronization and per-window tracing perturb execution. Subtracting export time does not produce an uninstrumented benchmark.
  • Two runs are not a statistical characterization. Path variability might be expected under some scheduling conditions; this report does not establish that it is erroneous.
  • No conclusion is established about MTP causality, cross-chunk numerical equivalence, a specific kernel, layer-major speedup, or suitability for deployment.

Question for maintainers

For this native CUDA split path, is the observed later suffix/MTP path variation expected with the same request seed and matching early state? Which existing counter or trace point would best distinguish verify-call synchronization/initialization cost from actual model work before attempting any cross-chunk attribution?

We are keeping this separate from the cache-copy work in #4002 and linking #3976 only for validation-method context. No fix is claimed.

Only allowlisted configuration fields, hashes and aggregate diagnostic measurements are included here. No internal addresses, hostnames, filesystem paths, credentials, raw request text, model files or raw state dumps are published.

Activity

  1. Niko1221 commented on Oct 26, 2026

    @Niko1221
    Owner

    Thanks for the careful write-up. The different path with the same seed is expected: the speculative policy picks the window size from the measured time of recent rounds, so two runs can diverge while the verified output stays the same. The 150 to 600 ms first verifies are more likely first-use setup than compute, and STRATA_DECODE_TIMING=1 with STRATA_VERIFY_PROFILE=1 shows per-stage timings to compare early and later windows. We are not changing the code for this, and you are welcome to reopen with a case where the output text or the early state differs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions