Adds Hugging Face download targets for the Q2, Q4_K, and native FP8 artifacts. Co-authored-by: esvhd <7330385+esvhd@users.noreply.github.com>
399 lines
12 KiB
Bash
Executable File
399 lines
12 KiB
Bash
Executable File
#!/bin/sh
|
|
set -e
|
|
|
|
GLM_UNSLOTH_REPO="unsloth/GLM-5.2-GGUF"
|
|
GLM_ANTIREZ_REPO="antirez/GLM-5.2-GGUF"
|
|
GLM_53_FLASH_ANTIREZ_REPO="antirez/glm-5.3-flash-gguf"
|
|
REPO="antirez/deepseek-v4-gguf"
|
|
DS4F_Q2_FILE="DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix-0731.gguf"
|
|
DS4F_Q4_FILE="DeepSeek-V4-Flash-Q4KExperts-F16HC-F16Compressor-F16Indexer-Q8Attn-Q8Shared-Q8Out-chat-v2-imatrix-0731.gguf"
|
|
DS4F_MXFP4_FILE="DeepSeek-V4-Flash-MXFP4Experts-F16HC-F16Compressor-F16Indexer-Q8Attn-Q8Shared-Q8Out-chat-v2-mxfp4-0731.gguf"
|
|
DS4F_Q2_Q4_FILE="DeepSeek-V4-Flash-Layers37-42Q4KExperts-OtherExpertLayersIQ2XXSGateUp-Q2KDown-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix-fixed-0731.gguf"
|
|
PRO_Q2_IMATRIX_FILE="DeepSeek-V4-Pro-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-Instruct-imatrix-0813.gguf"
|
|
PRO_Q4_LAYERS00_30_FILE="DeepSeek-V4-Pro-Q4K-Layers00-30.gguf"
|
|
PRO_Q4_LAYERS31_OUTPUT_FILE="DeepSeek-V4-Pro-Q4K-Layers-31-output.gguf"
|
|
DS4F_DSPARK_FILE="DeepSeek-V4-Flash-DSpark-support-0731.gguf"
|
|
GLM_UNSLOTH_Q4_REMOTE_BASE="UD-Q4_K_XL/GLM-5.2-UD-Q4_K_XL"
|
|
GLM_UNSLOTH_Q4_LOCAL_BASE="GLM-5.2-UD-Q4_K_XL"
|
|
GLM_UNSLOTH_Q4_FIRST_FILE="$GLM_UNSLOTH_Q4_LOCAL_BASE-00001-of-00011.gguf"
|
|
GLM_ANTIREZ_IQ2XXS_FILE="GLM-5.2-UD-IQ2_XXS_RoutedIQ2XXS_blk78Q2K.gguf"
|
|
GLM_ANTIREZ_Q2_FILE="GLM-5.2-UD-Q2_K_RoutedQ2K.gguf"
|
|
GLM_ANTIREZ_Q4_FILE="GLM-5.2-UD-Q4_K_RoutedQ4K.gguf"
|
|
GLM_53_FLASH_ANTIREZ_Q2_FILE="GLM-5.3-Flash-Q2.gguf"
|
|
GLM_53_FLASH_ANTIREZ_FP8_FILE="GLM-5.3-Flash-FP8.gguf"
|
|
GLM_53_FLASH_ANTIREZ_Q4_FILE="GLM-5.3-Flash-Q4_K.gguf"
|
|
|
|
ROOT=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
OUT_DIR=${DS4_GGUF_DIR:-"$ROOT/gguf"}
|
|
case "$OUT_DIR" in
|
|
/*) ;;
|
|
*) OUT_DIR="$ROOT/$OUT_DIR" ;;
|
|
esac
|
|
TOKEN=${HF_TOKEN:-}
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
DwarfStar GGUF downloader
|
|
|
|
Usage:
|
|
./download_model.sh ds4f-q2 [--token TOKEN]
|
|
./download_model.sh ds4f-q2-q4 [--token TOKEN]
|
|
./download_model.sh ds4f-q4 [--token TOKEN]
|
|
./download_model.sh ds4f-mxfp4 [--token TOKEN]
|
|
./download_model.sh ds4f-dspark [--token TOKEN]
|
|
./download_model.sh pro-q2-imatrix [--token TOKEN]
|
|
./download_model.sh pro-q4-layers00-30 [--token TOKEN]
|
|
./download_model.sh pro-q4-layers31-output [--token TOKEN]
|
|
./download_model.sh pro-q4-split [--token TOKEN]
|
|
./download_model.sh glm-unsloth-q4 [--token TOKEN]
|
|
./download_model.sh glm-antirez-iq2xxs [--token TOKEN]
|
|
./download_model.sh glm-antirez-q2 [--token TOKEN]
|
|
./download_model.sh glm-antirez-q4 [--token TOKEN]
|
|
./download_model.sh glm-53-flash-antirez-fp8 [--token TOKEN]
|
|
./download_model.sh glm-53-flash-antirez-q2 [--token TOKEN]
|
|
./download_model.sh glm-53-flash-antirez-q4 [--token TOKEN]
|
|
|
|
Targets:
|
|
|
|
ds4f-q2
|
|
2-bit routed experts, about 81 GB on disk.
|
|
Recommended model for 96 and 128 GB RAM machines.
|
|
|
|
ds4f-q2-q4
|
|
Mixed Flash quant: mostly q2 routed experts, with the last 6 layers
|
|
using q4 routed experts. About 98 GB on disk. Good for higher
|
|
quality inference for 128 GB MacBooks. Works on DGX Spark but loading
|
|
may struggle compared to ds4f-q2.
|
|
|
|
ds4f-q4
|
|
4-bit routed experts, about 153 GB on disk.
|
|
Recommended model for machines with 256 GB RAM or more.
|
|
|
|
ds4f-mxfp4
|
|
Native DeepSeek V4 Flash MXFP4 routed experts, about 156 GB on disk.
|
|
Supported by Metal and CUDA; Blackwell uses FP4 tensor cores for batched
|
|
expert work, while CUDA decode keeps Q8 activations.
|
|
|
|
ds4f-dspark
|
|
Optional DSpark speculative decoding support GGUF for Flash 0731, about
|
|
6 GB. Enable it with --dspark and --mtp when running ds4 or ds4-server.
|
|
|
|
pro-q2-imatrix
|
|
DeepSeek V4 PRO 0813 q2 imatrix quant, as a single GGUF file. About
|
|
430 GB on disk; intended for 512 GB RAM machines.
|
|
|
|
pro-q4-layers00-30
|
|
First half of the DeepSeek V4 PRO Q4 routed-expert quant, layers 0..30.
|
|
Use on the coordinator in a two-Mac-Studio distributed run. About 426 GB.
|
|
|
|
pro-q4-layers31-output
|
|
Second half of the DeepSeek V4 PRO Q4 routed-expert quant, layers
|
|
31..output. Use on the worker in a two-Mac-Studio distributed run.
|
|
About 412 GB.
|
|
|
|
pro-q4-split
|
|
Downloads both PRO Q4 split files into the download directory. About
|
|
838 GB total. This target does not update ./ds4flash.gguf.
|
|
|
|
glm-unsloth-q4
|
|
GLM 5.2 Unsloth UD-Q4_K_XL quant from unsloth/GLM-5.2-GGUF.
|
|
Downloads all 11 shards and links ./ds4flash.gguf to the first shard.
|
|
|
|
glm-antirez-iq2xxs
|
|
GLM 5.2 antirez routed IQ2_XXS GGUF from antirez/GLM-5.2-GGUF.
|
|
Includes Q2_K block 78 and is intended for reduced-memory testing.
|
|
|
|
glm-antirez-q2
|
|
GLM 5.2 antirez routed Q2_K GGUF from antirez/GLM-5.2-GGUF.
|
|
About 262 GB on disk.
|
|
|
|
glm-antirez-q4
|
|
GLM 5.2 antirez routed Q4_K GGUF from antirez/GLM-5.2-GGUF.
|
|
About 434 GB on disk.
|
|
|
|
glm-53-flash-antirez-q2
|
|
GLM 5.3-flash antirez routed Q2 GGUF from antirez/glm-5.3-flash-gguf.
|
|
About 96 GB on disk.
|
|
|
|
glm-53-flash-antirez-q4
|
|
GLM 5.3-flash antirez routed Q4_K GGUF from antirez/glm-5.3-flash-gguf.
|
|
About 191 GB on disk.
|
|
|
|
glm-53-flash-antirez-fp8
|
|
GLM 5.3-flash antirez routed FP8 GGUF from antirez/glm-5.3-flash-gguf.
|
|
About 327 GB on disk.
|
|
|
|
Options:
|
|
--token TOKEN Hugging Face token. Otherwise HF_TOKEN or the local HF token
|
|
cache is used if present.
|
|
|
|
Environment:
|
|
DS4_GGUF_DIR Directory used for downloaded GGUF files.
|
|
Default: ./gguf
|
|
|
|
After main-model downloads the script updates:
|
|
./ds4flash.gguf -> <download directory>/<selected model>
|
|
|
|
Then the default commands work:
|
|
./ds4 -p "Hello"
|
|
./ds4-server --ctx 100000
|
|
|
|
After downloading DSpark support, enable it explicitly in greedy mode:
|
|
./ds4 --dspark --mtp <download directory>/$DS4F_DSPARK_FILE --temp 0
|
|
|
|
PRO and GLM files are downloaded with the official Hugging Face downloader
|
|
because they are too large, sharded, or nested for the curl path used by the
|
|
smaller DeepSeek Flash GGUF files.
|
|
EOF
|
|
}
|
|
|
|
if [ $# -eq 0 ]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
MODEL=$1
|
|
shift
|
|
MODEL_FILES=
|
|
LINK_MODEL=1
|
|
FORCE_HF_DOWNLOAD=0
|
|
FLATTEN_DOWNLOADS=0
|
|
|
|
case "$MODEL" in
|
|
ds4f-q2) MODEL_FILE=$DS4F_Q2_FILE ;;
|
|
ds4f-q2-q4) MODEL_FILE=$DS4F_Q2_Q4_FILE ;;
|
|
ds4f-q4) MODEL_FILE=$DS4F_Q4_FILE ;;
|
|
ds4f-mxfp4) MODEL_FILE=$DS4F_MXFP4_FILE; FORCE_HF_DOWNLOAD=1 ;;
|
|
ds4f-dspark) MODEL_FILE=$DS4F_DSPARK_FILE; LINK_MODEL=0 ;;
|
|
pro-q2-imatrix) MODEL_FILE=$PRO_Q2_IMATRIX_FILE ;;
|
|
pro-q4-layers00-30) MODEL_FILE=$PRO_Q4_LAYERS00_30_FILE; LINK_MODEL=0 ;;
|
|
pro-q4-layers31-output) MODEL_FILE=$PRO_Q4_LAYERS31_OUTPUT_FILE; LINK_MODEL=0 ;;
|
|
pro-q4-split)
|
|
MODEL_FILES="$PRO_Q4_LAYERS00_30_FILE $PRO_Q4_LAYERS31_OUTPUT_FILE"
|
|
LINK_MODEL=0
|
|
;;
|
|
glm-unsloth-q4)
|
|
REPO=$GLM_UNSLOTH_REPO
|
|
MODEL_FILE=$GLM_UNSLOTH_Q4_FIRST_FILE
|
|
MODEL_FILES=
|
|
for part in 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011; do
|
|
MODEL_FILES="$MODEL_FILES $GLM_UNSLOTH_Q4_REMOTE_BASE-${part}-of-00011.gguf"
|
|
done
|
|
FORCE_HF_DOWNLOAD=1
|
|
FLATTEN_DOWNLOADS=1
|
|
;;
|
|
glm-antirez-q2)
|
|
REPO=$GLM_ANTIREZ_REPO
|
|
MODEL_FILE=$GLM_ANTIREZ_Q2_FILE
|
|
FORCE_HF_DOWNLOAD=1
|
|
;;
|
|
glm-antirez-iq2xxs)
|
|
REPO=$GLM_ANTIREZ_REPO
|
|
MODEL_FILE=$GLM_ANTIREZ_IQ2XXS_FILE
|
|
FORCE_HF_DOWNLOAD=1
|
|
;;
|
|
glm-antirez-q4)
|
|
REPO=$GLM_ANTIREZ_REPO
|
|
MODEL_FILE=$GLM_ANTIREZ_Q4_FILE
|
|
FORCE_HF_DOWNLOAD=1
|
|
;;
|
|
glm-53-flash-antirez-q2)
|
|
REPO=$GLM_53_FLASH_ANTIREZ_REPO
|
|
MODEL_FILE=$GLM_53_FLASH_ANTIREZ_Q2_FILE
|
|
FORCE_HF_DOWNLOAD=1
|
|
;;
|
|
glm-53-flash-antirez-q4)
|
|
REPO=$GLM_53_FLASH_ANTIREZ_REPO
|
|
MODEL_FILE=$GLM_53_FLASH_ANTIREZ_Q4_FILE
|
|
FORCE_HF_DOWNLOAD=1
|
|
;;
|
|
glm-53-flash-antirez-fp8)
|
|
REPO=$GLM_53_FLASH_ANTIREZ_REPO
|
|
MODEL_FILE=$GLM_53_FLASH_ANTIREZ_FP8_FILE
|
|
FORCE_HF_DOWNLOAD=1
|
|
;;
|
|
-h|--help|help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown model: $MODEL" >&2
|
|
echo >&2
|
|
usage >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--token)
|
|
shift
|
|
if [ $# -eq 0 ]; then
|
|
echo "Missing value after --token" >&2
|
|
exit 1
|
|
fi
|
|
TOKEN=$1
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ -z "$TOKEN" ] && [ -s "$HOME/.cache/huggingface/token" ]; then
|
|
TOKEN=$(cat "$HOME/.cache/huggingface/token")
|
|
fi
|
|
|
|
needs_hf_download() {
|
|
if [ "${FORCE_HF_DOWNLOAD:-0}" -eq 1 ]; then
|
|
return 0
|
|
fi
|
|
case "$1" in
|
|
"$PRO_Q2_IMATRIX_FILE"|"$PRO_Q4_LAYERS00_30_FILE"|"$PRO_Q4_LAYERS31_OUTPUT_FILE")
|
|
return 0
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
find_hf_command() {
|
|
if command -v hf >/dev/null 2>&1; then
|
|
printf '%s\n' hf
|
|
return 0
|
|
fi
|
|
for dir in "$HOME"/Library/Python/*/bin "$HOME"/.local/bin; do
|
|
if [ -x "$dir/hf" ]; then
|
|
printf '%s\n' "$dir/hf"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
local_download_name() {
|
|
if [ "${FLATTEN_DOWNLOADS:-0}" -eq 1 ]; then
|
|
basename "$1"
|
|
else
|
|
printf '%s\n' "$1"
|
|
fi
|
|
}
|
|
|
|
download_one_hf() {
|
|
file=$1
|
|
local_file=$(local_download_name "$file")
|
|
out="$OUT_DIR/$local_file"
|
|
hf_out="$OUT_DIR/$file"
|
|
part="$out.part"
|
|
|
|
mkdir -p "$(dirname "$out")"
|
|
|
|
if [ -s "$out" ]; then
|
|
echo "Already downloaded: $out"
|
|
return
|
|
fi
|
|
|
|
if [ -e "$part" ]; then
|
|
echo "Found curl partial download: $part" >&2
|
|
echo "The Hugging Face downloader cannot resume curl .part files." >&2
|
|
echo "Move or remove that partial download before retrying this target." >&2
|
|
exit 1
|
|
fi
|
|
|
|
HF_CMD=$(find_hf_command || true)
|
|
if [ -z "$HF_CMD" ]; then
|
|
echo "Large GGUF downloads require the official Hugging Face CLI." >&2
|
|
echo "Install it with:" >&2
|
|
echo " python3 -m pip install -U huggingface_hub hf_xet" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Downloading $file"
|
|
echo "from https://huggingface.co/$REPO"
|
|
echo "using $HF_CMD download"
|
|
echo "If the download stops, run the same command again to resume it."
|
|
|
|
if [ -n "$TOKEN" ]; then
|
|
"$HF_CMD" download "$REPO" "$file" --repo-type model --local-dir "$OUT_DIR" --token "$TOKEN"
|
|
else
|
|
"$HF_CMD" download "$REPO" "$file" --repo-type model --local-dir "$OUT_DIR"
|
|
fi
|
|
|
|
if [ "$hf_out" != "$out" ] && [ -s "$hf_out" ]; then
|
|
mv "$hf_out" "$out"
|
|
rmdir "$(dirname "$hf_out")" 2>/dev/null || true
|
|
fi
|
|
|
|
if [ ! -s "$out" ]; then
|
|
echo "Hugging Face download finished but expected file is missing: $out" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
download_one() {
|
|
file=$1
|
|
local_file=$(local_download_name "$file")
|
|
out="$OUT_DIR/$local_file"
|
|
part="$out.part"
|
|
aria2_part="$out.aria2"
|
|
url="https://huggingface.co/$REPO/resolve/main/$file"
|
|
|
|
if needs_hf_download "$file"; then
|
|
download_one_hf "$file"
|
|
return
|
|
fi
|
|
|
|
mkdir -p "$(dirname "$out")"
|
|
|
|
if [ -e "$aria2_part" ]; then
|
|
echo "Found incomplete aria2 download sidecar: $aria2_part" >&2
|
|
echo "Finish or remove that partial download before using this curl downloader." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ -s "$out" ]; then
|
|
echo "Already downloaded: $out"
|
|
return
|
|
fi
|
|
|
|
echo "Downloading $file"
|
|
echo "from https://huggingface.co/$REPO"
|
|
echo "If the download stops, run the same command again to resume it."
|
|
|
|
if [ -n "$TOKEN" ]; then
|
|
curl -fL --progress-meter -C - -H "Authorization: Bearer $TOKEN" -o "$part" "$url"
|
|
else
|
|
curl -fL --progress-meter -C - -o "$part" "$url"
|
|
fi
|
|
|
|
mv "$part" "$out"
|
|
}
|
|
|
|
if [ -n "$MODEL_FILES" ]; then
|
|
for file in $MODEL_FILES; do
|
|
download_one "$file"
|
|
done
|
|
else
|
|
download_one "$MODEL_FILE"
|
|
fi
|
|
|
|
if [ "$MODEL" = "ds4f-dspark" ]; then
|
|
echo
|
|
echo "DSpark support downloaded. Enable it explicitly in greedy mode:"
|
|
echo " ./ds4 --dspark -m ./ds4flash.gguf --mtp $OUT_DIR/$DS4F_DSPARK_FILE --temp 0"
|
|
elif [ "$MODEL" = "pro-q4-layers00-30" ] || [ "$MODEL" = "pro-q4-layers31-output" ] || [ "$MODEL" = "pro-q4-split" ]; then
|
|
echo
|
|
echo "Downloaded PRO Q4 distributed split file(s). Use them with --layers,"
|
|
echo "for example coordinator layers 0:30 and worker layers 31:output."
|
|
elif [ "$LINK_MODEL" -eq 1 ]; then
|
|
cd "$ROOT"
|
|
ln -sfn "$OUT_DIR/$MODEL_FILE" ds4flash.gguf
|
|
echo "Linked ./ds4flash.gguf -> $OUT_DIR/$MODEL_FILE"
|
|
fi
|
|
|
|
echo
|
|
echo "Done."
|