Skip to content

[RFC]: Support for current v0.2.0 features on different GPU architectures #172

Open

Description

@0z5a

[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:

3. Platform contract

  1. Detection. One helper decides is_rocm() / is_cuda(); call sites never test torch.version.hip directly.
  2. Attention. On CUDA, auto prefers 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.
  3. 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.
  4. UVA. Triton receives host pointers directly, so mapped host metadata is enabled only after hipHostGetDevicePointer returns the host address. VLLM_RLT_UVA=0 forces H2D copies; =1 skips the probe.
  5. Device namespace. ROCm uses torch.cuda and CUDA_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:

  1. capability detection and auto backend wiring;
  2. async scheduling and multi-stream;
  3. graph capture/replay equivalent;
  4. prefix cache and preemption/recovery;
  5. synchronous and asynchronous self-speculation;
  6. packed prefill and WCPB;
  7. PD transport and KV transfer;
  8. KV quantization and sparse decode from RFC [RFC]: FlashLoop integration — token-sparse prefill, sparse decode attention, and KV residual quantization #156;
  9. 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

  1. Enable packed prefill by default on ROCm, or keep the prefill_uva opt-in until multi-sequence numerics are qualified?
  2. Probe UVA on every platform, or keep the CUDA fast path without a probe?
  3. Does Ascend need the same capability object, or a separate backend adapter?
  4. Which ROCm CI runner is acceptable (self-hosted MI300/MI350 vs none)?
  5. Should auto warn when prefill_uva is requested without packed support?

10. Community directions

Entry points left to the community, not implied commitments:

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

  1. changed the title [-][RFC]: ROCm platform parity and community-owned follow-ups[/-] [+][RFC]: Support for v0.2.0 features across GPU architectures[/+] on Nov 5, 2026
  2. changed the title [-][RFC]: Support for v0.2.0 features across GPU architectures[/-] [+][RFC]: Support for current v0.2.0 features on different GPU architectures[/+] on Nov 5, 2026
  3. O1range commented on Nov 6, 2026

    @O1range

    @0z5a ,I can use 4x Ascend 910B3, and I’d like to take ownership of the PD / KV transfer work

  4. 0z5a commented on Nov 6, 2026

    @0z5a
    ContributorAuthor

    @0z5a ,I can use 4x Ascend 910B3, and I’d like to take ownership of the PD / KV transfer work

    Sounds great! Please based on the current #168 and coordinate with the author. ^^

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions