DSpark (Q8_0, 1.27 GiB) replaces z-lab DFlash2 (1.92 GiB): same 5-layer block-diffusion shape, Markov head instead of the candidate selector, and block_size 7, so the draft depth drops 7 -> 6 (llama.cpp asserts n_max <= block_size - 1). The serve script's dspark branch never passed --spec-draft-model (only the dflash branch did), so dspark was not deployable as written; the model file gate now covers both types. Download script, env and the unit seam track the new file and its exact byte count.
195 lines
6.8 KiB
Bash
Executable File
195 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Serve ajgazin/Swift-Qwen3.8-27B-Uncensored-Dynamic-MTP-GGUF @ UD-Q8_K_XL as
|
|
# frank-medium on Dankserver's two Radeon AI PRO R9700 (gfx1201), with the
|
|
# magnitudedev DSpark block-diffusion drafter, using mainline llama.cpp.
|
|
#
|
|
# Runtime: llama.cpp master fb27a525 (2026-09-16), a gfx1201 HIP build that
|
|
# bundles its own ROCm 7.14 runtime (RPATH $ORIGIN/../lib), produced by
|
|
# scripts/build-llama-rdna4.sh. Two features pin that ref: DFlash2
|
|
# (ggml-org/llama.cpp#27342) and qwen35 MTP. The charlie12345/ROCmFPX fork
|
|
# this deployment replaced has neither (its tip is c49ebdb, 2026-08-22).
|
|
#
|
|
# Parallelism: --split-mode layer across both cards. Tensor split would need a
|
|
# cross-card allreduce and this host cannot dispatch one -- RCCL's kernels
|
|
# require a hostcall buffer that ROCr refuses on a card without PCIe atomics,
|
|
# and the second R9700 sits behind the chipset (AtomicOpsCap: Routing-). Layer
|
|
# split crosses the wire once per forward pass instead of once per layer.
|
|
#
|
|
# The vLLM replica pair and its routing proxy were retired with this cutover:
|
|
# one process, one model, both cards.
|
|
#
|
|
# Tunables come from frank-medium.env unless FRANK_MEDIUM_ENV_FILE overrides it.
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
ENV_FILE="${FRANK_MEDIUM_ENV_FILE:-$SCRIPT_DIR/frank-medium.env}"
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "$ENV_FILE"
|
|
set +a
|
|
fi
|
|
|
|
# --- defaults (used when the env file does not set them) ------------------
|
|
: "${LLAMA_BIN:=/home/dank/GitPackages/llama.cpp-dflash2/build-rdna4-rocm714/bin/llama-server}"
|
|
: "${MODEL_DIR:=/home/dank/models/Swift-Qwen3.8-27B-Uncensored-Dynamic-MTP-GGUF}"
|
|
: "${MODEL_FILE:=Swift-Qwen3.8-27B-Uncensored-Dynamic-MTP-UD-Q8_K_XL.gguf}"
|
|
: "${DRAFT_MODEL_DIR:=/home/dank/models/Qwen3.8-27B-DFlash2-GGUF}"
|
|
: "${DRAFT_MODEL_FILE:=Qwen3.8-27B-DFlash2-Q8_0.gguf}"
|
|
: "${ALIAS:=frank-medium}"
|
|
: "${BIND_ADDR:=0.0.0.0}"
|
|
: "${LISTEN_PORT:=7770}"
|
|
|
|
# Devices. HIP_VISIBLE_DEVICES hides the Raphael iGPU (HIP device 2) so nothing
|
|
# can drift onto shared system RAM; DEVICES is what llama.cpp splits across.
|
|
: "${HIP_VISIBLE_DEVICES:=0,1}"
|
|
: "${DEVICES:=ROCm0,ROCm1}"
|
|
: "${SPLIT_MODE:=layer}"
|
|
: "${TENSOR_SPLIT:=1,1}"
|
|
: "${NGL:=999}"
|
|
: "${FIT:=off}"
|
|
: "${FLASH_ATTN:=on}"
|
|
|
|
: "${CTX_SIZE:=131072}"
|
|
: "${PARALLEL:=1}"
|
|
: "${BATCH_SIZE:=2048}"
|
|
: "${UBATCH_SIZE:=512}"
|
|
: "${NUM_THREADS:=8}"
|
|
: "${THREAD_BATCH:=8}"
|
|
: "${CACHE_TYPE_K:=f16}"
|
|
: "${CACHE_TYPE_V:=f16}"
|
|
: "${CTX_CHECKPOINTS:=8}"
|
|
: "${CACHE_RAM:=8192}"
|
|
|
|
# Sampling defaults for silent clients: the values the vLLM predecessor served.
|
|
: "${TEMPERATURE:=0.7}"
|
|
: "${TOP_P:=0.95}"
|
|
: "${TOP_K:=20}"
|
|
: "${MIN_P:=0.0}"
|
|
: "${PRESENCE_PENALTY:=0.0}"
|
|
|
|
: "${REASONING:=on}"
|
|
: "${REASONING_FORMAT:=deepseek}"
|
|
: "${REASONING_BUDGET:=-1}"
|
|
: "${CHAT_TEMPLATE_FILE:=}"
|
|
: "${CHAT_TEMPLATE_KWARGS:={\"enable_thinking\":true,\"preserve_thinking\":true}}"
|
|
|
|
# Speculative decoding: draft-dflash (the DFlash2 drafter is a file, not a
|
|
# flag) or draft-mtp (the target GGUF's own MTP head -- no draft file).
|
|
: "${SPEC_TYPE:=draft-dflash}"
|
|
: "${SPEC_DRAFT_N_MAX:=7}"
|
|
: "${SPEC_DRAFT_N_MIN:=0}"
|
|
: "${SPEC_DRAFT_P_MIN:=0.0}"
|
|
: "${SPEC_DRAFT_P_SPLIT:=0.10}"
|
|
: "${SPEC_DRAFT_NGL:=999}"
|
|
: "${SPEC_DRAFT_DEVICE:=}"
|
|
: "${SPEC_DRAFT_TYPE_K:=f16}"
|
|
: "${SPEC_DRAFT_TYPE_V:=f16}"
|
|
: "${SPEC_DRAFT_POLL:=1}"
|
|
: "${SPEC_DRAFT_POLL_BATCH:=1}"
|
|
: "${SPEC_NGRAM_N_MATCH:=24}"
|
|
: "${SPEC_NGRAM_N_MIN:=48}"
|
|
: "${SPEC_NGRAM_N_MAX:=64}"
|
|
|
|
NO_MMPROJ="${NO_MMPROJ:-1}"
|
|
|
|
export HIP_VISIBLE_DEVICES
|
|
|
|
MODEL="$MODEL_DIR/$MODEL_FILE"
|
|
DRAFT_MODEL="$DRAFT_MODEL_DIR/$DRAFT_MODEL_FILE"
|
|
|
|
if [[ ! -x "$LLAMA_BIN" ]]; then
|
|
echo "missing executable runtime: $LLAMA_BIN" >&2
|
|
echo "build it with: bash $SCRIPT_DIR/build-llama-rdna4.sh" >&2
|
|
exit 1
|
|
fi
|
|
if [[ ! -r "$MODEL" ]]; then
|
|
echo "missing or unreadable target model: $MODEL" >&2
|
|
echo "fetch it with: bash $SCRIPT_DIR/download-frank-medium-gguf.sh" >&2
|
|
exit 1
|
|
fi
|
|
if [[ -n "$CHAT_TEMPLATE_FILE" && ! -r "$CHAT_TEMPLATE_FILE" ]]; then
|
|
echo "missing or unreadable chat template: $CHAT_TEMPLATE_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- speculative decoding -------------------------------------------------
|
|
SPEC_ARGS=()
|
|
if [[ -n "$SPEC_TYPE" && "$SPEC_TYPE" != "none" ]]; then
|
|
SPEC_ARGS=(--spec-type "$SPEC_TYPE" --spec-draft-n-max "$SPEC_DRAFT_N_MAX")
|
|
if [[ "$SPEC_TYPE" == *dflash* || "$SPEC_TYPE" == *dspark* ]]; then
|
|
if [[ ! -r "$DRAFT_MODEL" ]]; then
|
|
echo "missing or unreadable draft model: $DRAFT_MODEL" >&2
|
|
exit 1
|
|
fi
|
|
SPEC_ARGS+=(
|
|
--spec-draft-model "$DRAFT_MODEL"
|
|
--spec-draft-ngl "$SPEC_DRAFT_NGL"
|
|
--spec-draft-type-k "$SPEC_DRAFT_TYPE_K"
|
|
--spec-draft-type-v "$SPEC_DRAFT_TYPE_V"
|
|
)
|
|
fi
|
|
if [[ "$SPEC_TYPE" == *dspark* || ( "$SPEC_DRAFT_P_MIN" != "0.0" && "$SPEC_DRAFT_P_MIN" != "0" ) ]]; then
|
|
SPEC_ARGS+=(--spec-draft-n-min "$SPEC_DRAFT_N_MIN" --spec-draft-p-min "$SPEC_DRAFT_P_MIN")
|
|
fi
|
|
# ngram-mod is draftless: it needs no draft context and its window is its
|
|
# own (--spec-ngram-mod-*), so it can ride in the chain beside a model
|
|
# drafter. It also costs no VRAM -- a CPU hash table.
|
|
if [[ "$SPEC_TYPE" == *ngram* ]]; then
|
|
SPEC_ARGS+=(
|
|
--spec-ngram-mod-n-match "$SPEC_NGRAM_N_MATCH"
|
|
--spec-ngram-mod-n-min "$SPEC_NGRAM_N_MIN"
|
|
--spec-ngram-mod-n-max "$SPEC_NGRAM_N_MAX"
|
|
)
|
|
fi
|
|
if [[ -n "$SPEC_DRAFT_DEVICE" ]]; then
|
|
SPEC_ARGS+=(--spec-draft-device "$SPEC_DRAFT_DEVICE")
|
|
fi
|
|
fi
|
|
|
|
# --- template + placement -------------------------------------------------
|
|
TEMPLATE_ARGS=()
|
|
if [[ -n "$CHAT_TEMPLATE_FILE" ]]; then
|
|
TEMPLATE_ARGS+=(--chat-template-file "$CHAT_TEMPLATE_FILE")
|
|
fi
|
|
TEMPLATE_ARGS+=(--chat-template-kwargs "$CHAT_TEMPLATE_KWARGS")
|
|
|
|
PLACEMENT_ARGS=(--device "$DEVICES" --split-mode "$SPLIT_MODE" --tensor-split "$TENSOR_SPLIT")
|
|
|
|
MMPROJ_ARGS=()
|
|
[[ "$NO_MMPROJ" == "1" ]] && MMPROJ_ARGS=(--no-mmproj)
|
|
|
|
exec "$LLAMA_BIN" \
|
|
--model "$MODEL" \
|
|
--alias "$ALIAS" \
|
|
--host "$BIND_ADDR" \
|
|
--port "$LISTEN_PORT" \
|
|
--jinja \
|
|
--gpu-layers "$NGL" \
|
|
--fit "$FIT" \
|
|
--parallel "$PARALLEL" \
|
|
--ctx-size "$CTX_SIZE" \
|
|
--batch-size "$BATCH_SIZE" \
|
|
--ubatch-size "$UBATCH_SIZE" \
|
|
--flash-attn "$FLASH_ATTN" \
|
|
--cache-type-k "$CACHE_TYPE_K" \
|
|
--cache-type-v "$CACHE_TYPE_V" \
|
|
--threads "$NUM_THREADS" \
|
|
--threads-batch "$THREAD_BATCH" \
|
|
--ctx-checkpoints "$CTX_CHECKPOINTS" \
|
|
--cache-ram "$CACHE_RAM" \
|
|
--cache-prompt \
|
|
--metrics \
|
|
--temp "$TEMPERATURE" \
|
|
--top-p "$TOP_P" \
|
|
--top-k "$TOP_K" \
|
|
--min-p "$MIN_P" \
|
|
--presence-penalty "$PRESENCE_PENALTY" \
|
|
--reasoning "$REASONING" \
|
|
--reasoning-format "$REASONING_FORMAT" \
|
|
--reasoning-budget "$REASONING_BUDGET" \
|
|
"${TEMPLATE_ARGS[@]}" \
|
|
"${PLACEMENT_ARGS[@]}" \
|
|
"${MMPROJ_ARGS[@]}" \
|
|
"${SPEC_ARGS[@]}"
|