[Feat]: Add NPU ModelRunnerV2 DBO with Eager and FULL_DECODE_ONLY ACL Graph Support - #275
[Feat]: Add NPU ModelRunnerV2 DBO with Eager and FULL_DECODE_ONLY ACL Graph Support#275lirx-pd wants to merge 7 commits into
Conversation
7552e07 to
616d97b
Compare
jiangkuaixue123
left a comment
There was a problem hiding this comment.
Thanks for the detailed design and test coverage. I found two blockers before this can merge:
- The temporary backport copies/adapts upstream execution code but does not follow this repository's patch-marking requirements; see the inline comment.
- The current head fails the
pre-commitworkflow. The failing job reports mypy errors in the changed source/test files and the SPDX hook modifies four touched test files. Please run the full pre-commit checks and make the workflow green.
| ) | ||
|
|
||
|
|
||
| def execute_model_v026_eager_dbo( |
There was a problem hiding this comment.
This function is a copied/adapted upstream execution path, but the AFD-specific differences are not marked. The repository guidelines require copied or wrapped upstream functions to have the patch reason/functionality/signature comments immediately above them and to surround only the AFD-specific deltas with # ### PATCH START: ... / # ### PATCH END: .... Please re-copy from the exact pinned source and mark the adaptations so future vLLM upgrades can mechanically compare and reapply this backport. The same applies to the copied helpers in runtime.py.
There was a problem hiding this comment.
All the related files have been refactored
jiangkuaixue123
left a comment
There was a problem hiding this comment.
A follow-up pass focused specifically on abstraction and defensive programming. Most of the larger boundaries (AFDAscendUBatchRunnerV2, graph-entry state, and the scoped graph-manager context managers) are justified because they isolate substantial lifecycle/state. The overengineering is concentrated in compatibility sentries and optional attribute probing. assert_backport_required() is also a single-use helper that duplicates the module ABI sentry; I suggest removing both and relying on the pinned ABI plus direct accesses/tests.
|
|
||
|
|
||
| _EXPECTED_RUNTIME_ABI = 3 | ||
| _loaded_runtime_abi = getattr(dbo_runtime, "AFD_MRV2_DBO_RUNTIME_ABI", 1) |
There was a problem hiding this comment.
This module-to-module ABI handshake looks over-defensive. These modules are shipped from the same package/checkout, and there is already a second proactive guard in assert_backport_required(). The getattr(..., 1) fallback also masks the actual missing-symbol failure. Please remove this private ABI protocol (and the single-use descriptor-field sentry) and let the pinned vLLM contract plus normal import/static-test failures expose drift.
| num_ubatches=ubatches, | ||
| ) | ||
|
|
||
| dispatch_ubatches = getattr(cudagraph_manager, "dispatch_ubatches", None) |
There was a problem hiding this comment.
Please avoid probing this contract with getattr and replacing the original failure with a custom RuntimeError. The DBO initialization path installs AFDModelAclGraphManagerV2, which defines dispatch_ubatches; call cudagraph_manager.dispatch_ubatches(...) directly (and preferably give the manager a concrete protocol/type). If that contract changes, the original attribute/type failure should remain visible, per the repository's upstream-compatibility guidance.
| for groups in attn_groups: | ||
| for group in groups: | ||
| for builder in group.metadata_builders: | ||
| if workspace is None and hasattr(builder, "_get_workspace_buffer"): |
There was a problem hiding this comment.
These hasattr branches silently turn an ABI mismatch into partially initialized graph state. Because this backport targets pinned vLLM/vLLM-Ascend versions, access _get_workspace_buffer() / set_workspace_buffer() directly with the expected builder type and let an upstream incompatibility fail at its source. This removes defensive branching and makes static checking useful.
247ce27 to
5c8dad5
Compare
5c8dad5 to
cd8511d
Compare
Signed-off-by: lirx-pd <616517220@qq.com>
Signed-off-by: lirx-pd <616517220@qq.com>
Signed-off-by: lirx-pd <616517220@qq.com>
…rived code with patch markers and remove redundant defensive logic. Signed-off-by: lirx-pd <616517220@qq.com>
Signed-off-by: lirx-pd <616517220@qq.com>
Signed-off-by: lirx-pd <616517220@qq.com>
cd8511d to
884ac64
Compare
hsliuustc0106
left a comment
There was a problem hiding this comment.
Four actionable findings from review of the current head.
| @@ -0,0 +1,23 @@ | |||
| # SPDX-License-Identifier: Apache-2.0 | |||
There was a problem hiding this comment.
[P1] Package the new backport modules
Package discovery sets namespaces = false, but afd_plugin/compat/backports has no __init__.py. I verified that setuptools.find_packages() excludes afd_plugin.compat.backports.vllm_v026_mrv2_dbo; checkout tests pass through implicit namespace imports, while an installed wheel will omit these modules and fail the new imports. Please add the parent package marker or enable namespace discovery, plus a wheel-import smoke test.
| ) -> torch.Tensor | tuple[torch.Tensor, list[torch.Tensor]] | IntermediateTensors: | ||
| # ### PATCH START: bypass native replay metadata for AFD DBO graphs. | ||
| if isinstance(desc, AFDBatchExecutionDescriptor): | ||
| return original_run_fullgraph(desc) |
There was a problem hiding this comment.
[P1] Mark DBO graph replay in control metadata
This early return bypasses the code that sets _afd_is_graph_replaying = True. AFDModelAclGraphManagerV2.run_fullgraph() subsequently calls send_dp_metadata(), so the FFN receives is_graph_replaying=False and selects eager execution rather than its matching captured graph. Please wrap this call with the same replay-flag save/set/restore logic, or set the flag in the plugin manager before it sends control.
| except BaseException as error: # noqa: BLE001 | ||
| errors[context.id] = error | ||
| # ### PATCH START: Failed worker release | ||
| self.ready_barrier.abort() |
There was a problem hiding this comment.
[P1] Cancel event waits after a stage failure
Aborting ready_barrier only releases threads still entering their contexts. Once execution begins, stages wait on cpu_wait_event; if one stage fails, its sibling can resume, reach the next DBO yield, and wait forever because the failed stage can no longer signal it. close_execution() then blocks indefinitely in thread.join(). Please add shared cancellation checked by the event-wait loop and wake every stage on failure, with a regression test that fails one stage mid-forward.
| self.cudagraph_manager, | ||
| AFDModelAclGraphManagerV2, | ||
| ): | ||
| self.cudagraph_manager.clear_afd_graphs() |
There was a problem hiding this comment.
[P2] Release ubatch ownership before native shutdown
clear_afd_graphs() only clears graph entries. Both this runner and the graph manager still retain ubatch_runner, which retains model_state; ModelState owns the model itself. Therefore super().shutdown() deleting self.model_state and self.model does not release the weights, defeating same-process memory reclamation. Please break these plugin-owned references before native shutdown.
hsliuustc0106
left a comment
There was a problem hiding this comment.
Independent review found two blocking correctness gaps in the NPU ModelRunnerV2 DBO graph path.
| # ### PATCH START: bypass native replay metadata for AFD DBO graphs. | ||
| if isinstance(desc, AFDBatchExecutionDescriptor): | ||
| return original_run_fullgraph(desc) |
There was a problem hiding this comment.
[P1] Preserve replay state for AFD DBO descriptors. execute_model resets _afd_is_graph_replaying to false, and this branch delegates before setting it true. AFDModelAclGraphManagerV2.run_fullgraph then sends the control payload with that false value, while the FFN graph policy selects REPLAY only when is_graph_replaying is true. As a result, the Attention DBO graph replays but the matching FFN graph runs eagerly. Please set and restore the replay flag around this delegation and add a cross-role payload/replay regression test.
| if ( | ||
| not vllm_config.model_config.enforce_eager | ||
| and cudagraph_mode_name(vllm_config) != "FULL_DECODE_ONLY" | ||
| ): | ||
| raise RuntimeError( | ||
| "AFD NPU ModelRunnerV2 DBO ACL graph requires FULL_DECODE_ONLY", | ||
| ) |
There was a problem hiding this comment.
[P1] Reject unsupported non-MLA DBO graph configurations. A registered Qwen3MoeForCausalLM configuration with use_mla=false, DP=2, two ubatches, and FULL_DECODE_ONLY passes this validator. The new AFDModelAclGraphManagerV2 capture path then unconditionally requires an MLA/FIA workspace and raises. Please either require MLA here for DBO graph mode or provide a backend-generic capture path, with a non-MLA regression test.
Signed-off-by: lirx-pd <616517220@qq.com>
Purpose
This PR adds temporary Dual Batch Overlap (DBO) support to the AFD NPU
ModelRunnerV2 path. The pinned vLLM
v0.26.0ABI does not yet include theModelRunnerV2 DBO implementation it needs.
It adapts ModelRunnerV2 DBO behavior from
specture724/vllmbranchfeat/v2/dbo-fullcgat commit626fee7831to vLLM ABI568afb3a13. Themissing upstream pieces live in an isolated compatibility backport. When the
pinned vLLM release gains native ModelRunnerV2 DBO support, this backport can
be removed.
The AFD NPU ModelRunnerV2 path supports:
FULLorFULL_DECODE_ONLY;FULL_DECODE_ONLY.The change does not modify the vLLM or vLLM-Ascend source trees. NPU
ModelRunnerV1 keeps its existing execution path.
Architecture diagram
flowchart TB Config["AFD NPU V2 configuration"] Validation["Scoped v0.26 validation shim"] Runner["AFDNPUAttentionModelRunnerV2"] Dispatch["DP synchronization and DBO dispatch"] Single["Native single-batch V2 path"] Split["Two request-boundary uBatches"] Eager["AFDAscendUBatchRunnerV2<br/>eager execution"] Graph["AFDModelAclGraphManagerV2<br/>DBO graph capture/replay"] Yield["Per-layer DBO handoff"] Connector["CAMP2pAFDConnector"] FFN["Existing AFD NPU FFN runner"] Output["Merged model output"] Guard["Upstream capability guard<br/>remove backport when native DBO lands"] Config --> Validation --> Runner Runner --> Dispatch Dispatch -->|threshold not met| Single --> Connector Dispatch -->|eager DBO| Split --> Eager --> Yield Dispatch -->|captured DBO shape| Split --> Graph --> Yield Yield --> Connector --> FFN --> Connector --> Output Guard -.-> Validation classDef new fill:#fff7ed,stroke:#f59e0b,color:#92400e,stroke-width:2px; classDef reused fill:#ecfdf5,stroke:#16a34a,color:#166534,stroke-width:2px; classDef upstream fill:#eff6ff,stroke:#3b82f6,color:#1e40af,stroke-width:2px; class Validation,Dispatch,Split,Eager,Graph,Guard new; class Runner,Yield,Connector,FFN,Output reused; class Single upstream;Issue
Scope
In scope
v0.26.0ABI intoafd-plugin.FULL_DECODE_ONLYACL graph capture and replay.across DP ranks before execution.
token count across DP ranks.
single batch when graph padding would leave the second microbatch empty.
input, attention, block-table, slot-mapping, and forward-context state for
each microbatch.
tensor, auxiliary-hidden-state, and intermediate outputs in request order.
graphs and publish matching AFD metadata for warmup, capture, and replay.
parameters and updating the captured task-group handles during replay.
during repeated Attention-side capture events.
NPU ModelRunnerV2 configuration.
not met.
Out of scope
FULL_DECODE_ONLY.NPU ModelRunnerV2 DBO.
parallel MoE, or other topologies already unsupported by AFD NPU
ModelRunnerV2.
Implementation notes
Temporary vLLM v0.26 ABI backport
afd_plugin/compat/backports/vllm_v026_mrv2_dbocontains the copied andadapted behavior missing from the pinned upstream ABI:
num_ubatches;At startup, the backport checks the upstream
BatchExecutionDescriptorshape.If upstream already provides
num_ubatches, initialization fails with aninstruction to remove the compatibility layer rather than shadowing the native
implementation.
Eager DBO execution
AFDNPUAttentionModelRunnerV2.execute_model()uses the backported execute pathonly when vLLM reports
use_ubatching; otherwise it uses the nativevLLM-Ascend runner.
For a selected DBO batch, it:
and forward contexts for both stages;
ModelRunnerV2 stores stage-specific Ascend state in
ForwardContext.additional_kwargs. ModelRunnerV1 continues to use its existingattributes, so this does not remove or redirect V1 state.
DP dispatch and fallback
All DP ranks participate in one CPU-group reduction for token count,
uniform-token state, local DBO eligibility, and requested graph mode. This
keeps the eager or graph and single- or dual-batch decision consistent across
ranks.
DBO is used only when every rank allows it, the configured threshold is met,
and both microbatches still contain real work after final graph padding.
Otherwise, the step uses the native single-batch descriptor. If a rank cannot
use a graph, all ranks run the two microbatches eagerly for that step.
Full ACL graph DBO
During ModelRunnerV2 initialization, a scoped wrapper replaces only the graph
manager factory used by the current AFD runner.
finallyblocks restore theoriginal vLLM and vLLM-Ascend symbols.
AFDModelAclGraphManagerV2keeps the native single-batch graph descriptors andowns separate two-microbatch twins for eligible, evenly divisible capture
shapes. Each DBO graph includes:
An uncaptured DBO shape uses eager DBO. A captured single-batch shape continues
through the native graph manager.
Compatibility and isolation
configurations and restores the original config values after upstream
validation.
is always restored.
after each execution scope.
graph ownership.
Configuration boundary
NPU ModelRunnerV2 DBO requires:
v0.26.0without native ModelRunnerV2 DBO descriptors;CAMP2pAFDConnector;compute_gate_on_attention=false;DP * TP;FULL_DECODE_ONLY.Unsupported combinations fail during validation before model execution.
Test plan
Unit and compatibility coverage
selection, and structured output merging.
values.
non-AFD/native-runner isolation.
Ascend E2E coverage
The hardware E2E matrix includes:
FULL_DECODE_ONLYDBO off versus on;Test result
eager and
FULL_DECODE_ONLYgraph execution.implementation path.
Limitations and follow-up
ModelRunnerV2 DBO behavior.
topology above.
dispatch, slicing, and execution, remove the compatibility package and scoped
validation and graph-manager patches. Retain only NPU-specific execution and
ACL graph integration that is still needed.
Essential PR checklist
FULL_DECODE_ONLYDBO behavior is documented.