File size: 4,607 Bytes
c41af55
 
7ad4cb2
 
 
 
 
c41af55
 
7ad4cb2
 
 
c41af55
7ad4cb2
 
 
2a351ad
7ad4cb2
 
 
 
c41af55
 
 
 
 
 
 
 
 
 
7ad4cb2
2a351ad
 
c41af55
7ad4cb2
 
 
 
 
 
 
2a351ad
 
7ad4cb2
c41af55
2a351ad
 
c41af55
7ad4cb2
c41af55
 
7ad4cb2
c41af55
7ad4cb2
 
 
 
c41af55
 
7ad4cb2
2a351ad
 
c41af55
7ad4cb2
 
 
2a351ad
7ad4cb2
 
 
 
f2e829c
7ad4cb2
c41af55
 
7ad4cb2
2a351ad
 
c41af55
7ad4cb2
 
 
 
 
c41af55
7ad4cb2
 
 
 
c41af55
7ad4cb2
2a351ad
aa11c99
7ad4cb2
aa11c99
2a351ad
7ad4cb2
aa11c99
7ad4cb2
 
 
 
 
 
aa11c99
 
 
c41af55
2a351ad
7ad4cb2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env bash
# =============================================================================
# DeepSeek-Math-V2 โ†’ GGUF Q8_0 conversion pipeline
#
# Uses the HF Storage Bucket mounted at /data as persistent disk.
# All large files (FP8 shards, BF16 shards, GGUF) live on /data โ€” the
# ephemeral overlay disk is never used for model data.
#
# Steps:
#   1. Stream: download FP8 shard โ†’ cast BF16 โ†’ save to /data/bf16 โ†’ delete FP8
#   2. Convert: /data/bf16 โ†’ Q8_0 GGUF โ†’ /data/output/
#   3. (Optional) upload GGUF to a separate HF repo
#
# Space Variables to set:
#   HF_TOKEN          โ€“ HuggingFace token (Secret)
#   HF_DATASET_REPO   โ€“ source/dest dataset repo e.g. memmywinks/DeepSeek_Math_V2
#
# Skip flags (set to 1 to skip a step):
#   SKIP_CAST=1       BF16 shards already in /data/bf16
#   SKIP_CONVERT=1    GGUF already exists
#   SKIP_UPLOAD=1     skip final upload (default: 1, upload manually if needed)
# =============================================================================

set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
log()  { echo -e "${BLUE}[$(date '+%H:%M:%S')] $*${NC}"; }
ok()   { echo -e "${GREEN}[$(date '+%H:%M:%S')] โœ” $*${NC}"; }
warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')] โš  $*${NC}"; }
err()  { echo -e "${RED}[$(date '+%H:%M:%S')] โœ˜ $*${NC}" >&2; exit 1; }

# โ”€โ”€ Paths โ€” all under /data (the bucket mount) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
SRC_REPO="${SRC_REPO:-deepseek-ai/DeepSeek-Math-V2}"
HF_DATASET_REPO="${HF_DATASET_REPO:-}"
LLAMA_CPP_DIR="${LLAMA_CPP_DIR:-/opt/llama.cpp}"

DATA_DIR="${DATA_DIR:-/data}"
FP8_DIR="${FP8_DIR:-$DATA_DIR/fp8}"          # temp FP8 shard (deleted after cast)
BF16_DIR="${BF16_DIR:-$DATA_DIR/bf16}"        # BF16 shards (persisted on bucket)
GGUF_Q8="${GGUF_Q8:-$DATA_DIR/output/deepseek-math-v2-q8_0.gguf}"
SCRATCH_DIR="${SCRATCH_DIR:-$DATA_DIR/scratch}"

SKIP_CAST="${SKIP_CAST:-0}"
SKIP_CONVERT="${SKIP_CONVERT:-0}"
SKIP_UPLOAD="${SKIP_UPLOAD:-1}"

[[ -z "$HF_DATASET_REPO" ]] && err "HF_DATASET_REPO is not set."
[[ -z "${HF_TOKEN:-}" ]]    && warn "HF_TOKEN not set"

mkdir -p "$FP8_DIR" "$BF16_DIR" "$SCRATCH_DIR" "$(dirname "$GGUF_Q8")"

log "========================================================"
log " DeepSeek-Math-V2 โ†’ GGUF Q8_0"
log "========================================================"
log "Source   : $SRC_REPO"
log "BF16 dir : $BF16_DIR   (on bucket)"
log "Output   : $GGUF_Q8    (on bucket)"
log "Disk (/data): $(df -h "$DATA_DIR" | tail -1)"
log ""

# โ”€โ”€ Step 1: stream FP8 โ†’ BF16, save to bucket โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
if [[ "$SKIP_CAST" == "1" ]]; then
    warn "Step 1 skipped (SKIP_CAST=1)"
else
    log "Step 1/3 โ€“ Streaming cast โ†’ saving BF16 shards to $BF16_DIR"
    log "Each shard: download (~4 GB FP8) โ†’ cast โ†’ save (~9 GB BF16) โ†’ delete FP8"

    python3 /workspace/scripts/streaming_cast.py \
        --src-repo   "$SRC_REPO" \
        --dst-repo   "$HF_DATASET_REPO" \
        --bf16-dir   "$BF16_DIR" \
        --work-dir   "$SCRATCH_DIR" \
        --resume
    ok "All BF16 shards saved to $BF16_DIR"
fi

# โ”€โ”€ Step 2: BF16 dir (on bucket) โ†’ Q8_0 GGUF โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
if [[ "$SKIP_CONVERT" == "1" ]]; then
    warn "Step 2 skipped (SKIP_CONVERT=1)"
else
    log "Step 2/3 โ€“ Converting $BF16_DIR โ†’ Q8_0 GGUF"
    [[ -d "$BF16_DIR" ]] || err "BF16 dir not found at $BF16_DIR"

    CONVERT_SCRIPT="$LLAMA_CPP_DIR/convert_hf_to_gguf.py"
    [[ -f "$CONVERT_SCRIPT" ]] || err "convert_hf_to_gguf.py not found at $CONVERT_SCRIPT"

    python3 "$CONVERT_SCRIPT" \
        "$BF16_DIR" \
        --outtype q8_0 \
        --outfile "$GGUF_Q8"

    ok "GGUF written โ†’ $GGUF_Q8  ($(du -sh "$GGUF_Q8" | cut -f1))"
fi

# โ”€โ”€ Step 3: upload GGUF to HF (optional โ€” it's already on the bucket) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
if [[ "$SKIP_UPLOAD" == "1" ]]; then
    warn "Step 3 skipped (SKIP_UPLOAD=1)"
    log "GGUF is at $GGUF_Q8 on your bucket โ€” accessible via HF dataset repo"
else
    log "Step 3/3 โ€“ Uploading GGUF to $HF_DATASET_REPO..."
    huggingface-cli upload-large-folder \
        "$HF_DATASET_REPO" \
        "$(dirname "$GGUF_Q8")" \
        --repo-type dataset \
        --include "*.gguf"
    ok "Upload complete โ†’ https://huggingface.co/datasets/$HF_DATASET_REPO"
fi

log ""
ok " Pipeline complete!"
echo "GGUF location: $GGUF_Q8"