Repository navigation
Description
[RFC]: Support for current v0.2.0 features on different GPU architectures
Status: RFC draft for discussion. Date: 2026-11-05.
Feedback period: at least one week after publication. The issue stays open afterward for ownership and implementation tracking.
References: PR #171 (ROCm), PR #168 (Ascend), RFC #156 (FlashLoop), RFC #111 (PD/KV transfer).
1. Motivation, goal and scope
The v0.2.0 runtime has one validated target: NVIDIA CUDA. This RFC defines what "supporting" the same feature set on another GPU architecture means, records the ROCm implementation, and sets the Ascend TODO list. It is not a kernel-portability claim: a feature is supported only when its public configuration path runs and its acceptance level is recorded.
Feature scope:
- packed prefill and
prefill_uva; - wavefront chunked prefill (WCPB);
- token-level decode pipeline;
- preemption and recovery;
- prefix cache;
- asynchronous scheduling and execution;
- synchronous self-speculation and its asynchronous variant;
- CUDA Graph replay, static buffers, multi-stream;
- mapped host metadata (UVA);
- HTTP serving.
ROCm is implemented by PR #171. Ascend is an experimental contribution in PR #168 and is intentionally TODO for most features. The Stage/Loop architecture, scheduler policies, model code and numerical contracts are unchanged; only platform capability decisions and one Triton precision argument change.
2. Baseline
Pinned for this RFC:
- vllm-rlt
444638bplus PR [ROCm] v0.2.0 feature support on AMD Instinct #171. - ROCm: 1× MI350X VF,
gfx950, 288 GiB HBM, ROCm 7.2, PyTorch 2.14.1+rocm7.2, Triton 3.5.1. - Ascend: PR [Feature] Add experimental Ascend support for Ouro #168 branch
ouro-ascend-contribution, one NPU. - Models: Ouro-1.4B, Ouro-2.6B, Ouro-1.4B/2.6B-Thinking, Nanbeige4.2-3B and Huginn-0125 (real-checkpoint generation; suite coverage follows the shared loaders).
3. Platform contract
- Detection. One helper decides
is_rocm()/is_cuda(); call sites never testtorch.version.hipdirectly. - Attention. On CUDA,
autoprefers FA4/FA3/FA2, then Triton, then Torch. On ROCm it considers Triton then Torch and never imports FlashAttention; an explicit FA request keeps its interface and raises an NVIDIA-only error. - Packed prefill. Triton's packed kernel is the ROCm path, opt-in through
prefill_uva, matching the existing capability-based selection. CUDA keeps FA4 as the packed owner. - UVA. Triton receives host pointers directly, so mapped host metadata is enabled only after
hipHostGetDevicePointerreturns the host address.VLLM_RLT_UVA=0forces H2D copies;=1skips the probe. - Device namespace. ROCm uses
torch.cudaandCUDA_VISIBLE_DEVICES; no new public device flag.
4. Changes delivered on ROCm
| Module | Responsibility |
|---|---|
vllm_rlt/platform.py |
Build-flavor predicates |
attention/backend.py |
ROCm candidate order, diagnostics |
kernels/triton_attention.py |
ieee dot precision on ROCm (Triton rejects tf32) |
worker/tensors.py |
UVA probe, env override, fallback |
engine/stage_engine.py |
Platform-neutral graph validation |
| tests/docs | ROCm suite partition, docs/rocm.md |
No model code or scheduler behavior changes.
5. Feature support
Status: ✅ validated (suite + real model), 🚧 smoke/in progress, ⬜ pending/TODO. Owners are the current PR coordinators; contributors can add themselves per row.
5.1 ROCm
| Feature | Status | PR | Owner |
|---|---|---|---|
| Ouro-1.4B | ✅ | #171 | @0z5a |
| Ouro-2.6B | ✅ | #171 | @0z5a |
| Ouro-1.4B/2.6B-Thinking | ✅ generation | #171 | @0z5a |
| Nanbeige4.2-3B | ✅ | #171 | @0z5a |
| Huginn-0125 | ✅ generation + graph replay | #171 | @0z5a |
| Triton attention + Torch reference | ✅ | #171 | @0z5a |
Packed prefill / prefill_uva |
🚧 opt-in (FP32 exact, BF16 <=0.0156) | #171 | @0z5a |
| WCPB | ✅ | #171 | @0z5a |
| Token pipeline | 🚧 opt-in (2.14x at 1.4B 256-out, 1.63x on 2.6B) | #171 | @0z5a |
| Preemption / recovery | ✅ | #171 | @0z5a |
| Prefix cache | ✅ | #171 | @0z5a |
| Priority scheduling | ✅ high-priority latency 7.80s→2.22s | #171 | @0z5a |
| Incremental KV | ✅ +3.8% | #171 | @0z5a |
| Sparse decode | ✅ tests on merged branch (--sparse-decode-attention, --sparse-decode-key-retention) |
#157 | @kunkunblueberry |
| Async scheduling / execution | ✅ | ||
| Async self-speculation | 🚧 opt-in (1.48x at 1.4B 256-out) | #171 | @0z5a |
| Sync self-speculation | 🚧 opt-in (1.41x at 1.4B 256-out, 1.18x on 2.6B) | #171 | @0z5a |
| CUDA Graph replay + static buffers | ✅ | #171 | @0z5a |
| UVA host metadata | ✅ probed | #171 | @0z5a |
| FlashAttention | N/A | — | — |
| PD / KV transfer | ⬜ needs 2 GPUs + NIXL/UCX | #111 | TBD |
| KV quantization / sparse decode | ⬜ | #156, #157 | @kunkunblueberry |
5.2 Ascend
| Feature | Status | PR | Owner |
|---|---|---|---|
| Ouro-1.4B, BF16 fixed four-loop, full prefill | 🚧 smoke | #168 | @KrystalRay |
| Ouro-2.6B / Thinking / Nanbeige / Huginn | ⬜ | — | TBD |
Attention backend and auto wiring |
🚧 | #168 | @KrystalRay |
| Async scheduling / multi-stream | ⬜ | — | TBD |
| Graph capture / replay | ⬜ | — | TBD |
| Prefix cache | ⬜ | — | TBD |
| Preemption / recovery | ⬜ | — | TBD |
| Sync and async self-speculation | ⬜ | — | TBD |
| Token pipeline | ⬜ | — | TBD |
| Packed prefill / WCPB | ⬜ | — | TBD |
| PD / KV transfer | 🚧 claimed on 4× Ascend 910B3 | #111 | @O1range |
| KV quantization / sparse decode | ⬜ | #156 | TBD |
| Serving + CI runner | ⬜ | — | TBD |
The Ascend PD/KV-transfer cell is claimed by @O1range on 4× Ascend 910B3. The Ouro-1.4B Ascend cell is claimed by @KrystalRay per the RFC #69 ownership comment: BF16, synchronous, fixed four-loop, single NPU, CANN attention through torch_npu, depth-aware LAST_EXITED KV, with declared numerical tolerances and bounded accuracy/performance evidence. Multi-device PD is a separate @O1range claim; asynchronous execution, adaptive exit, self-speculation and the Nanbeige/Huginn ports are outside the Ouro-1.4B cell.
6. Ascend status and TODO
PR #168 targets BF16, fixed four-loop, synchronous greedy inference with full prefill on one NPU. It does not claim async scheduling, graphs, prefix cache, preemption, speculation, packed prefill or WCPB. The Ascend TODO list:
- capability detection and
autobackend wiring; - async scheduling and multi-stream;
- graph capture/replay equivalent;
- prefix cache and preemption/recovery;
- synchronous and asynchronous self-speculation;
- packed prefill and WCPB;
- PD transport and KV transfer;
- KV quantization and sparse decode from RFC [RFC]: FlashLoop integration — token-sparse prefill, sparse decode attention, and KV residual quantization #156;
- serving parity and a CI runner.
Each item needs its own acceptance level; PR #168's smoke run is R0 only.
7. Configuration and environment
| Setting | ROCm | Ascend |
|---|---|---|
--attention-backend |
triton or auto |
branch-specific |
VLLM_RLT_UVA |
auto/0/1 |
TODO |
CUDA_VISIBLE_DEVICES |
device selector | N/A |
--wavefront-chunked-prefill |
supported | TODO |
--prefill-uva |
Triton packed, single sequence | TODO |
8. Validation and acceptance
- R0 smoke: one real checkpoint generates non-degenerate text.
- R1 suite: CPU suite plus GPU suite, with only explicit architecture/environment skips.
- R2 performance: matched workload/config, reported with device, runtime and kernel versions.
- R3 numerics: greedy equality against the Torch reference on fixed prompts; approximated paths labelled.
- R4 distributed: multi-GPU PD with output equality and transfer accounting.
ROCm reaches R1 and R2 for Ouro-1.4B, Ouro-2.6B, both Thinking checkpoints, Nanbeige4.2-3B and Huginn-0125. R3 remains open for speculative decoding (30/32 prompt equality; 0/20 GSM8K both arms). Packed prefill is located: FP32 greedy matches per-row exactly while BF16 differs by <=0.0156, so it stays opt-in. Ascend is R0.
Baseline definition: same commit, model, device and wheel set, attention_backend="triton", ExecutionConfig() defaults, same exit mode, VLLM_RLT_UVA=0, no optional feature. There was no earlier ROCm baseline, so all numbers are ROCm-relative; CUDA numbers were not measured on this lease. One warm-up generation is discarded, then the median of three runs is reported:
| Workload | Baseline tok/s | All features tok/s | Speedup |
|---|---|---|---|
| short, batch 1, 64 out | 18.4 | 32.8 | 1.78x |
| short, batch 32, 64 out | 446 | 916 | 2.05x |
| short, batch 128, 64 out | 1148 | 2909 | 2.53x |
| short, batch 256, 64 out | 1606 | 3270 | 2.04x |
| short, batch 512, 64 out | 1864 | 3919 | 2.10x |
| long, batch 8, 32 out | 84.8 | 171.0 | 2.02x |
| long, batch 32, 32 out | 153.8 | 544.4 | 3.54x |
| long, batch 64, 32 out | 179.8 | 866.4 | 4.82x |
all excludes packed prefill. The 32-token cells are prefill-heavy; the 256-token cell is decode-heavy (baseline 6.3 ms/step, all 3.4 ms/step). Environment micro-tuning: HIP_FORCE_DEV_KERNARG=1 2781, HSA_ENABLE_INTERRUPT=0 2843 vs default 2798. PyTorch already selects hipBLASLt; forcing it did not improve throughput.
Full-feature sweep
Short context (80-token prompt, 64 output), Ouro-1.4B:
| Workload | Baseline | runtime | spec | Best |
|---|---|---|---|---|
| short b128 | 1194 | 2208 | 2069 | 1.85x |
| short b256 | 1670 | 4329 | 2126 | 2.59x |
| short b512 | 2008 | 4184 | 2031 | 2.08x |
Long context and checkpoints (1k/4k/8k). runtime = async + graphs + static/pad2 + UVA + WCPB + prefix; spec adds pipeline K4/draft1. Huginn's optimized column is graph replay; Nanbeige has no spec path:
| Model | Context | Batch | Out | Baseline | runtime | spec | Best |
|---|---|---|---|---|---|---|---|
| Ouro-1.4B | 1k | 32 | 32 | 155.7 | 407.6 | 761.0 | 4.89x |
| Ouro-1.4B | 1k | 64 | 32 | 176.5 | 661.5 | 894.2 | 5.07x |
| Ouro-1.4B | 1k | 128 | 32 | 177.9 | 1019.1 | 998.2 | 5.73x |
| Ouro-1.4B | 4k | 4 | 128 | 37.9 | 84.8 | 263.6 | 6.96x |
| Ouro-1.4B | 4k | 2 | 256 | 28.7 | 54.7 | 168.4 | 5.87x |
| Ouro-1.4B | 8k | 2 | 32 | 5.0 | 46.2 | 107.2 | 21.4x |
| Ouro-1.4B | 8k | 1 | 128 | 10.1 | 27.7 | 80.3 | 7.95x |
| Nanbeige4.2-3B | 1k | 32 | 32 | 167.4 | 854.7 | — | 5.11x |
| Nanbeige4.2-3B | 1k | 64 | 32 | 176.4 | 1083.7 | — | 6.14x |
| Nanbeige4.2-3B | 1k | 128 | 32 | 177.2 | 1464.8 | — | 8.27x |
| Nanbeige4.2-3B | 4k | 4 | 64 | 27.7 | 199.9 | — | 7.2x |
| Nanbeige4.2-3B | 8k | 2 | 32 | 4.2 | 87.1 | — | 20.7x |
| Huginn-0125 | 1k | 1 | 32 | 8.8 | 9.5 | — | 1.08x |
| Huginn-0125 | 1k | 2 | 32 | 13.6 | 14.8 | — | 1.09x |
| Huginn-0125 | 1k | 4 | 32 | 14.0 | 14.7 | — | 1.05x |
| Huginn-0125 | 1k | 8 | 32 | 16.5 | — | — | — |
| Huginn-0125 | 4k | 1 | 32 | 3.1 | 3.2 | — | 1.03x |
| Huginn-0125 | 4k | 2 | 32 | 3.1 | — | — | — |
| Huginn-0125 | 4k | 4 | 32 | 3.1 | — | — | — |
| Huginn-0125 | 4k | 8 | 32 | 3.1 | — | — | — |
Huginn is compute-bound by 32 recurrent steps (flat across batch), graph replay adds 3-9%, and 8k is rejected by its context limit. 8k Ouro prefill: 1247 -> 11544 -> 26800 tok/s.
Per-feature warmed A/B at batch 128, one warm-up discarded, median of three. Non-spec rows use 32 output tokens and the baseline_delayed reference (970 tok/s); spec rows use 256 output tokens and the ouro baseline (1527 tok/s). The 32-output spec numbers (0.51x/0.95x/0.89x) are in the workload-dependent paragraph below.
| Config | tok/s | vs reference |
|---|---|---|
| async scheduling | 1025 | 1.06x |
| CUDA graphs | 986 | 1.02x |
| static buffers + pad2 | 1056 | 1.09x |
| UVA | 1019 | 1.05x |
| WCPB | 1402 | 1.45x |
| prefix cache | 1105 | 1.14x |
| all features | 2798 | 2.88x |
| sync self-speculation (256 out) | 2148 | 1.41x |
| token pipeline (256 out) | 3270 | 2.14x |
| async self-speculation (256 out) | 2314 | 1.48x |
Speculation is workload-dependent. At 32 output tokens prefill dominates and it loses; at 256 output tokens it wins on Ouro-1.4B (baseline 1527): pipeline K4/draft1 3270 in the sweep and 2842 confirmed (1.82x), block K2/draft1 2148/2251, async K2/draft1 2314 (1.48x). On Ouro-2.6B pipeline K2/draft1 is 814 vs 500 (1.63x). Greedy match against baseline is 0.66-0.80 and GSM8K scored 0/20 for both arms, so it stays opt-in. WCPB is the largest single win for non-speculative workloads.
Priority scheduling is positive: 64 low- plus 8 high-priority requests at 16 slots drop high-priority median completion from 7.80s (fcfs) to 2.22s, while total time moves 7.81s to 8.15s. Incremental KV gives 817 -> 848 tok/s (+3.8%). Sparse decode from #157 passes its ROCm suites (137 passed, 3 skipped) after merging #171; it is tracked in #157, not shipped here.
Not done on ROCm: packed engine parity, PD/KV transfer (two GPUs + ROCm NIXL/UCX), KV quantization (not on current main; RFC #156), profiling flags, multi-node, FlashAttention (NVIDIA-only).
9. Open decisions
- Enable packed prefill by default on ROCm, or keep the
prefill_uvaopt-in until multi-sequence numerics are qualified? - Probe UVA on every platform, or keep the CUDA fast path without a probe?
- Does Ascend need the same capability object, or a separate backend adapter?
- Which ROCm CI runner is acceptable (self-hosted MI300/MI350 vs none)?
- Should
autowarn whenprefill_uvais requested without packed support?
10. Community directions
Entry points left to the community, not implied commitments:
- ROCm PD and KV transfer (NIXL/UCX/RCCL, RFC [RFC]: PD coordination and KV transfer contracts #111);
- KV cache quantization and cross-loop residuals on
gfx950(RFC [RFC]: FlashLoop integration — token-sparse prefill, sparse decode attention, and KV residual quantization #156); - sparse decode and FlashLoop kernels (RFC [RFC]: FlashLoop integration — token-sparse prefill, sparse decode attention, and KV residual quantization #156, PR Sparse decode attention: per-token reference lifecycle for async self-speculation #157);
- AITER/CK attention alternatives to Triton;
- graph budget/eviction behavior on ROCm;
- MI300/
gfx942qualification; - Ascend CI and the TODO list above.
11. Ownership
Core maintainers own the platform contract, backend selection and UVA probe. Each architecture port has an owner per row in Section 5. Community PRs must pin versions and state the acceptance level they reach.
Activity
[-][RFC]: ROCm platform parity and community-owned follow-ups[/-][+][RFC]: Support for v0.2.0 features across GPU architectures[/+][-][RFC]: Support for v0.2.0 features across GPU architectures[/-][+][RFC]: Support for current v0.2.0 features on different GPU architectures[/+]O1range commentedon Nov 6, 2026
@0z5a ,I can use 4x Ascend 910B3, and I’d like to take ownership of the PD / KV transfer work
0z5a commentedon Nov 6, 2026
Sounds great! Please based on the current #168 and coordinate with the author. ^^