Files
2026-05-29 11:05:12 -04:00

1053 lines
44 KiB
ReStructuredText
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.. meta::
:description: Learn about vLLM V1 inference tuning on AMD Instinct GPUs for optimal performance.
:keywords: AMD, Instinct, MI300X, MI325X, MI350X, MI355X, HPC, tuning, BIOS settings, NBIO, ROCm,
environment variable, performance, HIP, Triton, PyTorch TunableOp, vLLM, RCCL,
MIOpen, GPU, resource utilization
.. _mi300x-vllm-optimization:
.. _vllm-optimization:
********************************
vLLM V1 performance optimization
********************************
This guide helps you maximize vLLM throughput and minimize latency on AMD
Instinct MI300X, MI325X, MI350X, and MI355X GPUs. Learn how to:
* Enable AITER (AI Tensor Engine for ROCm) for speedups on LLM models.
* Configure environment variables for optimal HIP, RCCL, and Quick Reduce performance.
* Select the right attention backend for your workload (AITER MHA/MLA vs. Triton).
* Choose parallelism strategies (tensor, pipeline, data, expert) for multi-GPU deployments.
* Apply quantization (``FP8``/``FP4``) to reduce memory usage by 2-4× with minimal accuracy loss.
* Tune engine arguments (batch size, memory utilization, graph modes) for your use case.
* Benchmark and scale across single-node and multi-node configurations.
Performance environment variables
=================================
The following variables are generally useful for Instinct MI300X/MI325X/MI350X/MI355X GPUs and vLLM:
* **HIP and math libraries**
* ``export HIP_FORCE_DEV_KERNARG=1`` — improves kernel launch performance by
forcing device kernel arguments. This is already set by default in
:doc:`vLLM ROCm Docker images
</how-to/rocm-for-ai/inference/benchmark-docker/vllm>`. Bare-metal users
should set this manually.
* ``export SAFETENSORS_FAST_GPU=1`` — enables GPU-accelerated safetensors
loading, significantly reducing model load time for large models. Already
set in vLLM ROCm Docker images. Bare-metal users should set this manually.
* ``export TORCH_BLAS_PREFER_HIPBLASLT=1`` — explicitly prefers hipBLASLt
over hipBLAS for GEMM operations. By default, PyTorch uses heuristics to
choose the best BLAS library. Setting this can improve linear layer
performance in some workloads.
* **RCCL (collectives for multi-GPU)**
* ``export NCCL_MIN_NCHANNELS=112`` — increases RCCL channels from default
(typically 32-64) to 112 on the Instinct MI300X/MI325X. **Only beneficial for
multi-GPU distributed workloads** (tensor parallelism, pipeline
parallelism). Single-GPU inference does not need this.
.. _vllm-optimization-aiter-switches:
AITER (AI Tensor Engine for ROCm) switches
==========================================
AITER (AI Tensor Engine for ROCm) provides ROCm-specific fused kernels optimized for Instinct MI350 Series and MI300X/MI325X GPUs in vLLM V1.
Enable all AITER optimizations with a single master switch:
.. code-block:: bash
export VLLM_ROCM_USE_AITER=1
vllm serve MODEL_NAME
Most individual AITER sub-flags default to ``1`` when the master switch is on,
while specialized features retain the defaults listed below. You rarely need to
change them. To select a specific attention backend, use ``--attention-backend``
(see :ref:`backend selection <vllm-optimization-aiter-backend-selection>`).
**Flags you might adjust:**
* ``VLLM_ROCM_SHUFFLE_KV_CACHE_LAYOUT=1`` — Set for high-concurrency MHA workloads (≥32 concurrent requests) with ``ROCM_AITER_FA``. Defaults to ``0``.
* ``VLLM_ROCM_USE_AITER_MOE=0`` — Disable only if you hit ``RuntimeError: wrong! device_gemm ...``. Try ``AITER_ONLINE_TUNE=1`` first. See :ref:`AITER MoE requirements <vllm-optimization-aiter-moe-requirements>`.
* ``VLLM_ROCM_USE_AITER=0`` — Disable AITER entirely to fall back to Triton kernels (for debugging).
Advanced: individual AITER flags
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The following table lists AITER-related sub-flags for fine-grained control. Most
users do not need to modify these; the default behavior for each flag is listed below.
.. list-table::
:header-rows: 1
:widths: 30 70
* - Environment variable
- Description (default behavior)
* - ``VLLM_ROCM_USE_AITER``
- Master switch to enable AITER kernels (``0`` by default). All other ``VLLM_ROCM_USE_AITER_*`` flags require this to be set to ``1``.
* - ``VLLM_ROCM_USE_AITER_LINEAR``
- Use AITER quantization operators + GEMM for linear layers (defaults to ``1`` when AITER is on). Accelerates matrix multiplications in all transformer layers. **Recommended to keep enabled**.
* - ``VLLM_ROCM_USE_AITER_MOE``
- Use AITER fused-MoE kernels (defaults to ``1`` when AITER is on). Accelerates Mixture-of-Experts routing and computation. See the note on :ref:`AITER MoE requirements <vllm-optimization-aiter-moe-requirements>`.
* - ``VLLM_ROCM_USE_AITER_RMSNORM``
- Use AITER RMSNorm kernels (defaults to ``1`` when AITER is on). Accelerates normalization layers. **Recommended: keep enabled.**
* - ``VLLM_ROCM_USE_AITER_MLA``
- Use AITER Multi-head Latent Attention for supported models, for example, DeepSeek-V3/R1 (defaults to ``1`` when AITER is on). See the section on :ref:`AITER MLA requirements <vllm-optimization-aiter-mla-requirements>`.
* - ``VLLM_ROCM_USE_AITER_MHA``
- Use AITER Multi-Head Attention kernels (defaults to ``1`` when AITER is on; set to ``0`` to use Triton attention backends or ``ROCM_ATTN`` backend instead). See :ref:`attention backend selection <vllm-optimization-aiter-backend-selection>`.
* - ``VLLM_ROCM_USE_AITER_UNIFIED_ATTENTION``
- Enable AITER's optimized unified attention kernel (defaults to ``0``). Only takes effect when AITER is enabled and AITER MHA is disabled (``VLLM_ROCM_USE_AITER_MHA=0``). When set to ``0``, falls back to vLLM's Triton unified attention. Can also be enabled via ``--attention-backend ROCM_AITER_UNIFIED_ATTN``.
* - ``VLLM_ROCM_USE_AITER_FP8BMM``
- Use AITER ``FP8`` batched matmul (defaults to ``1`` when AITER is on). Fuses ``FP8`` per-token quantization with batched GEMM (used in MLA models like DeepSeek-V3).
* - ``VLLM_ROCM_USE_AITER_FP4BMM``
- Use AITER ``FP4`` batched matmul (defaults to ``1`` when AITER is on). Fuses ``FP4`` per-token quantization with batched GEMM (used in MLA models like DeepSeek-V3). Requires an Instinct MI350X/MI355X GPU.
* - ``VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS``
- Fuse shared expert computation into the AITER fused-MoE kernel (defaults to ``0``). Applies to MoE models with shared experts (for example, DeepSeek-V3/R1 with 1 shared expert). Requires SiLU/GELU activation (``is_act_and_mul``). Incompatible with `MoRI <https://github.com/ROCm/mori#mori>`__ scheduling — disable with ``VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=0`` if using MoRI.
* - ``VLLM_ROCM_USE_AITER_FP4_ASM_GEMM``
- Enable AITER assembly (HIP) FP4 GEMM kernels for MXFP4-quantized models (defaults to ``0``). When set to ``1``, uses hand-tuned ASM kernels instead of Triton for ``FP4×FP4`` weight GEMMs — faster at small batch sizes (``M`` ≤ 64). Requires Instinct MI350X/MI355X (``supports_mx()``). Combine with ``--quantization quark`` for MXFP4 models.
* - ``VLLM_ROCM_USE_SKINNY_GEMM``
- Prefer skinny-GEMM kernel variants for small batch sizes (defaults to ``1``). Improves performance when ``M`` dimension is small. **Recommended to keep enabled**.
* - ``VLLM_ROCM_FP8_PADDING``
- Pad ``FP8`` linear weight tensors to improve memory locality (defaults to ``1``). Minor memory overhead for better performance.
* - ``VLLM_ROCM_MOE_PADDING``
- Pad MoE weight tensors for better memory access patterns (defaults to ``1``). Same memory/performance tradeoff as ``FP8`` padding.
* - ``VLLM_ROCM_SHUFFLE_KV_CACHE_LAYOUT``
- This only affects the ``ROCM_AITER_FA`` backend. When set to ``0``, it uses the HIP Paged Attention implementation ``torch.ops.aiter.paged_attention_v1`` from AITER. **Good for low concurrency (for example, concurrency ≤32).** When set to ``1``, it uses the ASM Paged Attention Kernel ``pa_fwd_asm`` from AITER. **Good for high concurrency (for example, concurrency ≥32).** (Defaults to ``0`` when AITER is on.)
* - ``VLLM_ROCM_CUSTOM_PAGED_ATTN``
- Use custom paged-attention decode kernel when ``ROCM_ATTN`` backend is selected (defaults to ``1``). See :ref:`Attention backend selection with AITER <vllm-optimization-aiter-backend-selection>`.
.. _vllm-optimization-aiter-moe-requirements:
.. _vllm-optimization-aiter-mla-requirements:
.. _vllm-optimization-aiter-mla-sparse-requirements:
.. _vllm-optimization-aiter-backend-selection:
Attention backend selection with AITER
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Most models work out of the box with ``VLLM_ROCM_USE_AITER=1`` — vLLM auto-selects
the optimal backend. Use ``--attention-backend`` to override the auto-selected backend.
.. code-block:: bash
export VLLM_ROCM_USE_AITER=1
vllm serve <your-model> --tensor-parallel-size <tp>
.. note::
Always set ``VLLM_ROCM_USE_AITER=1`` even when using ``--attention-backend`` explicitly.
``--attention-backend`` only overrides the attention kernel; ``VLLM_ROCM_USE_AITER=1``
is still required to enable AITER for GEMM, RMSNorm, and MoE kernels.
The Radeon/fallback backends (``ROCM_ATTN``, ``TRITON_MLA``) are the exception —
they do not use AITER and do not require the env var.
The table below shows which backend is selected per model type and how to tune it.
.. list-table::
:header-rows: 1
:widths: 15 18 35 32
* - Model type
- Backend
- How to enable
- Tuning tips
* - **MHA models** (Llama, Mistral, Qwen, Mixtral, MiniMax-M2.5)
- **ROCM_AITER_FA** (recommended, auto-selected)
- ``VLLM_ROCM_USE_AITER=1`` (auto-selected). To override: ``VLLM_ROCM_USE_AITER=1 --attention-backend ROCM_AITER_FA``. Add ``VLLM_ROCM_SHUFFLE_KV_CACHE_LAYOUT=1`` for shuffled KV cache.
- **2.7–4.4x TPS** over legacy ``ROCM_ATTN``. Set ``VLLM_ROCM_SHUFFLE_KV_CACHE_LAYOUT=1`` for **15–20% decode improvement** at high concurrency. Low TTFT: ``--max-num-batched-tokens`` ≤ 8k–16k. High throughput: ≥ 32k with ``cudagraph_mode=FULL``.
* - **MLA models** (DeepSeek-V3/R1/V2, Kimi-K2.5, Mistral-Large-3-675B)
- **ROCM_AITER_MLA** (recommended, auto-selected)
- ``VLLM_ROCM_USE_AITER=1`` (auto-selected). To override: ``VLLM_ROCM_USE_AITER=1 --attention-backend ROCM_AITER_MLA``. ``--block-size 1`` is no longer mandatory (vLLM ≥0.14); still recommended for prefix-caching workloads.
- **1.2–1.5x higher TPS** over ``TRITON_MLA``. Supports uniform-batch CUDA graphs and MTP. On MI300X/MI325X (gfx942), ``ROCM_AITER_TRITON_MLA`` may show 2–3% higher TPS. On MI355X (gfx950), ``ROCM_AITER_MLA`` is preferred (uses AITER assembly MHA for prefill).
* - **DSA models** (DeepSeek-V3.2, GLM-5)
- **ROCM_AITER_MLA_SPARSE** (auto-selected)
- ``VLLM_ROCM_USE_AITER=1`` — auto-detected from ``index_topk`` in model config. Requires ``--block-size 1``.
- Instinct MI300X/MI325X/MI350X/MI355X only.
* - **gpt-oss models** (gpt-oss-120b/20b)
- **ROCM_AITER_UNIFIED_ATTN**
- ``VLLM_ROCM_USE_AITER=1 --attention-backend ROCM_AITER_UNIFIED_ATTN``
-
* - **Radeon / fallback**
- **ROCM_ATTN** (MHA) or **TRITON_MLA** (MLA)
- ``--attention-backend ROCM_ATTN`` or ``TRITON_MLA``
- ``ROCM_ATTN`` is preferred over ``TRITON_ATTN`` — it uses a custom HIP paged-attention kernel for decode when the model's KV head size is supported, and falls back to Triton only when not. If ``ROCM_ATTN`` is slow for your model (unsupported head size triggers Triton decode), try ``TRITON_ATTN``. Both work on Radeon GPUs.
.. note::
**MoE models** (Mixtral, Llama-4-Scout/Maverick, DeepSeek-V2/V3/R1, Kimi-K2.5, MiniMax-M2.5, GLM-5, Qwen-MoE): AITER MoE kernels activate automatically with ``VLLM_ROCM_USE_AITER=1`` — no extra attention backend flags needed. If you hit ``RuntimeError: wrong! device_gemm ...``, set ``AITER_ONLINE_TUNE=1`` and retry. Only disable MoE kernels (``VLLM_ROCM_USE_AITER_MOE=0``) if that also fails.
Once AITER is configured, see `Parallelism strategies (run vLLM on multiple GPUs)`_ for TP/DP/EP choices — especially for MLA and MoE models where the wrong strategy wastes memory or throughput.
**Quick start examples**:
.. code-block:: bash
# DSA model (DeepSeek-V3.2) — backend auto-selected from model config
VLLM_ROCM_USE_AITER=1 vllm serve deepseek-ai/DeepSeek-V3.2 \
--block-size 1 \
--tensor-parallel-size 8
# Explicitly select a backend for MLA models
VLLM_ROCM_USE_AITER=1 vllm serve deepseek-ai/DeepSeek-R1-0528 \
--tensor-parallel-size 8 \
--attention-backend ROCM_AITER_MLA
# MHA model with shuffled KV cache layout for high concurrency
VLLM_ROCM_USE_AITER=1 VLLM_ROCM_SHUFFLE_KV_CACHE_LAYOUT=1 \
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--attention-backend ROCM_AITER_FA
**How to verify which backend is active**
Check vLLM's startup logs to confirm which attention backend is being used:
.. code-block:: bash
# Start vLLM and check logs
VLLM_ROCM_USE_AITER=1 vllm serve meta-llama/Llama-3.3-70B-Instruct 2>&1 | grep -i "using.*backend"
Look for ``Using <backend_name> backend.`` in the startup output — for example,
``Using ROCM_AITER_FA backend.``
For in-depth architecture and benchmarks of all 7 ROCm attention backends, see the
`ROCm Attention Backend blog post <https://vllm.ai/blog/rocm-attention-backend>`_.
Quick Reduce (large all-reduces on ROCm)
========================================
**Quick Reduce** is an alternative to RCCL/custom all-reduce for **large** inputs (MI300-class GPUs).
It supports FP16/BF16 as well as symmetric INT8/INT6/INT4 quantized all-reduce (group size 32).
.. warning::
Quantization can affect accuracy. Validate quality before deploying.
Control via:
* ``VLLM_ROCM_QUICK_REDUCE_QUANTIZATION`` ∈ ``["NONE","FP","INT8","INT6","INT4"]`` (default ``NONE``).
* ``VLLM_ROCM_QUICK_REDUCE_CAST_BF16_TO_FP16``: cast BF16 input to FP16 (``1`` by default for performance).
* ``VLLM_ROCM_QUICK_REDUCE_MAX_SIZE_BYTES_MB``: cap the preset buffer (default ``NONE`` ≈ ``2048`` MB).
Quick Reduce tends to help **throughput** at higher TP counts (for example, 4–8) with many concurrent requests.
Parallelism strategies (run vLLM on multiple GPUs)
==================================================
vLLM supports the following parallelism strategies:
1. Tensor parallelism
2. Pipeline parallelism
3. Data parallelism
4. Expert parallelism
For more details, see `Parallelism and scaling <https://docs.vllm.ai/en/stable/serving/parallelism_scaling.html>`_.
**Quick-reference decision table:**
.. list-table::
:header-rows: 1
:widths: 30 35 35
* - Model type
- Low concurrency (≤128 requests)
- High concurrency (≥512 requests)
* - **Dense** (for example, Llama, Qwen-dense, Mistral-dense)
- TP only
- TP + independent DP replicas (your own load balancer)
* - **MoE, standard density ≥3%** (for example, Qwen3-235B-A22B, DeepSeek-V3/R1)
- TP + EP
- DP + EP
* - **MoE, ultra-sparse <1%** (for example, Llama-4-Maverick at 0.78%)
- TP only — **no EP** (AllToAll overhead exceeds benefit)
- DP only — **no EP**
* - **MLA models** (for example, DeepSeek-V2/V3/R1, Kimi-K2.5, Mistral-Large-3-675B)
- TP + EP
- **DP + EP** — TP alone duplicates the full KV cache on every GPU; use DP Attention to partition it
EP = ``--enable-expert-parallel``. DP = ``--data-parallel-size N``.
See `Data Parallel Attention (advanced)`_ for the MLA memory explanation and `Expert parallelism`_ for EP details.
Tensor parallelism
^^^^^^^^^^^^^^^^^^
Tensor parallelism splits each layer of the model weights across multiple GPUs when the model doesn't fit on a single GPU. This is primarily for memory capacity.
**Use tensor parallelism when:**
* Model does not fit on one GPU (OOM)
* Need to enable larger batch sizes by distributing KV cache across GPUs
**Examples:**
.. code-block:: bash
# Tensor parallelism: Split model across 2 GPUs
vllm serve /path/to/model --dtype float16 --tensor-parallel-size 2
# Combining TP and two vLLM instance, each split across 2 GPUs (4 GPUs total)
CUDA_VISIBLE_DEVICES=0,1 vllm serve /path/to/model --dtype float16 --tensor-parallel-size 2 --port 8000
CUDA_VISIBLE_DEVICES=2,3 vllm serve /path/to/model --dtype float16 --tensor-parallel-size 2 --port 8001
.. note::
**ROCm GPU visibility:** vLLM on ROCm reads ``CUDA_VISIBLE_DEVICES``. Keep ``HIP_VISIBLE_DEVICES`` unset to avoid conflicts.
.. tip::
For structured data parallelism deployments with load balancing, see :ref:`data-parallelism-section`.
.. note::
**MLA models (DeepSeek, Kimi-K2.5, Mistral-Large-3-675B):** TP alone replicates the full KV cache on every GPU, which wastes memory at high concurrency. See `Data Parallel Attention (advanced)`_ for the DP+EP configuration that partitions the KV cache instead.
Pipeline parallelism
^^^^^^^^^^^^^^^^^^^^
Pipeline parallelism splits the model's layers across multiple GPUs or nodes, with each GPU processing different layers sequentially. This is primarily used for multi-node deployments where the model is too large for a single node.
**Use pipeline parallelism when:**
* Model is too large for a single node (combine PP with TP)
* GPUs on a node lack high-speed interconnect (e.g., no NVLink/XGMI) - PP may perform better than TP
* GPU count doesn't evenly divide the model (PP supports uneven splits)
**Common pattern for multi-node:**
.. code-block:: bash
# 2 nodes × 8 GPUs = 16 GPUs total
# TP=8 per node, PP=2 across nodes
vllm serve meta-llama/Llama-3.1-405B-Instruct \
--tensor-parallel-size 8 \
--pipeline-parallel-size 2
.. note::
**ROCm best practice**: On Instinct MI300X/MI325X/MI350X/MI355X, prefer staying within a single XGMI island (≤8 GPUs) using TP only. Use PP when scaling beyond eight GPUs or across nodes.
.. _data-parallelism-section:
Data parallelism
^^^^^^^^^^^^^^^^
Data parallelism replicates model weights across separate instances/GPUs to process independent batches of requests. This approach increases throughput by distributing the workload across multiple replicas.
**Use data parallelism when:**
* Model fits on one GPU, but you need higher request throughput
* Scaling across multiple nodes horizontally
* Combining with tensor parallelism (for example, DP=2 + TP=4 = 8 GPUs total)
**Quick start - single-node:**
.. code-block:: bash
# Model fit in 1 GPU. Creates 2 model replicas (requires 2 GPUs)
VLLM_ALL2ALL_BACKEND="allgather_reducescatter" vllm serve /path/to/model \
--data-parallel-size 2 \
--disable-nccl-for-dp-synchronization
.. tip::
For ROCm, currently use ``VLLM_ALL2ALL_BACKEND="allgather_reducescatter"`` and ``--disable-nccl-for-dp-synchronization`` with data parallelism.
Choosing a load balancing strategy
"""""""""""""""""""""""""""""""""""
vLLM supports two modes for routing requests to DP ranks:
.. list-table::
:header-rows: 1
:widths: 30 35 35
* -
- **Internal LB** (recommended)
- **External LB**
* - **HTTP endpoints**
- 1 endpoint, vLLM routes internally
- N endpoints, you provide external router
* - **Single-node config**
- ``--data-parallel-size N``
- ``--data-parallel-size N --data-parallel-rank 0..N-1`` + different ports
* - **Multi-node config**
- ``--data-parallel-size``, ``--data-parallel-size-local``, ``--data-parallel-address``
- ``--data-parallel-size N --data-parallel-rank 0..N-1`` + ``--data-parallel-address``
* - **Client view**
- Single URL/port
- Multiple URLs/ports
* - **Load balancer**
- Built-in (vLLM handles)
- External (Nginx, Kong, K8s Service)
* - **Coordination**
- DP ranks sync via RPC (for MoE/MLA)
- DP ranks sync via RPC (for MoE/MLA)
* - **Best for**
- Most deployments (simpler)
- K8s/cloud environments with existing LB
.. tip::
**Dense (non-MoE) models only:** You can run fully independent ``vllm serve`` instances without any DP flags, using your own load balancer. This avoids RPC coordination overhead entirely.
For more technical details, see `vLLM Data Parallel Deployment <https://docs.vllm.ai/en/stable/serving/data_parallel_deployment.html>`_
Data Parallel Attention (advanced)
""""""""""""""""""""""""""""""""""
For MLA models (DeepSeek V2/V3/R1, Kimi-K2.5), **DP+EP is the recommended configuration at high concurrency** (≥512 concurrent requests). Unlike traditional DP which replicates model weights, Data Parallel Attention uses inter-GPU AllToAll communication to partition KV cache across GPUs, avoiding the KV cache duplication that occurs with tensor parallelism.
* At **≤128 concurrent requests**, TP=8 provides 40–86% higher throughput
* At **≥512 concurrent requests**, DP=8+EP provides 16–47% higher throughput
* Crossover typically occurs around **256–512 concurrent requests**
.. code-block:: bash
# DeepSeek-R1 with DP attention and expert parallelism (high concurrency)
VLLM_ALL2ALL_BACKEND="allgather_reducescatter" vllm serve deepseek-ai/DeepSeek-R1 \
--data-parallel-size 8 \
--enable-expert-parallel \
--disable-nccl-for-dp-synchronization
For more technical details, see `vLLM RFC #16037 <https://github.com/vllm-project/vllm/issues/16037>`_ and the `vLLM MoE Playbook <https://rocm.blogs.amd.com/software-tools-optimization/vllm-moe-guide/README.html>`_.
Expert parallelism
^^^^^^^^^^^^^^^^^^
Expert parallelism (EP) distributes expert layers of Mixture-of-Experts (MoE) models across multiple GPUs,
where tokens are routed to the GPUs holding the experts they need.
**When to use EP:**
.. list-table::
:header-rows: 1
:widths: 30 35 35
* - Scenario
- Recommended config
- Rationale
* - **Low concurrency** (≤128 requests)
- TP=8 (EP optional)
- 40–86% higher throughput than DP at low concurrency.
* - **High concurrency** (≥512 requests)
- DP=8 + EP
- 16–47% higher throughput at scale (for example, 7,114 TPS for DeepSeek-R1 at 1024 concurrent requests).
* - **MLA/MQA models** (DeepSeek-V2/V3/R1, Kimi-K2.5)
- DP + EP
- Avoids KV cache duplication across TP ranks. Mandatory for optimal memory at high concurrency.
* - **Ultra-sparse MoE** (<1% activation density, for example, Llama-4-Maverick)
- DP or TP **without** EP
- EP adds AllToAll overhead that exceeds the benefit — EP is 7–12% *slower* for these models.
* - **Standard MoE** (≥3% activation density, for example, DeepSeek-R1, Qwen3-235B)
- EP flag
- Improves expert routing efficiency.
**Basic usage:**
.. code-block:: bash
# DP + EP for MLA+MoE models (DeepSeek-R1, high concurrency)
VLLM_ALL2ALL_BACKEND="allgather_reducescatter" vllm serve deepseek-ai/DeepSeek-R1 \
--data-parallel-size 8 \
--enable-expert-parallel \
--disable-nccl-for-dp-synchronization
# TP + EP (low concurrency, non-MLA models)
vllm serve deepseek-ai/DeepSeek-R1 \
--tensor-parallel-size 8 \
--enable-expert-parallel
**Combining with Tensor Parallelism:**
When EP is enabled alongside tensor parallelism:
* Fused MoE layers use expert parallelism
* Non-fused MoE layers use tensor parallelism
Multimodal model optimization (vision-language)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For multimodal models (Qwen3-VL, InternVL, step3), use batch-level data parallelism
for the vision encoder instead of the default tensor parallelism:
.. code-block:: bash
vllm serve Qwen/Qwen3-VL-235B-A22B-Instruct \
--tensor-parallel-size 8 \
--mm-encoder-tp-mode data \
--enable-expert-parallel \
--max-model-len 32768
``--mm-encoder-tp-mode data`` replaces per-layer all-reduce synchronization (58–126 ops
in TP mode) with a single all-gather after encoding, yielding **10–45% throughput
improvement** with negligible memory overhead (0.2–2.3% model size increase).
**When it helps most:**
* High-resolution images (1024×1024 px): **+16% average** throughput
* 1–3 images per request: **+13–16%** throughput
* Deep vision encoders (for example, InternVL 45 blocks, step3 63 blocks)
**When to skip it:**
* Very small vision encoders (<1% of total model parameters)
* 10+ small images per request (diminishing returns)
* Memory-constrained deployments (encoder weights are replicated per GPU)
For more details, see the `vLLM Multimodal DP blog post <https://rocm.blogs.amd.com/software-tools-optimization/vllm-dp-vision/README.html>`_.
Throughput benchmarking
=======================
This guide evaluates LLM inference by tokens per second (TPS). vLLM provides a
built-in benchmark:
.. code-block:: bash
# Synthetic or dataset-driven benchmark
vllm bench throughput --model /path/to/model [other args]
* **Real-world dataset** (ShareGPT) example:
.. code-block:: bash
wget https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/resolve/main/ShareGPT_V3_unfiltered_cleaned_split.json
vllm bench throughput --model /path/to/model --dataset /path/to/ShareGPT_V3_unfiltered_cleaned_split.json
* **Synthetic**: set fixed ``--input-len`` and ``--output-len`` for reproducible runs.
.. tip::
**Profiling checklist (ROCm)**
1. Fix your prompt distribution (ISL/OSL) and **vary one knob at a time** (graph mode, MBT).
2. Measure **TTFT**, **ITL**, and **TPS** together; don't optimize one in isolation.
3. Compare graph modes: **PIECEWISE** (balanced) vs **FULL**/``FULL_DECODE_ONLY`` (max throughput).
4. Sweep ``--max-num-batched-tokens`` around **8k–64k** to find your latency/throughput balance.
Maximizing instances per node
=============================
To maximize **per-node throughput**, run as many vLLM instances as model memory allows,
balancing KV-cache capacity.
* **HBM capacities**: MI300X = 192 GB HBM3; MI325X = 256 GB HBM3E; MI350X/MI355X = 288 GB HBM3E.
* Up to **eight** single-GPU vLLM instances can run in parallel on an 8×GPU node (one per GPU):
.. code-block:: bash
for i in $(seq 0 7); do
CUDA_VISIBLE_DEVICES="$i" vllm bench throughput
-tp 1 --model /path/to/model
--dataset /path/to/ShareGPT_V3_unfiltered_cleaned_split.json &
done
Total throughput from **N** single-GPU instances usually exceeds one instance stretched across **N** GPUs (``-tp N``).
**Model coverage**: Llama 2 (7B/13B/70B), Llama 3 (8B/70B), Qwen2 (7B/72B), Mixtral-8x7B/8x22B, and others Llama2‑70B
and Llama3‑70B can fit a single MI300X/MI325X/MI350X/MI355X; Llama3.1‑405B fits on a single 8×MI300X/MI325X/MI350X/MI355X node.
Configure the gpu-memory-utilization parameter
==================================================
The ``--gpu-memory-utilization`` parameter controls the fraction of GPU memory reserved for the KV-cache. The default is **0.9** (90%).
There are two strategies:
1. **Increase** ``--gpu-memory-utilization`` to maximize throughput for a single instance (up to **0.95**).
Example:
.. code-block:: bash
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--gpu-memory-utilization 0.95 \
--max-model-len 8192 \
--port 8000
2. **Decrease** to pack **multiple** instances on the same GPU (for small models like 7B/8B), keeping KV-cache viable:
.. code-block:: bash
# Instance 1 on GPU 0
CUDA_VISIBLE_DEVICES=0 vllm serve meta-llama/Llama-3.1-8B-Instruct \
--gpu-memory-utilization 0.45 \
--max-model-len 4096 \
--port 8000
# Instance 2 on GPU 0
CUDA_VISIBLE_DEVICES=0 vllm serve meta-llama/Llama-Guard-3-8B \
--gpu-memory-utilization 0.45 \
--max-model-len 4096 \
--port 8001
vLLM engine arguments
=====================
Selected arguments that often help on ROCm. See `Engine Arguments
<https://docs.vllm.ai/en/stable/configuration/engine_args.html>`__ in the vLLM
documentation for the full list.
Configure --max-num-seqs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The default value is **1024** in vLLM V1 (increased from **256** in V0). This flag controls the maximum number of sequences processed per batch, directly affecting concurrency and memory usage.
* **To increase throughput**: Raise to **2048** or **4096** if memory allows, enabling more sequences per iteration.
* **To reduce memory usage**: Lower to **256** or **128** for large models or long-context generation. For example, set ``--max-num-seqs 128`` to reduce concurrency and lower memory requirements.
In vLLM V1, KV-cache token requirements are computed as ``max-num-seqs * max-model-len``.
Example usage:
.. code-block:: bash
vllm serve <model> --max-num-seqs 128 --max-model-len 8192
Configure --max-num-batched-tokens
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Chunked prefill is enabled by default** in vLLM V1.
* Lower values improve **ITL** (less prefill interrupting decode).
* Higher values improve **TTFT** (more prefill per batch).
Defaults: **8192** for online serving, **16384** for offline. However, optimal values vary significantly by model size. Smaller models can efficiently handle larger batch sizes. Setting it near ``--max-model-len`` mimics V0 behavior and often maximizes throughput.
**Guidance:**
* **Interactive (low TTFT)**: keep MBT ≤ **8k–16k**.
* **Streaming (low ITL)**: MBT **16k–32k**.
* **Offline max throughput**: MBT **≥32k** (diminishing TPS returns beyond ~32k).
**Pattern:** Smaller/more efficient models benefit from larger batch sizes. MoE models with expert parallelism can handle very large batches efficiently.
**Rule of thumb**
* Push MBT **up** to trade TTFT↑ for ITL↓ and slightly higher TPS.
* Pull MBT **down** to trade ITL↑ for TTFT↓ (interactive UX).
Async scheduling
^^^^^^^^^^^^^^^^
``--async-scheduling`` (replaces deprecated ``num_scheduler_steps``) can improve throughput/ITL by trading off TTFT.
Prefer **off** for latency-sensitive serving; **on** for offline batch throughput.
CUDA graphs configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^
CUDA graphs reduce kernel launch overhead by capturing and replaying GPU operations, improving inference throughput. Configure using ``--compilation-config '{"cudagraph_mode": "MODE"}'``.
**Available modes:**
* ``NONE`` — CUDA graphs disabled (debugging)
* ``PIECEWISE`` — Attention stays eager, other ops use CUDA graphs (most compatible)
* ``FULL`` — Full CUDA graphs for all batches (best for small models/prompts)
* ``FULL_DECODE_ONLY`` — Full CUDA graphs only for decode (saves memory in prefill/decode split setups)
* ``FULL_AND_PIECEWISE`` — **(default)** Full graphs for decode + piecewise for prefill (best performance, highest memory)
**Default behavior:** V1 defaults to ``FULL_AND_PIECEWISE`` with piecewise compilation enabled; otherwise ``NONE``.
**Backend compatibility:** Not all attention backends support all CUDA graph modes. Choose a mode your backend supports:
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attention backend
- CUDA graph support
* - ``TRITON_ATTN``
- Full support (prefill + decode)
* - ``ROCM_ATTN``, ``ROCM_AITER_UNIFIED_ATTN``
- Full support (prefill + decode)
* - ``ROCM_AITER_FA``, ``ROCM_AITER_MLA``, ``ROCM_AITER_TRITON_MLA``
- Uniform batches only
* - ``ROCM_AITER_MLA_SPARSE``
- Uniform single-token decode only
* - ``TRITON_MLA``
- Must exclude attention from graph — ``PIECEWISE`` required
**Usage examples:**
.. code-block:: bash
# Default (best performance, highest memory)
vllm serve meta-llama/Llama-3.1-8B-Instruct
# Decode-only graphs (lower memory, good for P/D split)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}'
# Full graphs for offline throughput (small models)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--compilation-config '{"cudagraph_mode": "FULL"}'
**Migration from legacy flags:**
* ``use_cudagraph=False`` → ``NONE``
* ``use_cudagraph=True, full_cuda_graph=False`` → ``PIECEWISE``
* ``full_cuda_graph=True`` → ``FULL`` (with automatic fallback)
Quantization support
====================
vLLM supports FP4/FP8 (4-bit/8-bit floating point) weight and activation quantization using hardware acceleration on the Instinct MI300X, MI325X, MI350X, and MI355X.
Quantization of models with FP4/FP8 allows for a **2x-4x** reduction in model memory requirements and up to a **1.6x**
improvement in throughput with minimal impact on accuracy.
vLLM ROCm supports a variety of quantization demands:
* On-the-fly quantization
* Pre-quantized model through Quark and llm-compressor
Supported quantization methods
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
vLLM on ROCm supports the following quantization methods for the AMD Instinct MI300 series and Instinct MI350 series GPUs:
.. list-table::
:header-rows: 1
:widths: 20 15 15 20 30
* - Method
- Precision
- ROCm support
- Memory reduction
- Best use case
* - **FP8** (W8A8)
- 8-bit float
- Excellent
- 2× (50%)
- Production, balanced speed/accuracy
* - **PTPC-FP8**
- 8-bit float
- Excellent
- 2× (50%)
- High throughput, better than ``FP8``
* - **AWQ**
- 4-bit int (W4A16)
- Good
- 4× (75%)
- Large models, memory-constrained
* - **GPTQ**
- 4-bit/8-bit int
- Good
- 2-4× (50-75%)
- Pre-quantized models available
* - **FP8 KV-cache**
- 8-bit float
- Excellent
- KV cache: 50%
- All inference workloads
* - **Quark (AMD)**
- ``FP8``/``MXFP4``
- Optimized
- 2-4× (50-75%)
- AMD pre-quantized models
* - **compressed-tensors**
- W8A8 ``INT8``/``FP8``
- Good
- 2× (50%)
- LLM Compressor models
**ROCm support key:**
- Excellent: Fully supported with optimized kernels
- Good: Supported, might not have AMD-optimized kernels
- Optimized: AMD-specific optimizations available
Using Pre-quantized Models
^^^^^^^^^^^^^^^^^^^^^^^^^^^
AMD provides pre-quantized models optimized for ROCm. These models are ready to use with vLLM.
**AMD Quark-quantized models**:
Available on `Hugging Face <https://huggingface.co/models?other=quark>`_:
* `Llama‑3.1‑8B‑Instruct‑FP8‑KV <https://huggingface.co/amd/Llama-3.1-8B-Instruct-FP8-KV>`__ (FP8 W8A8)
* `Llama‑3.1‑70B‑Instruct‑FP8‑KV <https://huggingface.co/amd/Llama-3.1-70B-Instruct-FP8-KV>`__ (FP8 W8A8)
* `Llama‑3.1‑405B‑Instruct‑FP8‑KV <https://huggingface.co/amd/Llama-3.1-405B-Instruct-FP8-KV>`__ (FP8 W8A8)
* `Mixtral‑8x7B‑Instruct‑v0.1‑FP8‑KV <https://huggingface.co/amd/Mixtral-8x7B-Instruct-v0.1-FP8-KV>`__ (FP8 W8A8)
* `Mixtral‑8x22B‑Instruct‑v0.1‑FP8‑KV <https://huggingface.co/amd/Mixtral-8x22B-Instruct-v0.1-FP8-KV>`__ (FP8 W8A8)
* `Llama-3.3-70B-Instruct-MXFP4-Preview <https://huggingface.co/amd/Llama-3.3-70B-Instruct-MXFP4-Preview>`__ (MXFP4 for MI350/MI355)
* `Llama-3.1-405B-Instruct-MXFP4-Preview <https://huggingface.co/amd/Llama-3.1-405B-Instruct-MXFP4-Preview>`__ (MXFP4 for MI350/MI355)
* `DeepSeek-R1-0528-MXFP4-Preview <https://huggingface.co/amd/DeepSeek-R1-0528-MXFP4-Preview>`__ (MXFP4 for MI350/MI355)
**Quick start**:
.. code-block:: bash
# FP8 W8A8 Quark model
vllm serve amd/Llama-3.1-8B-Instruct-FP8-KV \
--dtype auto
# MXFP4 Quark model for MI350/MI355
vllm serve amd/Llama-3.3-70B-Instruct-MXFP4-Preview \
--dtype auto \
--tensor-parallel-size 1
**Other pre-quantized models**:
- AWQ models: `Hugging Face awq flag <https://huggingface.co/models?other=awq>`_
- GPTQ models: `Hugging Face gptq flag <https://huggingface.co/models?other=gptq>`_
- LLM Compressor models: `Hugging Face compressed-tensors flag <https://huggingface.co/models?other=compressed-tensors>`_
On-the-fly quantization
^^^^^^^^^^^^^^^^^^^^^^^^
For models without pre-quantization, vLLM can quantize ``FP16``/``BF16`` models at server startup.
**Supported methods**:
- ``fp8``: Per-tensor ``FP8`` weight and activation quantization
- ``ptpc_fp8``: Per-token-activation per-channel-weight ``FP8`` (better accuracy same ``FP8`` speed). See `PTPC-FP8 on ROCm blog post <https://blog.vllm.ai/2025/02/24/ptpc-fp8-rocm.html>`_ for details
**Usage:**
.. code-block:: bash
# On-the-fly FP8 quantization
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--quantization fp8 \
--dtype auto
# On-the-fly PTPC-FP8 (recommended as default)
vllm serve meta-llama/Llama-3.1-70B-Instruct \
--quantization ptpc_fp8 \
--dtype auto \
--tensor-parallel-size 4
.. note::
On-the-fly quantization adds two to five minutes of startup time but eliminates pre-quantization. For production with frequent restarts, use pre-quantized models.
GPTQ
^^^^
GPTQ (4-bit/8-bit weight quantization) is fully supported on ROCm via HIP-compiled kernels.
Pre-quantized GPTQ models from Hugging Face work out of the box. For better throughput on AMD Instinct GPUs,
consider **AWQ with Triton kernels** or **FP8 quantization** instead.
.. code-block:: bash
vllm serve RedHatAI/Meta-Llama-3.1-70B-Instruct-quantized.w4a16 \
--quantization gptq \
--dtype auto \
--tensor-parallel-size 1
AWQ (Activation-aware Weight Quantization)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AWQ (Activation-aware Weight Quantization) is a 4-bit weight quantization technique that provides excellent
model compression with minimal accuracy loss (<1%). ROCm supports AWQ quantization on the AMD Instinct MI300 series and
MI350 series GPUs with vLLM.
**Using pre-quantized AWQ models:**
Many AWQ-quantized models are available on Hugging Face. Use them directly with vLLM:
.. code-block:: bash
# vLLM serve with AWQ model
VLLM_USE_TRITON_AWQ=1 \
vllm serve hugging-quants/Meta-Llama-3.1-70B-Instruct-AWQ-INT4 \
--quantization awq \
--tensor-parallel-size 1 \
--dtype auto
**Important Notes:**
* **ROCm requirement:** Set ``VLLM_USE_TRITON_AWQ=1`` to enable Triton-based AWQ kernels on ROCm
* **dtype parameter:** AWQ requires ``--dtype auto`` or ``--dtype float16``. The ``--dtype`` flag controls
the **activation dtype** (``FP16``/``BF16`` for computations), not the weight dtype. AWQ weights remain as INT4
(4-bit integers) as specified in the model's quantization config, but are dequantized to ``FP16``/``BF16`` during
matrix multiplication operations.
* **Group size:** 128 is recommended for optimal performance/accuracy balance
* **Model compatibility:** AWQ is primarily tested on Llama, Mistral, and Qwen model families
Quark (AMD quantization toolkit)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AMD Quark is the AMD quantization toolkit optimized for ROCm. It supports ``FP8 W8A8``, ``MXFP4``, ``W8A8 INT8``, and
other quantization formats with native vLLM integration. The quantization format will automatically be inferred
from the model config file, so you can omit ``--quantization quark``.
**Running Quark Models:**
.. code-block:: bash
# FP8 W8A8: Single GPU
vllm serve amd/Llama-3.1-8B-Instruct-FP8-KV \
--dtype auto \
--max-model-len 8192 \
--gpu-memory-utilization 0.90
# MXFP4: Extreme memory efficiency
vllm serve amd/Llama-3.3-70B-Instruct-MXFP4-Preview \
--dtype auto \
--tensor-parallel-size 1 \
--max-model-len 8192
**Key features:**
- **FP8 models**: ~50% memory reduction, 2× compression
- **MXFP4 models**: ~75% memory reduction, 4× compression
- **Embedded scales**: Quark FP8-KV models include pre-calibrated KV-cache scales
- **Hardware optimized**: Leverages the AMD Instinct MI300 series ``FP8`` acceleration
For creating your own Quark-quantized models, see `Quark Documentation <https://quark.docs.amd.com/latest/>`_.
FP8 kv-cache dtype
^^^^^^^^^^^^^^^^^^^^
FP8 KV-cache quantization reduces memory footprint by approximately 50%, enabling longer context lengths
or higher concurrency. ROCm supports FP8 KV-cache with both ``fp8_e4m3`` and ``fp8_e5m2`` formats on
AMD Instinct MI300 series and other CDNA™ GPUs.
Use ``--kv-cache-dtype fp8`` to enable ``FP8`` KV-cache quantization. For best accuracy, use calibrated
scaling factors generated via `LLM Compressor <https://github.com/vllm-project/llm-compressor>`_.
Without calibration, scales are calculated dynamically (``--calculate-kv-scales``) with minimal
accuracy impact.
**Quick start (dynamic scaling)**:
.. code-block:: bash
# vLLM serve with dynamic FP8 KV-cache
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--kv-cache-dtype fp8 \
--calculate-kv-scales \
--gpu-memory-utilization 0.90
**Calibrated scaling (advanced)**:
For optimal accuracy, pre-calibrate KV-cache scales using representative data. The calibration process:
#. Runs the model on calibration data (512+ samples recommended)
#. Computes optimal ``FP8`` quantization scales for key/value cache tensors
#. Embeds these scales into the saved model as additional parameters
#. vLLM loads the model and uses the embedded scales automatically when ``--kv-cache-dtype fp8`` is specified
The quantized model can be used like any other model. The embedded scales are stored as part of the model weights.
**Using pre-calibrated models:**
AMD provides ready-to-use models with pre-calibrated ``FP8`` KV cache scales:
* `amd/Llama-3.1-8B-Instruct-FP8-KV <https://huggingface.co/amd/Llama-3.1-8B-Instruct-FP8-KV>`_
* `amd/Llama-3.3-70B-Instruct-FP8-KV <https://huggingface.co/amd/Llama-3.3-70B-Instruct-FP8-KV>`_
To verify a model has pre-calibrated KV cache scales, check ``config.json`` for:
.. code-block:: json
"quantization_config": {
"kv_cache_scheme": "static" // Indicates pre-calibrated scales are embedded
}
**Creating your own calibrated model:**
.. code-block:: bash
# 1. Install LLM Compressor
pip install llmcompressor
# 2. Run calibration script (see llm-compressor repo for full example)
python llama3_fp8_kv_example.py
# 3. Use calibrated model in vLLM
vllm serve ./Meta-Llama-3-8B-Instruct-FP8-KV \
--kv-cache-dtype fp8
For detailed instructions and the complete calibration script, see the `FP8 KV Cache Quantization Guide <https://github.com/vllm-project/llm-compressor/blob/main/examples/quantization_kv_cache/README.md>`_.
**Format options**:
- ``fp8`` or ``fp8_e4m3``: Higher precision (default, recommended)
- ``fp8_e5m2``: Larger dynamic range, slightly lower precision
Speculative decoding (experimental)
===================================
Recent vLLM versions add support for speculative decoding backends (for example, Eagle‑v3). Evaluate for your model and latency/throughput goals.
Speculative decoding is a technique to reduce latency when max number of concurrency is low.
Depending on the methods, the effective concurrency varies, for example, from 16 to 64.
Example command:
.. code-block:: bash
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--trust-remote-code \
--swap-space 16 \
--disable-log-requests \
--tensor-parallel-size 1 \
--distributed-executor-backend mp \
--dtype float16 \
--quantization fp8 \
--kv-cache-dtype fp8 \
--no-enable-chunked-prefill \
--max-num-seqs 300 \
--max-num-batched-tokens 131072 \
--gpu-memory-utilization 0.8 \
--speculative_config '{"method": "eagle3", "model": "yuhuili/EAGLE3-LLaMA3.1-Instruct-8B", "num_speculative_tokens": 2, "draft_tensor_parallel_size": 1, "dtype": "float16"}' \
--port 8001
.. important::
It has been observed that more ``num_speculative_tokens`` causes less
acceptance rate of draft model tokens and a decline in throughput. As a
workaround, set ``num_speculative_tokens`` to <= 2.
Multi-node checklist and troubleshooting
========================================
1. Use ``--distributed-executor-backend ray`` across nodes to manage HIP-visible ranks and RCCL communicators. (``ray`` is the default for multi-node. Explicitly setting this flag is optional.)
2. Ensure ``/dev/shm`` is shared across ranks (Docker ``--shm-size``, Kubernetes ``emptyDir``), as RCCL uses shared memory for rendezvous.
3. For GPUDirect RDMA, set ``RCCL_NET_GDR_LEVEL=2`` and verify links (``ibstat``). Requires supported NICs (for example, ConnectX‑6+).
4. Collect RCCL logs: ``RCCL_DEBUG=INFO`` and optionally ``RCCL_DEBUG_SUBSYS=INIT,GRAPH`` for init/graph stalls.
Deprecated terms
================
* **Prefill-Decode attention** has been renamed to **ROCM_ATTN** (ROCm attention). Use ``--attention-backend ROCM_ATTN`` to select this backend.
Further reading
===============
* :doc:`workload`
* :doc:`/how-to/rocm-for-ai/inference/benchmark-docker/vllm`
* `ROCm Attention Backend deep-dive <https://vllm.ai/blog/rocm-attention-backend>`_ — architecture and benchmarks for all 7 backends
* `vLLM MoE Playbook - A Practical Guide to TP, DP, PP and Expert Parallelism <https://rocm.blogs.amd.com/software-tools-optimization/vllm-moe-guide/README.html>`_ — DP+EP tuning for MoE models
* `Multimodal DP optimization <https://rocm.blogs.amd.com/software-tools-optimization/vllm-dp-vision/README.html>`_ — batch-level DP for vision encoders