[CPU][Docs] Update docs and dockerfile for s390x (#49523)

Signed-off-by: Rehan Khan <Rehan.Khan7@ibm.com>

Rehan Khan committed Jul 23, 2026 at 12:47 UTC f83de6d44c2473656f95357900d53f1b7401d21c
3 files changed +111 -22
docker/Dockerfile.s390x
+25 -1
@@ -86,6 +86,29 @@ RUN --mount=type=cache,target=/root/.cache/uv \
86 mkdir -p /tmp/hf-xet/dist && \
87 cp dist/*.whl /tmp/hf-xet/dist/
88
89 +# Build LLVM 20 from source for llvmlite (system repos ship LLVM 21 which
90 +# llvmlite v0.47 does not support; only SystemZ target is needed).
91 +FROM base AS llvm20-build
92 +ARG LLVM_VERSION=20.1.8
93 +WORKDIR /tmp
94 +RUN microdnf install -y ninja-build gcc gcc-c++ python3 xz && \
95 + curl -LO https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/llvm-project-${LLVM_VERSION}.src.tar.xz && \
96 + tar -xf llvm-project-${LLVM_VERSION}.src.tar.xz && \
97 + cmake -G Ninja -S llvm-project-${LLVM_VERSION}.src/llvm -B build \
98 + -DCMAKE_BUILD_TYPE=Release \
99 + -DCMAKE_INSTALL_PREFIX=/opt/llvm20 \
100 + -DLLVM_TARGETS_TO_BUILD="SystemZ" \
101 + -DLLVM_ENABLE_RTTI=ON \
102 + -DLLVM_BUILD_TOOLS=OFF \
103 + -DLLVM_BUILD_UTILS=ON \
104 + -DLLVM_BUILD_EXAMPLES=OFF \
105 + -DLLVM_BUILD_TESTS=OFF \
106 + -DLLVM_INCLUDE_TESTS=OFF \
107 + -DLLVM_INCLUDE_EXAMPLES=OFF \
108 + -DLLVM_INCLUDE_BENCHMARKS=OFF && \
109 + ninja -C build install && \
110 + rm -rf build llvm-project-${LLVM_VERSION}.src*
111 +
112 # Build numba
113 FROM python-install AS numba-builder
114
@@ -96,11 +119,13 @@ WORKDIR /tmp
119
120 # Clone all required dependencies
121 RUN --mount=type=cache,target=/root/.cache/uv \
122 + --mount=type=bind,from=llvm20-build,source=/opt/llvm20,target=/opt/llvm20 \
123 microdnf install ninja-build gcc gcc-c++ -y && \
124 git clone --recursive https://github.com/numba/llvmlite.git -b v0.47.0 && \
125 git clone --recursive https://github.com/numba/numba.git -b ${NUMBA_VERSION} && \
126 cd llvmlite && \
127 uv pip install 'cmake<4' 'setuptools<70' numpy && \
128 + CMAKE_PREFIX_PATH=/opt/llvm20 LLVM_CONFIG=/opt/llvm20/bin/llvm-config \
129 python setup.py bdist_wheel && \
130 cd ../numba && \
131 if ! grep '#include "dynamic_annotations.h"' numba/_dispatcher.cpp; then \
@@ -158,7 +183,6 @@ RUN --mount=type=cache,target=/root/.cache/uv \
183 NUMBA_WHL_FILE=$(ls /tmp/numba-wheels/*.whl) && \
184 OPENCV_WHL_FILE=$(ls /tmp/opencv-wheels/*.whl) && \
185 uv pip install -v \
161 - $ARROW_WHL_FILE \
186 $VISION_WHL_FILE \
187 $HF_XET_WHL_FILE \
188 $LLVM_WHL_FILE \
docs/getting_started/installation/cpu.md
+1 -1
@@ -315,7 +315,7 @@ vLLM CPU supports data parallel (DP), tensor parallel (TP) and pipeline parallel
315 - vLLM CPU supports quantizations:
316 - AWQ (x86 only)
317 - GPTQ (x86 only)
318 - - compressed-tensor INT8 W8A8 (x86, s390x)
318 + - compressed-tensor INT8 W8A8 (x86 only)
319
320 ### Why do I see `get_mempolicy: Operation not permitted` when running in Docker?
321
docs/getting_started/installation/cpu.s390x.inc.md
+85 -20
@@ -11,7 +11,7 @@ Currently, the CPU implementation for s390x architecture supports FP32, BF16 and
11 - OS: `Linux`
12 - SDK: `gcc/g++ >= 14.0.0` or later with Command Line Tools
13 - Instruction Set Architecture (ISA): VXE support is required. Works with Z14 and above.
14 -- Build install python packages: `torchvision`, `llvmlite`, `numba`, `pyarrow (for testing)`, `opencv-headless`
14 +- Build from source python packages (no pre-built s390x wheels): `torchvision`, `llvmlite`, `numba`, `opencv-python-headless`, `hf-xet`
15
16 --8<-- [end:requirements]
17 --8<-- [start:set-up-using-python]
@@ -28,13 +28,24 @@ Install the following packages from the package manager before building the vLLM
28
29 ```bash
30 dnf install -y \
31 - which procps findutils tar vim git gcc-toolset-14 gcc-toolset-14-binutils gcc-toolset-14-libatomic-devel zlib-devel \
31 + which procps findutils tar vim git patch xz ninja-build \
32 + gcc-toolset-14 gcc-toolset-14-binutils gcc-toolset-14-libatomic-devel zlib-devel \
33 libjpeg-turbo-devel libtiff-devel libpng-devel libwebp-devel freetype-devel harfbuzz-devel \
34 openssl-devel openblas openblas-devel autoconf automake libtool cmake numpy libsndfile \
35 clang llvm-devel llvm-static clang-devel
36 ```
37
37 -Install rust>=1.80 which is needed for `outlines-core` and `uvloop` python packages installation.
38 +Build and install `numactl` from source:
39 +
40 +```bash
41 +curl -LO https://github.com/numactl/numactl/archive/refs/tags/v2.0.19.tar.gz
42 +tar -xvzf v2.0.19.tar.gz
43 +cd numactl-2.0.19
44 +./autogen.sh && ./configure && make && make install
45 +cd ..
46 +```
47 +
48 +Install rust>=1.80 which is needed for `outlines-core`, `uvloop`, and `hf-xet` python packages installation.
49
50 ```bash
51 curl https://sh.rustup.rs -sSf | sh -s -- -y && \
@@ -44,26 +55,79 @@ curl https://sh.rustup.rs -sSf | sh -s -- -y && \
55 Execute the following commands to build and install vLLM from source.
56
57 !!! tip
47 - Please build the following dependencies, `torchvision`, `llvmlite`, `numba`, `llguidance`, `pyarrow`, `opencv-headless` from source before building vLLM.
58 + Pre-built wheels are not available for s390x for the following packages. Build them from source before building vLLM: `torchvision`, `llvmlite`, `numba`, `opencv-python-headless`, `hf-xet`.
59 + See `docker/Dockerfile.s390x` for exact versions and build commands used in each multi-stage build.
60 +
61 +!!! note "LLVM 20 required for llvmlite"
62 + `llvmlite v0.47` requires LLVM 20, but UBI 9.6 repos ship LLVM 21 which is
63 + not compatible. You must build LLVM 20 from source before building `llvmlite`:
64 +
65 + ```bash
66 + curl -LO https://github.com/llvm/llvm-project/releases/download/llvmorg-20.1.8/llvm-project-20.1.8.src.tar.xz
67 + tar -xf llvm-project-20.1.8.src.tar.xz
68 + cmake -G Ninja -S llvm-project-20.1.8.src/llvm -B llvm-build \
69 + -DCMAKE_BUILD_TYPE=Release \
70 + -DCMAKE_INSTALL_PREFIX=/opt/llvm20 \
71 + -DLLVM_TARGETS_TO_BUILD="SystemZ" \
72 + -DLLVM_ENABLE_RTTI=ON \
73 + -DLLVM_BUILD_TOOLS=OFF \
74 + -DLLVM_BUILD_UTILS=ON \
75 + -DLLVM_BUILD_EXAMPLES=OFF \
76 + -DLLVM_BUILD_TESTS=OFF \
77 + -DLLVM_INCLUDE_TESTS=OFF \
78 + -DLLVM_INCLUDE_EXAMPLES=OFF \
79 + -DLLVM_INCLUDE_BENCHMARKS=OFF
80 + ninja -C llvm-build install
81 + ```
82 +
83 + Then build `llvmlite` pointing to LLVM 20:
84 +
85 + ```bash
86 + CMAKE_PREFIX_PATH=/opt/llvm20 LLVM_CONFIG=/opt/llvm20/bin/llvm-config \
87 + python setup.py bdist_wheel
88 + ```
89
90 ```bash
50 - uv pip install -v \
51 - -r requirements/build/cpu.txt \
52 - -r requirements/cpu.txt \
53 - --torch-backend cpu \
54 - --index-strategy unsafe-best-match && \
55 - VLLM_TARGET_DEVICE=cpu python setup.py bdist_wheel && \
56 - uv pip install dist/*.whl
91 +uv pip install -v \
92 + /path/to/torchvision.whl \
93 + /path/to/llvmlite.whl \
94 + /path/to/numba.whl \
95 + /path/to/opencv_python_headless.whl \
96 + /path/to/hf_xet.whl \
97 + -r requirements/build/cpu.txt \
98 + -r requirements/cpu.txt \
99 + --torch-backend cpu \
100 + --index-strategy unsafe-best-match && \
101 +VLLM_TARGET_DEVICE=cpu VLLM_CPU_MOE_PREPACK=0 python setup.py bdist_wheel && \
102 + uv pip install dist/*.whl
103 ```
104
105 ??? console "pip"
106 ```bash
61 - pip install -v \
62 - --extra-index-url https://download.pytorch.org/whl/cpu \
63 - -r requirements/build/cpu.txt \
64 - -r requirements/cpu.txt \
65 - VLLM_TARGET_DEVICE=cpu python setup.py bdist_wheel && \
66 - pip install dist/*.whl
107 + pip install -v \
108 + --extra-index-url https://download.pytorch.org/whl/cpu \
109 + /path/to/torchvision.whl \
110 + /path/to/llvmlite.whl \
111 + /path/to/numba.whl \
112 + /path/to/opencv_python_headless.whl \
113 + /path/to/hf_xet.whl \
114 + -r requirements/build/cpu.txt \
115 + -r requirements/cpu.txt && \
116 + VLLM_TARGET_DEVICE=cpu VLLM_CPU_MOE_PREPACK=0 python setup.py bdist_wheel && \
117 + pip install dist/*.whl
118 + ```
119 +
120 +!!! warning "Protobuf workaround for s390x"
121 + The C++ protobuf extension crashes on s390x. After installation, set the
122 + following environment variable and remove the C++ extensions:
123 +
124 + ```bash
125 + export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
126 +
127 + # Remove C++ protobuf extensions that crash on s390x
128 + SITE_PKGS=$(python -c "import site; print(site.getsitepackages()[0])")
129 + rm -rf "$SITE_PKGS/google/_upb/"*.so \
130 + "$SITE_PKGS/google/protobuf/pyext/"*.so 2>/dev/null || true
131 ```
132
133 --8<-- [end:build-wheel-from-source]
@@ -80,19 +144,20 @@ docker build -f docker/Dockerfile.s390x \
144
145 # Launch OpenAI server
146 docker run --rm \
83 - --privileged true \
147 + --security-opt seccomp=unconfined \
148 + --cap-add SYS_NICE \
149 --shm-size 4g \
150 -p 8000:8000 \
151 -e VLLM_CPU_KVCACHE_SPACE=<KV cache space> \
152 -e VLLM_CPU_OMP_THREADS_BIND=<CPU cores for inference> \
153 vllm-cpu-env \
154 --model meta-llama/Llama-3.2-1B-Instruct \
90 - --dtype float \
155 + --dtype bfloat16 \
156 other vLLM OpenAI server arguments
157 ```
158
159 !!! tip
95 - An alternative of `--privileged true` is `--cap-add SYS_NICE --security-opt seccomp=unconfined`.
160 + Alternatively, `--privileged=true` also works but is broader and not generally recommended.
161
162 --8<-- [end:build-image-from-source]
163 --8<-- [start:extra-information]