|
#!/usr/bin/env bash |
|
set -euo pipefail |
|
|
|
MODE="${1:-cuda}" |
|
ROCM_DOCKER_ARCH="${2:-gfx1100,gfx1101,gfx1102,gfx1200,gfx1201}" |
|
|
|
case "$MODE" in |
|
cpu|cuda|rocm) |
|
;; |
|
*) |
|
echo "Usage: $0 {cpu|cuda|rocm} [ROCM_DOCKER_ARCH]" >&2 |
|
exit 2 |
|
;; |
|
esac |
|
|
|
GITHUB_REPOSITORY="ggml-org/llama.cpp" |
|
GITHUB_REMOTE="git@github.com:${GITHUB_REPOSITORY}.git" |
|
REPOSITORY_PATH="${HOME}/workspace/llama.cpp" |
|
PROJECT="llama-server" |
|
IMAGE="local/llama.cpp:server-${MODE}" |
|
DOCKERFILE_RELATIVE_PATH=".devops/${MODE}.Dockerfile" |
|
BUILD_TARGET="server" |
|
CUDA_UBUNTU_VERSION="24.04" |
|
CUDA_VERSION="12.9.2" |
|
CUDA_DEV_CONTAINER="docker.io/nvidia/cuda:${CUDA_VERSION}-devel-ubuntu${CUDA_UBUNTU_VERSION}" |
|
CUDA_RUN_CONTAINER="docker.io/nvidia/cuda:${CUDA_VERSION}-runtime-ubuntu${CUDA_UBUNTU_VERSION}" |
|
ROCM_UBUNTU_VERSION="26.04" |
|
ROCM_VERSION="7.14.0" |
|
ROCM_DEV_CONTAINER="docker.io/rocm/dev-ubuntu-${ROCM_UBUNTU_VERSION}:${ROCM_VERSION}-full" |
|
ROCM_LIBRARY_PATH="/opt/rocm/core-${ROCM_VERSION%.*}/lib" |
|
ROCM_LIBRARY_ENV="ENV LD_LIBRARY_PATH=${ROCM_LIBRARY_PATH}" |
|
|
|
git init --quiet "$REPOSITORY_PATH" |
|
git -C "$REPOSITORY_PATH" config --replace-all remote.origin.url "$GITHUB_REMOTE" |
|
|
|
LATEST_TAG="$( |
|
gh release view \ |
|
--repo "$GITHUB_REPOSITORY" \ |
|
--json "tagName" \ |
|
--jq ".tagName" |
|
)" |
|
|
|
git \ |
|
-C "$REPOSITORY_PATH" \ |
|
fetch \ |
|
--depth "1" \ |
|
--no-tags \ |
|
"origin" \ |
|
"refs/tags/${LATEST_TAG}" |
|
|
|
SOURCE_COMMIT="$(git -C "$REPOSITORY_PATH" rev-parse "FETCH_HEAD^{commit}")" |
|
BUILD_KEY="${LATEST_TAG}:${SOURCE_COMMIT}:${MODE}:${DOCKERFILE_RELATIVE_PATH}:${BUILD_TARGET}" |
|
MODE_BUILD_ARGS=() |
|
|
|
if [[ "$MODE" == "cuda" ]]; then |
|
MODE_BUILD_ARGS+=( |
|
--build-arg "BASE_CUDA_DEV_CONTAINER=${CUDA_DEV_CONTAINER}" |
|
--build-arg "BASE_CUDA_RUN_CONTAINER=${CUDA_RUN_CONTAINER}" |
|
) |
|
BUILD_KEY="${BUILD_KEY}:${CUDA_DEV_CONTAINER}:${CUDA_RUN_CONTAINER}" |
|
elif [[ "$MODE" == "rocm" ]]; then |
|
ROCM_BUILD_ARG="ROCM_DOCKER_ARCH=${ROCM_DOCKER_ARCH//,/;}" |
|
MODE_BUILD_ARGS+=( |
|
--build-arg "$ROCM_BUILD_ARG" |
|
--build-arg "BASE_ROCM_DEV_CONTAINER=${ROCM_DEV_CONTAINER}" |
|
) |
|
RCCL_CMAKE_OPTION="-DGGML_HIP_RCCL=ON" |
|
BUILD_KEY="${BUILD_KEY}:${ROCM_BUILD_ARG}:${ROCM_DEV_CONTAINER}:${RCCL_CMAKE_OPTION}" |
|
fi |
|
|
|
CURRENT_BUILD_KEY="$( |
|
docker image inspect \ |
|
--format '{{ index .Config.Labels "local.build-key" }}' \ |
|
"$IMAGE" \ |
|
2> /dev/null || true |
|
)" |
|
|
|
if [[ "$CURRENT_BUILD_KEY" != "$BUILD_KEY" ]]; then |
|
git -C "$REPOSITORY_PATH" checkout --force --detach "$SOURCE_COMMIT" |
|
git -C "$REPOSITORY_PATH" clean -dffx |
|
|
|
DOCKERFILE_PATH="${REPOSITORY_PATH}/${DOCKERFILE_RELATIVE_PATH}" |
|
|
|
if [[ "$MODE" == "rocm" ]]; then |
|
sed -i \ |
|
"/FROM \${BASE_ROCM_DEV_CONTAINER} AS base/a ${ROCM_LIBRARY_ENV}" \ |
|
"$DOCKERFILE_PATH" |
|
|
|
if ! grep -qF -- "$RCCL_CMAKE_OPTION" "$DOCKERFILE_PATH"; then |
|
sed -i '/-DGGML_HIP=ON \\/a\ -DGGML_HIP_RCCL=ON \\' "$DOCKERFILE_PATH" |
|
fi |
|
|
|
if ! grep -qF -- "$RCCL_CMAKE_OPTION" "$DOCKERFILE_PATH"; then |
|
echo "Failed to enable RCCL in ${DOCKERFILE_PATH}" >&2 |
|
exit 1 |
|
fi |
|
|
|
if ! grep -qFx -- "$ROCM_LIBRARY_ENV" "$DOCKERFILE_PATH"; then |
|
echo "Failed to configure ROCm library path in ${DOCKERFILE_PATH}" >&2 |
|
exit 1 |
|
fi |
|
fi |
|
|
|
BUILD_ARGS=( |
|
--file "$DOCKERFILE_PATH" |
|
--target "$BUILD_TARGET" |
|
--tag "$IMAGE" |
|
--label "local.project=${PROJECT}" |
|
--label "local.source-ref=${LATEST_TAG}" |
|
--label "local.source-commit=${SOURCE_COMMIT}" |
|
--label "local.build-key=${BUILD_KEY}" |
|
--progress "plain" |
|
"${MODE_BUILD_ARGS[@]}" |
|
) |
|
|
|
DOCKER_BUILDKIT=1 docker build "${BUILD_ARGS[@]}" "$REPOSITORY_PATH" |
|
fi |
|
|
|
docker system prune --all --force --volumes --filter "label!=local.build-key=${BUILD_KEY}" |