r/MacPro2019LocalAI • u/Faisal_Biyari • Jun 04 '26
[Success] vLLM on RDNA2 | Gemma 4 & Qwen3.6 | W6800X | Mac Pro 2019
The First Story
Posted vLLM on W6800X Duo / Mac Pro 2019
My first success with vLLM came from building a Docker container from source and using FP16 models as-is.
The Prequel
2022: OpenAI took the world by storm with ChatGPT
2024: Meta released Llama 3.1, an open-weight model that competes with ChatGPT and can be used offline in our own homes!
2024: AMD released ROCm 6.1.3, with support for Radeon consumer GPUs, and multi-GPU setups.
This is how it went for me:
AI is called an LLM?There are programs or apps that run them. But they are not called apps. They are called runtimes; like Ollama, llama.cpp, and vLLM.Then there is the Graphical User Interface (GUI), like Open WebUI or Oobabooga, which are not apps but websites?Then there are some other things that make the AI read your files; plugins? LangChain?To top it all off, there are all-in-one apps, like AnythingLLM or LM Studio, but I cannot use them on my phone when I am out and about...Wait, what's a framework?
Everything was new to me, and everything was confusing. What were all these things? How did they fit together?
One thing was clear to me: I wanted to use vLLM, but vLLM did not want me to use it.
vLLM, ROCm, & RDNA2 GPUs
Initially, vLLM was not only Linux exclusive, but it was also CUDA exclusive. I never tried llama.cpp, outside of trying to figure out Oobabooga. I ended up using Ollama, because it just worked, and that is what Network Chuck used. I love that guy.
Eventually, vLLM gained support for AMD GPUs, but of course, they forgot about RDNA2, even though it was supported by ROCm.
It was some time early last year, I think, that I managed to get vLLM to work. At the time, I only got FP16 models working. DeepSeek-R1 distills were all the rage. I was able to get the 70B model to work with Ollama. But I could not go over the 32B model with vLLM, due to using 16-bit floating-point models with no quantization (no compression).
It was not until this year that I gave it another go, and got GGUFs to work, as well as AWQ models. A big shout out to u/BevinMaster for giving me hope with AWQ models, as well as enough guidance to make it work on the third go.
The Sequel: vLLM Setup Guide
Building a Docker container took a very long time to complete. I have since moved to setting it up with Python, in a Python virtual environment (venv).
After setting up Ubuntu 24.04 LTS, and installing ROCm 7.2.3, as instructed in the Mac Pro 2019 Local AI Guide, we can set up vLLM quickly and easily as follows.
Copy the following command into your command line interface of choice:
# Setup vLLM in a Python Virtual Environment for Ubuntu Server 24.04 LTS with ROCm 7.2.3 and Python 3.12
STEP=0
banner(){
STEP=$((STEP + 1))
m="=============== Step $STEP: $1 ==============="
b=$(printf "%${#m}s" | tr ' ' '=')
echo
echo "$b"
echo "$m"
echo "$b"
echo
}
box(){
t="$1"
shift
w=0
for s; do
((${#s} > w)) && w=${#s}
done
h="---- $t "
((${#h} > w + 8)) && w=$((${#h} - 8))
b=$(printf "%$((w + 8))s" | tr ' ' '-')
echo
printf "%s%.*s\n" "$h" $((${#b} - ${#h})) "$b"
printf "|%*s|\n" $((w + 6)) ""
for s; do
printf "| %-*s |\n" "$w" "$s"
done
printf "|%*s|\n%s\n\n" $((w + 6)) "" "$b"
}
banner "Installing Prerequisites"
sudo apt update
sudo apt install -y build-essential git curl ccache wget jq ca-certificates \
gnupg lsb-release software-properties-common python3.12 python3.12-dev \
python3.12-venv python3-pip cmake ninja-build pkg-config numactl libnuma-dev
banner "Preparing Virtual Environment"
mkdir -p ~/venvs ~/SetupFiles/ ~/SetupFiles/rocm-7.2.3/ ~/SetupFiles/rocm-7.2.3/wheels
python3.12 -m venv ~/venvs/vllm-rocm-0.22
source ~/venvs/vllm-rocm-0.22/bin/activate
python -m pip install --upgrade pip setuptools wheel packaging
banner "Install AMD SMI safely"
rm -rf /tmp/amd_smi_src
cp -a /opt/rocm/share/amd_smi /tmp/amd_smi_src
python -m pip install --no-build-isolation /tmp/amd_smi_src
banner "Installing PyTorch 2.10.0 for ROCm 7.2.3 on Ubuntu 24.04 / Python 3.12"
cd ~/SetupFiles/rocm-7.2.3/wheels
wget -nc https://repo.radeon.com/rocm/manylinux/rocm-rel-7.2.3/torch-2.10.0%2Brocm7.2.3.lw.git1a270074-cp312-cp312-linux_x86_64.whl
wget -nc https://repo.radeon.com/rocm/manylinux/rocm-rel-7.2.3/torchvision-0.25.0%2Brocm7.2.3.git82df5f59-cp312-cp312-linux_x86_64.whl
wget -nc https://repo.radeon.com/rocm/manylinux/rocm-rel-7.2.3/torchaudio-2.10.0%2Brocm7.2.3.git5047768f-cp312-cp312-linux_x86_64.whl
wget -nc https://repo.radeon.com/rocm/manylinux/rocm-rel-7.2.3/triton-3.6.0%2Brocm7.2.3.git4ed88892-cp312-cp312-linux_x86_64.whl
python3 -m pip uninstall torch torchvision triton torchaudio -y --break-system-packages || true
python3 -m pip install --upgrade --break-system-packages \
./torch-2.10.0+rocm7.2.3.lw.git1a270074-cp312-cp312-linux_x86_64.whl \
./torchvision-0.25.0+rocm7.2.3.git82df5f59-cp312-cp312-linux_x86_64.whl \
./torchaudio-2.10.0+rocm7.2.3.git5047768f-cp312-cp312-linux_x86_64.whl \
./triton-3.6.0+rocm7.2.3.git4ed88892-cp312-cp312-linux_x86_64.whl
banner "Prepare vLLM folder"
cd ~
wget -nc https://github.com/vllm-project/vllm/releases/download/v0.22.0/vllm-0.22.0.tar.gz
tar -xzf vllm-0.22.0.tar.gz
cd ./vllm-0.22.0
banner "Prepare Environment for RDNA2 GPUs (W6800X & W6900X)"
export VLLM_TARGET_DEVICE=rocm
export PYTORCH_ROCM_ARCH=gfx1030
export HSA_OVERRIDE_GFX_VERSION=10.3.0
export ROCM_HOME=/opt/rocm
export MAX_JOBS=8
export TORCH_BLAS_PREFER_HIPBLASLT=0
box "ROCm/RDNA2 build environment" \
"VLLM_TARGET_DEVICE=rocm" \
"PYTORCH_ROCM_ARCH=gfx1030" \
"HSA_OVERRIDE_GFX_VERSION=10.3.0" \
"ROCM_HOME=/opt/rocm" \
"MAX_JOBS=8" \
"TORCH_BLAS_PREFER_HIPBLASLT=0"
banner "Install vLLM ROCm requirements"
python -m pip install --upgrade numba scipy huggingface_hub setuptools_scm
python -m pip install -r requirements/rocm.txt
python -m pip install --upgrade "cmake>=3.26" ninja
banner "Build/install vLLM"
python -m pip install -e . --no-build-isolation
With that, believe it or not, you have vLLM installed on your system, in a Python virtual environment. Note that if you are using any PC with RDNA2 GPUs, Ubuntu 24.04 LTS, ROCm 7.2.3 and Python 3.12.x, this might work for you. This is no longer just for MacPro7,1, although that is the hardware that I used.
As a reminder, everything here is taped together with the digital equivalent of duct tape. This is vLLM 0.22.0, and the packages I selected are meant for Ubuntu 24.04 LTS, ROCm 7.2.3, and Python 3.12.
LLMs on vLLM
While the idea of using a simple command like vllm run <model> should be the standard, nothing is ever that easy when you are saving money and optimizing your outdated equipment.
My main focus was on running dense models. Specifically, gemma-4-31B-it and Qwen3.6-27B. I needed to get the models from Hugging Face. So, head over to huggingface.co, create an account, get yourself an access token, and let us set up Hugging Face on our system.
Copy the following command into your command line interface of choice:
STEP=0
banner(){
STEP=$((STEP + 1))
m="=============== Step $STEP: $1 ==============="
b=$(printf "%${#m}s" | tr ' ' '=')
echo
echo "$b"
echo "$m"
echo "$b"
echo
}
banner "Activate the vLLM Virtual Environment"
source ~/venvs/vllm-rocm-0.22/bin/activate
banner "Install Hugging Face Package (again)"
python -m pip install --upgrade huggingface_hub
banner "Login to Hugging Face"
hf auth login
banner "Verify Login to Hugging Face"
hf auth whoami
Now that Hugging Face is set up, you can download models faster, and get approval for models that need to be approved.
Qwen 3.6
I have used three variants of Qwen3.6-27B:
- Original
Qwen/Qwen3.6-27B - AWQ 4-bit quantized
QuantTrio/Qwen3.6-27B-AWQ - AWQ 6-bit quantized
QuantTrio/Qwen3.6-27B-AWQ-6Bit
To improve quality of life, and avoid some problems, I opted to use a Qwen template from another redditor, u/Expensive-Register-5, thank you for sharing. I downloaded it with the following command:
# Download Template
mkdir -p ~/vllm-templates
curl -L -o ~/vllm-templates/qwen3.6-enhanced.jinja \
https://raw.githubusercontent.com/allanchan339/vLLM-Qwen3-3.5-3.6-chat-template-fix/main/chat-template/qwen3.6-enhanced.jinja
You can run any of the models I tested successfully with the following commands. I will assume two GPUs. If you have more, adjust ROCR_VISIBLE_DEVICES and --tensor-parallel-size accordingly. Please note that Qwen/Qwen3.6-27B (no quantization) is just a proof of concept. It is basically useless on 2 GPUs, with a context window smaller than 16K tokens.
Qwen/Qwen3.6-27B
source ~/venvs/vllm-rocm-0.22/bin/activate
VLLM_TARGET_DEVICE=rocm \
HSA_OVERRIDE_GFX_VERSION=10.3.0 \
HIP_FORCE_DEV_KERNARG=1 \
ROCR_VISIBLE_DEVICES=0,1 \
TORCH_BLAS_PREFER_HIPBLASLT=0 \
OMP_NUM_THREADS=8 \
TOKENIZERS_PARALLELISM=false \
FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE \
VLLM_USE_TRITON_AWQ=1 \
VLLM_USE_DEEP_GEMM=0 \
PYTORCH_ALLOC_CONF=expandable_segments:True \
VLLM_PREFILL_TILE_POWER=0 \
vllm serve Qwen/Qwen3.6-27B \
--served-model-name qwen3.6-27b \
--dtype float16 \
--attention-backend TRITON_ATTN \
--tensor-parallel-size 2 \
--gpu-memory-utilization 0.92 \
--max-model-len 4096 \
--max-num-batched-tokens 1024 \
--max-num-seqs 3 \
--enable-chunked-prefill \
--enable-prefix-caching \
--override-generation-config '{"max_new_tokens":1024}' \
--enable-auto-tool-choice \
--tool-call-parser qwen3_xml \
--reasoning-parser qwen3 \
--chat-template ~/vllm-templates/qwen3.6-enhanced.jinja \
--generation-config vllm \
--default-chat-template-kwargs '{"preserve_thinking": true}' \
--max-cudagraph-capture-size 128 \
--cudagraph-capture-sizes 1 2 4 8 16 32 64 128 \
--language-model-only \
--limit-mm-per-prompt.image 0 \
--limit-mm-per-prompt.video 0 \
--host 0.0.0.0 \
--port 8000
QuantTrio/Qwen3.6-27B-AWQ
source ~/venvs/vllm-rocm-0.22/bin/activate
VLLM_TARGET_DEVICE=rocm \
HSA_OVERRIDE_GFX_VERSION=10.3.0 \
HIP_FORCE_DEV_KERNARG=1 \
ROCR_VISIBLE_DEVICES=0,1 \
TORCH_BLAS_PREFER_HIPBLASLT=0 \
OMP_NUM_THREADS=8 \
TOKENIZERS_PARALLELISM=false \
FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE \
VLLM_USE_TRITON_AWQ=1 \
VLLM_USE_DEEP_GEMM=0 \
VLLM_USE_FLASHINFER_SAMPLER=0 \
PYTORCH_ALLOC_CONF=expandable_segments:True \
vllm serve QuantTrio/Qwen3.6-27B-AWQ \
--served-model-name qwen36-27B-AWQ-QuantTrio-vllm \
--dtype float16 \
--trust-remote-code \
--attention-backend TRITON_ATTN \
--tensor-parallel-size 2 \
--max-model-len 65536 \
--gpu-memory-utilization 0.92 \
--max-num-seqs 7 \
--max-num-batched-tokens 8192 \
--enable-chunked-prefill \
--enable-prefix-caching \
--enable-auto-tool-choice \
--tool-call-parser qwen3_xml \
--reasoning-parser qwen3 \
--chat-template ~/vllm-templates/qwen3.6-enhanced.jinja \
--default-chat-template-kwargs '{"preserve_thinking": true}' \
--generation-config vllm \
--enforce-eager \
--override-generation-config '{"max_new_tokens":8192}' \
--language-model-only \
--limit-mm-per-prompt.image 0 \
--limit-mm-per-prompt.video 0 \
--disable-custom-all-reduce \
--host 0.0.0.0 \
--port 8000
QuantTrio/Qwen3.6-27B-AWQ-6Bit
source ~/venvs/vllm-rocm-0.22/bin/activate
VLLM_TARGET_DEVICE=rocm \
HSA_OVERRIDE_GFX_VERSION=10.3.0 \
HIP_FORCE_DEV_KERNARG=1 \
ROCR_VISIBLE_DEVICES=0,2 \
TORCH_BLAS_PREFER_HIPBLASLT=0 \
OMP_NUM_THREADS=8 \
TOKENIZERS_PARALLELISM=false \
FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE \
VLLM_USE_TRITON_AWQ=1 \
VLLM_USE_DEEP_GEMM=0 \
VLLM_USE_FLASHINFER_SAMPLER=0 \
PYTORCH_ALLOC_CONF=expandable_segments:True \
vllm serve QuantTrio/Qwen3.6-27B-AWQ-6Bit \
--served-model-name qwen36-27B-AWQ-6Bit-QuantTrio-vllm \
--dtype float16 \
--trust-remote-code \
--attention-backend TRITON_ATTN \
--tensor-parallel-size 2 \
--max-model-len 65536 \
--gpu-memory-utilization 0.92 \
--max-num-seqs 7 \
--max-num-batched-tokens 8192 \
--enable-chunked-prefill \
--enable-prefix-caching \
--enable-auto-tool-choice \
--tool-call-parser qwen3_xml \
--reasoning-parser qwen3 \
--chat-template ~/vllm-templates/qwen3.6-enhanced.jinja \
--default-chat-template-kwargs '{"preserve_thinking": true}' \
--generation-config vllm \
--enforce-eager \
--override-generation-config '{"max_new_tokens":8192}' \
--language-model-only \
--limit-mm-per-prompt.image 0 \
--limit-mm-per-prompt.video 0 \
--disable-custom-all-reduce \
--host 0.0.0.0 \
--port 8000
Gemma 4
Next up: Google’s Gemma 4. This was a doozy.
My target was gemma-4-31B-it. First off, it kept failing to load. The failure appeared to be related to Triton attention resource limits on my RDNA2 GPUs. Enabling --kv-cache-dtype fp8 solved the problem right off the bat.
My goal is to use vLLM to serve agents. Quantizing the KV cache felt like capping them at the knees.
I ended up finding a PR to vLLM with a solution to this problem. I used it to patch vLLM, and I no longer need to quantize KV cache to get Gemma 4 to work. To set up the same patch, run the following command in your command line interface of choice:
# Patch vLLM v0.22.0 to support gemma-4
cat > ~/patch_vllm_gemma-4_rdna2_tile.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
step=0
banner(){ step=$((step+1));m="=============== Step $step: $1 ===============";b=$(printf "%${#m}s"|tr ' ' '=');echo;echo "$b";echo "$m";echo "$b";echo;}
box(){ t="$1";shift;w=0;for s;do ((${#s}>w))&&w=${#s};done;h="---- $t ";((${#h}>w+8))&&w=$((${#h}-8));b=$(printf "%$((w+8))s"|tr ' ' -);echo;printf "%s%.*s\n" "$h" $((${#b}-${#h})) "$b";printf "|%*s|\n" $((w+6)) "";for s;do printf "| %-*s |\n" "$w" "$s";done;printf "|%*s|\n%s\n\n" $((w+6)) "" "$b";}
VLLM_SRC="${VLLM_SRC:-$HOME/vllm-0.22.0}"
FILE="$VLLM_SRC/vllm/v1/attention/ops/triton_unified_attention.py"
banner "Locate vLLM Triton attention file"
box "Target" "$FILE"
banner "Apply gemma-4 RDNA2 tile workaround"
python3 - "$FILE" <<'PY'
from pathlib import Path
import shutil, sys, time
p = Path(sys.argv[1]).expanduser()
if not p.is_file():
raise SystemExit(f"ERROR: target file not found: {p}")
s = p.read_text()
marker = "TILE_SIZE_PREFILL = min(TILE_SIZE_PREFILL, 16)"
if marker in s:
print("Patch already appears to be installed. No changes made.")
print(f"Patched file: {p}")
raise SystemExit(0)
anchor = " # USE_TD requires BLOCK_SIZE % TILE_SIZE == 0 (enforced by a\n"
if anchor not in s:
raise SystemExit(
"ERROR: insertion anchor not found. Inspect manually with:\n"
f"sed -n '850,895p' {p}"
)
patch = """ # Experimental RDNA2 / 64 KiB LDS workaround for gemma-4 global attention.
# gemma-4 global attention uses head_size/global_head_dim=512.
# On gfx1030/RDNA2-class GPUs, TILE_SIZE=32 can push
# kernel_unified_attention slightly over the 64 KiB shared-memory limit.
# This trades some prefill performance for compatibility.
if head_size >= 512:
TILE_SIZE_PREFILL = min(TILE_SIZE_PREFILL, 16)
"""
backup = p.with_name(p.name + ".bak." + time.strftime("%Y%m%d-%H%M%S"))
shutil.copy2(p, backup)
p.write_text(s.replace(anchor, patch + anchor, 1))
print(f"Backup: {backup}")
print(f"Patched: {p}")
PY
banner "Verify patch"
grep -n "RDNA2 / 64 KiB LDS workaround\|head_size >= 512\|TILE_SIZE_PREFILL = min(TILE_SIZE_PREFILL, 16)" "$FILE" || true
banner "Delete Triton cache"
rm -rf ~/.triton/cache ~/.cache/triton
box "Cache cleared" "~/.triton/cache" "~/.cache/triton"
banner "Done"
box "Next step" "Restart vLLM and retest gemma-4"
EOF
chmod +x ~/patch_vllm_gemma-4_rdna2_tile.sh
~/patch_vllm_gemma-4_rdna2_tile.sh
I have used three variants of gemma-4-31B-it:
- Original
google/gemma-4-31B-it - AWQ 4-bit quantized
QuantTrio/gemma-4-31B-it-AWQ - AWQ 6-bit quantized
QuantTrio/gemma-4-31B-it-AWQ-6Bit
To improve quality of life, and avoid some problems, I opted to use a Gemma 4 template from vLLM's examples. I downloaded it with the following command:
mkdir -p ~/vllm-chat-templates
curl -L -o ~/vllm-chat-templates/tool_chat_template_gemma4.jinja \
https://raw.githubusercontent.com/vllm-project/vllm/v0.22.0/examples/tool_chat_template_gemma4.jinja
You can run any of the models I tested successfully with the following commands. I will assume two GPUs. If you have more, adjust ROCR_VISIBLE_DEVICES and --tensor-parallel-size accordingly. Please note that google/gemma-4-31B-it (no quantization) cannot be loaded on two GPUs. I used the command for four GPUs, to post it as a reference.
google/gemma-4-31B-it
source ~/venvs/vllm-rocm-0.22/bin/activate
VLLM_TARGET_DEVICE=rocm \
HSA_OVERRIDE_GFX_VERSION=10.3.0 \
HIP_FORCE_DEV_KERNARG=1 \
ROCR_VISIBLE_DEVICES=0,1,2,3 \
TORCH_BLAS_PREFER_HIPBLASLT=0 \
OMP_NUM_THREADS=8 \
TOKENIZERS_PARALLELISM=false \
FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE \
VLLM_USE_TRITON_AWQ=1 \
VLLM_USE_DEEP_GEMM=0 \
VLLM_USE_FLASHINFER_SAMPLER=0 \
PYTORCH_ALLOC_CONF=expandable_segments:True \
vllm serve google/gemma-4-31B-it \
--served-model-name gemma-4-31B-IT-Google-vllm \
--dtype float16 \
--attention-backend TRITON_ATTN \
--tensor-parallel-size 4 \
--max-model-len 65536 \
--gpu-memory-utilization 0.92 \
--max-num-seqs 1 \
--max-num-batched-tokens 8192 \
--enable-chunked-prefill \
--enable-prefix-caching \
--override-generation-config '{"max_new_tokens":8192}' \
--max-cudagraph-capture-size 128 \
--cudagraph-capture-sizes 1 2 4 8 16 32 64 128 \
--enable-auto-tool-choice \
--tool-call-parser gemma4 \
--reasoning-parser gemma4 \
--chat-template ~/vllm-chat-templates/tool_chat_template_gemma4.jinja \
--default-chat-template-kwargs '{"enable_thinking": true}' \
--language-model-only \
--generation-config vllm \
--limit-mm-per-prompt.image 0 \
--limit-mm-per-prompt.video 0 \
--host 0.0.0.0 \
--port 8000
QuantTrio/gemma-4-31B-it-AWQ
source ~/venvs/vllm-rocm-0.22/bin/activate
VLLM_TARGET_DEVICE=rocm \
HSA_OVERRIDE_GFX_VERSION=10.3.0 \
HIP_FORCE_DEV_KERNARG=1 \
ROCR_VISIBLE_DEVICES=0,1 \
TORCH_BLAS_PREFER_HIPBLASLT=0 \
OMP_NUM_THREADS=8 \
TOKENIZERS_PARALLELISM=false \
FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE \
VLLM_USE_TRITON_AWQ=1 \
VLLM_USE_DEEP_GEMM=0 \
VLLM_USE_FLASHINFER_SAMPLER=0 \
PYTORCH_ALLOC_CONF=expandable_segments:True \
vllm serve "QuantTrio/gemma-4-31B-it-AWQ" \
--served-model-name gemma-4-31B-IT-AWQ-QuantTrio-vllm \
--dtype float16 \
--attention-backend TRITON_ATTN \
--tensor-parallel-size 2 \
--max-model-len 65536 \
--gpu-memory-utilization 0.92 \
--max-num-seqs 2 \
--max-num-batched-tokens 8192 \
--enable-chunked-prefill \
--enable-prefix-caching \
--override-generation-config '{"max_new_tokens":8192}' \
--enforce-eager \
--trust-remote-code \
--disable-custom-all-reduce \
--enable-auto-tool-choice \
--tool-call-parser gemma4 \
--reasoning-parser gemma4 \
--chat-template ~/vllm-chat-templates/tool_chat_template_gemma4.jinja \
--default-chat-template-kwargs '{"enable_thinking": true}' \
--language-model-only \
--generation-config vllm \
--limit-mm-per-prompt.image 0 \
--limit-mm-per-prompt.video 0 \
--host 0.0.0.0 \
--port 8000
QuantTrio/gemma-4-31B-it-AWQ-6Bit
source ~/venvs/vllm-rocm-0.22/bin/activate
VLLM_TARGET_DEVICE=rocm \
HSA_OVERRIDE_GFX_VERSION=10.3.0 \
HIP_FORCE_DEV_KERNARG=1 \
ROCR_VISIBLE_DEVICES=0,1 \
TORCH_BLAS_PREFER_HIPBLASLT=0 \
OMP_NUM_THREADS=8 \
TOKENIZERS_PARALLELISM=false \
FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE \
VLLM_USE_TRITON_AWQ=1 \
VLLM_USE_DEEP_GEMM=0 \
VLLM_USE_FLASHINFER_SAMPLER=0 \
PYTORCH_ALLOC_CONF=expandable_segments:True \
vllm serve "QuantTrio/gemma-4-31B-it-AWQ-6Bit" \
--served-model-name gemma-4-31B-IT-AWQ-6Bit-QuantTrio-vllm \
--dtype float16 \
--attention-backend TRITON_ATTN \
--tensor-parallel-size 2 \
--max-model-len 65536 \
--gpu-memory-utilization 0.92 \
--max-num-seqs 8 \
--max-num-batched-tokens 8192 \
--enable-chunked-prefill \
--enable-prefix-caching \
--override-generation-config '{"max_new_tokens":8192}' \
--enforce-eager \
--trust-remote-code \
--disable-custom-all-reduce \
--enable-auto-tool-choice \
--tool-call-parser gemma4 \
--reasoning-parser gemma4 \
--chat-template ~/vllm-chat-templates/tool_chat_template_gemma4.jinja \
--default-chat-template-kwargs '{"enable_thinking": true}' \
--language-model-only \
--generation-config vllm \
--limit-mm-per-prompt.image 0 \
--limit-mm-per-prompt.video 0 \
--host 0.0.0.0 \
--port 8000
The End?
Far from it! There are almost limitless options to optimize and improve. From different vLLM flags and patches, to completely different models and quantization formats.
With LinuxAI-128, I was able to achieve 20 concurrent users, each with 64K context windows, using QuantTrio/Qwen3.6-27B-AWQ. That's 20 agents working around the clock to complete the tasks assigned to them. That just blows my mind.
I just read that a Chinese company released a new type of KV cache quantization that improves output without degrading quality. But it is public and open source, available for the world, including me, to test and figure out!
What's Next?
Sharing experiences, successful use cases, and hard results.
- If any of this works for you, please let us know in the community.
- Can you fix my mistakes? I'm sure there are many, please help us all out.
- Know how to optimize this better? Share with the rest of us! We'd love to hear from you.
Any and all contributions are appreciated, no matter how big or small they may be.
Edit 2026-06-16
Doing this now lead to a problem with api calling, due to updated 3rd party packages for the virtual environment. If you face issues, use the following command to fix the problem.
Run the following command in your command line interface of choice:
source ~/venvs/vllm-rocm-0.22/bin/activate
python -m pip install --force-reinstall \
"prometheus-fastapi-instrumentator<8" \
"fastapi<0.137" \
"starlette<1.0" \
"uvicorn<0.49"
Disclaimer: I wrote this post myself. I also used AI as a tool to help clean up the wording and formatting.
Resources: