# vLLM nightly aarch64 (arm64) CUDA wheels

Unofficial nightly builds of **vLLM `main`** for **aarch64 + CUDA**, built from
source on native arm64 hardware. Nothing here comes from PyPI or from the vLLM
project; these are produced locally, once a day, and each file is validated before
it appears in this directory.

Regenerated 2026-09-07 06:33 +07 · newest 2 of 13 wheels described below.

## Where these live

* Directory listing: <https://wheels.baonq.me/wheels/aarch64-armv9/vllm_latest/>
* This file: <https://wheels.baonq.me/wheels/aarch64-armv9/vllm_latest/README.md>

Plain static hosting: no index API, no authentication, and `Range` requests are
supported, so `curl -C -` and `wget -c` resume interrupted downloads. `pip` can
install straight from a file URL, but it cannot resolve a version from this
directory — it is not a PEP 503 index — so pass the full filename.

## Which file do I want?

Filename format:

```
vllm-<version>+<cuda>.<YYYYMMDD>.g<commit8>-cp38-abi3-manylinux_2_28_aarch64.whl
```

* `<cuda>` is `cu129` or `cu130` — **match this to your CUDA runtime / driver**, and
  to the PyTorch build you intend to install.
* `<YYYYMMDD>` is the build date, `g<commit8>` the upstream vLLM commit it was built
  from. Both are inside a PEP 440 local version, so `pip` sorts them correctly and
  the newest build always wins.
* `cp38-abi3` means the stable Python ABI: built with CPython 3.12, installable on
  **Python 3.9 or newer**.
* `manylinux_2_28_aarch64` is the compatibility tag. The binaries actually only need
  **glibc 2.17 and libstdc++ GLIBCXX_3.4.21**, so they load on much older systems
  than the tag implies.

Alongside each wheel sit two companions with the same base name:

* `....json` — machine-readable provenance: exact commit, build date, cubin list,
  measured symbol-version floors, peak build memory.
* `....report.html` — the same thing for a human: build settings, GPU coverage,
  what was validated, and the tail of the build log. Self-contained, no external
  CSS or JS.

### pip index

This directory is a plain file listing, not a package index, so `pip` cannot resolve
a version from it. The server does publish a **PEP 503 index** covering every wheel
in the archive, which can:

```bash
pip install --index-url https://wheels.baonq.me/simple/ \
    --extra-index-url https://pypi.org/simple vllm
```

That resolves the newest vLLM wheel across *both* CUDA variants, so pin the exact
version when you care which one you get:

```bash
pip install --index-url https://wheels.baonq.me/simple/ \
    --extra-index-url https://pypi.org/simple \
    "vllm==0.28.1rc1.dev461+cu130.20260907.g6865e67f"
```

## Current wheels

