The runtime for the next frank-medium shape is mainline llama.cpp at fb27a525, built for gfx1201 against the ROCm 7.14 nightly the ROCmFPX build already used on this host, with the runtime bundled next to the binary. Two things that pin the ref: DFlash2 (ggml-org/llama.cpp#27342) and qwen35 MTP. Neither is in the ROCmFPX fork's tip (c49ebdb, 2026-08-22), and the DFlash2 drafter cannot run without the first. The fetch script pulls the target at UD-Q8_K_XL plus the DFlash2 draft at Q8_0, resumable and byte-verified -- a truncated 31 GB GGUF is otherwise a load-time crash.
135 lines
6.9 KiB
Bash
Executable File
135 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build mainline llama.cpp for Dankserver's two Radeon AI PRO R9700 (gfx1201,
|
|
# Navi 48) with DFlash2 speculative decoding.
|
|
#
|
|
# Run on Dankserver. Produces a self-contained build: the binary carries an
|
|
# RPATH of $ORIGIN/../lib and the ROCm runtime is copied beside it, so nothing
|
|
# depends on the host's ROCm packages (Ubuntu's 7.1) or on LD_LIBRARY_PATH.
|
|
#
|
|
# bash scripts/build-llama-rdna4.sh
|
|
#
|
|
# WHY A PRIVATE TOOLCHAIN (ROCm 7.14.0a20260624, ~17 GiB extracted): the host's
|
|
# ROCm is Ubuntu's 7.1 packaging, and the pre-existing RDNA4 llama.cpp build on
|
|
# this box (charlie12345/ROCmFPX) was built against this same TheRock nightly.
|
|
# Reusing it keeps the toolchain that is known to emit working gfx1201 code
|
|
# objects; the tarball is only downloaded when the prefix is missing.
|
|
#
|
|
# WHY THIS REF: master at fb27a525 carries what this service needs and nothing
|
|
# older does:
|
|
# * DFlash2 (`DFlash2DraftModel`): grouped dynamic depthwise convolution plus
|
|
# the candidate selector, detected from the draft GGUF
|
|
# (`selector_top_k > 0`) and served through the ordinary `--spec-type
|
|
# draft-dflash` path. Landed with ggml-org/llama.cpp#27342.
|
|
# * qwen35 MTP: the `draft-mtp` implementation covers qwen35's single trained
|
|
# MTP head (common/speculative.cpp), which the target GGUF carries.
|
|
# Do not "update to latest" casually: both features landed days apart and the
|
|
# service depends on the pair.
|
|
#
|
|
# gfx1201 IS NOT gfx1200. The ROCmFPX fork's docs/BUILD-AMD-ARCHITECTURES.md
|
|
# records that a gfx1200 build links, loads the model and then segfaults on
|
|
# these cards, so the arch list here is exactly gfx1201 and no other.
|
|
set -euo pipefail
|
|
|
|
LLAMA_SRC="${LLAMA_SRC:-/home/dank/GitPackages/llama.cpp-dflash2}"
|
|
LLAMA_REPO="${LLAMA_REPO:-https://github.com/ggml-org/llama.cpp.git}"
|
|
LLAMA_REF="${LLAMA_REF:-fb27a525d28381a16a4bb038858a10e4927381ca}"
|
|
BUILD_DIR="${BUILD_DIR:-$LLAMA_SRC/build-rdna4-rocm714}"
|
|
JOBS="${JOBS:-$(nproc)}"
|
|
ROCM_VERSION="${ROCM_VERSION:-7.14.0a20260624}"
|
|
ROCM_LOCAL_PATH="${ROCM_LOCAL_PATH:-${XDG_DATA_HOME:-$HOME/.local/share}/rocm-${ROCM_VERSION}}"
|
|
HIP_ARCH="${HIP_ARCH:-gfx1201}"
|
|
|
|
# ── Source ────────────────────────────────────────────────────────────
|
|
if [[ ! -d "$LLAMA_SRC/.git" ]]; then
|
|
echo "cloning $LLAMA_REPO into $LLAMA_SRC"
|
|
git clone "$LLAMA_REPO" "$LLAMA_SRC"
|
|
fi
|
|
git -C "$LLAMA_SRC" fetch --quiet origin "$LLAMA_REF" 2>/dev/null || git -C "$LLAMA_SRC" fetch --quiet origin
|
|
git -C "$LLAMA_SRC" checkout --detach "$LLAMA_REF"
|
|
echo "building llama.cpp $(git -C "$LLAMA_SRC" rev-parse --short HEAD) from $LLAMA_SRC"
|
|
|
|
# ── ROCm toolchain ────────────────────────────────────────────────────
|
|
if [[ ! -x "$ROCM_LOCAL_PATH/llvm/bin/clang" ]]; then
|
|
TARBALL_URL="https://rocm.nightlies.amd.com/tarball-multi-arch/therock-dist-linux-gfx120X-all-${ROCM_VERSION}.tar.gz"
|
|
TARBALL="$LLAMA_SRC/rocm-${ROCM_VERSION}.tar.gz"
|
|
if [[ ! -s "$TARBALL" ]]; then
|
|
echo "downloading ROCm $ROCM_VERSION from TheRock nightlies"
|
|
curl -fL --retry 5 -o "$TARBALL" "$TARBALL_URL"
|
|
fi
|
|
echo "extracting into $ROCM_LOCAL_PATH"
|
|
mkdir -p "$ROCM_LOCAL_PATH"
|
|
tar --use-compress-program=gzip -xf "$TARBALL" -C "$ROCM_LOCAL_PATH" --strip-components=1
|
|
fi
|
|
CLANG="$ROCM_LOCAL_PATH/llvm/bin/clang"
|
|
CLANGXX="$ROCM_LOCAL_PATH/llvm/bin/clang++"
|
|
[[ -x "$CLANG" && -x "$CLANGXX" ]] || { echo "no clang/clang++ under $ROCM_LOCAL_PATH" >&2; exit 1; }
|
|
|
|
# ggml-hip's CMake falls back to $ENV{ROCM_PATH} or /opt/rocm when these are
|
|
# unset, which links a second, mismatched HIP runtime next to the local one.
|
|
export ROCM_PATH="$ROCM_LOCAL_PATH"
|
|
export HIP_PATH="$ROCM_LOCAL_PATH"
|
|
|
|
# ── Configure ─────────────────────────────────────────────────────────
|
|
# GGML_HIP_RCCL stays OFF: this host's second card cannot dispatch a RCCL
|
|
# kernel at all (its PCIe path has no atomic routing), and layer-split serving
|
|
# needs no collectives. With RCCL off, llama.cpp logs "internal AllReduce init
|
|
# failed ... falling back to meta-backend butterfly" and only --split-mode
|
|
# tensor pays for it.
|
|
cmake -S "$LLAMA_SRC" -B "$BUILD_DIR" \
|
|
-G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_C_COMPILER="$CLANG" \
|
|
-DCMAKE_CXX_COMPILER="$CLANGXX" \
|
|
-DCMAKE_CXX_FLAGS="-I${ROCM_LOCAL_PATH}/include" \
|
|
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
|
|
-DGGML_HIP=ON \
|
|
-DGGML_HIP_RCCL=OFF \
|
|
-DGGML_CUDA=OFF \
|
|
-DGGML_VULKAN=OFF \
|
|
-DGGML_NATIVE=OFF \
|
|
-DCMAKE_HIP_ARCHITECTURES="$HIP_ARCH" \
|
|
-DGPU_TARGETS="$HIP_ARCH" \
|
|
-DLLAMA_BUILD_SERVER=ON \
|
|
-DLLAMA_BUILD_WEBUI=OFF \
|
|
-DLLAMA_USE_PREBUILT_WEBUI=OFF \
|
|
-DLLAMA_BUILD_TESTS=OFF \
|
|
-DGGML_BUILD_TESTS=OFF \
|
|
-DCMAKE_PREFIX_PATH="$ROCM_LOCAL_PATH" \
|
|
-DROCM_DIR="$ROCM_LOCAL_PATH" \
|
|
-DBUILD_SHARED_LIBS=OFF
|
|
|
|
# ── Build ─────────────────────────────────────────────────────────────
|
|
cmake --build "$BUILD_DIR" -j "$JOBS" \
|
|
--target llama-server llama-cli llama-quantize llama-bench
|
|
|
|
# ── Bundle the runtime ────────────────────────────────────────────────
|
|
if command -v patchelf >/dev/null; then
|
|
LIB_DIR="$BUILD_DIR/lib"
|
|
mkdir -p "$LIB_DIR"
|
|
for pat in libamdhip64 librocblas libhipblas libhipblaslt librocsolver \
|
|
libroctx64 libamd_comgr libhsa-runtime64 librocm_kpack \
|
|
librocroller librocprofiler-register; do
|
|
cp -v "$ROCM_LOCAL_PATH/lib/$pat".so* "$LIB_DIR/" 2>/dev/null || true
|
|
done
|
|
cp -v "$ROCM_LOCAL_PATH/lib/llvm/lib"/libLLVM.so* \
|
|
"$ROCM_LOCAL_PATH/lib/llvm/lib"/libclang-cpp.so* \
|
|
"$ROCM_LOCAL_PATH/lib/llvm/lib"/libomp.so* \
|
|
"$ROCM_LOCAL_PATH/lib/llvm/lib"/libomptarget.so* "$LIB_DIR/" 2>/dev/null || true
|
|
cp -v "$ROCM_LOCAL_PATH/lib/rocm_sysdeps/lib"/librocm_sysdeps_*.so* "$LIB_DIR/" 2>/dev/null || true
|
|
[[ -d "$ROCM_LOCAL_PATH/lib/rocblas/library" ]] && \
|
|
cp -r "$ROCM_LOCAL_PATH/lib/rocblas/library" "$LIB_DIR/rocblas/" 2>/dev/null || true
|
|
[[ -d "$ROCM_LOCAL_PATH/lib/hipblaslt/library" ]] && \
|
|
cp -r "$ROCM_LOCAL_PATH/lib/hipblaslt/library" "$LIB_DIR/hipblaslt/" 2>/dev/null || true
|
|
for bin in "$BUILD_DIR"/bin/llama-*; do
|
|
[[ -f "$bin" ]] && patchelf --set-rpath '$ORIGIN/../lib' "$bin"
|
|
done
|
|
else
|
|
echo "patchelf missing; run with LD_LIBRARY_PATH=$ROCM_LOCAL_PATH/lib:$ROCM_LOCAL_PATH/lib/llvm/lib" >&2
|
|
fi
|
|
|
|
echo
|
|
echo "built for $HIP_ARCH:"
|
|
"$BUILD_DIR/bin/llama-server" --version 2>&1 | head -3
|
|
ldd "$BUILD_DIR/bin/llama-server" 2>/dev/null | grep -E "not found" && exit 1 || true
|
|
echo " $BUILD_DIR/bin/llama-server"
|