Files
esh-pfi-infrastructure/stacks/meromero-charrp/compose.yaml
T
vh 27155c0f3b feat(char-rp): swap the seat to the Gemma-4 26B-A4B MoE, NVFP4, same port
Straight-across replacement of the dense G4-MeroMero-v2-31B-NVFP4A16 seat with
google/gemma-4-26B-A4B-it on ana-ml2 GPU0. Port, served-model-names and every
gateway route are unchanged, so no consumer sees a difference in addressing:
`char-rp` -> hosted_vllm/char-rp and `char-rp-reasoning` ->
hosted_vllm/char-rp-thinking, both still :8016. The seat's requirements now
include chain-of-thought, which makes throughput more critical rather than less
— the user waits through the whole reasoning block before the first visible
token, and the MoE measures ~114 tok/s @32K against the dense 31B's ~40.7.

Both artifacts are on disk and they are NOT interchangeable. The BF16 weights
(/tank/aimodels/gemma4-26b-a4b-it-bf16, 49 GB) are the QLoRA tuning base, since
QLoRA does its own quantization. They CANNOT be served here: 48.10 GiB of
weights against ~49 GiB of free GPU0 leaves nothing for KV cache, and the
engine would die at allocation exactly the way the predecessor did this
afternoon. The serving copy is RedHatAI/gemma-4-26B-A4B-it-NVFP4 (16 GB),
chosen over the other -it quants because it is compressed-tensors
(nvfp4-pack-quantized) — the same loader path the outgoing seat used — from the
llm-compressor team at 357k downloads. The nvidia/ repo is the base rather than
-it, and the thinking channel lives in the instruction-tuned weights.

Smaller weights at the same 0.47 memory budget buy a much larger KV pool:
27.37 GiB and 1,724,110 tokens, against the predecessor's 371,023 at the same
budget. That is 6.5 full-length 262K sequences concurrent rather than 1.4.

The gemma4 tool-call parser, reasoning parser and the enable_thinking:false
default all carry over unchanged — they are architecture-level, not
checkpoint-level. The --chat-template override does NOT carry over: MeroMero
pointed at a jinja hand-patched against that checkpoint, and this model ships
its own. Verified that dropping it did not reintroduce the failure that flag
existed to prevent — non-thinking prose lands in content with reasoning_content
empty, and the thinking alias populates reasoning_content with content
carrying the answer.

⚠ Scheme differs from the incumbent and the bench should say so: this quant
declares 4-bit input activations (W4A4) where the outgoing seat was NVFP4A16.
Faster, and not like-for-like on the activation axis.

meromero-charrp is retained stopped in `created` state and relabelled to
AI - Dormant, per the house rollback pattern. Both stacks want :8016, so
rolling back means stopping the gemma4 seat first.
2026-08-24 12:02:59 -07:00

103 lines
4.3 KiB
YAML

# meromero-charrp — G4-MeroMero-v2-31B NVFP4A16 char-rp PROSE seat (non-thinking, MULTIMODAL)
# on ana-ml2 GPU0. Replaces the retired Magidonia GGUF seat (char-rp-gguf / llama-charrp).
#
# Gemma-4 dense but with SLIDING-WINDOW attention -> KV-efficient, serves the full native 256K
# at ~2x concurrency. Vision enabled: preprocessor_config.json was materialized from
# processor_config.json's image_processor section (Gemma4ImageProcessor); audio is
# config-declared but weightless (no audio tensors) so it serves image + text.
#
# Co-located on GPU0 with vllm-aeon-gen (gen). util 0.52 leaves ~5GB GPU0 headroom
# (0.55 left only ~1.8GB). Tunables in .env.
name: meromero-charrp
services:
vllm-meromero-rp:
image: ${MEROMERO_IMAGE:-vllm/vllm-openai:latest}
container_name: ${MEROMERO_CONTAINER:-vllm-meromero-rp}
restart: unless-stopped
ipc: host
ports:
- "${MEROMERO_PORT:-8016}:8000"
volumes:
- /tank/aimodels:/tank/aimodels
environment:
- PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
- VLLM_API_KEY=${API_KEY:-}
command:
- ${MEROMERO_MODEL:-/tank/aimodels/meromero-v2-nvfp4-work/G4-MeroMero-v2-31B-NVFP4A16}
- --quantization
- compressed-tensors
- --served-model-name
- char-rp
- char-rp-thinking
# Tool-calling: Gemma-4 emits its OWN native syntax
# (<|tool_call>call:name{...}<tool_call|>), NOT the qwen3_coder XML the
# other seats use. vLLM 0.24 ships a matching `gemma4` parser whose token
# constants line up with this tokenizer's etc/eoc/escape tokens exactly.
# Without these two flags any tools-bearing request 400s outright.
- --tool-call-parser
- gemma4
- --enable-auto-tool-choice
# The gemma4 REASONING parser is what absorbs the <|channel>...<channel|>
# thought markers; without it they leak into `content` verbatim on the
# post-tool-response turn (upstream vllm #45834 — the chat template leaves
# the prompt inside an open channel block).
- --reasoning-parser
- gemma4
# Dwarf-panel CoT patch 2026-08-21: force-open <|channel> on enable_thinking:true
- --chat-template
- /tank/aimodels/meromero-v2-nvfp4-work/patched_chat_template.jinja
# MANDATORY companion to the reasoning parser on this seat. The parser
# reads enable_thinking from chat_template_kwargs and DEFAULTS IT TO TRUE
# (vllm/parser/gemma4.py:439). True makes is_reasoning_end() return False
# at a new turn, which pre-initialises the engine to REASONING -> ALL plain
# RP prose lands in reasoning_content with a NULL content, breaking every
# char-rp consumer. This template already defaults enable_thinking to false
# (chat_template.jinja:350), so passing it explicitly renders a BYTE-
# IDENTICAL prompt (verified across plain/tools/post-tool/system shapes) --
# it only corrects the parser's state machine. Do not remove.
- --default-chat-template-kwargs
- '{"enable_thinking": false}'
- --max-model-len
- "${MEROMERO_MAX_MODEL_LEN:-262144}"
- --max-num-seqs
- "${MEROMERO_MAX_NUM_SEQS:-32}"
- --gpu-memory-utilization
- "${MEROMERO_GPU_MEM_UTIL:-0.52}"
- --kv-cache-dtype
- fp8
- --trust-remote-code
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids:
- "${MEROMERO_GPU_ID:-0}"
capabilities:
- gpu
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 600s
networks:
- tnet
labels:
# STOPPED 2026-08-24 — superseded by stacks/gemma4-charrp (gemma-4-26B-A4B
# -it NVFP4 MoE) on the same port and the same served-model-names. Kept as
# the rollback seat: `docker compose up -d vllm-meromero-rp` here after
# stopping the gemma4 one, since both want :8016.
- homepage.group=AI - Dormant
- homepage.name=char-rp (MeroMero-v2 NVFP4) — rollback
- homepage.icon=mdi-drama-masks
- homepage.description=Superseded 2026-08-24 by the Gemma-4 26B-A4B MoE seat; dense 31B NVFP4A16, kept for rollback (ana-ml2 GPU0)
- homepage.href=http://10.250.50.54:${MEROMERO_PORT:-8016}/docs
networks:
tnet:
name: traefik-net
external: true