Prepare isolated Qwen3.8 IQ4_XS A/B tests
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
# Qwen3.8 September 2026 A/B preparation
|
||||||
|
|
||||||
|
This directory prepares an isolated comparison of two Qwen3.8-27B IQ4_XS
|
||||||
|
artifacts without adding router profiles or changing the running Athena stack.
|
||||||
|
|
||||||
|
## Candidates
|
||||||
|
|
||||||
|
| ID | Artifact | Purpose | Pinned revision | Size |
|
||||||
|
| --- | --- | --- | --- | ---: |
|
||||||
|
| `qwopus` | `Jackrong/Qwopus3.8-27B-Flash-GGUF` / `Qwopus3.8-27B-Flash-MTP-IQ4_XS.gguf` | Efficiency fine-tune | `e146d61e88782677805b3b68ad3adf8674dde80d` | 15,420,445,792 B |
|
||||||
|
| `bartowski` | `bartowski/Qwen3.8-27B-GGUF` / `Qwen3.8-27B-IQ4_XS.gguf` | Standard Qwen, alternative IQ4_XS quant | `f0eec4a4bb4975114a030d048952d83c0a53c034` | 15,567,824,480 B |
|
||||||
|
|
||||||
|
The production reference remains
|
||||||
|
`jpetrina/Qwen3.8-27B-IQ4_XS-pure-GGUF`. The candidates intentionally use the
|
||||||
|
same IQ4_XS quantization class so that the first comparison does not mix a
|
||||||
|
fine-tune difference with a quantization-class difference.
|
||||||
|
|
||||||
|
## Safety boundary
|
||||||
|
|
||||||
|
- Nothing in this directory is called by installation, Compose or the router.
|
||||||
|
- No production profile is added.
|
||||||
|
- Downloads happen only after explicitly running `download-candidate.sh`.
|
||||||
|
- `run-case.sh` refuses to start while a production `mike-ai-llama-*` model is
|
||||||
|
running. It never stops production itself.
|
||||||
|
- The test server binds to `127.0.0.1:5005` and is not exposed to the LAN.
|
||||||
|
- Cleanup is a dry run unless an explicit deletion flag is supplied. It only
|
||||||
|
addresses the exact test container, result directory and two pinned files.
|
||||||
|
|
||||||
|
## Later test sequence
|
||||||
|
|
||||||
|
Run these commands on Athena only after the active coding task has finished and
|
||||||
|
the GPUs have deliberately been released:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /opt/mike-ai/stack/experiments/qwen38-20260907-ab
|
||||||
|
./inventory.sh
|
||||||
|
./download-candidate.sh qwopus
|
||||||
|
./download-candidate.sh bartowski
|
||||||
|
|
||||||
|
./run-case.sh qwopus 160000 85,15
|
||||||
|
./wait-ready.sh
|
||||||
|
./run-benchmark.sh qwopus-160k
|
||||||
|
./stop-case.sh
|
||||||
|
|
||||||
|
./run-case.sh bartowski 160000 85,15
|
||||||
|
./wait-ready.sh
|
||||||
|
./run-benchmark.sh bartowski-160k
|
||||||
|
./stop-case.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Only after both candidates pass the 160K quality and tool-call tests should
|
||||||
|
192K and 262144 be attempted. Promotion into the router is a separate decision
|
||||||
|
and is deliberately not implemented here.
|
||||||
|
|
||||||
|
## Cleanup
|
||||||
|
|
||||||
|
Preview everything owned by this experiment:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./cleanup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove only the test container and benchmark results:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./cleanup.sh --results
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove only the two downloaded candidate files and their now-empty directory:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./cleanup.sh --models
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove both:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./cleanup.sh --all
|
||||||
|
```
|
||||||
|
|
||||||
|
The script never touches the production Pure, Mix, Beta 1 or uncensored model
|
||||||
|
directories.
|
||||||
Executable
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
candidate_config() {
|
||||||
|
case "${1:-}" in
|
||||||
|
qwopus)
|
||||||
|
CANDIDATE_ID=qwopus
|
||||||
|
REPOSITORY=Jackrong/Qwopus3.8-27B-Flash-GGUF
|
||||||
|
REVISION=e146d61e88782677805b3b68ad3adf8674dde80d
|
||||||
|
MODEL_FILE=Qwopus3.8-27B-Flash-MTP-IQ4_XS.gguf
|
||||||
|
MODEL_SHA256=88848920fd069ecfe509afd60d4b1f2192327f1edde5e10491a48f7f80c16fb8
|
||||||
|
MODEL_SIZE=15420445792
|
||||||
|
MODEL_ALIAS=qwen-qwopus-flash-ab
|
||||||
|
;;
|
||||||
|
bartowski)
|
||||||
|
CANDIDATE_ID=bartowski
|
||||||
|
REPOSITORY=bartowski/Qwen3.8-27B-GGUF
|
||||||
|
REVISION=f0eec4a4bb4975114a030d048952d83c0a53c034
|
||||||
|
MODEL_FILE=Qwen3.8-27B-IQ4_XS.gguf
|
||||||
|
MODEL_SHA256=c2ae2b018f967370087c196c86d6811b2340ec19138a3752252ade5fbd1f4786
|
||||||
|
MODEL_SIZE=15567824480
|
||||||
|
MODEL_ALIAS=qwen-bartowski-iq4-xs-ab
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Candidate must be qwopus or bartowski" >&2
|
||||||
|
return 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
MODEL_ROOT=${MODEL_ROOT:-/data/models/experiments/qwen38-ab-20260907}
|
||||||
|
MODEL_PATH="$MODEL_ROOT/$CANDIDATE_ID/$MODEL_FILE"
|
||||||
|
MODEL_URL="https://huggingface.co/$REPOSITORY/resolve/$REVISION/$MODEL_FILE"
|
||||||
|
}
|
||||||
Executable
+42
@@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
MODE=${1:-preview}
|
||||||
|
MODEL_ROOT=${MODEL_ROOT:-/data/models/experiments/qwen38-ab-20260907}
|
||||||
|
RESULT_DIR=${RESULT_DIR:-/data/benchmarks/qwen38-ab-20260907}
|
||||||
|
NAME=mike-ai-llama-qwen38-ab
|
||||||
|
|
||||||
|
QWOPUS="$MODEL_ROOT/qwopus/Qwopus3.8-27B-Flash-MTP-IQ4_XS.gguf"
|
||||||
|
BARTOWSKI="$MODEL_ROOT/bartowski/Qwen3.8-27B-IQ4_XS.gguf"
|
||||||
|
|
||||||
|
case "$MODE" in
|
||||||
|
preview)
|
||||||
|
echo "Dry run only. Exact owned targets:"
|
||||||
|
printf ' container: %s\n results: %s\n model: %s\n model: %s\n' \
|
||||||
|
"$NAME" "$RESULT_DIR" "$QWOPUS" "$BARTOWSKI"
|
||||||
|
echo "Use --results, --models or --all to delete these exact targets."
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--results|--models|--all) ;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 [--results|--models|--all]" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
docker rm -f "$NAME" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
if [[ $MODE == --results || $MODE == --all ]]; then
|
||||||
|
if [[ -d $RESULT_DIR ]]; then
|
||||||
|
find "$RESULT_DIR" -maxdepth 1 -type f -name '*.json' -delete
|
||||||
|
rmdir "$RESULT_DIR" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $MODE == --models || $MODE == --all ]]; then
|
||||||
|
rm -f -- "$QWOPUS" "$QWOPUS.part" "$BARTOWSKI" "$BARTOWSKI.part"
|
||||||
|
rmdir "$MODEL_ROOT/qwopus" "$MODEL_ROOT/bartowski" 2>/dev/null || true
|
||||||
|
rmdir "$MODEL_ROOT" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cleanup complete for mode $MODE. No production model path was addressed."
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck source=candidates.sh
|
||||||
|
source "$SCRIPT_DIR/candidates.sh"
|
||||||
|
candidate_config "${1:-}"
|
||||||
|
|
||||||
|
target_dir="$MODEL_ROOT/$CANDIDATE_ID"
|
||||||
|
target="$target_dir/$MODEL_FILE"
|
||||||
|
partial="$target.part"
|
||||||
|
|
||||||
|
install -d -m 0755 "$target_dir"
|
||||||
|
|
||||||
|
if [[ -s $target ]]; then
|
||||||
|
printf '%s %s\n' "$MODEL_SHA256" "$target" | sha256sum -c -
|
||||||
|
echo "Already prepared: $target"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Downloading pinned $CANDIDATE_ID artifact ($MODEL_SIZE bytes)"
|
||||||
|
curl --fail --location --retry 8 --retry-delay 5 --continue-at - \
|
||||||
|
--output "$partial" "$MODEL_URL"
|
||||||
|
|
||||||
|
actual_size=$(stat -c %s "$partial")
|
||||||
|
if [[ $actual_size != "$MODEL_SIZE" ]]; then
|
||||||
|
echo "Size mismatch: expected $MODEL_SIZE, got $actual_size; keeping $partial for inspection" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
printf '%s %s\n' "$MODEL_SHA256" "$partial" | sha256sum -c -
|
||||||
|
mv -f "$partial" "$target"
|
||||||
|
echo "Prepared and verified: $target"
|
||||||
Executable
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
MODEL_ROOT=${MODEL_ROOT:-/data/models/experiments/qwen38-ab-20260907}
|
||||||
|
RESULT_DIR=${RESULT_DIR:-/data/benchmarks/qwen38-ab-20260907}
|
||||||
|
|
||||||
|
echo "== Containers owned by this experiment =="
|
||||||
|
docker ps -a --filter label=mike-ai.experiment=qwen38-ab-20260907 \
|
||||||
|
--format 'table {{.Names}}\t{{.Status}}\t{{.Label "mike-ai.candidate"}}' || true
|
||||||
|
|
||||||
|
echo "== Candidate model files and partial downloads =="
|
||||||
|
if [[ -d $MODEL_ROOT ]]; then
|
||||||
|
find "$MODEL_ROOT" -maxdepth 2 -type f -exec ls -lh {} +
|
||||||
|
else
|
||||||
|
echo "Not present: $MODEL_ROOT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "== Benchmark results =="
|
||||||
|
if [[ -d $RESULT_DIR ]]; then
|
||||||
|
find "$RESULT_DIR" -maxdepth 1 -type f -exec ls -lh {} +
|
||||||
|
else
|
||||||
|
echo "Not present: $RESULT_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "== Known older experimental model directories (read-only report) =="
|
||||||
|
for path in \
|
||||||
|
/data/models/qwen3.8-27b-dirk \
|
||||||
|
/data/models/qwen3.8-27b-gsq-rco-test \
|
||||||
|
/data/models/qwen3.8-27b-iq4-mix \
|
||||||
|
/data/models/qwen3.8-27b-iq4-xs-pure; do
|
||||||
|
[[ -d $path ]] && du -sh "$path"
|
||||||
|
done
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
LABEL=${1:-}
|
||||||
|
CONTEXT=${2:-160000}
|
||||||
|
[[ -n $LABEL && $LABEL =~ ^[a-zA-Z0-9._-]+$ ]] || {
|
||||||
|
echo "Usage: $0 SAFE_LABEL [CONTEXT]" >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
[[ $CONTEXT =~ ^[0-9]+$ ]] || {
|
||||||
|
echo "CONTEXT must be an integer" >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REFERENCE_DIR="$SCRIPT_DIR/../dirk-qwen38"
|
||||||
|
RESULT_DIR=${RESULT_DIR:-/data/benchmarks/qwen38-ab-20260907}
|
||||||
|
TASKS=${TASKS:-/opt/mike-ai/stack/dev/QWEN38-FINAL-ACCEPTANCE-v1.json}
|
||||||
|
|
||||||
|
curl -fsS --max-time 3 http://127.0.0.1:5005/health >/dev/null
|
||||||
|
python3 "$REFERENCE_DIR/bench-case.py" "$LABEL" "$CONTEXT" \
|
||||||
|
--base http://127.0.0.1:5005 --output "$RESULT_DIR"
|
||||||
|
python3 "$REFERENCE_DIR/quality-ab.py" "$LABEL" \
|
||||||
|
--base http://127.0.0.1:5005 --tasks "$TASKS" --output "$RESULT_DIR"
|
||||||
Executable
+103
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
CANDIDATE=${1:-}
|
||||||
|
CONTEXT=${2:-}
|
||||||
|
SPLIT=${3:-}
|
||||||
|
|
||||||
|
if [[ -z $CANDIDATE || -z $CONTEXT || -z $SPLIT || ! $CONTEXT =~ ^[0-9]+$ || ! $SPLIT =~ ^[0-9]+,[0-9]+$ ]]; then
|
||||||
|
echo "Usage: $0 {qwopus|bartowski} CONTEXT TENSOR_SPLIT" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck source=candidates.sh
|
||||||
|
source "$SCRIPT_DIR/candidates.sh"
|
||||||
|
candidate_config "$CANDIDATE"
|
||||||
|
|
||||||
|
HOST_MODEL_FILE=$MODEL_PATH
|
||||||
|
CONTAINER_MODEL="/models/$CANDIDATE_ID/$MODEL_FILE"
|
||||||
|
IMAGE=${LLAMA_IMAGE:-mike-ai/llama.cpp:local}
|
||||||
|
NAME=mike-ai-llama-qwen38-ab
|
||||||
|
RESULT_DIR=${RESULT_DIR:-/data/benchmarks/qwen38-ab-20260907}
|
||||||
|
|
||||||
|
[[ -s $HOST_MODEL_FILE ]] || {
|
||||||
|
echo "Candidate is not downloaded: $HOST_MODEL_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
printf '%s %s\n' "$MODEL_SHA256" "$HOST_MODEL_FILE" | sha256sum -c -
|
||||||
|
|
||||||
|
mapfile -t blockers < <(
|
||||||
|
docker ps --format '{{.Names}}' |
|
||||||
|
grep -E '^mike-ai-llama-' |
|
||||||
|
grep -vE '^mike-ai-llama-dashboard$|^mike-ai-llama-qwen38-ab$' || true
|
||||||
|
)
|
||||||
|
if ((${#blockers[@]})); then
|
||||||
|
printf 'Refusing to start: production model container(s) still running: %s\n' "${blockers[*]}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if docker ps --format '{{.Names}}' | grep -qx "$NAME"; then
|
||||||
|
echo "Refusing to replace a running A/B container; run ./stop-case.sh first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
install -d -m 0755 "$RESULT_DIR"
|
||||||
|
|
||||||
|
args=(
|
||||||
|
--model "$CONTAINER_MODEL"
|
||||||
|
--alias "$MODEL_ALIAS"
|
||||||
|
--ctx-size "$CONTEXT"
|
||||||
|
--flash-attn on
|
||||||
|
--cache-type-k q4_0
|
||||||
|
--cache-type-v q4_0
|
||||||
|
--cache-prompt
|
||||||
|
--cache-ram 8192
|
||||||
|
--threads 6
|
||||||
|
--threads-batch 6
|
||||||
|
--batch-size 64
|
||||||
|
--ubatch-size 32
|
||||||
|
--parallel 1
|
||||||
|
--jinja
|
||||||
|
--reasoning auto
|
||||||
|
--reasoning-budget 8192
|
||||||
|
--reasoning-preserve
|
||||||
|
--host 127.0.0.1
|
||||||
|
--port 5005
|
||||||
|
--metrics
|
||||||
|
--fit off
|
||||||
|
--n-gpu-layers all
|
||||||
|
--no-mmap
|
||||||
|
--temperature 1.0
|
||||||
|
--top-p 0.95
|
||||||
|
--top-k 20
|
||||||
|
--device CUDA0,CUDA1
|
||||||
|
--main-gpu 0
|
||||||
|
--split-mode layer
|
||||||
|
--tensor-split "$SPLIT"
|
||||||
|
--spec-type draft-mtp
|
||||||
|
--spec-draft-n-max 3
|
||||||
|
--spec-draft-type-k f16
|
||||||
|
--spec-draft-type-v f16
|
||||||
|
)
|
||||||
|
|
||||||
|
label="$CANDIDATE-ctx${CONTEXT}-split${SPLIT//,/-}"
|
||||||
|
docker run -d \
|
||||||
|
--name "$NAME" \
|
||||||
|
--gpus all \
|
||||||
|
--network host \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs /tmp:rw,noexec,nosuid,nodev,size=256m \
|
||||||
|
--security-opt no-new-privileges:true \
|
||||||
|
--cap-drop ALL \
|
||||||
|
--pids-limit 1024 \
|
||||||
|
--log-opt max-size=20m \
|
||||||
|
--log-opt max-file=2 \
|
||||||
|
-v "$MODEL_ROOT":/models:ro \
|
||||||
|
-v "$RESULT_DIR":/results \
|
||||||
|
--label mike-ai.experiment=qwen38-ab-20260907 \
|
||||||
|
--label mike-ai.candidate="$CANDIDATE" \
|
||||||
|
--label mike-ai.case="$label" \
|
||||||
|
"$IMAGE" "${args[@]}"
|
||||||
|
|
||||||
|
printf 'Started isolated case %s on http://127.0.0.1:5005\n' "$label"
|
||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
docker rm -f mike-ai-llama-qwen38-ab >/dev/null 2>&1 || true
|
||||||
|
echo "A/B test container removed. Production was not changed."
|
||||||
Executable
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
NAME=mike-ai-llama-qwen38-ab
|
||||||
|
deadline=$((SECONDS + ${READY_TIMEOUT:-900}))
|
||||||
|
until curl -fsS --max-time 3 http://127.0.0.1:5005/health >/dev/null; do
|
||||||
|
state=$(docker inspect -f '{{.State.Running}}' "$NAME" 2>/dev/null || true)
|
||||||
|
if [[ $state != true ]]; then
|
||||||
|
docker logs --tail 100 "$NAME" >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ((SECONDS >= deadline)); then
|
||||||
|
docker logs --tail 100 "$NAME" >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
curl -fsS http://127.0.0.1:5005/props
|
||||||
|
printf '\nA/B test server is ready.\n'
|
||||||
Reference in New Issue
Block a user