frank-small: two wide unquantized contexts (2 x 200,704) on the 3090
Frank's order, two messages: "extend the max context of frank-small to 200700 per individual stream without further quantization", then "reduce it to 2 streams for a total of 401400-ish tokens, set ubatch to 1k", then "unquantize the KV if we have extra space". CTX_SIZE 540672 -> 401408 with PARALLEL 3 -> 2 gives n_ctx_slot 200,704: above the 200,700 the harness compacts at, so a full-length request lands in one stream instead of a 400 exceed_context_size_error. The pool must divide evenly across slots and stay 256-aligned for the FA path, which is why it is 401,408 and not 401,400. CACHE_TYPE_V q8_0 -> f16: the freed third slot is exactly what pays for unquantized values (24.5 -> 32 KiB/token), and the budget lands back in the 2-3 GiB band Frank set on 2026-10-02 instead of leaving ~6 GiB of the card idle. The asymmetric-KV contract that created this endpoint is spent with it; both --cache-type flags stay explicit. --batch-size/--ubatch-size are now passed (2048/1024). The endpoint had never passed either, so it ran on engine defaults nobody wrote down. Franksdank-Runbook: serverAppConfigs-docs/LLM/frank-small-llama-mimo-q5km.md
This commit is contained in:
1 parent
7d3dd33de0
commit
6584c059d6
4 files changed
+112
-72
No files matched your search
+41
-28
@@ -2,11 +2,11 @@
|
||||
# Seam: the frank-small llama.cpp root unit on dankclaw.
|
||||
# frank-small is the RTX 3090 endpoint; since 2026-10-01 night it serves
|
||||
# bartowski/MiMo-V2.6-Distill-Qwen-9B-GGUF:Q5_K_M via a CUDA (sm_86) build of
|
||||
# llama.cpp master, chosen for the ASYMMETRIC KV Frank asked for: K f16
|
||||
# (unquantized) + V q8_0, which only llama.cpp exposes per-tensor. Since
|
||||
# 2026-10-02 it runs THREE contexts and carries a vision projector, and the
|
||||
# card must keep 2-3 GiB free. This seam runs the serve script against a stub
|
||||
# engine and asserts on the argv it actually execs, so what is pinned is the
|
||||
# llama.cpp master, chosen because it is the only runtime here that moves K and
|
||||
# V independently. Since 2026-10-03 it runs TWO unquantized contexts of
|
||||
# 200,704 tokens each and carries a vision projector, and the card must keep
|
||||
# 2-3 GiB free. This seam runs the serve script against a stub engine and
|
||||
# asserts on the argv it actually execs, so what is pinned is the
|
||||
# command the operator gets.
|
||||
|
||||
load helpers
|
||||
@@ -98,7 +98,7 @@ argv_value() {
|
||||
done
|
||||
}
|
||||
|
||||
@test "the shipped env serves the fleet shape: three 180224-token contexts" {
|
||||
@test "the shipped env serves the fleet shape: two 200704-token contexts" {
|
||||
serve_argv
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(argv_value --alias)" = "frank-small" ]
|
||||
@@ -108,43 +108,56 @@ argv_value() {
|
||||
[ "$(argv_value --n-gpu-layers)" -gt 0 ]
|
||||
# llama.cpp divides --ctx-size across slots and a mamba hybrid cannot
|
||||
# share one cache, so the observable contract is the per-slot window.
|
||||
[ "$(argv_value --parallel)" -eq 3 ]
|
||||
[ "$(argv_value --parallel)" -eq 2 ]
|
||||
ctx="$(argv_value --ctx-size)"
|
||||
par="$(argv_value --parallel)"
|
||||
[ $((ctx % par)) -eq 0 ]
|
||||
[ $((ctx / par)) -eq 180224 ]
|
||||
[ $((ctx / par)) -eq 200704 ]
|
||||
[ $((ctx / par)) -le 262144 ]
|
||||
}
|
||||
|
||||
@test "the KV contract is asymmetric: unquantized K, q8_0 V, flash-attn on" {
|
||||
@test "the KV contract is unquantized both halves, flash-attn on" {
|
||||
serve_argv
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(argv_value --cache-type-k)" = "f16" ]
|
||||
[ "$(argv_value --cache-type-v)" = "q8_0" ]
|
||||
# q8_0 on V only exists on the flash-attention path; without this flag
|
||||
# pair the KV contract in the env file is a lie the engine never sees.
|
||||
# Frank, 2026-10-03: the values are unquantized too. The flag pair is what
|
||||
# makes this observable — a build without the FA path silently falls back,
|
||||
# so both must appear in the argv the supervisor runs.
|
||||
[ "$(argv_value --cache-type-v)" = "f16" ]
|
||||
[ "$(argv_value --flash-attn)" = "on" ]
|
||||
}
|
||||
|
||||
@test "the KV budget leaves 2-3 GiB of the 3090 free" {
|
||||
# Rate: K f16 (16 KiB/token) + V q8_0 (~8.5, budgeted 25 with slack).
|
||||
# The non-KV half is MEASURED on this card on 2026-10-02: with the
|
||||
# projector loaded the engine reported 22,972 MiB used against 14,113
|
||||
# MiB of KV, so weights + vision tower + DeltaNet state + compute
|
||||
# buffers + CUDA graphs = 8,859 MiB => 9 GiB. Two asserts, both about
|
||||
# the output the operator sees: the pool must still fit with 2 GiB
|
||||
# spare, and it must be large enough that 5 GiB spare is NOT reachable
|
||||
# (an undersized pool is as wrong as an oversized one). Arithmetic, not
|
||||
# a boot log: change CTX_SIZE and this bites before the deploy does —
|
||||
# it rejects the 3 x 196,608 pool that measured only 1.1 GiB free. The
|
||||
# same pool with f16 V (34 KiB/token) lands past the card, which is why
|
||||
# the contract is asymmetric.
|
||||
# Rate, from the GGUF geometry: 8 full-attention layers x 4 kv heads x
|
||||
# 256 dim x 2 B = 16 KiB/token for K and the same for V => 32 KiB/token
|
||||
# (budgeted 33 with slack). The non-KV half is MEASURED on this card on
|
||||
# 2026-10-02: with the projector loaded the engine reported 22,972 MiB
|
||||
# used against 14,113 MiB of KV, so weights + vision tower + DeltaNet
|
||||
# state + compute buffers + CUDA graphs = 8,859 MiB => 9 GiB. Two asserts,
|
||||
# both about the output the operator sees: the pool must still fit with
|
||||
# 2 GiB spare, and it must be large enough that 5 GiB spare is NOT
|
||||
# reachable (an undersized pool is as wrong as an oversized one).
|
||||
# Arithmetic, not a boot log: change CTX_SIZE and this bites before the
|
||||
# deploy does. The same pool with the OLD 24.5 KiB/token rate would leave
|
||||
# ~6 GiB free — i.e. the unquantized V is what puts this shape in the band.
|
||||
ctx="$(sed -nE 's/^CTX_SIZE=([0-9]+)$/\1/p' "$ENV_FILE")"
|
||||
kv_gib=$((ctx * 25 / 1048576))
|
||||
kv_gib=$((ctx * 33 / 1048576))
|
||||
[ $((kv_gib + 9 + 2)) -le 24 ]
|
||||
[ $((kv_gib + 9 + 5)) -gt 24 ]
|
||||
f16v_gib=$((ctx * 34 / 1048576))
|
||||
[ $((f16v_gib + 9)) -gt 24 ]
|
||||
# And the ceiling that sets the per-slot window: two NATIVE windows cannot
|
||||
# be paid for in full precision on this card.
|
||||
native=$((2 * 262144))
|
||||
[ $((native * 33 / 1048576 + 9)) -gt 24 ]
|
||||
}
|
||||
|
||||
@test "the compute-buffer pair is explicit" {
|
||||
# This endpoint ran on llama.cpp's own defaults until 2026-10-03; the
|
||||
# fleet now pins 2048/1024 so the number a benchmark attributes the
|
||||
# prefill rate to is a repo value, not an engine default nobody wrote down.
|
||||
serve_argv
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(argv_value --batch-size)" = "2048" ]
|
||||
[ "$(argv_value --ubatch-size)" = "1024" ]
|
||||
}
|
||||
|
||||
@test "no speculative draft ships by default" {
|
||||
@@ -170,7 +183,7 @@ argv_value() {
|
||||
! grep -qxF -- '--mmproj' <<<"$output"
|
||||
}
|
||||
|
||||
@test "the fleet reasoning contract survives the reslice to three contexts" {
|
||||
@test "the fleet reasoning contract survives the reslice to two wide contexts" {
|
||||
serve_argv
|
||||
[ "$status" -eq 0 ]
|
||||
# deepseek format = thinking lands in reasoning_content, the field the
|
||||
|
||||
Reference in new issue
Block a user