| #!/usr/bin/env bash |
|
|
| set -euo pipefail |
|
|
| recipes=( |
| " |
| MIX=Q5_K |
| TYPE_FFN_GATE_UP_EXPS=IQ3_S |
| TYPE_FFN_DOWN_EXPS=Q5_K |
| TYPE_DEFAULT=Q8_0 |
| " |
|
|
| " |
| MIX=Q4_K |
| TYPE_FFN_GATE_UP_EXPS=IQ3_S |
| TYPE_FFN_DOWN_EXPS=Q4_K |
| TYPE_DEFAULT=Q8_0 |
| " |
| ) |
|
|
| |
| if [ $# -lt 2 ] || [ $# -gt 3 ]; then |
| echo "Error: Exactly 2 arguments required (plus optional --dry-run)." |
| echo "Usage: $0 <llama_cpp_dir> <quant_type> [--dry-run]" |
| echo "Example: $0 ~/code/llama.cpp IQ4_XS" |
| echo "Example: $0 ~/code/llama.cpp IQ4_XS --dry-run" |
| exit 1 |
| fi |
|
|
| |
| LLAMA_CPP_DIR="$1" |
| QUANT_TYPE="$2" |
|
|
| |
| DRY_RUN=false |
| if [ $# -eq 3 ]; then |
| if [ "$3" != "--dry-run" ]; then |
| echo "Error: Unexpected third argument: $3" |
| echo "Usage: $0 <llama_cpp_dir> <quant_type> [--dry-run]" |
| exit 1 |
| fi |
| DRY_RUN=true |
| fi |
|
|
| |
| if [ ! -d "$LLAMA_CPP_DIR" ]; then |
| echo "Error: llama.cpp directory not found: $LLAMA_CPP_DIR" |
| exit 1 |
| fi |
|
|
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| PROJECT_DIR="$(cd $SCRIPT_DIR/.. && pwd)" |
|
|
| |
| BF16_DIR="$PROJECT_DIR/BF16" |
| if [ ! -d "$BF16_DIR" ]; then |
| echo "Error: BF16 directory not found: $BF16_DIR" |
| exit 1 |
| fi |
|
|
| |
| |
| |
| INPUT_GGUF=$(find "$BF16_DIR" -maxdepth 1 -name "*BF16*.gguf" -type f | sort | head -n 1) |
|
|
| if [ -z "$INPUT_GGUF" ]; then |
| echo "Error: No BF16 GGUF files found in $BF16_DIR" |
| echo "Expected pattern: *BF16*.gguf" |
| exit 1 |
| fi |
|
|
| echo "Found input file: $INPUT_GGUF" |
|
|
| |
| |
| MODEL_NAME=$(basename "$INPUT_GGUF" | sed 's/-BF16.*\.gguf//') |
|
|
| |
| IMATRIX_PATH="$PROJECT_DIR/imatrix.gguf" |
| if [ ! -e "$IMATRIX_PATH" ]; then |
| echo "Error: imatrix file not found: $IMATRIX_PATH" |
| echo "Please generate imatrix.gguf before running quantization." |
| exit 1 |
| fi |
|
|
| |
| QUANTIZE_BIN="$LLAMA_CPP_DIR/build/bin/llama-quantize" |
| SPLIT_BIN="$LLAMA_CPP_DIR/build/bin/llama-gguf-split" |
|
|
| if [ ! -x "$QUANTIZE_BIN" ]; then |
| echo "Error: llama-quantize binary not found: $QUANTIZE_BIN" |
| exit 1 |
| fi |
|
|
| if [ ! -x "$SPLIT_BIN" ]; then |
| echo "Error: llama-gguf-split binary not found: $SPLIT_BIN" |
| exit 1 |
| fi |
|
|
| |
| INTERMEDIATE_OUTPUT="$PROJECT_DIR/${MODEL_NAME}-${QUANT_TYPE}.gguf" |
|
|
| |
| |
| if [ "$DRY_RUN" = false ] && [ -e "$INTERMEDIATE_OUTPUT" ]; then |
| echo "Error: Intermediate output already exists: $INTERMEDIATE_OUTPUT" |
| exit 1 |
| fi |
|
|
| echo "Starting quantization..." |
|
|
| |
| DRY_RUN_ARG="" |
| if [ "$DRY_RUN" = true ]; then |
| DRY_RUN_ARG="--dry-run" |
| fi |
|
|
| |
| for recipe in "${recipes[@]}"; do |
| MIX= |
| TYPE_FFN_GATE_UP_EXPS= |
| TYPE_FFN_DOWN_EXPS= |
| TYPE_TOKEN_EMBEDDING= |
| TYPE_OUTPUT= |
| TYPE_DEFAULT= |
|
|
| eval "$recipe" |
|
|
| if [ "$MIX" != "$QUANT_TYPE" ]; then |
| continue |
| fi |
|
|
| if [ -z "${TYPE_DEFAULT}" ]; then |
| echo "TYPE_DEFAULT not defined for recipe $MIX!" >&2 |
| exit 1 |
| fi |
|
|
| TYPE_ARGS=() |
|
|
| if [ -n "${TYPE_FFN_GATE_UP_EXPS:-}" ]; then |
| TYPE_ARGS+=( |
| "--tensor-type" "ffn_gate_up_exps=${TYPE_FFN_GATE_UP_EXPS}" |
| "--tensor-type" "ffn_gate_exps=${TYPE_FFN_GATE_UP_EXPS}" |
| "--tensor-type" "ffn_up_exps=${TYPE_FFN_GATE_UP_EXPS}" |
| ) |
| fi |
|
|
| if [ -n "${TYPE_FFN_DOWN_EXPS:-}" ]; then |
| TYPE_ARGS+=("--tensor-type" "ffn_down_exps=${TYPE_FFN_DOWN_EXPS}") |
| fi |
|
|
| if [ -n "${TYPE_OUTPUT:-}" ]; then |
| TYPE_ARGS+=("--output-tensor-type" "${TYPE_OUTPUT}") |
| fi |
|
|
| if [ -n "${TYPE_TOKEN_EMBEDDING:-}" ]; then |
| TYPE_ARGS+=("--token-embedding-type" "${TYPE_TOKEN_EMBEDDING}") |
| fi |
|
|
| "$QUANTIZE_BIN" \ |
| $DRY_RUN_ARG \ |
| "${TYPE_ARGS[@]}" \ |
| --imatrix "$IMATRIX_PATH" \ |
| "$INPUT_GGUF" \ |
| "$INTERMEDIATE_OUTPUT" \ |
| $TYPE_DEFAULT |
|
|
| if [ "$DRY_RUN" = false ]; then |
| echo "Starting split..." |
| OUTPUT_DIR="${PROJECT_DIR}/$QUANT_TYPE" |
| mkdir -p $OUTPUT_DIR |
|
|
| OUTPUT_PREFIX="${OUTPUT_DIR}/${MODEL_NAME}-${QUANT_TYPE}" |
|
|
| |
| "$SPLIT_BIN" \ |
| --split-max-size 42G \ |
| --no-tensor-first-split \ |
| "$INTERMEDIATE_OUTPUT" \ |
| "$OUTPUT_PREFIX" |
|
|
| |
| rm -f "$INTERMEDIATE_OUTPUT" |
|
|
| echo "Quantization complete. Output saved to: $OUTPUT_DIR" |
| fi |
|
|
| exit 0 |
| done |
|
|
| echo "Quantization recipe $QUANT_TYPE not found!" >&2 |
| exit 1 |
|
|