Commit Graph

393 Commits

Author SHA1 Message Date
noonghunna
78798eb659 docs: note W8A8 INT8 is Ampere/Ada/Hopper-only (dead on Blackwell sm>=10.0)
Per llm-compressor's W8A8 guide, INT8 W8A8 quant is unsupported on compute
capability >= 10.0 (RTX 5090 sm_120, RTX 6000-Blackwell). Record it where it
matters: the experimental W8A8 "prefill corner" BENCHMARKS row (a factor
against promotion — can't serve the Blackwell community; FP8 weights stay the
Blackwell-safe 8-bit path) + a "silicon != kernel" note on the DTYPE_MATRIX
Blackwell line (the INT8 TCs exist, but the W8A8 kernel doesn't build there).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-06 15:42:14 +00:00
noonghunna
fabf9ce1ea feat(qwen): flip multi-max to fp8/e4m3 KV + weights-conditional Ampere compat
Follow-up to #594 (which flipped dual-max int8-PTH -> fp8). Mirrors it on the
4-card tier and makes the registry/compat model reflect reality:

- multi4/fp8/mtp.yml: KV default int8_per_token_head -> fp8 (+ header, mirrors
  dual-max: fp8->e4m3, FlashInfer, scale=1.0, not-e5m2)
- registry kv_format: dual-max + multi-max int8_per_token_head -> fp8_e4m3
  (jesse's #594 changed only the compose, leaving the registry stale) + de-stale
  the status_notes (fp8 KV, 8-pack 109 ties 107, soak p50 125.5)
- compat.py C5: weights-conditional rule. fp8_e4m3 KV is allowed on Ampere
  (sm>=8.6) ONLY for fp8-weights checkpoints (FlashInfer path). Non-fp8 weights
  (Gemma W4A16) still route to Triton (needs SM89+) and stay correctly rejected.
  No rtx-3090 profile change -> Gemma protection intact via the profile.
- test-launch-compat: assert BOTH directions (Qwen fp8-weights passes, Gemma
  gemma-mtp-tp1 still fails C5) so the rule + registry stay in sync.
- DTYPE_MATRIX: cite vLLM's fp8-KV blog (scale=1.0 = near-lossless lower bound;
  Qwen3.5-27B matches baseline AUC @1M) + document the weights-conditional rule.

Validated: dual-max + multi-max validate-variant PASS with fp8_e4m3 on 2x/4x
3090; gemma-mtp-tp1 still rejected. 11 compat/registry guards green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-06 14:55:01 +00:00
noonghunna
b56b7bdce3 docs: fp8/e4m3 KV finding for dual-max (#594) — backend, scale, quality tie
Records the int8-PTH -> fp8 KV finding merged in #594:
- BENCHMARKS: fp8/e4m3 A/B row (decode 2.3x at depth, prefill ~2x, recall tie,
  quality 109 ties int8-PTH 107, soak-continuous PASS)
- DTYPE_MATRIX: KV-format -> attention-backend availability (int8-PTH is
  TRITON_ATTN-only; fp8/e4m3 -> FlashInfer). fp8 runs at scale=1.0
  (checkpoint weight-only; calculate_kv_scales disabled on Qwen3-Next hybrid);
  ties int8-PTH on the 8-pack anyway
- DUAL_CARD / MULTI_CARD: max-tier decode-at-depth split + the multi-max
  follow-up (registry kv_format + rtx-3090 fp8_e4m3-compat sync)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-06 14:14:50 +00:00
noonghunna
fd56fe7ad5 dual-max: induct 2x3090 baseline row + correct the stale ~56 TPS probe
The dual-max FP8 2x3090 decode bench (83.1/108.2, v0.24.0, 2026-06-30) lived
only in BENCHMARKS.md:122 + disc #515 (c17490565) — never inducted into
baselines.yml, so c3 / the registry-emit join showed only guybrush01's
2x5090 submission and no local bar. Surfaced while diagnosing #585.

- baselines.yml: vllm/qwen-27b-dual-max gains its primary tier: local row
  (83.1/108.2 · TTFT 158 · prefill 1364->875 · 8-pack 107/150 · NIAH 240K ·
  v0.24.0 = current pin -> FRESH); guybrush's 2x5090 submission preserved.
- compose header + DUAL_CARD.md: the stale '~56 TPS' probe (and the now-false
  'slowest of the three' framing) -> real decode 83/108; the genuine
  tradeoffs (smallest KV pool 295K/1.13x, slowest prefill/TTFT 158ms from
  FP8's compute-heavy Marlin W8A16 dequant) kept. BENCHMARKS.md already
  corrected; this closes the two spots that still read ~56.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-05 22:07:39 +00:00
noonghunna
6af5ccfbf5 docs: cross-engine note — the consumer-vs-datacenter KV limit is vLLM-only
Adds a subsection to DTYPE_MATRIX's two-axes section clarifying that the
FMHA-kernel arch gating is a vLLM-family (vLLM + SGLang) phenomenon.
The llama.cpp family (mainline / ik-llama / beellama) is always-dequant:
KV quant is storage-only on every arch (dequant inside the FA kernel, no
FP8/FP4 tensor cores even on Hopper), so no consumer-vs-datacenter split
— q4_0 KV behaves the same on a 3090/4090/5090/Spark, which is why our
single-card GGUF configs hit 262K anywhere. GGUF weight quant is
dequant-to-FP16 too, so the native-FP8/NVFP4-weights win is vLLM-only.

Division of labor: native low-precision COMPUTE wins are vLLM-only (and
mostly datacenter for KV); the CAPACITY win (KV compression for long
ctx) is delivered arch-agnostically by the GGUF family — the right tool
for a consumer card that wants big context.

Verified: llama.cpp #22411 / #24109, ik_llama #1142.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-05 04:23:39 +00:00
noonghunna
b0872f5989 docs: document the weights-vs-KV and consumer-vs-datacenter quant splits
Consolidates the validated findings from the #246 A/B + #571 volunteer
data + vLLM/TRT-LLM source review. New DTYPE_MATRIX section "Having the
Tensor Cores ≠ using them" makes the two load-bearing distinctions
explicit:

- Axis 1 — weights vs KV are gated SEPARATELY. FP8/FP4 *weights* work
  wherever the TCs exist (sm_89+ FP8, all Blackwell FP4). KV is
  different because it rides the attention (FMHA) kernel.
- Axis 2 — KV compute vs KV storage. Native FP8/FP4 *attention* compute
  needs FA3 (Hopper sm_90 only) or trtllm-gen FMHA (datacenter Blackwell
  sm_100/103 only). On EVERY consumer card — Ada 4090 (sm_89), consumer
  Blackwell 5090/PRO-6000 (sm_120), DGX Spark GB10 (sm_121) — FP8 KV is
  storage-only and nvfp4 KV doesn't work.

Consequences documented (both empirically confirmed): e4m3 ≡ e5m2 in
speed on consumer cards (86.73 vs 86.66 on a 5090, disc #571 — a
precision choice, not a perf lever); nvfp4 KV crashes on consumer
Blackwell (#43562). DGX Spark = same sm_12x family as the 5090.

Corrected now-wrong claims: DTYPE_MATRIX "Ada/Blackwell get a real win
on FP8 KV" (false — Hopper/DC-only) + the per-arch Ada/Blackwell-consumer
rows; QUANTIZATION + HARDWARE "native FP8 compute on sm_89+" → storage-
only + precision framing. Compute-win KV on consumer cards = INT8-PTH.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-05 03:58:49 +00:00
noonghunna
6f674fa2ce Gate nvfp4 KV to datacenter Blackwell only (sm_100/103) — found on #571
Two 5090 owners hit `--kv-cache-dtype nvfp4 requires sm100f` crashing
mid-boot on the #246 A/B (disc #571). Root-caused from vLLM #43562 /
TRT-LLM #10241: nvfp4 KV forces the trtllm-gen FP4 FMHA, built ONLY for
datacenter Blackwell sm_100/sm_103. Consumer Blackwell (sm_120/121 —
RTX 5090 / PRO 6000 Blackwell) is a HIGHER cc number but a different
family with no FMHA build. NVFP4 *weights* work there; only the KV path
doesn't. Our #246 gate had used a numeric ">=10.0" floor that wrongly
passed sm_120 — a floor can't express "sm_100/103 but not the
numerically-higher sm_120".

- gates.py: new `_ARCH_KERNEL_SM_FAMILY` allowlist ({nvfp4: sm_100/103});
  dropped nvfp4 from the numeric `_ARCH_KERNEL_SM` floor; family-membership
  reject with the FMHA reason + fp8_e4m3 fallback.
- arch-ab.sh: nvfp4 arm now refuses on consumer Blackwell (not just
  <sm_10), naming the FMHA gap + the fp8_e4m3 path; dropped nvfp4 from the
  recommended arms in help.
- hardware profiles: removed nvfp4 from rtx-5090 / rtx-6000-pro-blackwell
  KV lists (both sm_120) + added a why-not note.
- docs (DTYPE_MATRIX / HARDWARE / KV_MATH / QUANTIZATION): corrected the
  "Blackwell sm >= 10.0" framing to "datacenter sm_100/103 only".
- UPSTREAM.md: #43562 / TRT-LLM #10241 row + re-test trigger.
- test-arch-ab: nvfp4 refuses on sm_86 AND sm_120, allowed on sm_100;
  the dual-5090 all-arms test drops nvfp4.

Full scripts gate 66/66.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-05 03:23:49 +00:00
noonghunna
b0c8933800 p2p verdict: point WARN/INFO at docs/PCIE_P2P.md; doc catches up with the automated verdict
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-05 00:10:57 +00:00
noonghunna
717cb431a9 Un-track A1's compiled torch cache — it crashed Blackwell boots
Root cause of club-3090 #548, pinned from the stack trace: A1's
promotion accidentally committed the whole torch_compile cache (3,667
files, ~20 MB) compiled on THIS sm_86 rig, and the compose warm-start
mount fed it to every fresh pull. On sm_120 the AOT graph (baked
against Marlin-processed FP8 layers -> reads layer.workspace) loads
onto Cutlass-processed layers -> AttributeError -> restart loop.
vLLM's AOT cache key doesn't include arch/kernel selection, so the
cross-arch hit is silent (upstream issue to follow; UPSTREAM.md row
updated with the pinned mechanism).

Fix = the house pattern every other model already has: cache contents
gitignored (cache/.gitignore + README), directory kept for the mount,
local files untouched (our warm-start intact). Fresh users pay one
~60-90s compile on first boot and warm-start locally thereafter --
against THEIR OWN silicon's kernel selection.

Also retires the recurring dirty-tree noise from best_config files
updating during our own runs.

Full scripts gate 65/65.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-04 22:54:50 +00:00
noonghunna
6b7001aae6 Docs: first Blackwell A1 row (#567) + sumo quality (#552) + sm_120 FP8 tracking
- BENCHMARKS: guybrush01 2x5090 A1 row (decode 220.21/220.36 n=5 CV
  0.0%, +43% over the 3090 gate) with the forced-Marlin workaround
  caveat labeled explicitly (NOT native FP8 GEMMs -- headroom pending
  the upstream fix); sumo-dandan row gains his --medium quality
  (69/75, current harness).
- UPSTREAM: row for the v0.24.0 sm_120 FP8 kernel-selection
  AttributeError (to-file status; workaround validated cross-rig via
  #548 -> #567).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-04 22:41:57 +00:00
noonghunna
e8bcfd8da1 Launcher arch-aware KV dtype injection for pilot slugs (#246 Phase 1)
launch.sh/switch.sh now detect GPU arch and export KV_CACHE_DTYPE=
fp8_e4m3 (native FP8 compute) on sm_89+ cards for the pilot slugs
(vllm/dual, vllm/minimal). The injected value is the hardware
profiles' dormant kv_format_default.balanced -- one source of truth
shared with the pull gates; the Ampere no-op is data equality
(3090-class balanced = fp8_e5m2 = compose default -> nothing emitted),
not a code branch.

Injection guards (all load-bearing):
- pilot allowlist only; expansion gated on the #246 cross-rig A/B
- per-variant: registry kv_format == fp8_e5m2 only (int8-PTH/TQ/bf16
  slugs never touched -- compressed-tensors weights reject fp8 KV)
- vLLM-family variants only; explicit user KV_CACHE_DTYPE= wins;
  unmapped cards / heterogeneous rigs / no nvidia-smi -> no injection
- direct `docker compose up` keeps Ampere-safe compose defaults

Rides the existing resolve-variant-pin export seam (new optional
--gpu-spec); VLLM_ATTENTION_BACKEND is whitelisted but ships no value
(vLLM auto-detect stays the default until measured). Preflight banner
names the detected arch class.

Consistency fixes the injection exposed:
- gates.py _ARCH_KERNEL_SM: fp8_e4m3 9.0 -> 8.9 (vLLM's real floor is
  SM89+; we'd otherwise inject e4m3 on 4090s our own pull-gate calls
  unloadable) + new nvfp4: 10.0 row (v0.24.0 literal had NO gate --
  a 3090 pull of an nvfp4 config wouldn't have been rejected)
- Blackwell hardware profiles: nvfp4 declared as CANDIDATE capability
  (engine list unchanged until validated -- gates take the intersection)
- kv-calc: projected nvfp4 rows (bytes/elem + activation coefs),
  calibration unchanged

Docs: HARDWARE.md new section, KV_MATH/QUANTIZATION/DTYPE_MATRIX rows
(incl. retiring the Genesis-era "e4m3 undertuned per #51" advisory in
favor of the A/B).

Validated: 8-case injection matrix in test-launch-compat; live no-op
on the real 2x3090 (spec built, nothing injected); faked 4090 through
the real bash detection path emits e4m3; compose interpolation both
ways; kv-calc --calibration green; full scripts gate 64/64.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-04 20:45:28 +00:00
noonghunna
d19d00b9d3 quality/baselines: rescore-materialization practice — artifacts carry the accepted truth
Closes the rescore-materialization gap the induction tool's first live
run surfaced (#562): the benchlocal-cli 'rescore' subcommand ALREADY
supports write-back (--in-place / --output) — the gap was practice, not
a missing upstream feature. The T2 rescore ran to stdout only, so the
published A1 thinking-on 110/150 diverged from the tag artifact (108).

- A1's rescore MATERIALIZED into the tag JSONs (rescore --in-place; OFF
  105 unchanged, ON 108→110) — induction now extracts 110 and the
  regenerated corpus record carries 110; artifact, corpus, baseline row
  and publication all agree. Pre-rescore JSON backed up outside the tag.
- docs/QUALITY_TEST.md: 'Rescoring saved results — MATERIALIZE, don't
  just read' — the rule (a rescore that changes a published number must
  be written back in the same session), the command, what rescore can't
  re-run (sandbox packs), and the A1 case as the cautionary example.
- catalog-baseline.sh header: reads-artifacts-as-truth warning + the
  header's gate text updated to the actual n>=3/warn-under-5 behavior.
- baselines.yml A1 comment: gap note -> materialized + doc pointer.

Guards green (test-catalog-baseline, test-baselines).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-04 16:30:53 +00:00
noonghunna
c2c06e47a7 beellama docs: sm_120 root cause + Anbeeld#85 ask + verified self-build recipe
Investigation of a Discord cross-rig report (WSL, 3060Ti+4090: verify
fails on the pinned v0.3.2-preview digest, passes on the old noonghunna
snapshot; NOT reproducible on our 3090s — verify-full all-pass) surfaced
three doc-level truths worth recording:

- The 50-series gap is a TOOLCHAIN ceiling: Anbeeld's CI builds on the
  Dockerfile-default CUDA 12.4, whose nvcc cannot target sm_120 (no
  cubin, max PTX compute_90) — every official tag lacks Blackwell.
  Upstream ask filed: Anbeeld#85 (CUDA_VERSION 12.8.1 + arch list incl
  120); when it lands we retire the noonghunna snapshot entirely.
- Three registry status_notes claimed launchers inject 'server-cuda-
  v0.3.0' — stale since the 2026-06-12 pin bump; they inject the
  v0.3.2-preview digest from engines/beellama-local.yml install.spec.
  Fixed all three (qwen dflash, gemma-12b, gemma dflash) + honest
  labeling of the noonghunna snapshot as v0.3.0-feature-level and
  unmaintained (predates KVarN + v0.3.1 fixes).
- The engine-notes self-build guidance was outdated: FA_ALL_QUANTS is
  hardcoded in Anbeeld's cuda.Dockerfile since our PR Anbeeld#48, so a
  self-build needs only CUDA_DOCKER_ARCH (+ CUDA_VERSION=12.8.1 for
  sm_120). Recipe verified against his master Dockerfile 2026-07-04.

UPSTREAM.md beellama row updated (dated entry + next-triggers; the 'no
official image' claim struck through as historical). Gates: YAML +
registry import clean; status-drift / profiles-compat / switch-parity
green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-04 14:17:55 +00:00
John Shojaei
c22a9d2d84 tools: add HTTP model-switch service (thin wrapper over switch.sh)
Adds a stdlib HTTP control plane that wraps scripts/switch.sh so a harness
can POST /switch and block until the new model is serving. Introduces no new
orchestration logic — switch.sh stays the single source of truth (registry
lookup, down/up, readiness).

- tools/model-switch/server.py: GET /healthz|/status|/models, POST /switch
  ({slug}|{model}); registry-validated; /health readiness (works with or
  without VLLM_API_KEY); single-flight lock; refuses to start unauthenticated
  on a non-loopback bind.
- scripts/systemd/club3090-model-switch.service: host daemon unit.
- scripts/tests/test-model-switch.sh: hermetic HTTP/auth/validation contract.
- docs/EXAMPLES.md, .env.example: usage + config.

Mirrors the existing stdlib HTTP style (services/studio/*); zero new deps.
Experimental/opt-in per the repo's staging convention.
2026-07-03 17:44:17 -07:00
noonghunna
7a60a12f9d Merge pull request #536 from noonghunna/docs/pr3-quant-tradespace
docs(quant): add QUANTIZATION §4b tier trade-space (fast/balanced/max)
2026-07-02 16:37:01 +05:00
noonghunna
7e9f5cb930 serve: neutral primary model name (qwen3.6-27b / gemma-4-31b), keep -autoround alias
The shared served-model-name `qwen3.6-27b-autoround` (from #490) mislabels the
non-autoround 27b scenes (fp8 dual-max, lmcache): /v1/models advertises
"autoround" while `root` points at qwen3.6-27b-fp8. Same class on gemma-4-31b —
after the v0.24.0 consolidation the default is cyankiwi qat-AWQ-INT4 (bf16 KV),
yet the LiteLLM route still targeted `gemma-4-31b-autoround` (a latent #482 drift).

Fix WITHOUT breaking anything, via vLLM multi-served-name:
- Every 27b scene now serves `qwen3.6-27b <its-quant-name>`; every gemma-31b
  scene serves `gemma-4-31b <its-quant-name>`. The neutral name is PRIMARY
  (honest /v1/models id); the quant-specific name is retained as a live ALIAS.
- LiteLLM: add `qwen3.6-27b` / `gemma-4-31b` canonical public routes; keep the
  `-autoround` routes as back-compat aliases (same upstream). Repairs the gemma drift.
- Migrate our own MODEL= defaults + docs (bench/verify/quality/launch/setup, c3,
  tui-core, EXAMPLES, ...) to the neutral name. Weights slugs (`-autoround-int4`)
  untouched; CHANGELOG + results/ history left as-is.

Retiring the `-autoround` alias entirely is a deliberate later step once nothing
still asks for it.

Live-verified on-rig (single/minimal, stock v0.24.0): /v1/models lists BOTH names
(root=...-autoround-int4); chat to `qwen3.6-27b` AND `qwen3.6-27b-autoround` both
return 200; `qwen3.6-27b-fp8` correctly 404s. Full shell gate 59/59 (1 = known
worktree-fixture); c3 pytest 41 passed; served-name arg-order + YAML validated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-02 11:28:31 +00:00
noonghunna
ae4d1fcad6 patches: de-register vllm-marlin-pad (merged upstream, native in v0.24.0)
Our vllm#40361 sub-tile-n Marlin pad was closed-superseded by mgoin's
vllm#45295 (consolidated marlin_padded_nk across all dense Marlin paths),
native in vLLM v0.24.0. `vllm-stable` now pins v0.24.0 and the AutoRound
INT4 TP=2 path (vllm/dual) boots clean without the overlay (validated in
#533 Phase 0b). No live compose mounts the patch (archive-only), so this
is a tracking-only de-registration — the cleanup deferred from #533.

- patches.yml: qwen-vllm-marlin-pad -> deprecated (upstream.status
  open->merged, load_bearing_when [], delivery none, drift_guard null),
  mirroring the gemma-vllm-pr41800 merged-and-dropped precedent. Kept as
  history (foundational false; entry not deleted).
- arch_patches.yml: correct the stale kernel_constraints note (#40361 ->
  #45295 native in v0.24.0). required_patches / marlin_alignment_required
  unchanged: the alignment is a real arch property (now satisfied stock),
  and deprecated patches stay listed per the pr41800 precedent.
- UPSTREAM.md: mark the #40361 / #40354 / v0.24.0-bump marlin rows DONE
  (native in v0.24.0, patch de-registered, no live mount) and correct the
  stale "composes still mount it" line (all mounts are under _archive/).

Full shell gate green (59/59; the 1 = known worktree-fixture-absent
test-submit-bench). test-patch-attribution (reads both registry files) passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-02 10:03:44 +00:00
noonghunna
a6373533e1 Merge pull request #539 from noonghunna/feat/diffusiongemma-v0.24.0
DiffusionGemma → stock vLLM v0.24.0 (drop the :gemma branch digest)
2026-07-02 13:37:39 +05:00
noonghunna
68c6ea80fb bump(diffusiongemma): :gemma branch digest -> stock vLLM v0.24.0
The DiffusionGemma arch is NATIVE in v0.24.0 (PR #45163 merged 2026-06-12), so
the vllm-diffusion-gemma engine drops the mutable/branch :gemma digest for the
same pinned stable tag the rest of the stack uses. The 3 Ampere/TP fix-mounts
STAY (not in #45163): marlin.py + marlin_utils_fp8.py (sm_86 fp8 MoE Marlin
K-pad — #45295's dense marlin-pad in v0.24.0 does NOT cover marlin_moe_wna16)
and diffusion_gemma.py (TP-vocab; native #45163 copy is still TP=1).

Also fixes the compose for v0.24.0's arg-parser: the bare positional model must
be the --model flag (the entrypoint prepends --disable-custom-all-reduce).

Live-validated 2026-07-02: the actual compose boots + serves coherent at TP=2 on
stock v0.24.0 (Paris / primary colors / 42). Suite 59 pass / 1 pre-existing
(test-submit-bench worktree-fixture-absent).

- engine vllm-diffusion-gemma.yml: install.spec :gemma@digest -> v0.24.0 + provenance
- compose base.yml: image default -> v0.24.0 + --model flag fix + header
- patches.yml dgemma-gemma-image-fixes: reason/drift_guard/drop_when -> v0.24.0
- BENCHMARKS + UPSTREAM #45163 row: reflect the bump

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-02 08:23:39 +00:00
noonghunna
f7214fb4d3 docs(gemma-31b): reflect the v0.24.0 bf16 consolidation
README + DUAL_CARD: single bf16 vllm/gemma-31b-dual @224K default (stock
v0.24.0, overlay-free); the v0.22.0 int8-PTH/bf16-mtp/qat-w4a16 composes are
deprecated. UPSTREAM #40391 row: the 31b DEFAULT moved to bf16 (int8-PTH craters
recall on v0.24.0 without #40391); the #40391/#42006 overlays + vllm-gemma-stable
STAY for the 26b-a4b-single + the deprecated 31b composes. 262K int8-PTH returns
overlay-free when #40391 merges.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-02 08:05:25 +00:00
noonghunna
8d4a6ecc11 docs(quant): add QUANTIZATION §4b tier trade-space
The fast/balanced/max composes aren't rungs on a single fidelity axis —
they're corners of a 3-axis trade-space (weight-fidelity / decode+context
/ prefill-TTFT). §4b names the axes, the corner map, the legitimacy rule
(a differentiator no instrument can measure isn't a tier), scheme-vs-
algorithm, and why "balanced" stays provisional. It fills the prefill
corner with the measured INT8 W8A8 vs FP8 result (v0.24.0): quality tied
107/150, W8A8 wins prefill/TTFT (native CUTLASS INT8), FP8 wins decode —
a prefill-vs-decode tradeoff, not a replacement. W8A8 qualifies as an
analyzed tier; shipping it as a slug is deferred (not committed).

- §4a "Tiering principle" now points into §4b (topology projection).
- DUAL_CARD balanced/max footnote cross-links §4b for the rationale.
- QUANTIZATION.md added to the docs/README.md index.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-01 07:34:55 +00:00
noonghunna
3291b6099f Bump vllm-stable v0.22.0 → v0.24.0 (overlay-free; marlin-pad native) (#533)
* Bump vllm-stable v0.22.0 → v0.24.0 (engine spec + 10 compose defaults)

Live-validated on 2x3090: TP=2 clean, MTP accept 3.51, KV 622K/2.37x,
NIAH to 240K, soak Cliff2b PASS, toolcall 11/15 / instructfollow 15/15.
marlin-pad confirmed unneeded (native via #45295/#45176).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* arch_patches: add vllm-stable@v0.24.0 loads:true rows (keep v0.22.0 as history)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* tests: assert v0.24.0 for vllm-stable pins (gemma stays on v0.22.0)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* docs: record vllm-stable v0.24.0 bump (BENCHMARKS row + UPSTREAM pin status)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

---------

Co-authored-by: noonghunna <10742901+noonghunna@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 01:23:06 +05:00
noonghunna
81181fc4fa docs(ai-studio): add design rationale + 3 complements from the production-agent design
Folds the current-design rationale from the parked production-agent design doc
into the public architecture page (leaving out roadmap/staging/target arch):

- "Why this shape — creative within bounds": serial dissolves the VRAM problem
  on a PCIe rig (the hard part is creative orchestration); the model proposes,
  the executor disposes (never trusted to sequence GPU ops); creative in the
  film-making layer, never the control plane.
- Cross-shot consistency framed as the quality ceiling the Character Bible +
  continuity modes attack.
- "Transport-success ≠ real success" added to Key decisions — the executor
  ffprobe-validates the actual output (duration/audio/placeholder), not just
  "a file appeared".
- Reproducible productions/<job_id>/ + typed manifest (seeds, workflow versions,
  exact ffmpeg cmd, validator results) added to the troubleshooting section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-30 03:56:22 +00:00
noonghunna
f28dde4167 docs(ai-studio): explain storyboard continuity + add a troubleshooting section
- Expand the continuity modes into a table; spell out the DEFAULT "storyboard"
  mode (each shot gets its own keyframe sharing one style bible, then animated
  i2v from that keyframe) vs hero / chain / none.
- Add "Diagnosing & troubleshooting": health checks for the 3 moving parts
  (pipe / 4B :8090 / planner :8195), the offline plan dry-run
  (run.py --backend synthetic — the key diagnostic), live job inspection
  (/job/<id>), the offline unit tests, and a symptom -> cause -> where-to-look
  table (intent misreads, off-topic plans, thinking runaway, research-fail-open,
  the decade duration mis-parse).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-30 03:38:53 +00:00
noonghunna
01cb15b17e docs(ai-studio): rewrite director flow as behavioral + add Character Bible / continuity / research
Two pieces of feedback:
- The decision-flow diagrams read like a code walkthrough (function names,
  file:line, FLOOR/CONTROLLER). Rewrite Shape A + the Production Director's
  Stage 1 ("how it responds to you") and Stage 2 ("what 'go' builds") as
  behavioral flows — what the agent does from the user's side — and move the
  code-level pointers into a compact "under the hood" aside + the existing
  system-prompt map. Lighten the comparison table + the double-gate decision
  to drop residual code identifiers.
- Mine the recent studio commits (#502/#513/#523) for agent-behavior detail
  worth surfacing: the **Character Bible** (recurring characters defined once
  with a fixed look + seed, referenced per shot for visual consistency),
  **continuity modes** (storyboard/hero/chain/none), and the **honesty fix**
  (the director won't claim it can browse arbitrary pages). Added to Stage 2,
  the comparison table (new "Visual continuity" row), and Key decisions.

Also surfaces SearXNG as the documentary-research backend (agents doc callout +
the ai-studio README services line).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-30 03:34:01 +00:00
noonghunna
b494b509c3 docs(ai-studio): flag Production Director as WIP / not production-ready
Add a prominent status banner at the top of agents-architecture.md and reinforce
it in the challenges intro: the Production Director is a work in progress, NOT
recommended for production use — the multi-turn chat is still buggy and does not
follow instructions reliably yet. The single-shot lanes are simpler/further along
but carry the listed rough edges. Sets reader expectations up front.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-30 03:23:03 +00:00
noonghunna
a517324a26 docs(ai-studio): add "Current challenges / known limitations" to agents doc
Documents the open director limitations as of #519-#524: no cross-lane routing
(manual lane pick → documentary-in-LTX gets a scenic clip), the 4B capability
ceiling (thinking-OFF + borderline critic, 27B/35B = the injectable upgrade path),
shallow single-shot-lane chat, the decade duration-parse bug (_target_seconds
reads "1980s"/"90s" as seconds — verified), fragmented prompt sources, and the
pending live end-to-end validation. Each row pairs the symptom with a path
forward (parked Q4 router / 27B critic / regex fix).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-30 03:20:10 +00:00
noonghunna
38487e5c41 docs(ai-studio): add agents-architecture.md (director decision flow)
Documents the AI Studio agent architecture, which wasn't written down: the one
4B director (qwen3.5-4b-uncensored @:8090, thinking-OFF) behind all 13 lanes, the
two agent shapes (single-shot craft-or-decline vs the conversational plan-then-
execute Production Director), the Production decision flow (conversation controller
→ confirm latch → decide_action → /produce planning pipeline), a per-lane
comparison table, and the system-prompt map (8 prompts across AGENTS.md /
director_intent.py / prompts.py / inline DIRECTOR_*_SYS). Links to the editable
sources (AGENTS.md, director_intent.py, the :8195 server). Indexed from the
ai-studio README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-30 03:11:37 +00:00
noonghunna
b0eeb21ff5 fix(quality-test): preflight sandbox images + document the build step (#492) (#494)
`quality-test.sh --full` (which docs tell cross-rig contributors to run)
needs the 3 sandboxed packs' Docker images — but they aren't auto-pulled,
and benchlocal-cli's mid-run hint pointed at a relative
`tools/build-sandboxes.sh` that's only valid inside a benchlocal-cli
checkout (absent on a pip install). guybrush01 followed it into a dead
path (#492).

- quality-test.sh: on --full / --sandboxed-only, preflight the
  benchlocal-sandbox-{bugfind,cli,hermes} images UP FRONT. If missing,
  print the correct clone + build steps (our context, not benchlocal-cli's
  broken relative path) + the --medium no-Docker fallback, then continue
  with the deterministic packs.
- QUALITY_TEST.md: document that --full needs the sandbox images built
  first ("needs Docker" undersold it) — the clone + build-sandboxes.sh
  step, with --medium / --no-sandboxed as the no-Docker path.

Full suite green (59/59). Pairs with benchlocal-cli#69 (the upstream hint).


Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

Co-authored-by: noonghunna <10742901+noonghunna@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 13:47:08 +05:00
noonghunna
394ec87dae fix(ai-studio): derive ComfyUI paths from MODEL_DIR + make gpu-mode portable (#493)
setup-ai-studio.sh's director download honored MODEL_DIR, but the ComfyUI
assets (image/video/audio) defaulted to a hardcoded /mnt/models/comfyui — so
any rig whose models don't live under /mnt failed mid-download with
"mkdir: Permission denied" (sumo Discord report, 2026-06-27). Two more walls
behind it: the disk-space preflight checked the hardcoded /mnt path and had no
override (an idempotent resume under-threshold was blocked), and gpu-mode.sh —
which setup calls at step 3 — hardcoded CLUB3090_DIR=/opt/ai/github/club-3090,
breaking on any other clone.

- New services/comfyui/comfyui-paths.sh: derive COMFYUI_ROOT / COMFYUI_MODELS_DIR
  as a "comfyui" sibling of MODEL_DIR (read from repo-root .env when unset).
  Backward-compatible on the rig (/mnt/models/huggingface -> /mnt/models/comfyui);
  explicit overrides respected. Sourced by setup-ai-studio.sh,
  download_studio_models.sh, and gpu-mode.sh so the download target, the disk
  check, and the container mounts all agree.
- setup-ai-studio.sh: disk check uses the derived path; add SKIP_DISK_CHECK=1 to
  bypass the free-space preflight independently of SKIP_DOWNLOAD.
- gpu-mode.sh: auto-detect CLUB3090_DIR from the script's real location (resolving
  the /usr/local/bin symlink), overridable via env — removes the hardcoded path.
- The 3 legacy hardcoded download scripts (flux2/hunyuan_llava/models) honor
  COMFYUI_MODELS_DIR.
- New test-comfyui-paths.sh guards the derivation; docs/ai-studio config note.

Full suite green (59/59).


Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

Co-authored-by: noonghunna <10742901+noonghunna@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 13:08:07 +05:00
noonghunna
df419c9bd7 docs: add PCIE_P2P.md — PCIe topology & enabling P2P (no NVLink)
New dedicated guide for getting the most out of a PCIe-only multi-GPU
rig: reading nvidia-smi topo -m (why PHB not PIX), NUMA/NPS1, triple-slot
placement + M.2 lane-sharing, BIOS (Above 4G / ReBAR / ACS / IOMMU),
enabling consumer P2P via the patched driver + NVLINK_MODE=pcie_p2p,
realistic measured expectations (cross-rig #91/#95/#77), verifying
engagement via report.sh's new field, and troubleshooting. Generic
guidance with ROMED8-2T as a labeled example board.

Cross-referenced from HARDWARE.md (NVLink section), DUAL_CARD.md (NVLink
auto-detection), FAQ.md (Do I need NVLink?), and the docs index.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-26 21:37:08 +00:00
noonghunna
47ac38385a Director placement lever: CPU / GPU0 / GPU1 (c3 Settings) (#473)
* Director placement lever: env-driven CPU / GPU0 / GPU1 (backend)

The studio director's GPU/CPU placement is now a single lever,
STUDIO_DIRECTOR_DEVICE (gpu0 | gpu1 | cpu, default gpu0), read from the rig
.env by gpu-mode's start_studio_director and translated into the compose
env (-ngl + CUDA_VISIBLE_DEVICES + device_ids):

- gpu0 (default): -ngl 99, GPU0 — fast craft (~50-100 tok/s), ~4.6 GB,
  coexists with the image lanes. Unchanged from before.
- gpu1: -ngl 99, GPU1 — only when GPU1 has room (NOT during a video render;
  GPU1 is the DisTorch DiT donor).
- cpu: -ngl 0, CUDA_VISIBLE_DEVICES="" — frees ~4.6 GB off GPU0 (lifts the
  single-card Wan window 121→161 frames) at ~single-digit tok/s craft.

Compose now reads ${DIRECTOR_NGL:-99} + ${STUDIO_DIRECTOR_CUDA-0} (no-colon
so an explicit empty value = CPU survives). Default (no override) preserves
current GPU0 behaviour exactly.

Live-validated: CPU mode starts with GPU0 full (gemma12b), adds 0 MiB VRAM
to GPU0, serves on :8090, generates (~5 tok/s CPU). The c3 Settings field
that writes STUDIO_DIRECTOR_DEVICE follows in the next commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* c3 Settings: Director placement (CPU / GPU0 / GPU1) + CPU thread cap

Exposes the director-placement lever in the c3 Settings modal so users pick
GPU0 (fast, default) / GPU1 / CPU without hand-editing the .env.

- services.py: director_device() reads STUDIO_DIRECTOR_DEVICE from the repo
  .env (default gpu0, validates the value); set_repo_env_var() upserts a key
  in place (preserves other lines, no duplicates, creates the file if absent).
- app.py: SettingsScreen gains a "Director placement" Select; apply_settings
  persists the choice to the repo .env (the SHARED config gpu-mode reads —
  distinct from c3-settings.json for MODEL_DIR/HF_TOKEN). Applies on the next
  ai-studio start.
- compose: CPU thread cap — -t ${DIRECTOR_THREADS:-8} bounds CPU use so the
  director doesn't starve OWUI's embedder/reranker (also CPU). The ~2.6 GB
  GGUF loads into system RAM (mmap'd; resident in page cache, not run from SSD).
- tests: +6 data-layer (TestDirectorPlacement) + 1 headless apply-settings
  round-trip (persists STUDIO_DIRECTOR_DEVICE, idempotent re-apply). Full
  suite green (728), settings/director subset 13/13.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* tests: fix stale scene names in gpu-mode-list EXPECT

The scene catalog renamed its dispatch keywords to qwen27b / gemma-31b,
but the test's EXPECT spot-check map still referenced the old 27b / gemma
short names — so the JSON-shape assertion had been red on master. Point
EXPECT at the canonical names the catalog now emits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* studio: run director in chat scene as the catalog-support layer

Bring the uncensored director up in the `chat` scene (honoring the
STUDIO_DIRECTOR_DEVICE placement knob), framing chat as the supporting-
infra home — OWUI + LiteLLM + Qdrant + SearXNG + director — for ad-hoc
Catalog models launched via `switch.sh --owui`.

A CPU-placed director uses no GPU, so it's the always-on path: it survives
scene switches and stays live in OWUI. New _director_evict_if_gpu helper
frees only a GPU-resident director when a dual-card LLM scene claims the
cards; mode_off stops it outright. Also brings mode_gemma_int8 in line with
its dual-card siblings (it was missing the studio teardown entirely).

Docs: requirements.md gains a "Chat scene — the Catalog-support layer"
section + reframes director placement around the unified knob / c3 Setting;
video.md note synced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* studio: disable director thinking on CPU only (latency)

The uncensored director is an "Aggressive" reasoning fine-tune that emits
a full <think> trace before every answer. On GPU that's cheap and the
trace lands in reasoning_content (content stays clean), so leave it on.
On CPU (~14 tok/s) the trace dominates latency, so gpu-mode now passes
`--jinja --reasoning off` for the cpu placement only — forcing the
template's enable_thinking=false (this fine-tune ignores /no_think and
--reasoning-budget 0, but honors --reasoning off).

Wired via a new DIRECTOR_THINK_ARGS compose param (empty on GPU). Live:
CPU director now answers in one pass, no reasoning trace, craft quality
intact (full cinematic spec, finish=stop).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* c3: Containers-pane director start honors placement + enumerate sidecars

Two consistency fixes for the Containers tab:

1. Starting studio-director from Containers now honors STUDIO_DIRECTOR_DEVICE
   instead of falling back to the GPU0/thinking-on compose default. New
   director_compose_env() mirrors gpu-mode's start_studio_director translation
   (NGL/CUDA/GPU/THINK_ARGS), injected as an `env K=V …` prefix on the compose
   up cmd (process env wins over --env-file). cpu → -ngl 0 + --reasoning off.

2. The nested studio sidecars (director/gallery/orchestrator/image-shim/
   step-voice/tts) now enumerate when STOPPED, so they're startable rows — not
   only visible while running. New STUDIO_SIDECARS map is the single SoT for
   resolving the container-name → services/studio/<sub>/ project (fixing the
   director↔enhancer name mismatch that previously returned None → docker
   restart, which fails on a fresh install).

+8 tests (director_compose_env cpu/gpu, director resolves to enhancer with the
env prefix, sidecar enumeration). Live: c3 service_start plan starts the director
CPU + no-think (argv -ngl 0 --reasoning off, GPU0 free, clean generation).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

---------

Co-authored-by: noonghunna <10742901+noonghunna@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 09:01:46 +05:00
noonghunna
7daef3ec1e docs(ai-studio): Krea 2 is a real image lane (was "dropped")
image.md: replace the "evaluated and dropped (cloud-only)" note with the lane
write-up — local Krea2 landed in ComfyUI v0.26.0 (#14589); aesthetic/stylized,
aligned (Z-Image stays the uncensored pick). README: 11→12 lanes, +Krea row,
image-lane count 3→5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-24 16:13:42 +00:00
noonghunna
aad1e69d09 studio: one-command setup-ai-studio.sh + auto-install the OWUI pipe
Make a fresh clone go straight to generating, with the single-command UX the Image
Studio beta had — but for the consolidated image+video+audio studio.

- scripts/setup-ai-studio.sh (NEW, canonical): preflight (docker/gpu/~120 GB disk) →
  build ComfyUI image → download_studio_models.sh (full roster) → gpu-mode ai-studio →
  install the OWUI Studio pipe → onboarding. Flags: --yes / SKIP_BUILD / SKIP_DOWNLOAD / SKIP_PIPE.
- push-pipe-to-owui.sh now **UPSERTs**: installs the OWUI `function` row if absent (the
  one previously-manual step — paste into Admin → Functions), else updates it. First-time
  install just needs an OWUI admin account to exist. Validated: INSERT against a DB copy
  (clean row + valid meta JSON), UPDATE live on the running OWUI.
- Retire the now-misnamed setup-image-studio.sh / setup-video-studio.sh → thin redirects to
  setup-ai-studio.sh (they only pulled one modality post-consolidation and still echoed the
  removed `gpu-mode image-studio`/`video-studio` scenes).
- Docs: services/studio/README.md (install is automated) + docs/ai-studio/README.md "Bring it up"
  now leads with the one-command path.

Gate: scripts/tests 57/57; setup scripts syntax-clean; no test references the old script bodies.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-24 03:47:18 +00:00
noonghunna
bf7a62551e Merge pull request #448: c3 two-surface cockpit (Phase R) + AI Studio consolidation
c3 cockpit two-surface realignment (Phase R) + AI Studio consolidation
2026-06-24 07:59:55 +05:00
noonghunna
852820d2c3 docs: note the image-lane quality ceiling + optional HQ upgrade path
Record the 2026-06-24 finding: the image lanes ship the fast/distilled checkpoints
(Z-Image-Turbo, HiDream-O1-Dev), and tuning them is a dead end (measured — Z-Image
steps/sampler/shift identical; HiDream negative-prompt no-op; noise_scale is a calibrated
constant that blanks the image if changed). The only real quality lever is the non-distilled
sibling: Z-Image base (50-step CFG — fits our card, clean drop-in) and HiDream-I1-Full
(50-step CFG — won't fit 2048² with the director resident; needs the director-off-GPU0 lever
+ 1024²/DisTorch). Parked as a future option — the current lanes are strong as-is.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-24 02:20:13 +00:00
noonghunna
11984d19da docs: AI Studio requirements + Wan tuning + director placement
- requirements.md (new): hardware / software / disk / RAM to self-host AI Studio, expressed
  generically (2× 24 GB Ampere+, PCIe ok / no NVLink; ~120 GB disk; 32 GB+ RAM), single-vs-dual-card,
  and the director-placement VRAM lever. Linked from README's deep-dive index.
- video.md: a "Wan2.2 — tuning & limits" section (recipe + the sampler finding, 480p default /
  720p-DisTorch valve, the corrected length-ceiling table, i2v-seeded chaining) + Wan model files in
  the manifest. The ceiling table now shows the director as the single-card swing factor (121↔161)
  and adds the DisTorch both-card column.
- Director placement documented as a lever (default GPU0; STUDIO_DIRECTOR_GPU / -ngl 0 relocate it),
  with the caveat that GPU1 is unsafe for the LTX lanes (their 22 GB donor) — CPU is universal.
- The director carries its model name (Qwen3.5-4B-Uncensored) in the services manifest, matching the
  lane-naming convention.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-24 01:37:55 +00:00
noonghunna
5c2ed400d2 docs: Z-Image + Wan2.2 lanes (11 lanes); Krea2 dropped (cloud-only)
- README.md: 9→11 lanes, +Wan2.2 / +Z-Image rows, video labels aligned to the unified
  `Studio · Video (Model)` naming.
- image.md: +Z-Image lane (table + section) + the "Krea2 dropped — cloud-only, no local
  detection" note.
- video.md: four video lanes now (LTX / Sulphur / 10Eros / Wan2.2); Wan caveats (text→video,
  no synced audio, 832×480) in the capabilities table; 8→11-lane matrix ref.
- services/studio/README.md: 9→11 picker entries + the two new workflow-graph rows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-24 00:16:33 +00:00
noonghunna
813ddf94d8 docs: ai-studio consolidation pass (one scene, lanes inside it)
Sweep the studio docs to match the consolidation: `image-studio` /
`video-studio` / `comfyui` scene refs → the single `ai-studio` scene, drop the
gemma-12b chat-on-the-other-card framing, and document the new pieces.

- README: 8→9 lanes (+10Eros); "Lanes vs modes" → "One scene, lanes inside it".
- video.md: model manifest LoRA `-384`→`-384-1.1`, +10Eros unet row, lane matrix
  +🔓 10Eros, VRAM note → `ai-studio`.
- audio.md: step-voice ⊕-video mutex bullet (c3 guards it) + start-from-c3 note.
- image.md / FAQ.md / services/studio/README.md: scene-name + bring-up fixups.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-06-23 23:43:47 +00:00
noonghunna
05962838cf docs(upstream): add ParserEngine tracker rows (#45413, #45588)
UPSTREAM.md rows authored by qwen max while assisting on this repo and left
uncommitted; landing them on master per the direct-commit-for-docs convention.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 01:23:38 +00:00
Ryan Ludwig
611587dff3 docs(upstream): clarify #40812 is merged-but-insufficient; point at #43923
expandable_segments around the cumem sleep-mode pool, not the
custom_all_reduce graph-buffer registration path — so it does not cover
this crash. The open in-engine fix for our path is #43923; that's the
drop condition for the detect_nvlink.sh guard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-20 23:42:41 +00:00
Ryan Ludwig
f5d5dca09a fix(nvlink): strip only expandable_segments on custom-AR path
Dual composes inject PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True,...
for the PCIe (custom-all-reduce OFF) path. On NVLink / patched-PCIe-P2P
rigs detect_nvlink.sh turns custom all-reduce ON, where expandable_segments
backs allocations with a cuMemMap VA range that cudaIpcGetMemHandle rejects
during graph-buffer registration -> custom_all_reduce.cuh:455 'invalid
argument', worker dies at boot.

The prior fix clobbered PYTORCH_CUDA_ALLOC_CONF to max_split_size_mb:512,
discarding any other knob the user set (custom max_split_size_mb,
garbage_collection_threshold, ...). Instead strip ONLY the expandable_segments
token on the P2P path and keep the rest; fall back to max_split_size_mb:512
when nothing remains. The PCIe path keeps expandable_segments untouched.

Strengthen test-detect-nvlink-alloc-conf.sh to assert the surgical contract
(preserve neighbors, strip in any position, no dangling commas) and add the
vllm#42609 row to docs/UPSTREAM.md (its "DP>1 AND TP>1" title under-scopes
the bug; the same cuh:455 crash fires TP-only -- cf. vllm#42583 / vllm#45604).

Validated on a 2x RTX 3090 NVLink rig (TP=2, NV4): before, boot crashes at
custom_all_reduce.cuh:455 'invalid argument'; after, the dual stack boots
clean (custom AR ON, expandable_segments stripped), /v1/models ready, serves
a completion.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-20 23:41:47 +00:00
Ryan Ludwig
2549563ac2 docs: mark transformers>=5.8.0 / gemma4_assistant upstream row resolved (#453)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-21 04:40:48 +05:00
Ryan Ludwig
1e9f92b7a7 docs: fix vLLM upstream table render (drop stray blank line) (#452)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-21 04:40:45 +05:00
noonghunna
5cedde3572 Pull gate: actionable messages for uncurated derives of curated models (#424)
Three related [C0]/eligibility pull-gate fixes for the curated-swap surface —
an uncurated derive (abliterated / fine-tune) of a model we already serve.

1. Wrapper-arch alias. `pull.sh --profile-like` was false-aborting at [C0] with
   "no arch_patches matrix row for 'Qwen3_5ForConditionalGeneration'". That is
   the OUTER multimodal wrapper class the weights report; the patch matrix is
   keyed on the inner canonical `Qwen3NextForCausalLM`. arch_patches.yml is a
   closed key-set, so the alias lives in the editable arch_model_xref.
   - profile_runtime.yml: `config_architectures: [Qwen3_5ForConditionalGeneration]`
     on the Qwen3NextForCausalLM xref entry.
   - generate_compose.py: `resolve_arch_from_config()` maps a config.json
     architectures[0] string -> (canonical_arch, arch_row) via that alias.
   - gates.py [C0]: resolve the wrapper arch via the alias before declaring
     NO_ARCH_ROW. The hybrid now reports ENGINE_SUPPORTED.

2. GGUF axis. `supported_weight_formats` was declared on every engine but never
   enforced (only `kv_format` was). The deriver blocks GGUF on the derive path,
   but the curated registry / curated-swap path had no such guard. gates.py [C0]
   now rejects a `gguf` weight_format on an engine whose supported_weight_formats
   lacks `gguf` (structural axis; matches the `gguf` token only, so a derive's
   raw dtype spelling bf16/float16 is never false-rejected).

3. Won't-fit size advisory. The eligibility no-fit-model abort for a hybrid/MoE
   derive now appends (a) an actionable NOTE pointing at the curated-swap path +
   docs/BRING_YOUR_OWN.md, and (b) a coarse weights-only VRAM verdict: when the
   raw weights exceed the detected topology's total VRAM they won't fit at ANY
   KV, so say so concretely (the huihui abliterated bf16 ~54 GB vs 2×24 GB case)
   instead of a generic stop. `_weights_oversize_advisory()` is pure/total —
   empty when it fits / size unknown / headless.

Docs + tests:
   - BRING_YOUR_OWN.md: new section C — "Swap a curated model for a fine-tune /
     abliterated variant -> reuse its compose" (artifact↔engine + quant + MTP
     caveats, worked example).
   - test-pullgate-gates.sh: wrapper-arch ALIAS [C0] case + resolve_arch_from_config()
     unit + GGUF-on-vLLM runtime-incompatible + no-false-positive control +
     _weights_oversize_advisory() unit (oversize / fits / headless / malformed).

Co-authored-by: noonghunna <10742901+noonghunna@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 01:10:01 +05:00
noonghunna
35a69650fe feat(catalog): add 🐣 Incubating status tier + VibeThinker-3B (incubating)
Introduce a new pre-experimental status tier, `incubating`, for composes that
work but aren't ready for the actionable list — niche specialists or models
that fail the standard functional gate by design. Incubating composes are
HIDDEN from `switch.sh --list` by default (revealed by `--list --all`) and
launch-gated behind `--force` (non-functional), so a half-validated model is
catalogued and discoverable without cluttering the recommended set.

Tier wiring (reuses the existing status plumbing — no new emit column):
- compose_registry.py: `incubating` in STATUS_VALUES + `🐣` in COMPOSE_STATUS_EMOJI
  (stays out of FUNCTIONAL_STATUSES → --force-gated, never auto-defaulted)
- switch.sh: both --list filters skip incubating unless --all, with a
  `(+N incubating hidden — --all)` header note
- AGENTS.md: Status enum row + Caveats-required references
- docs/ADDING_MODELS.md: new rule — NEW MODELS START at 🐣 Incubating, promote
  up the enum (🐣🧪⚠️/) as they earn the actionable list

First occupant — VibeThinker-3B (WeiboAI, Qwen2 dense reasoning fine-tune):
- `vllm/vibethinker-3b-single` — bf16 weights + fp8_e5m2 KV, single 3090,
  full 131072 ctx, mem_util 0.40 (~9.8 GB, single-concurrency sized),
  --reasoning-parser qwen3, no tool-calling
- Live-validated 2026-06-16: serves clean correct reasoning/code (~110 TPS),
  qwen3 parser splits <think>. fp8 WEIGHTS rejected (break the quant-sensitive
  3B: non-terminating empty output). Always-reasoning + no-tools → fails
  verify-full's fixed-small-budget checks (5/9) by design → incubating, not gate-passing.

Guard suite 47/47 green (nex-n2-mini parked aside; it's an unrelated local experiment).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 15:03:06 +00:00
noonghunna
a728832f60 docs: add ANNOUNCEMENT_TEMPLATE.md (Announcements-post skeleton)
Distills the #350 Deckard-40B post into a reusable 'we shipped X' skeleton
that wraps a Results Card (intro+credits / Results Card / getting it / run it
/ what'd help / credits). References RESULTS_CARD.md for the measurement panel
rather than duplicating it; wired into the docs/README.md reference index.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 12:02:24 +00:00
DeuceBucket
6be52294c8 feat(weights): optional revision: pin in weights-fetch schema (#319) (#408)
adds an optional `revision:` key per weights variant. weights.py emits
WEIGHT_REVISION; setup.sh threads it into `hf download --revision` and
pins the post-download sha-verify etag lookup to the same revision, so a
stale pin can't false-fail against a newer HEAD. preflight's manual hint
mirrors the flag. unset = track HEAD, so behavior is unchanged for every
current entry (nothing sets revision: today).

this is the weights half of #316: upstream quant repos re-quant
silently, and we had no lever to pin the bytes a BENCHMARKS row was
measured against. engine images already pin; weights didn't. mechanism
only, no real entry is pinned in this PR (that's a per-entry,
rig-validated call that's yours to make).

refs #319, #316
2026-06-15 06:35:43 +05:00
noonghunna
8e38f7a5ec docs(UPSTREAM): #39598 MTP-streaming tool-call drop is un-mitigated on v0.22.0 (P64 retired); #145 closed
The streaming sweep for the qwen3_xml PR (#400) surfaced the real picture:
- #39056 auto+thinking+streaming is fixed natively on v0.22.0; the qwen3_coder→
  qwen3_xml swap is a no-op (byte-identical A/B, both parsers) → PR #400 closed.
- The residual #145 failure is tool_choice=required + thinking + streaming, and
  it's MTP-gated: confirmed 2026-06-13 (scripts/stream-toolcall-probe.py) MTP n=3
  dropped 13/20, no-MTP clean 0/20, parser-independent. That's #39598 (MTP
  streaming early-return) resurfacing — its Genesis P64 mitigation was retired
  with Genesis (#182/#254), so the drop shipped silently back into the dual
  composes (benchlocal is non-streaming; verify-full's streaming check has no
  tools, so neither caught it).

Updated both rows; mitigation = tool_choice=auto (clean w/ MTP) or no-MTP;
durable fix is upstream (#45413 is parser-side, likely doesn't cover the
spec-decode-streaming path).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 22:55:19 +00:00
noonghunna
2c904d3d40 ik-llama: migrate spec-dec flags to --spec-type + digest-pin the image (#401)
The rolling ghcr.io/ikawrakow/ik-llama-cpp:cu13-server tag moved (2026-05-23
-> 2026-06-10, digest 5f914f1c) and the new build REJECTS the legacy
speculative-decode flags: "legacy speculative option '--multi-token-prediction'
is disabled; use --spec-type mtp:n_max=1,p_min=0.0". Every ik-llama MTP compose
crash-restart-loops on a fresh pull (reported by furfix, Discord — single 3090
WSL). The binary's own --help confirms `-mtp`/`--draft-*`/`--spec-stage` are all
rejected in favour of the unified `--spec-type SPEC[:k=v,...]`.

Flag migration (13 composes):
- 11 MTP composes: --multi-token-prediction + --draft-max N + --draft-p-min P
  -> --spec-type mtp:n_max=N,p_min=P (per-compose N preserved).
- 2 two-stage composes: the ngram-mod + mtp cascade used the rejected
  --spec-stage with legacy keys -> --spec-type ngram-mod:...,ngram_size_n=... +
  --spec-type mtp:...,p_min=... (spec-ngram-size-n -> ngram_size_n,
  draft-p-min -> p_min, the canonical keys).

Digest-pin (decided to stop the recurrence — this is the 2nd flag churn from
the moving tag; ik-llama has no engine profile, so the per-compose image:
default is the only pin point): :cu13-server -> @sha256:5f914f1c... in all 13
ik composes + the preflight test fixture + 3 docs (IK_LLAMA / SINGLE_CARD /
INFERENCE_ENGINES). VLLM-style central injection isn't available for ik-llama;
a follow-up could add an engine profile so future pins are one-line.

Live-validated on the pinned image (single 3090):
- ik-llama/iq4ks-mtp: healthy, 0 restarts, no legacy error, MTP context ready,
  served a completion, draft acceptance 0.62 (26/42).
- ik-llama/iq4ks-two-stage: healthy, 0 restarts, both stages load
  (ngram_mod n=16 + MTP context ready), speculative decoding initialized.

Full test suite green (test-compose-registry-disk pre-existing on an unrelated
untracked model dir). The 3 untracked nex-n2-mini ik composes also carry the
rolling tag but are out of scope here (in-progress catalog work).

Co-authored-by: noonghunna <10742901+noonghunna@users.noreply.github.com>
2026-06-14 00:21:35 +05:00