| variant | wheel | vLLM commit | built | size |
|---|---|---|---|---|
| `cu129` | `vllm-0.28.1rc1.dev461+cu129.20260907.g6865e67f-cp38-abi3-manylinux_2_28_aarch64.whl` | [`6865e67f`](https://github.com/vllm-project/vllm/commit/6865e67f0be02d53694517f6f71d7fb96492792d) | 20260907 | 697.3 MB |
| `cu130` | `vllm-0.28.1rc1.dev461+cu130.20260907.g6865e67f-cp38-abi3-manylinux_2_28_aarch64.whl` | [`6865e67f`](https://github.com/vllm-project/vllm/commit/6865e67f0be02d53694517f6f71d7fb96492792d) | 20260907 | 508.6 MB |

## Supported GPUs

Compiled kernels only, no JIT fallback needed. `+PTX` for `sm_80`/`sm_89` is
also present, so older Ampere/Ada arm64 boards will run via PTX JIT.

### `cu129` — CUDA 12.9.1, torch `2.13.0+cu129`

| GPU | requested arch | cubin in wheel |
|---|---|---|
| GH200 / H200 (Grace Hopper) | `9.0a` | `sm_90a` |
| GB200 (Blackwell) | `10.0a` | `sm_100a` |
| GB300 (Blackwell Ultra) | `10.3a` | `sm_103a` |
| GB10 (DGX Spark) | `12.1a` | `sm_121a` |

Verified present in `vllm/_C_stable_libtorch.abi3.so`: `100, 100a, 103, 103a, 121, 121a, 80, 89, 90, 90a`.

### `cu130` — CUDA 13.0.0, torch `2.13.0+cu130`

| GPU | requested arch | cubin in wheel |
|---|---|---|
| GH200 / H200 (Grace Hopper) | `9.0a` | `sm_90a` |
| GB200 + GB300 (Blackwell family) | `10.0f` | `sm_100` |
| GB10 (DGX Spark) | `12.0f` | `sm_120` |

Verified present in `vllm/_C_stable_libtorch.abi3.so`: `100, 120, 80, 89, 90, 90a`.

> `cu129` targets each GPU with its own architecture-specific cubin. `cu130` uses
> CUDA 13 *family* targets, where `10.0f` covers GB200 **and** GB300, and `12.0f`
> covers GB10 — same hardware coverage, fewer cubins, smaller and faster to build.

## Installing

Install a matching PyTorch **first**, from the index for the same CUDA version:

```bash
# cu130 example - use whl/cu129 and a cu129 wheel for the other variant
pip install torch==2.13.0 torchvision==0.28.0 \
    --index-url https://download.pytorch.org/whl/cu130 \
    --extra-index-url https://pypi.org/simple

# then the wheel itself, straight from the mirror
pip install https://wheels.baonq.me/wheels/aarch64-armv9/vllm_latest/vllm-0.28.1rc1.dev461+cu130.20260907.g6865e67f-cp38-abi3-manylinux_2_28_aarch64.whl
```

Fetch first instead if you prefer - these are 500-700 MB and resumable:

```bash
curl -fL -C - -O https://wheels.baonq.me/wheels/aarch64-armv9/vllm_latest/<filename>.whl
curl -fsS https://wheels.baonq.me/wheels/aarch64-armv9/vllm_latest/<filename>.json    # provenance sidecar
```

Resolve the newest wheel for a variant programmatically:

```bash
curl -fsS https://wheels.baonq.me/wheels/aarch64-armv9/vllm_latest/ \
  | grep -oE 'vllm-[^"]+[+]cu130[.][0-9]{8}[.]g[0-9a-f]+[^"]*[.]whl' \
  | sort -u | tail -1
```

Notes that have actually bitten us:

* **Install torch before the wheel, and re-pin it afterwards.** Installing the vLLM
  wheel re-resolves `torch` and can pull the default-CUDA build from PyPI, leaving
  torch and torchvision on different CUDA majors. Re-run the torch/torchvision
  install with `--force-reinstall --no-deps` from the correct index if that happens.
* **`torchvision` is required**, not optional: vLLM's kernel warmup imports it.
* **FlashInfer JIT-compiles at runtime and needs `nvcc` on the machine.** On a host
  without a CUDA toolkit, either install one or set `VLLM_USE_FLASHINFER_SAMPLER=0`.
* The wheel does not bundle CUDA libraries; they come from your PyTorch install or
  from a system CUDA toolkit.

## How these are built

* **Natively on arm64** (64-core aarch64 server), never cross-compiled and never
  emulated, inside a `quay.io/pypa/manylinux_2_28_aarch64` container
  (glibc 2.28, gcc-toolset-14, CPython 3.12).
* CUDA toolkits are the official NVIDIA **sbsa** runfiles
  (12.9.1 for cu129, 13.0.0 for cu130).
* Built with `python setup.py bdist_wheel --py-limited-api=cp38`, the same
  invocation upstream's Dockerfile uses.
* One build per variant per day from upstream `main`; a day with no new commits is
  skipped rather than rebuilt.

## What was checked before publishing

1. the wheel contains `vllm/_C*.so`;
2. `file` reports **ELF 64-bit LSB, ARM aarch64**;
3. `cuobjdump --list-elf` shows a cubin for **every** GPU in the table above —
   a wheel missing one is never published;
4. maximum required `GLIBC_`/`GLIBCXX_` symbol versions recorded in the sidecar.

Additionally, wheels are periodically installed on a **rented NVIDIA GB10 (DGX
Spark, sm_121)** where every native extension is imported and a real generation is
run. Both current variants have passed that test.

**Not covered:** GH200/GB200/GB300 are verified by cubin presence only — no such
hardware was available to run them on. These are unofficial nightly builds of a
moving branch; treat them as such and pin a specific file for anything reproducible.

Retention: the newest 30 wheels per CUDA variant are kept here;
older ones are pruned automatically.
