main
md 349 lines 17.5 KB
Rendered Raw
1 ---
2 toc_depth: 3
3 ---
4
5 # CPU
6
7 vLLM is a Python library that supports the following CPU variants. Select your CPU type to see vendor specific instructions:
8
9 === "Intel/AMD x86"
10
11 --8<-- "docs/getting_started/installation/cpu.x86.inc.md:installation"
12
13 === "ARM AArch64"
14
15 --8<-- "docs/getting_started/installation/cpu.arm.inc.md:installation"
16
17 === "Apple silicon"
18
19 --8<-- "docs/getting_started/installation/cpu.apple.inc.md:installation"
20
21 === "IBM Z (S390X)"
22
23 --8<-- "docs/getting_started/installation/cpu.s390x.inc.md:installation"
24
25 ## Technical Discussions
26
27 The main discussions happen in the `#sig-cpu` channel of [vLLM Slack](https://slack.vllm.ai/).
28
29 When open a Github issue about the CPU backend, please add `[CPU Backend]` in the title and it will be labeled with `cpu` for better awareness.
30
31 ## Requirements
32
33 - Python: 3.10 -- 3.13
34
35 === "Intel/AMD x86"
36
37 --8<-- "docs/getting_started/installation/cpu.x86.inc.md:requirements"
38
39 === "ARM AArch64"
40
41 --8<-- "docs/getting_started/installation/cpu.arm.inc.md:requirements"
42
43 === "Apple silicon"
44
45 --8<-- "docs/getting_started/installation/cpu.apple.inc.md:requirements"
46
47 === "IBM Z (S390X)"
48
49 --8<-- "docs/getting_started/installation/cpu.s390x.inc.md:requirements"
50
51 ## Set up using Python
52
53 ### Create a new Python environment
54
55 --8<-- "docs/getting_started/installation/python_env_setup.inc.md"
56
57 ### Pre-built wheels
58
59 When specifying the index URL, please make sure to use the `cpu` variant subdirectory.
60 For example, the nightly build index is: `https://wheels.vllm.ai/nightly/cpu/`.
61
62 === "Intel/AMD x86"
63
64 --8<-- "docs/getting_started/installation/cpu.x86.inc.md:pre-built-wheels"
65
66 === "ARM AArch64"
67
68 --8<-- "docs/getting_started/installation/cpu.arm.inc.md:pre-built-wheels"
69
70 === "Apple silicon"
71
72 --8<-- "docs/getting_started/installation/cpu.apple.inc.md:pre-built-wheels"
73
74 === "IBM Z (S390X)"
75
76 --8<-- "docs/getting_started/installation/cpu.s390x.inc.md:pre-built-wheels"
77
78 ### Build wheel from source
79
80 #### Set up using Python-only build (without compilation) {#python-only-build}
81
82 This method requires [pre-built wheels](#pre-built-wheels) for your platform.
83
84 Please refer to the instructions for [Python-only build on GPU](./gpu.md#python-only-build), and replace the build commands with:
85
86 ```bash
87 VLLM_USE_PRECOMPILED=1 VLLM_PRECOMPILED_WHEEL_VARIANT=cpu VLLM_TARGET_DEVICE=cpu uv pip install --editable .
88 ```
89
90 #### Full build (with compilation) {#full-build}
91
92 === "Intel/AMD x86"
93
94 --8<-- "docs/getting_started/installation/cpu.x86.inc.md:build-wheel-from-source"
95
96 === "ARM AArch64"
97
98 --8<-- "docs/getting_started/installation/cpu.arm.inc.md:build-wheel-from-source"
99
100 === "Apple silicon"
101
102 --8<-- "docs/getting_started/installation/cpu.apple.inc.md:build-wheel-from-source"
103
104 === "IBM Z (s390x)"
105
106 --8<-- "docs/getting_started/installation/cpu.s390x.inc.md:build-wheel-from-source"
107
108 ## Set up using Docker
109
110 ### Pre-built images
111
112 === "Intel/AMD x86"
113
114 --8<-- "docs/getting_started/installation/cpu.x86.inc.md:pre-built-images"
115
116 === "ARM AArch64"
117
118 --8<-- "docs/getting_started/installation/cpu.arm.inc.md:pre-built-images"
119
120 === "Apple silicon"
121
122 --8<-- "docs/getting_started/installation/cpu.apple.inc.md:pre-built-images"
123
124 === "IBM Z (S390X)"
125
126 --8<-- "docs/getting_started/installation/cpu.s390x.inc.md:pre-built-images"
127
128 ### Build image from source
129
130 === "Intel/AMD x86"
131
132 --8<-- "docs/getting_started/installation/cpu.x86.inc.md:build-image-from-source"
133
134 === "ARM AArch64"
135
136 --8<-- "docs/getting_started/installation/cpu.arm.inc.md:build-image-from-source"
137
138 === "Apple silicon"
139
140 --8<-- "docs/getting_started/installation/cpu.apple.inc.md:build-image-from-source"
141
142 === "IBM Z (S390X)"
143 --8<-- "docs/getting_started/installation/cpu.s390x.inc.md:build-image-from-source"
144
145 ## AMD Zen optimizations {#amd-zen-optimizations}
146
147 --8<-- "docs/getting_started/installation/cpu.x86.inc.md:amd-zen-optimizations"
148
149 ## Related runtime environment variables
150
151 - `VLLM_CPU_KVCACHE_SPACE`: specify the KV Cache size (e.g, `VLLM_CPU_KVCACHE_SPACE=40` means 40 GiB space for KV cache), larger setting will allow vLLM to run more requests in parallel. This parameter should be set based on the hardware configuration and memory management pattern of users. Default value is `0`.
152 - `VLLM_CPU_OMP_THREADS_BIND`: specify the CPU cores dedicated to the OpenMP threads, can be set as CPU id lists, `auto` (by default), or `nobind` (to disable binding to individual CPU cores and to inherit user-defined OpenMP variables). For example, `VLLM_CPU_OMP_THREADS_BIND=0-31` means there will be 32 OpenMP threads bound on 0-31 CPU cores. `VLLM_CPU_OMP_THREADS_BIND=0-31|32-63` means there will be 2 tensor parallel processes, 32 OpenMP threads of rank0 are bound on 0-31 CPU cores, and the OpenMP threads of rank1 are bound on 32-63 CPU cores. By setting to `auto`, the OpenMP threads of each rank are bound to the CPU cores in each NUMA node respectively. If set to `nobind`, the number of OpenMP threads is determined by the standard `OMP_NUM_THREADS` environment variable.
153 - `VLLM_CPU_NUM_OF_RESERVED_CPU`: specify the total number of CPU cores which are not dedicated to OpenMP threads. The variable only takes effect when `VLLM_CPU_OMP_THREADS_BIND` is set to `auto`. By default, x86, ARM, and RISC-V reserve `local_world_size` CPUs in total, while PowerPC and S390X retain a one-CPU default. When KV transfer is enabled, one additional CPU is reserved per local rank. Reserved CPUs are distributed across the local ranks.
154 - `CPU_VISIBLE_MEMORY_NODES`: specify visible NUMA memory nodes for vLLM CPU workers, similar to ```CUDA_VISIBLE_DEVICES```. The variable only takes effect when VLLM_CPU_OMP_THREADS_BIND is set to `auto`. The variable provides more control for the auto thread-binding feature, such as masking nodes and changing nodes binding sequence.
155 - `VLLM_ZENTORCH_WEIGHT_PREPACK` (AMD Zen only): when `ZenCpuPlatform` is active, eagerly prepack linear weights into ZenDNN's blocked layout at model load time, eliminating per-inference layout conversion overhead. Default is `1` (enabled). See [AMD Zen optimizations](#amd-zen-optimizations).
156
157 ## FAQ
158
159 ### Which `dtype` should be used?
160
161 - Currently, vLLM CPU uses model default settings as `dtype`. However, due to unstable float16 support in torch CPU, it is recommended to explicitly set `dtype=bfloat16` if there are any performance or accuracy problem.
162 - On AMD Zen CPUs (`ZenCpuPlatform`), `float16` is **not** supported. Only `bfloat16` and `float32` are accepted; models declared with `float16` are auto-downcast to `bfloat16` at model load time. See [AMD Zen optimizations](#amd-zen-optimizations).
163
164 ### How to launch a vLLM service on CPU?
165
166 - When using the online serving, it is recommended to reserve 1-2 CPU cores for the serving framework to avoid CPU oversubscription. For example, on a platform with 32 physical CPU cores, reserving CPU 31 for the framework and using CPU 0-30 for inference threads:
167
168 ```bash
169 export VLLM_CPU_KVCACHE_SPACE=40
170 export VLLM_CPU_OMP_THREADS_BIND=0-30
171 vllm serve facebook/opt-125m --dtype=bfloat16
172 ```
173
174 or using default auto thread binding:
175
176 ```bash
177 export VLLM_CPU_KVCACHE_SPACE=40
178 export VLLM_CPU_NUM_OF_RESERVED_CPU=1
179 vllm serve facebook/opt-125m --dtype=bfloat16
180 ```
181
182 Note, it is recommended to manually reserve 1 CPU for vLLM front-end process when `world_size == 1`.
183
184 ### What are supported models on CPU?
185
186 For the full and up-to-date list of models validated on CPU platforms, please see the official documentation: [Supported Models on CPU](../../models/hardware_supported_models/cpu.md)
187
188 ### How to find benchmark configuration examples for supported CPU models?
189
190 For any model listed under [Supported Models on CPU](../../models/hardware_supported_models/cpu.md), optimized runtime configurations are provided in the vLLM Benchmark Suite’s CPU test cases, defined in cpu test cases as serving-tests-cpu.json. Full test cases for Text-only models, Multi-Modal models and Embedded models are in cpu Text-Only test cases as serving-tests-cpu-text.json, cpu Multi-Modal test cases as serving-tests-cpu-multimodal.json and cpu Embedded test cases as serving-tests-cpu-embed.json.
191 For details on how these optimized configurations are determined, see: [performance-benchmark-details](../../../.buildkite/performance-benchmarks/README.md#performance-benchmark-details).
192 To benchmark the supported models using these optimized settings, follow the steps in [running vLLM Benchmark Suite manually](../../benchmarking/dashboard.md#manually-trigger-the-benchmark) and run the Benchmark Suite on a CPU environment.
193
194 Below is an example command to benchmark all CPU-supported models using optimized configurations.
195
196 ```bash
197 ON_CPU=1 bash .buildkite/performance-benchmarks/scripts/run-performance-benchmarks.sh
198 ```
199
200 The benchmark results will be saved in `./benchmark/results/`.
201 In the directory, the generated `.commands` files contain all example commands for the benchmark.
202
203 We recommend configuring tensor-parallel-size to match the number of NUMA nodes on your system. Note that the current release does not support tensor-parallel-size=6.
204 To determine the number of NUMA nodes available, use the following command:
205
206 ```bash
207 lscpu | grep "NUMA node(s):" | awk '{print $3}'
208 ```
209
210 For performance reference, users may also consult the [vLLM Performance Dashboard](https://hud.pytorch.org/benchmark/llms?repoName=vllm-project%2Fvllm&deviceName=cpu)
211 , which publishes default-model CPU results produced using the same Benchmark Suite.
212
213 #### Dry-Run
214
215 For users only need to get the optimized runtime configurations without running benchmark, a Dry-Run mode is provided.
216 By passing an environment variable DRY_RUN=1 with run-performance-benchmarks.sh,
217 all commands will be generated under `./benchmark/results/`.
218
219 ```bash
220 ON_CPU=1 DRY_RUN=1 bash .buildkite/performance-benchmarks/scripts/run-performance-benchmarks.sh
221 ```
222
223 By providing different JSON file, users can get runtime configurations for different models such as Embedded Models.
224
225 ```bash
226 ON_CPU=1 SERVING_JSON=serving-tests-cpu-embed.json DRY_RUN=1 bash .buildkite/performance-benchmarks/scripts/run-performance-benchmarks.sh
227 ```
228
229 By providing MODEL_FILTER and DTYPE_FILTER, only commands for related model ID and Data Type will be generated.
230
231 ```bash
232 ON_CPU=1 SERVING_JSON=serving-tests-cpu-text.json DRY_RUN=1 MODEL_FILTER=meta-llama/Llama-3.1-8B-Instruct DTYPE_FILTER=bfloat16 bash .buildkite/performance-benchmarks/scripts/run-performance-benchmarks.sh
233 ```
234
235 ### How do I enable AMD Zen optimizations? {#how-do-i-enable-amd-zen-optimizations}
236
237 On an AMD Zen 4 / Zen 5 CPU, install the CPU wheel with the `zen` extra so vLLM pulls the tested `zentorch` version for that release:
238
239 ```bash
240 export VLLM_VERSION=$(curl -s https://api.github.com/repos/vllm-project/vllm/releases/latest | jq -r .tag_name | sed 's/^v//')
241 uv pip install "vllm[zen]" --extra-index-url https://wheels.vllm.ai/${VLLM_VERSION}/cpu --index-strategy first-index --torch-backend cpu
242 ```
243
244 vLLM auto-detects the platform and routes linear layers through ZenDNN-optimized kernels - no flag needed. To verify it is engaged, look for the platform-selection line in the server's startup logs:
245
246 ```bash
247 vllm serve Qwen/Qwen3-0.6B 2>&1 | grep "AMD Zen CPU detected with zentorch installed"
248 ```
249
250 For per-backend dispatch details (which kernel each linear layer was bound to), re-run with `VLLM_LOGGING_LEVEL=DEBUG` and grep for `CPU unquantized GEMM dispatch`.
251
252 See [AMD Zen optimizations](#amd-zen-optimizations) for detection rules, supported dtypes, and the `VLLM_ZENTORCH_WEIGHT_PREPACK` knob.
253
254 ### How to decide `VLLM_CPU_OMP_THREADS_BIND`?
255
256 - Default `auto` thread-binding is recommended for most cases. Ideally, each OpenMP thread will be bound to a dedicated physical core respectively, threads of each rank will be bound to the same NUMA node respectively, and the default reserved CPUs will be kept for other vLLM components. On x86, ARM, and RISC-V, `local_world_size` CPUs are reserved in total, plus one additional CPU per local rank when KV transfer is enabled. If you have any performance problems or unexpected binding behaviours, please try to bind threads as following.
257
258 - On a hyper-threading enabled platform with 16 logical CPU cores / 8 physical CPU cores:
259
260 ??? console "Commands"
261
262 ```console
263 $ lscpu -e # check the mapping between logical CPU cores and physical CPU cores
264
265 # The "CPU" column means the logical CPU core IDs, and the "CORE" column means the physical core IDs. On this platform, two logical cores are sharing one physical core.
266 CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE MAXMHZ MINMHZ MHZ
267 0 0 0 0 0:0:0:0 yes 2401.0000 800.0000 800.000
268 1 0 0 1 1:1:1:0 yes 2401.0000 800.0000 800.000
269 2 0 0 2 2:2:2:0 yes 2401.0000 800.0000 800.000
270 3 0 0 3 3:3:3:0 yes 2401.0000 800.0000 800.000
271 4 0 0 4 4:4:4:0 yes 2401.0000 800.0000 800.000
272 5 0 0 5 5:5:5:0 yes 2401.0000 800.0000 800.000
273 6 0 0 6 6:6:6:0 yes 2401.0000 800.0000 800.000
274 7 0 0 7 7:7:7:0 yes 2401.0000 800.0000 800.000
275 8 0 0 0 0:0:0:0 yes 2401.0000 800.0000 800.000
276 9 0 0 1 1:1:1:0 yes 2401.0000 800.0000 800.000
277 10 0 0 2 2:2:2:0 yes 2401.0000 800.0000 800.000
278 11 0 0 3 3:3:3:0 yes 2401.0000 800.0000 800.000
279 12 0 0 4 4:4:4:0 yes 2401.0000 800.0000 800.000
280 13 0 0 5 5:5:5:0 yes 2401.0000 800.0000 800.000
281 14 0 0 6 6:6:6:0 yes 2401.0000 800.0000 800.000
282 15 0 0 7 7:7:7:0 yes 2401.0000 800.0000 800.000
283
284 # On this platform, it is recommended to only bind openMP threads on logical CPU cores 0-7 or 8-15
285 $ export VLLM_CPU_OMP_THREADS_BIND=0-7
286 $ python examples/basic/offline_inference/basic.py
287 ```
288
289 - When deploying vLLM CPU backend on a multi-socket machine with NUMA and enable tensor parallel or pipeline parallel, each NUMA node is treated as a TP/PP rank. So be aware to set CPU cores of a single rank on the same NUMA node to avoid cross NUMA node memory access.
290
291 ### How to decide `VLLM_CPU_KVCACHE_SPACE`?
292
293 This value is 4GB by default. Larger space can support more concurrent requests, longer context length. However, users should take care of memory capacity of each NUMA node. The memory usage of each TP rank is the sum of `weight shard size` and `VLLM_CPU_KVCACHE_SPACE`, if it exceeds the capacity of a single NUMA node, the TP worker will be killed with `exitcode 9` due to out-of-memory.
294
295 ### How to do performance tuning for vLLM CPU?
296
297 First of all, please make sure the thread-binding and KV cache space are properly set and take effect. You can check the thread-binding by running a vLLM benchmark and observing CPU cores usage via `htop`.
298
299 Use multiples of 32 as `--block-size`, which is 128 by default.
300
301 Inference batch size is an important parameter for the performance. A larger batch usually provides higher throughput, a smaller batch provides lower latency. Tuning the max batch size starting from the default value to balance throughput and latency is an effective way to improve vLLM CPU performance on specific platforms. There are two important related parameters in vLLM:
302
303 - `--max-num-batched-tokens`, defines the limit of token numbers in a single batch, has more impacts on the first token performance. The default value is set as:
304 - Offline Inference: `4096 * world_size`
305 - Online Serving: `2048 * world_size`
306 - `--max-num-seqs`, defines the limit of sequence numbers in a single batch, has more impacts on the output token performance.
307 - Offline Inference: `256 * world_size`
308 - Online Serving: `128 * world_size`
309
310 vLLM CPU supports data parallel (DP), tensor parallel (TP) and pipeline parallel (PP) to leverage multiple CPU sockets and memory nodes. For more details of tuning DP, TP and PP, please refer to [Optimization and Tuning](../../configuration/optimization.md). For vLLM CPU, it is recommended to use DP, TP and PP together if there are enough CPU sockets and memory nodes.
311
312 ### Which quantization configs does vLLM CPU support?
313
314 - vLLM CPU supports quantizations:
315 - AWQ (x86, s390x, Power)
316 - GPTQ (x86, s390x, Power)
317 - compressed-tensor INT8 W8A8 (x86, s390x only)
318
319 ### Why do I see `get_mempolicy: Operation not permitted` when running in Docker?
320
321 In some container environments (like Docker), NUMA-related syscalls used by vLLM (e.g., `get_mempolicy`, `migrate_pages`) are blocked/denied in the runtime's default seccomp/capabilities settings. This may lead to warnings like `get_mempolicy: Operation not permitted`. Functionality is not affected, but NUMA memory binding/migration optimizations may not take effect and performance can be suboptimal.
322
323 To enable these optimizations inside Docker with the least privilege, you can follow below tips:
324
325 ```bash
326 docker run ... --cap-add SYS_NICE --security-opt seccomp=unconfined ...
327
328 # 1) `--cap-add SYS_NICE` is to address `get_mempolicy` EPERM issue.
329
330 # 2) `--security-opt seccomp=unconfined` is to enable `migrate_pages` for `numa_migrate_pages()`.
331 # Actually, `seccomp=unconfined` bypasses the seccomp for container,
332 # if it's unacceptable, you can customize your own seccomp profile,
333 # based on docker/runtime default.json and add `migrate_pages` to `SCMP_ACT_ALLOW` list.
334
335 # reference : https://docs.docker.com/engine/security/seccomp/
336 ```
337
338 Alternatively, running with `--privileged=true` also works but is broader and not generally recommended.
339
340 In K8S, the following configuration can be added to workload yaml to achieve the same effect as above:
341
342 ```yaml
343 securityContext:
344 seccompProfile:
345 type: Unconfined
346 capabilities:
347 add:
348 - SYS_NICE
349 ```