@@ -13,62 +13,147 @@ setting_up_container
1313network_check
1414update_os
1515
16- var_backend=" ${var_backend:- auto} "
17- var_model_repo=" ${var_model_repo:- ggml-org/ gemma-3-1b-it-GGUF} "
16+ var_model_repo=" ${var_model_repo:- ggml-org/ gemma-4-E2B-it-GGUF: Q4_0} "
1817var_port=" ${var_port:- 8080} "
1918var_ctx_size=" ${var_ctx_size:- 4096} "
2019var_offload_layers=" ${var_offload_layers:- } "
2120var_api_key=" ${var_api_key:- } "
2221
23- # Which prebuilt upstream ships decides what the container can offload to, and
24- # for Linux that list is short: ubuntu-x64, ubuntu-arm64, ubuntu-vulkan-x64,
25- # ubuntu-vulkan-arm64, plus the Intel sycl and openvino builds. There is no
26- # Linux CUDA build and no Linux ROCm build either -- the only ROCm asset
27- # upstream publishes is win-rocm-*-x64.zip. Vulkan is therefore the GPU path for
28- # every vendor here, AMD included, and it reaches an AMD card through RADV.
29- #
30- # Asking for a ubuntu-rocm asset failed the install outright with "No asset
31- # matching 'llama--bin-ubuntu-rocm--x64.tar.gz' found" on any host where the
32- # engine had set up /dev/kfd.
22+ # The Linux prebuilts upstream publishes (see .github/workflows/release.yml):
23+ # cpu ubuntu-{x64,arm64}
24+ # vulkan ubuntu-vulkan-{x64,arm64} any GPU vendor (AMD through RADV)
25+ # cuda ubuntu-cuda-{12.x,13.x}-x64, ubuntu-cuda-13.x-arm64, plus a cudart tarball
26+ # rocm ubuntu-rocm-<ver>-x64 needs the matching ROCm (TheRock) runtime
27+ # sycl ubuntu-sycl-{fp16,fp32}-x64 Intel GPUs, needs oneAPI + Level Zero
28+ # openvino ubuntu-openvino-<ver>-x64 Intel CPU/GPU, OpenVINO runtime is bundled
29+ var_backend=" ${var_backend:- auto} "
30+
3331if [[ " $var_backend " == " auto" ]]; then
3432 if [[ -e /dev/kfd || -e /dev/nvidia0 || -d /dev/dri ]]; then
3533 var_backend=" vulkan"
3634 else
3735 var_backend=" cpu"
3836 fi
3937fi
40-
41- # rocm was a documented value, so keep accepting it rather than failing anyone
42- # who pinned it -- but say where they are actually being sent.
43- if [[ " $var_backend " == " rocm" ]]; then
44- msg_warn " llama.cpp publishes no Linux ROCm build - using the Vulkan build, which drives an AMD card through RADV"
45- var_backend=" vulkan"
46- fi
38+ [[ " $var_backend " == " sycl" ]] && var_backend=" sycl-fp16"
4739
4840LLAMA_ARCH=" $( arch_resolve x64 arm64) "
49-
5041case " $var_backend " in
51- vulkan) LLAMA_ASSET=" llama-*-bin-ubuntu-vulkan-${LLAMA_ARCH} .tar.gz" ;;
42+ rocm | sycl-fp16 | sycl-fp32 | openvino)
43+ if [[ " $LLAMA_ARCH " != " x64" ]]; then
44+ msg_error " llama.cpp publishes the ${var_backend} build for x64 only"
45+ exit 1
46+ fi
47+ ;;
48+ cpu | vulkan | cuda) ;;
5249* )
53- var_backend= " cpu"
54- LLAMA_ASSET= " llama-*-bin-ubuntu- ${LLAMA_ARCH} .tar.gz "
50+ msg_error " Unknown var_backend ' ${var_backend} ' (expected auto, cpu, vulkan, cuda, rocm, sycl-fp16, sycl-fp32 or openvino) "
51+ exit 1
5552 ;;
5653esac
5754
5855msg_info " Installing Dependencies"
5956LLAMA_DEPS=(libgomp1)
60- [[ " $var_backend " == " vulkan" ]] && LLAMA_DEPS+=(libvulkan1 mesa-vulkan-drivers vulkan-tools)
57+ case " $var_backend " in
58+ vulkan) LLAMA_DEPS+=(libvulkan1 mesa-vulkan-drivers vulkan-tools) ;;
59+ openvino) LLAMA_DEPS+=(libtbb12 ocl-icd-libopencl1) ;;
60+ sycl-* ) LLAMA_DEPS+=(ocl-icd-libopencl1) ;;
61+ esac
6162$STD apt install -y " ${LLAMA_DEPS[@]} "
6263msg_ok " Installed Dependencies"
6364
6465setup_hwaccel
6566
66- fetch_and_deploy_gh_release " llama-cpp" " ggml-org/llama.cpp" " prebuild" " latest" " /opt/llama-cpp" " $LLAMA_ASSET "
67+ # SYCL and OpenVINO reach an Intel GPU through Level Zero. release.yml builds
68+ # SYCL against the loader from oneapi-src/level-zero, so use the same package.
69+ if [[ " $var_backend " == sycl-* || " $var_backend " == " openvino" ]]; then
70+ fetch_and_deploy_gh_release " level-zero" " oneapi-src/level-zero" " binary" " latest" " " " libze1_*u24.04_amd64.deb"
71+ if [[ -d /dev/dri ]]; then
72+ fetch_and_deploy_gh_release " intel-level-zero-gpu" " intel/compute-runtime" " binary" " latest" " " " libze-intel-gpu1_*_amd64.deb" || true
73+ fi
74+ fi
75+
76+ # The SYCL tarball ships only llama.cpp itself; the DPC++/oneMKL/oneDNN/TBB
77+ # libraries it links against come from oneAPI. release.yml builds with the full
78+ # toolkit, but running needs only the runtime libraries.
79+ if [[ " $var_backend " == sycl-* ]]; then
80+ setup_deb822_repo \
81+ " oneapi" \
82+ " https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB" \
83+ " https://apt.repos.intel.com/oneapi" \
84+ " all" \
85+ " main"
86+ msg_info " Installing Intel oneAPI Runtime"
87+ $STD apt install -y intel-oneapi-runtime-libs
88+ # The runtime packages unpack under /opt/intel/oneapi without telling the
89+ # dynamic linker, so register every directory that holds one of them.
90+ find /opt/intel/oneapi -type f \( -name ' libsycl.so*' -o -name ' libur_loader.so*' -o -name ' libmkl_core.so*' \
91+ -o -name ' libdnnl.so*' -o -name ' libtbb.so*' -o -name ' libsvml.so' -o -name ' libiomp5.so' -o -name ' libumf.so*' \) \
92+ -printf ' %h\n' 2> /dev/null | sort -u > /etc/ld.so.conf.d/oneapi-llama-cpp.conf
93+ ldconfig
94+ msg_ok " Installed Intel oneAPI Runtime"
95+ fi
96+
97+ LLAMA_CUDART_ASSET=" "
98+ case " $var_backend " in
99+ vulkan) LLAMA_ASSET=" llama-*-bin-ubuntu-vulkan-${LLAMA_ARCH} .tar.gz" ;;
100+ cuda)
101+ # CUDA 13 needs a 580+ host driver; anything older gets the CUDA 12 build,
102+ # which upstream publishes for x64 only.
103+ NVIDIA_DRIVER_MAJOR=" $( grep -oP ' \d{3,}(?=\.\d+)' /proc/driver/nvidia/version 2> /dev/null | head -1) "
104+ if [[ " $LLAMA_ARCH " == " x64" && -n " $NVIDIA_DRIVER_MAJOR " && " $NVIDIA_DRIVER_MAJOR " -lt 580 ]]; then
105+ var_backend=" cuda-12"
106+ else
107+ var_backend=" cuda-13"
108+ fi
109+ [[ -z " $NVIDIA_DRIVER_MAJOR " ]] && msg_warn " No NVIDIA host driver visible - installing the CUDA 13 build, which needs driver 580 or newer"
110+ LLAMA_ASSET=" llama-*-bin-ubuntu-cuda-${var_backend# cuda-} .*-${LLAMA_ARCH} .tar.gz"
111+ LLAMA_CUDART_ASSET=" cudart-${LLAMA_ASSET} "
112+ ;;
113+ rocm) LLAMA_ASSET=" llama-*-bin-ubuntu-rocm-*-x64.tar.gz" ;;
114+ sycl-fp16 | sycl-fp32) LLAMA_ASSET=" llama-*-bin-ubuntu-${var_backend} -x64.tar.gz" ;;
115+ openvino) LLAMA_ASSET=" llama-*-bin-ubuntu-openvino-*x64.tar.gz" ;;
116+ * ) LLAMA_ASSET=" llama-*-bin-ubuntu-${LLAMA_ARCH} .tar.gz" ;;
117+ esac
118+
119+ # Only the bNNNN builds carry binaries, and upstream marks them prerelease. A
120+ # stable vX.Y.Z release ships just nightly-tag.txt, naming the build it was cut
121+ # from, so without GH_INCLUDE_PRERELEASE=1 that build is the one deployed.
122+ mkdir -p /opt/llama-cpp_data/models
123+ if [[ " ${GH_INCLUDE_PRERELEASE:- 0} " == " 1" ]]; then
124+ fetch_and_deploy_gh_release " llama-cpp" " ggml-org/llama.cpp" " prebuild" " latest" " /opt/llama-cpp" " $LLAMA_ASSET " " b"
125+ LLAMA_RELEASE=" $( cat ~ /.llama-cpp) "
126+ else
127+ USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release " llama-cpp-stable" " ggml-org/llama.cpp" " singlefile" " latest" " /opt/llama-cpp_data" " nightly-tag.txt"
128+ LLAMA_RELEASE=" $( < /opt/llama-cpp_data/nightly-tag.txt) "
129+ fetch_and_deploy_gh_release " llama-cpp" " ggml-org/llama.cpp" " prebuild" " $LLAMA_RELEASE " " /opt/llama-cpp" " $LLAMA_ASSET "
130+ fi
131+ if [[ -n " $LLAMA_CUDART_ASSET " ]]; then
132+ fetch_and_deploy_gh_release " llama-cpp-cudart" " ggml-org/llama.cpp" " prebuild" " $LLAMA_RELEASE " " /opt/llama-cpp" " $LLAMA_CUDART_ASSET "
133+ fi
134+ LLAMA_LIBPATH=" /opt/llama-cpp"
135+
136+ # The ROCm build carries no ROCm libraries. release.yml builds it against AMD's
137+ # TheRock wheels, so install the same ROCm release of those as the runtime.
138+ if [[ " $var_backend " == " rocm" ]]; then
139+ ROCM_VERSION=" $( jq -r --arg t " $LLAMA_RELEASE " ' if type == "array" then .[] else . end | select(.tag_name == $t) | .assets[].name' " $TOOLS_GH_REL_JSON " 2> /dev/null | grep -oP ' bin-ubuntu-rocm-\K[0-9.]+(?=-x64)' | head -1) "
140+ if [[ -z " $ROCM_VERSION " ]]; then
141+ msg_error " Could not read the ROCm release the llama.cpp ${LLAMA_RELEASE} build targets"
142+ exit 1
143+ fi
144+ PYTHON_VERSION=" 3.12" setup_uv
145+ msg_info " Installing ROCm ${ROCM_VERSION} Runtime"
146+ $STD uv venv --python 3.12 /opt/llama-cpp_data/rocm
147+ $STD uv pip install --python /opt/llama-cpp_data/rocm --index-url https://stable.repo.amd.com/rocm/whl-next/ " rocm[libraries]==${ROCM_VERSION} .*"
148+ echo " $ROCM_VERSION " > /opt/llama-cpp_data/rocm/.version
149+ LLAMA_LIBPATH=" ${LLAMA_LIBPATH} :$( /opt/llama-cpp_data/rocm/bin/rocm-sdk path --root) /lib"
150+ msg_ok " Installed ROCm ${ROCM_VERSION} Runtime"
151+ fi
67152
68153msg_info " Configuring llama.cpp"
69154chmod +x /opt/llama-cpp/llama-*
70- mkdir -p /opt/llama-cpp_data/models
71155echo " $var_backend " > /opt/llama-cpp_data/.backend
156+ echo " ${GH_INCLUDE_PRERELEASE:- 0} " > /opt/llama-cpp_data/.prerelease
72157if [[ -z " $var_offload_layers " ]]; then
73158 [[ " $var_backend " == " cpu" ]] && var_offload_layers=0 || var_offload_layers=999
74159fi
@@ -80,11 +165,36 @@ LLAMA_ARG_PORT=${var_port}
80165#LLAMA_ARG_MODEL=/opt/llama-cpp_data/models/your-model.gguf
81166# ...or let llama-server pull one from Hugging Face on first start:
82167LLAMA_ARG_HF_REPO=${var_model_repo}
168+ # Model switching: comment out LLAMA_ARG_HF_REPO (and LLAMA_ARG_MODEL) to serve
169+ # every model in this folder and pick one per request from the web UI or API:
170+ LLAMA_ARG_MODELS_DIR=/opt/llama-cpp_data/models
83171
84172LLAMA_CACHE=/opt/llama-cpp_data/models
85173LLAMA_ARG_CTX_SIZE=${var_ctx_size}
86174LLAMA_ARG_N_GPU_LAYERS=${var_offload_layers}
87175EOF
176+ case " $var_backend " in
177+ sycl-* )
178+ cat << EOF >>/opt/llama-cpp.env
179+
180+ # SYCL: the persistent kernel cache speeds up restarts but can stop models
181+ # from loading on some Intel GPUs, so it is off by default
182+ #SYCL_CACHE_PERSISTENT=1
183+ #SYCL_CACHE_DIR=/opt/llama-cpp_data/sycl-cache
184+ #ONEAPI_DEVICE_SELECTOR=level_zero:0
185+ EOF
186+ ;;
187+ openvino)
188+ OV_DEVICE=" CPU"
189+ compgen -G " /dev/dri/renderD*" > /dev/null && OV_DEVICE=" GPU"
190+ cat << EOF >>/opt/llama-cpp.env
191+
192+ # OpenVINO device: CPU, GPU (GPU.0, GPU.1, ...) or NPU
193+ GGML_OPENVINO_DEVICE=${OV_DEVICE}
194+ GGML_OPENVINO_CACHE_DIR=/opt/llama-cpp_data/openvino-cache
195+ EOF
196+ ;;
197+ esac
88198# An empty LLAMA_ARG_API_KEY makes llama-server demand an empty bearer token.
89199if [[ -n " $var_api_key " ]]; then
90200 echo " LLAMA_ARG_API_KEY=${var_api_key} " >> /opt/llama-cpp.env
@@ -95,10 +205,14 @@ chmod 600 /opt/llama-cpp.env
95205msg_ok " Configured llama.cpp (${var_backend} build)"
96206
97207if [[ " $var_backend " != " cpu" ]]; then
98- if LD_LIBRARY_PATH=/opt/llama-cpp ldd /opt/llama-cpp/llama-server 2> /dev/null | grep -q " not found" ; then
208+ if LD_LIBRARY_PATH=" $LLAMA_LIBPATH " ldd /opt/llama-cpp/llama-server /opt/llama-cpp/libggml- * .so 2> /dev/null | grep -q " not found" ; then
99209 msg_warn " The ${var_backend} build is missing shared libraries in this container - it will fall back to the CPU"
100210 elif [[ " $var_backend " == " vulkan" ]] && ! vulkaninfo --summary > /dev/null 2>&1 ; then
101211 msg_warn " Vulkan build installed but no Vulkan device is visible - check GPU passthrough and the driver libraries in the container"
212+ elif [[ " $var_backend " == cuda-* ]] && ! ldconfig -p | grep -q ' libcuda[.]so' ; then
213+ msg_warn " CUDA build installed but the NVIDIA driver library (libcuda) is missing - check GPU passthrough"
214+ elif [[ " $var_backend " == sycl-* || " $var_backend " == " rocm" ]] && [[ ! -d /dev/dri && ! -e /dev/kfd ]]; then
215+ msg_warn " ${var_backend} build installed but no GPU is passed through - it will fall back to the CPU"
102216 fi
103217fi
104218
@@ -114,7 +228,7 @@ Type=simple
114228User=root
115229WorkingDirectory=/opt/llama-cpp
116230EnvironmentFile=/opt/llama-cpp.env
117- Environment=LD_LIBRARY_PATH=/opt/llama-cpp
231+ Environment=LD_LIBRARY_PATH=${LLAMA_LIBPATH}
118232ExecStart=/opt/llama-cpp/llama-server
119233Restart=on-failure
120234RestartSec=10
0 commit comments