Commit Graph

320 Commits

Author SHA1 Message Date
vh 569e1af9ca feat(homepage): split AI fleet into role-based groups on a dedicated AI tab
Move the ~22-service flat "AI Systems" group off the Main tab into a new
four-tab layout (Main / AI / Infrastructure / Toolchain). The AI tab sorts
the inference fleet by function into seven groups:

  AI - Inference        gen, char-rp, char-rp-reasoning, Granite summarizer
  AI - Eval & Retrieval Selene, Skywork Reward, Qwen3 rerank/embed, image-bench
  AI - Gateways & Chat  LiteLLM, Asset Engine, Gateway Chat, Open WebUI, ...
  AI - Speech (TTS)     Chatterbox Fast, Kokoro, mOrpheus
  AI - Audio Tools      Parakeet ASR, YT Voice Clipper
  AI - Image & Media    ComfyUI, Arbo
  AI - Dormant          stopped rollback seats + retired auditions

Relabel each stack's homepage.group so canonical stacks/ matches the live
containers on ana-ml2, ana-docker, and irv-ml1. Dormant stacks were refreshed
with `docker compose up --no-start` so they carry the new label while staying
stopped (compose-start rollback preserved). settings.yaml drives tab/order/
columns; services.yaml and README updated to the new scheme.
2026-07-14 20:05:50 -07:00
vh f960a73a79 feat(char-rp-gguf): swap reasoning seat Deckard-PKD → NEO-CODE (Heretic2-Thinking Qwen3.6-27B)
R36 gate (2026-07-14) validated NEO-CODE ships on all axes: tool-calling 0.967
(attach_tool 1.00, 0 runaways — #355 eliminated), prose genre-artifact-fine
(less clichéd than gen), refusal uncensored-as-spec + CSAM-clean.

#355 root cause was MODEL-level, not the reasoning-budget-forcing bug: Deckard
emitted Qwen's native qwen3_coder XML tool format malformed -> llama.cpp leaked
the closing tags into the arg value -> Bifrost attach_tool schema error -> retry
-> reasoning runaway to max_tokens. NEO-CODE emits the same native format cleanly
on the same seat/parser -> no schema error -> no runaway. The fix was the model
swap; there was never a wrong parser (the XML is Qwen3.5/3.6-native).

- reasoning seat: Deckard-PKD (Qwen3.5) -> NEO-CODE=Heretic2-Thinking (Qwen3.6-27B) Q5
- samplers: card defaults (temp 1.0 / top_p 0.95 / top_k 20 / min_p 0.0), DRY dropped
- ctx: 256K max; custom llama.cpp kept (qwen3_coder parse + PR#25544 belt-and-suspenders)
- persistent-memory ACTIVE 1 marked resolved
2026-07-13 22:21:10 -07:00
vh 85792f4b55 feat(char-rp-gguf): swap reasoning seat to custom llama.cpp (master 6eddde0 + PR #25544)
The char-rp-reasoning (Deckard) seat now runs llamacpp-charrp:custom-latest via a
new LLAMA_REASONING_IMAGE var (Magidonia char-rp stays on stock — no reasoning bug).
Fixes Worldtree #355 at the source (budget multi-terminator handles Qwen3.5's
<tool_call> reasoning end-tag). Live 2026-07-13: Deckard loads on Blackwell, serves
coherent, reasoning bounds at the 400 budget. Rollback via .env LLAMA_REASONING_IMAGE.
2026-07-13 13:47:42 -07:00
vh 6cf3e78973 docs(char-rp-gguf): record custom llama.cpp build (master 6eddde0 + unmerged PR #25544)
Durable record of the custom llama.cpp the char-rp-reasoning seat will run to
fix Worldtree #355 (reasoning-budget forcing broken in stock b8840 — single
end-tag </think> can't match Qwen3.5's <tool_call> reasoning terminator, so the
budget never force-closes and reasoning runs away to max_tokens). PR #25544
adds multiple terminating sequences; unmerged upstream, so we build it.

- build.sh: reproducible recipe (clone master@6eddde0 + merge PR #25544 +
  resolve the 1 server-common.cpp conflict + CUDA build for Blackwell sm_120)
- README.md: why + acceptance test + rollback + REMOVE-WHEN-MERGED tracking

Image llamacpp-charrp:6eddde0-pr25544 BUILT + smoke-tested on ana-ml2; seat
swap pending. See also auto-memory reference_charrp_custom_llamacpp_pr25544.
2026-07-13 13:37:00 -07:00
vh a5735147d4 docs(morpheus): agent system prompt for quoted-text voicing + tag discipline
Drop-in system prompt for an agent whose quoted output is voiced by mOrpheus: speak in
double quotes (only quoted text is voiced), phrase each quoted line as one coherent
utterance (per-quote prosody), and the sparse/boundary/no-stack tag rules (measured
stability on the early checkpoint). Lists the honored tag set.
2026-07-09 02:02:40 -07:00
vh f295cc1f46 fix(gateway-chat): chunk by quoted section, not sentence (prosody)
Per-sentence chunking generated each sentence cold, flattening intonation/prosody that
spans the whole quoted line. Chunk by QUOTED SECTION instead — each contiguous quote is
generated whole (max_tokens 2400) so its prosody stays intact; multiple quotes in a reply
still play serially on the shared clock. extractQuotes already returns exactly these spans;
dropped splitSentences.
2026-07-09 01:54:39 -07:00
vh a1f3023f70 feat(gateway-chat): pre-chunk quoted text by sentence, play serially
Split the quoted dialogue into sentences and stream each as its own short /tts/stream
request (max_tokens 900), queued back-to-back on one shared AudioContext clock (speechHead)
so playback is gapless and in order. First sentence starts fast; each chunk is short so it
generates cleanly (no ramble/cap risk); the next sentence generates while the current plays.
A newer reply supersedes via the ttsGen counter; 🔊 replays.
2026-07-09 01:49:45 -07:00
vh 033f3685f5 fix(gateway-chat): resume AudioContext on user gesture (no-sound / autoplay)
Browsers suspend the Web Audio AudioContext until a user gesture; speakQuotes fires on
reply-complete (no active gesture), so a suspended context played silently. Prime/resume
the context on any click or keydown (capture phase) so it's running before playback.
Server side was fine throughout (/tts + /tts/stream both 200 with valid audio).
2026-07-09 01:41:26 -07:00
vh 0655a37bf6 feat(morpheus): staged clone voices + max_tokens 3500 (context-clamped)
- max_tokens default 2400->3500 (~42s) in wrapper + gateway-chat client, with a _cap()
  clamp so prompt+gen never exceeds MAX_CTX (4096) — a cloning ref block is ~1100 tokens,
  so an unclamped 3500 would overflow context on the clone path.
- Staged clone voices: /voices dir of <name>.wav + <name>.txt, each encoded to its Orpheus
  reference block at startup; voice="<name>" zero-shot clones it. Beatrice (a chatterbox
  reference) staged as the first normal-voice clone. GET /voices lists baddy + clones.
- compose: mount voices dir + pass MORPHEUS_MAX_LEN to the wrapper (clamp must match engine).

vLLM concurrency (measured, --max-num-seqs 8, 250-tok reqs): near-linear batching — 8
concurrent finish in the same ~2.8s as 1 (707 tok/s, 8.1x single, flat per-req latency).
Chunked-sentence production can fan out for ~8x throughput; CPU SNAC decode is the scale
bottleneck, not generation.
2026-07-09 01:35:14 -07:00
vh f363fe6c84 fix(morpheus): raise TTS max_tokens 1200->2400 (long lines clipped at ~14.6s)
Cut-offs were the max_tokens=1200 ceiling (~14.6s of audio), not memory (~1250 tokens
<< 4096 context). Diagnosis: the repetition penalty is load-bearing for clean stops —
rep 1.0 => the model never emits end-of-speech and rambles to the cap; rep 1.1 (the
wrapper default) => clean natural stop. So normal lines already complete; only genuinely
long dialogue (>~14.6s, ~25+ words) hit the cap. Raised default + client max_tokens to
2400 (~29s), still within the 4096 context (no memory cost). Verified: a 49-word line
now finishes at 16.73s (was clipped at 14.6s).
2026-07-09 01:25:56 -07:00
vh da7682969b feat(morpheus,gateway-chat): streaming decode — TTFA ~4.5s -> ~0.8s
Wrapper gains POST /tts/stream: reads the vLLM token stream, decodes SNAC in WINDOWED
CHUNKS (every 6 frames, decode [2 ctx | 6 | 2 ctx] and emit only the middle 6 — context
both sides => seamless), and streams raw PCM16 (24kHz mono) as it generates. Windowed
(not per-frame) because per-frame CPU decode's per-call overhead x ~60 frames serialized
to ~7s (RTF 2.2); windowed keeps up (RTF ~0.97). Whole-clip /tts kept for non-browser use.

gateway-chat plays the stream via the Web Audio API (fetch reader -> int16->float32 ->
scheduled AudioBufferSourceNodes on a running clock; a new reply supersedes the prior
stream via a generation counter; 🔊 replays). Measured: TTFA 0.80s (was ~4.5s whole-clip),
RTF 0.97, full-duration match. CORS already covers the new route.

Deployed: tts rebuilt on irv-ml1, page pushed to ana-docker.
2026-07-09 01:14:25 -07:00
vh c948013a36 feat(gateway-chat): auto-voice quoted dialogue via mOrpheus TTS
Gateway-chat now auto-plays quoted text from each assistant reply through the mOrpheus
TTS endpoint. Sidebar gains a 🔊 toggle + endpoint/voice fields (persist in localStorage,
prefilled to irv-ml1:8299 / baddy). On reply-complete, straight and typographic double
quotes are extracted, joined, POSTed to /tts, and the returned WAV plays (click 🔊 to
replay; a new reply interrupts the prior clip).

Requires CORS on the wrapper (page served from ana-docker:8091 fetches irv-ml1:8299
cross-origin) — added CORSMiddleware(allow_origins=[*]) to the mOrpheus tts app (internal-
only endpoint). Verified end-to-end: preflight + POST return ACAO=*, valid 24kHz WAV.

Deployed: tts container rebuilt/recreated on irv-ml1; page pushed to ana-docker conf
(bind-mounted, live on next request).
2026-07-09 00:58:13 -07:00
vh 01eedd8d27 feat(morpheus): permanent mOrpheus TTS stack (vLLM bf16 + SNAC/FastAPI wrapper) on irv-ml1
Two-container stack serving MrDragonFox/mOrpheus (uncensored Orpheus TTS, Llama-3.2-3B
-> SNAC 24kHz). vllm-morpheus (GPU/3090) emits Orpheus audio tokens; morpheus-tts (CPU)
SNAC-decodes them to WAV and exposes POST /tts (baddy voice + zero-shot cloning). Deployed
+ tested end-to-end (28/28 valid frames, valid WAV, reachable over WG).

Hard-won config, all encoded in compose/README:
- bf16 REQUIRED: --quantization fp8 destroys audio-token generation (0 valid SNAC frames
  even at greedy). Footprint ~7.9GB.
- Image PINNED to v0.23.0: 'latest' ships Blackwell oink/aiter kernels that crash on Ampere
  import.
- 3090 (not the comfy-contended A6000); --enforce-eager to fit the shared card.
- RTF ~1.0 end-to-end (gen ~98 tok/s / RTF 0.84 + CPU decode + HTTP).

INTERNAL RESEARCH ONLY (CC-BY-NC-4.0); do not expose externally.
2026-07-09 00:49:25 -07:00
vh 99a4a1721f config(litellm): name gen backend by real model (aeon → qwen3.6-35b-a3b-heretic)
The gen seat's vLLM served-name was still qwen3.6-27b-aeon, a stale skin
left over from the AEON-27B → 35B-A3B-heretic swap — it named neither the
right family (aeon) nor size (27b vs 35B-A3B). Renamed the served-name to
qwen3.6-35b-a3b-heretic (+ -thinking) on ana-ml2 :8015 via the stack .env,
and repointed litellm's gen / gen-reasoning / summarizer-large model refs +
comments to match, so /v1/models, the gateway config, and spend-logs all
reveal the actual model in the request path.

Verified end-to-end: gen -> 'PIPELINE OK', gen-reasoning -> content + reasoning
surfaced, all three aliases healthy. char-rp / char-rp-reasoning untouched.
2026-07-08 18:40:08 -07:00
vh 4954ca0831 docs(char-rp-reasoning): Deckard samplers dvalin-confirmed canonical + tuning ladder
dvalin confirmed the live A/B-proven set IS canonical for Deckard as a dark-RP reasoning seat:
temp 1.0/top_p 0.95/top_k 40/min_p 0.05, no presence/rep penalty, DRY 0.8 server-side. Endorsed
over the card's base-thinking (top_k 20/min_p 0/presence 1.5). No value change; comment + memory
record the confirmation + tuning ladder (flat->min_p 0.08, loops->DRY 0.9, over-damped->DRY 0.6/off).
2026-07-08 15:44:33 -07:00
vh 41305bf62c config(char-rp-gguf): Deckard reasoning seat to full 256K (GDN-hybrid KV cheap)
Deckard (Qwen3.5-27B) native ctx = 262144; GDN-hybrid arch (16 KV-caching layers) makes KV
cheap (8.7G q8_0 @ 256K vs Magidonia 10.9G @ 128K/40 dense layers). Bumped 40960 -> 262144;
GPU0 ~4G free (static -> stable). Canonical RP-reasoning samplers pending dvalin (card has
only generic base-Qwen3.5 profiles); empirical temp1.0/top_p0.95/top_k40/min_p0.05+DRY0.8 live.
2026-07-08 15:41:02 -07:00
vh 5f79b40982 feat(char-rp-reasoning): Deckard-PKD (Qwen3.5) replaces RpR-v4 after autonomous A/B
Operator wanted a reasoning-RP model that tolerates DRY (RpR-v4 forbids rep/DRY -> a
1/30 loop tail). Ran the full A/B on brokkr's 30-prompt D1 suite (content-only, slop-scored):

- Deckard-PKD (Qwen3.5-27B, DavidAU creative tune) WON: 0/30 loops, 0/30 refusals, clean
  managed reasoning (native Qwen3.5 <think>/enable_thinking), DRY-tolerant, ~57 tok/s,
  runs on the base llama-swap b8840 image. -> now the char-rp-reasoning seat (:8018).
- RpR-v4: 0 refusals but 1/30 loop (no-DRY). Pantheon-27B: clean slop but 7/30 explicit
  refusals + needs the newer ggml-org/llama.cpp image (Qwen3.6 won't load on b8840).
  Snowdrop + Gembrain (Gemma-4): floored (llama.cpp can't manage their reasoning without
  the vetoed template hacks). Losers kept on disk as alternates.
- char-rp (Magidonia) unchanged; gen unchanged. gateway char-rp-reasoning -> Deckard
  sampler (temp 1.0/top_p 0.95/top_k 40/min_p 0.05; DRY server-side).
2026-07-08 15:07:04 -07:00
vh f49c4e40a3 config(char-rp-gguf): char-rp to full 128K, funded by gen util 0.40->0.37
Completes the GPU0 rebalance discussed with the operator:
- gen util 0.40 -> 0.37 (qwen36-27b-aeon stack .env) — frees ~2.9G of gen's IDLE KV
  headroom (gen KV usage runs 0-2%; concurrency-at-256K 4.74x -> 3.66x, invisible).
- char-rp (Magidonia) 96K -> 131072 (full native 128K), q8_0 KV ~10.9G.
- char-rp-reasoning unchanged at 40K (QwQ native max).
- GPU0 ~4.4G margin, all 3 seats healthy, verified live.

Deployed .env values already set on ana-ml2; this canonicalizes the intent + rationale.
2026-07-08 13:01:22 -07:00
vh aac4bcfa3e feat(litellm): wire canonical sampler defaults for all 4 gateway seats
dvalin-smithy canonical set, infra-ops triaged + char-rp A/B-validated on the live serve.

- gen (+summarizer-large twin): presence_penalty 1.0 -> 1.5 (Qwen3.6 non-thinking rec).
- gen-reasoning: temp 0.6 -> 1.0, presence 1.0 -> 1.5 (Qwen general-thinking profile;
  the old 0.6 was the coding sub-profile).
- char-rp: temp 1.0 -> 1.1, min_p 0.03 -> 0.10, top_k 0, NO rep. A/B on 2 dark-romantasy
  prompts: min_p 0.10 richened imagery; repeat_penalty 1.05 REJECTED (injected a stray
  markdown title, hurts Drummer/Magistral RP creativity per the card + dvalin's own note).
- char-rp-reasoning: add explicit top_p 0.95 (else per the RpR card: no rep/DRY/XTC).

Canonical reference: docs/pfi/model-sampler-defaults.md (mirrors dvalin's derivation).
2026-07-08 11:10:28 -07:00
vh f5706046b1 feat(char-rp-gguf): max context — char-rp 96K, char-rp-reasoning 40K, q8_0 KV
Raise both RP seats to near-max context within the GPU0 budget using q8_0 KV cache
(near-lossless 8-bit, ~2x context/GB, flash-attn-backed). Verified coherent on both
(no Qwen KV-quant gibberish) at 64/50 tok/s.

- char-rp (Magidonia): 16K -> 96K (native 128K; 128K would starve the reasoning seat).
- char-rp-reasoning (QwQ): 16K -> 40960 (QwQ native max; beyond needs YaRN).
- kv_unified=true -> a single conversation gets the full n_ctx (slots share the pool).
- GPU0 ~93/97G, ~4.3G margin (gen fixed-util + static KV = stable, no OOM risk).
- New .env knobs: CHARRP_CTX / CHARRP_REASONING_CTX / CHARRP_KV_TYPE / CHARRP_REASONING_KV_TYPE.
2026-07-08 07:29:49 -07:00
vh b268f93035 feat(char-rp-gguf): replace broken Angel NVFP4 with dual GGUF RP seat on ana-ml2 GPU0
char-rp        -> TheDrummer Magidonia-24B-v4.3 Q6_K (Magistral prose, ~65 tok/s,
                  zero refusal, tight POV) via llama.cpp (:8016).
char-rp-reasoning -> ArliAI QwQ-32B-RpR-v4 Q5_K_M (abliterated managed reasoning,
                  ~52 tok/s, reasoning surfaces in reasoning_content) via llama.cpp (:8018).

- New canonical stack stacks/char-rp-gguf/ (llama-server x2, GPU0-pinned, ~86/97G
  co-resident with gen). GGUF sidesteps the vLLM-NVFP4 + Mistral-tokenizer traps that
  killed the Angel serve. Never Ollama.
- Best-of-breed per seat: no single dense 24-32B is both an elite non-thinking prose
  seat AND a clean managed-reasoning seat on llama.cpp (Magidonia [THINK] boundary is
  loose; Cydonia-R1 <think> runs away; QwQ is template-managed). Pantheon-Reasoning-27B
  stays rejected (re-censors in <think>; RpR-v4 abliterated reasoning is the fix).
- Gateway rewired: char-rp->:8016, char-rp-reasoning->:8018, Mistral/QwQ samplers,
  dropped the Qwen enable_thinking kwarg. One-model Magidonia fallback documented.
- Retired the ms32-24b-angel stack.
2026-07-08 02:43:00 -07:00
vh e6ab51c74a feat(aeon): deploy Qwen3.6-27B AEON as gen + char-rp, displace qwopus
New stacks/qwen36-27b-aeon: two co-located vLLM serves on ana-ml2 GPU0 —
gen (:8015, MTP off) and an RP seat (:8016, native MTP) — dense Qwen3.6-27B
(qwen3_5 GDN-hybrid, uncensored/abliterated), ModelOpt-NVFP4, multimodal,
256K context, depends_on-sequenced util split (~0.50/0.45). Each serve
carries a base + `-thinking` served-name so the `-reasoning` gateway records
target distinct LiteLLM deployments — otherwise a thinking-off request mutates
the shared litellm_params and clobbers enable_thinking (the shared-config
footgun that silently disabled char-rp-reasoning).

Gateway (stacks/litellm/conf/config.yaml): gen / gen-reasoning /
summarizer-large -> AEON :8015; char-rp / char-rp-reasoning added -> RP seat
:8016 (Qwen-RP sampler recs); gen-reasoning -> `-thinking`, char-rp-reasoning
-> `-rp-thinking`. Retired qwen3.5-122-a10b[-reasoning] + qwen-large[-reasoning]
(qwopus displaced; those named a 122B that no longer serves gen).
2026-07-06 00:53:38 -07:00
vh 624a07e9c2 docs(litellm): record glm-5.2 canonical limits in gateway config comment
Probed live vs z.ai 2026-07-05: glm-5.2 = 1,048,576-token (1M) input context,
131,072 (128K) max output; no gateway-side cap (pure z.ai passthrough). Comment-only,
no runtime effect.
2026-07-05 09:09:05 -07:00
vh 681eb705a2 Revert "ops(litellm): repoint gen/qwen-large/summarizer-large aliases -> qwen3.6-40b-deckard (Deckard trial)"
This reverts commit b63c48b19b.
2026-07-01 08:19:58 -07:00
vh b63c48b19b ops(litellm): repoint gen/qwen-large/summarizer-large aliases -> qwen3.6-40b-deckard (Deckard trial)
Displaced qwopus-122B on ana-ml2 GPU0:8013 with robbatt/Qwen3.6-40B-Deckard-NVFP4
(stock vLLM 0.23.0, loaded clean: hybrid attn + multimodal + fp4_gemm all green).
Repointed the 5 role aliases (gen, gen-reasoning, qwen-large, qwen-large-reasoning,
summarizer-large); added the qwen3.6-40b-deckard true-name record; left the true
names qwen3.5-122-a10b[-reasoning] to 404 (no-false-alias). Operator-directed
trial-by-fleet-traffic; revert path in the config banner + live backup
config.yaml.bak-pre-deckard-20260701-001036.
2026-07-01 00:18:40 -07:00
vh b9dcbc199f litellm(granite): revert temperature 0.1 -> 0 (research-dictated)
dvalin evidence pass: IBM canonical is temp 0; greedy-loop risk is an
open-ended-generation phenomenon, not summ/classify; temp 0.1 reduces
classification reproducibility without fixing loops (use repetition/presence
penalty if loops appear). image-judge stays 0 (Qwen judge card + W&B judge
practice = temp 0 for reproducibility; NVFP4-needs-0.1 unsupported). Both
gateway temps now 0, vendor-canonical.
2026-06-27 09:40:47 -07:00
vh 9a772ec1ae litellm(granite): temperature 0 -> 0.1 (near-greedy floor)
Operator call: avoid pure-greedy rigidity/loop-risk on granite summ/classify
while staying near-deterministic; matches the house nonzero-temp-floor lean.
image-judge held at temp 0 (scoring reproducibility) pending operator review.
2026-06-27 09:31:15 -07:00
vh 95d0b38d0a litellm: canonical defaults for granite + GLM (completes fleet sweep)
- granite-4.1-8b (+ summarizer/classifier): temperature 0 (IBM vendor-canonical
  "temp 0 for inferencing"; top_p/top_k no-ops at temp 0, omitted). Deterministic
  baseline for summ/classify; creative callers override.
- GLM family (z.ai cloud): temperature + top_p 0.95 only (the ONLY params z.ai
  chat API accepts per its OpenAPI schema; top_k/min_p/penalties absent -> not set).
  temp 1.0 for glm-5.1/5.2/5-turbo/4.7 + gen-frontier; temp 0.6 for glm-4.5-air.
  Matches z.ai API defaults -> explicit-over-implicit, future-proofs vs vendor drift.
Round-2 dvalin-researched (provenance-labeled), verified live, granite+glm smoked 200.
Embeddings/rerankers excluded (no sampling). Fleet-wide canonical-defaults sweep complete.
2026-06-27 08:33:43 -07:00
vh 4f094fa653 litellm: canonical general-use sampling defaults across gateway models
Per operator directive (overrideable defaults => sane optimal general-use
sampling on every served model, for quality not just repetition):
- qwen3.5-122-a10b: thinking-split canonicals (non-thinking temp 0.7/top_p 0.8;
  thinking temp 0.6/top_p 0.95; top_k 20 both), keep presence_penalty 1.0.
  Fixes the non-thinking routes previously running thinking-mode sampling.
- qwen-image-bench / image-judge: deterministic judge profile temp 0 / top_k 1 /
  top_p 1.0 / repetition_penalty 1.05.
- selene-1-mini-8b / chat-judge: temp 0.6 / top_p 0.9 (gen_config).
vLLM-only params (top_k, repetition_penalty) in extra_body to survive
drop_params. Values dvalin-researched + KB-corroborated (docs/pfi/
recommended-model-settings.md). granite + GLM pending dvalin deeper search.
2026-06-27 08:26:46 -07:00
vh 52d5f66216 litellm(gen/qwen3.5-122-a10b): presence_penalty=1.0 anti-repetition default
The abliterated/NVFP4 Qwopus 122B "gen" model (+ qwen-large / summarizer-large
aliases) had no repetition control in its sampling defaults, causing degenerate
repetition loops. Add presence_penalty: 1.0 (Qwen-documented anti-repetition
lever, range 0-2) to all 7 qwen3.5-122-a10b gateway records. Overrideable
default; bake into the vLLM serving def once the value is validated.
2026-06-27 08:09:53 -07:00
vh 3239b0a613 comfyui(irv-ml1): add PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
Native-allocator expandable segments to cut Qwen-Image-Edit fragmentation
OOMs on the A6000 (a ~2 GB alloc failing with 1.75 GB free while 45 GB sat
allocated + reserved-but-unallocated). Cache-preserving — packs better
without unloading the checkpoint, so no edit-latency hit. Paired with the
existing --disable-cuda-malloc (incompatible with cudaMallocAsync).

Deployed + recreated on irv-ml1; verified env present, PyTorch reads it,
container healthy. comfy-dev request 2026-06-25.
2026-06-25 07:30:12 -07:00
vh f8eda1c333 chore(litellm): retire Langfuse — drop success/failure callbacks (redundant + crash-prone)
Langfuse's ClickHouse member spewed ~94 GB of unrotated logs and filled ana-docker's
root disk (took the fleet host to 100%, 28/48 containers unhealthy). Its trace UI was
redundant with LiteLLM's native logging — store_prompts_in_spend_logs:true already
captures full prompts/responses/tokens/cost/latency at :4000/ui — and nothing used its
unique trace-grouping/eval features (it only received flat gateway success_callbacks).
Removed the callbacks (gateway observability stays fully native) and tore down the
6-container langfuse stack + volumes on ana-docker. Re-add the callbacks if it returns.
2026-06-20 13:21:31 -07:00
vh 7819f96003 feat(litellm): add gen-frontier / gen-frontier-reasoning aliases (→ GLM 5.2)
Capability aliases for the PAID frontier tier, mirroring glm-5.2 / glm-5.2-
reasoning (thinking off / on) → openai/glm-5.2 @ z.ai. Worldtree binds these for
a frontier-grade generation/reasoning capability so the backing frontier model
can be swapped gateway-side (operator jump-started WT's request). PAID: only
all-proxy-models / explicitly-scoped keys reach them; the free all-agents-local
key stays fenced off z.ai spend. Verified both resolve + route to GLM 5.2.
2026-06-20 10:14:28 -07:00
vh d0eb09cac1 fix(litellm): remove the * → llama-swap wildcard (decommissioned backend)
llama-swap (ana-ml2:9292) is decommissioned (:9292 confirmed down), so the
catch-all wildcard routed every unmatched / typo'd / stale model name to a DEAD
backend, surfacing a misleading "Connection error" instead of a clean
"model not found". This is the exact footgun that silently swallowed Worldtree's
defunct model names (mistral-small-4 etc.) instead of erroring. Removed (operator
call) so unknown models now 404 loudly. Verified: gateway healthy post-restart,
a bogus model name now returns a clean not-found error, real aliases (gen) still
serve. Re-add explicit per-model entries if a swappable zoo ever returns.
2026-06-20 10:08:20 -07:00
vh d3721034c1 feat(litellm): Worldtree capability aliases (chat-judge, reranker, scalar-judge)
Stand up the gateway-side capability aliases for the role→capability model
indirection (worldtree-dev's transparent-swap direction; operator: no wt-
prefix, reuse the existing summarizer/classifier/gen alias convention).

- chat-judge  -> selene-1-mini-8b (mode chat)  — WT selene-judgment role.
- reranker    -> qwen3-reranker (mode rerank)  — generic name for the cap.
- scalar-judge -> Skywork-Reward-V2 via a pass_through_endpoint to ana-ml2:8003
  (LiteLLM has no reward/pooling MODE, so it's a passthrough, gateway-key-gated;
  consumers hit /scalar-judge/<route> e.g. /score|/pooling|/classify).

Deliberately NO generic `embedding` alias: embedding vectors are model-specific
(not swap-transparent), so that capability stays `qwen3-embedding` — the model-
specific name is the guardrail against treating it as freely swappable. Verified
all three live (chat-judge 200, reranker present, scalar-judge passthrough 200
returning a Skywork reward). Deployed + gateway health-gated.
2026-06-20 09:53:09 -07:00
vh cd92b85157 feat(omnivoice): tune streaming defaults (16-step + aggressive packing)
Empirical follow-up to the streaming /tts smoke test on the 3090. OmniVoice
is diffusion: a ~fixed per-call overhead (~1.5s at 32 steps, ~0.7s at 16)
dominates regardless of chunk length, so the upstream-claimed 40x RTF does
NOT hold here (measured ~2.8x/32-step, ~5.6x/16-step) and the chatterbox-
tuned scheduler over-chunks and starves.

- Streaming /tts defaults to num_step=16 (TTFA ~1.5s -> ~0.7s); batch
  /v1/audio/speech stays num_step=32 for quality. Per-request override intact.
- Scheduler prior raised to rtf_prior=20 (env OMNIVOICE_STREAM_RTF_PRIOR,
  wired through compose + .env.example) so it packs whole-text-minus-first-
  sentence into a few chunks: validated ~3 chunks, no starvation, total wall
  ~= one-shot, less per-chunk silence padding.
- Docs corrected: the "sub-second / 40x" claims were wrong; streaming has a
  diffusion TTFA floor (~0.7s) and wins mainly on long replies. chatterbox-
  fast (autoregressive, ~0.5s TTFA) stays the lowest-latency front-end;
  OmniVoice is the multilingual / voice-design complement.
2026-06-19 22:58:55 -07:00
vh 288d085236 feat(omnivoice): streaming /tts + language-safe sanitizer
Add a live-consumer streaming path and text sanitation to the OmniVoice
wrapper, so it can front speech-to-speech chat engines (not just the
asset-engine's batch WAV use).

- POST /tts: chunked 24 kHz mono s16le PCM (or open-ended WAV), driven by
  the adaptive buffer-ratchet scheduler. Emits the first sentence
  immediately, then ratchets chunk size up on OmniVoice's ~40x realtime
  headroom -> sub-second time-to-first-audio. Wire-compatible with
  chatterbox-fast /tts (both 24 kHz mono PCM). Batch /v1/audio/speech is
  unchanged for asset/file callers.

- scheduler.py: VENDORED byte-faithful copy of chatterbox-fast's pure-
  Python (torch-free) scheduler, pinned to commit 7631462 (v0.1.0/v0.1.1).
  Vendor-copy over a shared package (operator call 2026-06-19): the module
  has no GPU deps, so reuse it without dragging chatterbox-fast's torch
  tree into this image. Promote to a shared package only on a 3rd consumer
  or real drift.

- sanitize.py: language-safe TTS sanitizer run on both endpoints. Strips
  markdown, <think> blocks, HTML, and model control tokens; deliberately
  SKIPS the fork's English-only number/phone normalization that would
  corrupt OmniVoice's 600-language input. Preserves [laughter]-style tags.

- Refactor: shared GenParams base for SpeechRequest + TTSStreamRequest;
  single GEN_LOCK serializes generation (single-stream interactive).

- Dockerfile/playbook: copy + upload the two new modules; build-time
  `import app` smoke; correct stale "Gradio demo / no FastAPI" comments.
2026-06-19 22:47:15 -07:00
vh 740bcae45d feat(gateway-chat): persistent static-serve stack for the model-smoking web chat
Stands up tools/gateway-chat.html as a permanent URL on ana-docker (http://10.250.50.70:8091)
via a tiny nginx:alpine static container (no GPU, no DB). conf/index.html is a deployed
mirror of tools/gateway-chat.html (re-sync one-liner in README). Homepage tile + tnet per
convention. The enhanced tool (auto-discovers /v1/models, system prompts, streaming +
reasoning, image upload for vision) is now always-on for smoking new gateway models.
2026-06-19 12:32:51 -07:00
vh ef45f6d826 feat(litellm): add classifier -> granite + summarizer-large -> gen aliases (operator)
Duplicate-entry aliases. classifier -> granite-4.1-8b (:8004, same backend as the
existing summarizer alias). summarizer-large -> gen/qwen3.5-122-a10b (:8013, thinking
off) for heavier summarization on the 122B Qwopus. summarizer -> granite already
existed (no-op). Config-staged + deployed without bouncing the gateway; like any
config-add these activate on the next restart (no live-add performed).
2026-06-19 12:08:26 -07:00
vh 75bd4c3679 remove gen-nt / gen-reasoning-nt litellm records (operator)
Source + deployed config cleaned without bouncing the gateway. NOTE: these were
config-loaded models, which the /model/delete API can't remove (DB-only -> 'not
found in db'), so the LIVE gateway still serves them until its next restart, at
which point the cleaned config drops them. No bounce performed.
2026-06-19 11:56:20 -07:00
vh 2e5ab72e2c feat(litellm): add gen-nt / gen-reasoning-nt (noop-tool + tool_choice:none compat variants)
Same Qwopus gen model as gen / gen-reasoning (served-name qwen3.5-122-a10b @
:8013, thinking off/on respectively), but each bakes a dummy 'noop' function tool
+ tool_choice:none into litellm_params so a NON-EMPTY tools array always reaches
vLLM — for consumers where the global strip_empty_tools hook isn't the right fix
(they need a valid tools structure present, not stripped). tool_choice:none means
the noop is never called. api_base = the real LAN endpoint http://10.250.50.54:8013
(the requested http://vllm:8000 template wouldn't resolve from the ana-docker
litellm container). Verified: gen-nt + gen-reasoning-nt both survive a client
tools:[] send; noop never invoked; reasoning split intact.
2026-06-19 11:35:48 -07:00
vh 5b06514020 docs(litellm): gen records now describe Qwopus3.5-122B (vision-intact), not bjk110 text-only
Comment-only — routing records (served-name qwen3.5-122-a10b @ :8013) unchanged,
so the live gateway is functionally identical; no reload needed.
2026-06-19 10:25:45 -07:00
vh 20e796cf6b feat(qwopus3.5-122b): gen model → Qwopus3.5-122B vision-intact NVFP4, full 256K @ fp8
Replaces the bjk110 text-only qwen3.5-122b as the `gen` model on ana-ml2 GPU 0.
OpenYourMind/Qwopus3.5-122B-A10B-Kimi-K2.6-destilled-abliterated-NVFP4 — Kimi-
distilled, abliterated, NVFP4, and crucially VISION-INTACT (serves as plain
multimodal, no text-only patch). Served as qwen3.5-122-a10b so the litellm
gen / gen-reasoning / qwen-large records route here unchanged.

Tuned for full native context on the 96GB Blackwell:
- stable vLLM image + fp8 KV → 11GB pool = 870,014 tokens = 3.32x concurrency
  at the full 262144 (256K) window. Nightly+turboquant-4bit was unnecessary.
- CUDA graphs ON (no --enforce-eager) → 92.7 tok/s warm single-stream.
- util 0.95 + PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True — 0.96 OOM'd by
  0.1GB on the 3.09GB FusedMoE transient workspace (the hard floor; defrag
  reclaims the 4.2GB fragmentation, 0.95 adds margin).
- max-num-seqs 16 (short reqs fan out ~16x32k; 256K reqs pool-limit to 3.32x).
- text + image + video all enabled; tool-calling via qwen3_coder (XML), verified.
2026-06-19 10:24:34 -07:00
vh a5b626b3d5 fix(qwen3.5-122b): enable tool-calling (--enable-auto-tool-choice --tool-call-parser qwen3_xml)
gen/gen-reasoning tool-calling 400'd (operator + brokkr's capability battery both caught it):
the bjk110 serve command shipped --reasoning-parser qwen3 but no tool flags. Qwen3.5 emits XML
tool calls (<tool_call><function=NAME><parameter=K>V</parameter></function></tool_call>), NOT
Hermes JSON — so `hermes` mis-parsed to raw text; `qwen3_xml` is the correct parser. Reasoning +
tools coexist (gen-reasoning keeps its thinking split). Verified live: a get_weather request
returns tool_calls=[get_weather {"city":"Paris"}].
2026-06-19 01:56:56 -07:00
vh 5dfce049f4 rename(litellm): qwen-image-judge alias -> image-judge 2026-06-19 01:43:25 -07:00
vh bfae924048 feat(qwen-image-bench): replace qwen3.6-35b-a3b on GPU1 with the T2I judge (NVFP4)
flukethoughts/Qwen-Image-Bench-NVFP4 — Qwen's text-to-image quality JUDGE (vision-intact,
NVFP4) on ana-ml2 GPU 1, replacing qwen3.6-35b-a3b:
- stacks/qwen-image-bench/ — vLLM multimodal serve (Qwen3_5ForConditionalGeneration, no
  text-only patch — vision wanted), GPU1 device pin, :8014. util 0.32 (0.22 KV-starved →
  crash-loop "no available memory for cache blocks"; util is a fraction of TOTAL so it
  must clear the ~20GB weight floor).
- litellm: removed qwen3.6-35b-a3b + -thinking; added qwen-image-bench + qwen-image-judge alias.

Verified live: healthy (KV 9.4GB / 133K tokens), text + IMAGE (vision path) both respond.
NOTE: arbo's hero-judge was bound to qwen3.6-35b-a3b — comfy-dev notified to repoint.
2026-06-19 01:40:59 -07:00
vh 3ba0e544db tune(qwen3.5-122b): gpu-mem-util 0.90->0.95, max-num-seqs 4->8 (KV 260K->446K tokens, 3.4x concurrency @131K, no OOM) 2026-06-19 01:21:28 -07:00
vh 89c83c4271 feat(qwen3.5-122b): replace mistral-small-4 as gen (abliterated NVFP4, text-only)
bjk110/Qwen3.5-122B-A10B-abliterated-NVFP4 on ana-ml2 GPU 0 (heretic downed):
- stacks/qwen3.5-122b/ — vLLM serve via the repo's text-only patch (Qwen3.5 MoE is a
  multimodal arch but this checkpoint is text-only weights), --reasoning-parser qwen3,
  GPU 0 pin, :8013; entrypoint+patch mounted from the model dir.
- serve-qwen3.5-122b.yaml — displace heretic + serve + verify.
- litellm: REMOVED dead mistral-small-4 / -reasoning; added qwen3.5-122-a10b[-reasoning]
  + aliases qwen-large[-reasoning] + repointed gen[-reasoning] -> qwen (thinking split via
  chat_template_kwargs.enable_thinking + --reasoning-parser qwen3).

Verified live: qwen healthy on :8013; gen / qwen-large / qwen3.5-122-a10b route, and
gen-reasoning returns reasoning_content; mistral-small-4 removed.
NOTE: Worldtree character backend (was bound to mistral-small-4) is dark until repointed
(operator-acknowledged).
2026-06-19 00:49:04 -07:00
vh 67102b5b94 feat(litellm): add model aliases summarizer / gen / gen-reasoning
Duplicate-entry aliases (NOT router_settings.model_group_alias — that's hidden from
/v1/models and can be silently ignored in config per litellm #15020/#5524):
- summarizer     -> granite-4.1-8b
- gen            -> mistral-small-4
- gen-reasoning  -> mistral-small-4-reasoning (reasoning_effort:high preserved)

Each alias is a real model_name co-located with its target (keep api_base in sync).
Verified live: all 3 in /v1/models + route end-to-end; gen-reasoning returns
reasoning_content.
2026-06-18 23:56:05 -07:00
vh 91688a234b revert(litellm): remove mistral-medium-3.5 entry (GPU0 reverted to small-4 heretic) 2026-06-18 23:50:34 -07:00