Skip to content

fix(inference): AUT-2539 fail impossible KV handoffs on arrival and honor aborts - #8267

Closed
svcnemo-autobot wants to merge 3 commits into
NVIDIA:mainfrom
svcnemo-autobot:fix/inference-handoff-reject-and-abort
Closed

svcnemo-autobot wants to merge 3 commits into
NVIDIA:mainfrom
svcnemo-autobot:fix/inference-handoff-reject-and-abort

Conversation

@svcnemo-autobot

@svcnemo-autobot svcnemo-autobot commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Background

In disaggregated inference, a decode-side KV handoff that exceeded a fixed limit (the KV pool or the maximum sequence length) waited at the head of the capacity queue forever and blocked every later handoff. An ABORT_REQUEST for a handoff that was still queued or transferring was dropped, so the client never got a reply.

What changed

  • dynamic_engine.py: a shared _request_limit_errors helper checks each handoff against the add_request limits before it reserves cache state or joins the queue. A rejected handoff replies once through _fail_submission.
  • An ABORT_REQUEST with no engine entry goes to _abort_kv_handoff:
    • A queued handoff replies at once.
    • A transferring import is marked cancelled. It is retired (released or quarantined) after every model-parallel rank reports its transfer terminal, and then it replies once.
  • NCCL push path (transfer_backends/nccl.py): a rejected or aborted push handoff keeps its FIFO position as a discard. begin_discard_blocks posts matching receives into scratch buffers.
  • Tests: new test_disagg_handoff_lifecycle.py and test_nccl_transfer_backend.py, new cases in test_dynamic_engine.py, and one updated test in test_dynamic_engine_async_sched.py.
  • Merges main ee6baa2e (test(checkpointing): seed CPU initialization in checkpoint load test #8263). It seeds the models in test_checkpoint_load_without_microbatch_calculator, which hung the H100 unit job on e638ce6a in an NCCL barrier.

Details

This fixes two review findings: impossible handoffs (F4) and aborts during a handoff (F5). A rejected or aborted handoff drains its transfer instead of cancelling it mid-flight.

flowchart LR
  A[Handoff arrives] --> B{Within request limits?}
  B -- no --> R[Reply failure once; NCCL push posts a discard receive]
  B -- yes --> Q[Capacity queue]
  Q -- abort --> X[Reply aborted once]
  Q --> T[Transferring]
  T -- abort --> C[Mark cancelled; retire after all MP ranks finish; reply once]
  T --> D[Admitted]
Loading

Tested

  • black, isort, pylint, ruff and py_compile pass on the changed files.
  • On 8×H100 with the CI image sha256:7b4e22a3, tests/unit_tests/**/*.py ran on this head merged with the main tip (ce8ee4cb): 3424 passed, 142 skipped, 0 failed. A second pass ran 24 more tests, all passed. The exit code was 0, and test_checkpoint_load_without_microbatch_calculator finished.
  • GitHub CI on this head has not reported yet.
  • No functional test case covers the disaggregated KV handoff path.

A decode KV handoff that exceeded a fixed limit (the KV pool or the maximum
sequence length) waited at the head of the capacity queue forever, because
capacity that can never appear blocked every later handoff behind it. An
ABORT_REQUEST for a handoff that was still queued or transferring was dropped,
because such a request has no engine entry until its import is admitted, so
the client never got a reply.

- Check each handoff against the limits add_request applies, through a shared
  _request_limit_errors helper, before it reserves cache state or joins the
  queue. A rejected handoff replies once through _fail_submission.
- Route ABORT_REQUEST for a request with no entry to _abort_kv_handoff. A
  queued handoff replies at once; an import still transferring is marked
  cancelled and retired, released or quarantined, once every model-parallel
  rank reports its transfer terminal, then replies once.
- On the NCCL push path the prefill sends regardless, and two-sided
  operations pair by post order per peer, so a rejected or aborted push
  handoff keeps its FIFO position as a discard. begin_discard_blocks posts
  matching receives into scratch buffers without needing cache capacity.

Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com>
@svcnemo-autobot
svcnemo-autobot requested review from a team as code owners October 15, 2026 19:30
@copy-pr-bot

copy-pr-bot Bot commented Oct 15, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@svcnvidia-nemo-ci
svcnvidia-nemo-ci marked this pull request as draft October 15, 2026 19:30
@github-actions

Copy link
Copy Markdown
Contributor

This PR has been automatically converted to draft because all PRs must start as drafts.

When you are ready for review, click Ready for Review to begin the review process. This will:

  1. Add the oncall reviewer (optional reviewer)
  2. Add required review teams based on your changes

See the contribution guide for more details.

@svcnvidia-nemo-ci svcnvidia-nemo-ci added the Run full unit tests Run the full H100 unit-test suite instead of PR impact selection label Oct 15, 2026
@svcnvidia-nemo-ci

Copy link
Copy Markdown
Contributor

/ok to test 5dcd028

…stub

has_admittable_kv_import now reads PendingKvImport.cancelled. The
SimpleNamespace stand-in for a pending import in
test_ready_handoff_uses_safe_no_overlap_admission_point lacked that field
and raised AttributeError, so give it cancelled=False to match the
dataclass default.

Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com>
@svcnvidia-nemo-ci

Copy link
Copy Markdown
Contributor

/ok to test e638ce6

Bring in NVIDIA#8263, which seeds the CPU-initialized models in test_checkpoint_load_without_microbatch_calculator. This PR's testmon selection runs those 16 cases alone. Without the seed, the data-parallel ranks build different reference weights, and the H100 unit job hangs in the NCCL barrier of the next case's fixture.

Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com>
@svcnvidia-nemo-ci

Copy link
Copy Markdown
Contributor

/ok to test a5b70b0

This branch was previously deployed

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

Labels

Run full unit tests Run the full H100 unit-test suite instead of PR impact selection

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants