Skip to content

feat(server): add Poolside V1 parsers - #197

Draft
pedro-moser wants to merge 5 commits into
FlashML-org:mainfrom
pedro-moser:feat/poolside-v1
Draft

feat(server): add Poolside V1 parsers#197
pedro-moser wants to merge 5 commits into
FlashML-org:mainfrom
pedro-moser:feat/poolside-v1

Conversation

@pedro-moser

@pedro-moser pedro-moser commented Aug 26, 2026

Copy link
Copy Markdown

Important

This is a draft stacked on #102. Until #102 lands, the GitHub diff against main includes its Laguna GGUF commits. The parser change to review is the final three commits (f275318, c6f0067, and 5f7ad9d, seven files). I will rebase onto main after #102 merges.

Summary

  • add poolside_v1 reasoning support for the implicit-open <think> ... </think> protocol
  • add poolside_v1 tool-call support using Poolside/GLM-style <tool_call>, <arg_key>, and <arg_value> tags
  • auto-select both parsers for Laguna/Poolside architecture and path markers
  • expose poolside_v1 as an explicit CLI reasoning/tool parser choice
  • mirror the embedded template's default-on reasoning mode while honoring explicit enable_thinking=false
  • preserve GLM's schema-aware coercion for explicitly typed non-string arguments while retaining exact string whitespace

Motivation

#102 adds Laguna GGUF serving, but parser auto-selection currently falls through to unrelated generic formats. The model can load and generate while reasoning and tool calls are silently classified incorrectly.

The Poolside tool format is close to GLM 4.7, so this reuses that state machine rather than introducing a second parser implementation. The only Poolside-specific semantic difference is preserving leading/trailing whitespace for arguments whose JSON Schema declares exactly type: "string"; enum-only, untyped, numeric, boolean, array, and object arguments retain existing typed conversion behavior.

Closes #195 after #102 lands.

Validation

On current main plus #102:

PYTHONPATH=$PWD:$PWD/python pytest -q \
  tests/server/test_parser_auto_selection.py \
  tests/server/test_poolside_v1_parsers.py \
  tests/server/test_function_call_parser.py \
  tests/server/test_minimax_m3_parsers.py \
  tests/server/test_muse_glimmer_parsers.py \
  tests/server/test_reasoning_parser_all_models.py \
  tests/server/test_reasoning_parser_dsv4.py

254 passed in 1.55s

Coverage includes:

  • buffered and arbitrary-chunk streaming
  • escaped string content and chunk boundaries inside tags
  • text after a tool call
  • schema-declared string whitespace
  • schema-aware GLM coercion for uppercase booleans, exponent numbers, Python-literal objects, and invalid integer representations
  • enum-only and untyped schemas
  • explicit CLI choices and Laguna auto-selection
  • regression coverage for existing GLM behavior

A real unsloth/Laguna-S-2.1-GGUF revision 750f92f90cf54159c4d7a610cb7b3e74498e75c6 run auto-selected both parsers with no explicit flags. Buffered and streaming requests produced valid API tool-call transport whenever the checkpoint emitted a closed tool block.

Risk and exclusions

  • Existing parser names and GLM behavior remain unchanged.
  • The IQ1 checkpoint often emits tool blocks inside unclosed reasoning. Those samples correctly remain reasoning content; this PR does not try to repair model output.
  • This PR does not change the Laguna loader, MoE cache, model template, or sampling defaults.

probe and others added 3 commits August 23, 2026 19:55
Adds the laguna GGUF architecture: hybrid full/SWA attention with per-layer
query-head counts, QK RMSNorm, per-layer-type rope (YaRN partial-dim on full
layers, plain rope on SWA), a per-head softplus attention output gate, and
sigmoid + score-correction-bias MoE routing with one always-on shared expert.
Semantics follow llama.cpp src/models/laguna.cpp.

Poolside/Unsloth laguna checkpoints quantize per tensor, so this also
generalizes the GGUF plumbing:

- six more ggml types (Q3_K, Q4_K, Q5_K, IQ1_S, IQ2_S, IQ2_XXS, IQ3_XXS,
  IQ4_XS) wired into the dequant tables and mmvq/mmq/dequant dispatch
- a "gguf" expert-bank format whose per-layer quant types vary: flat padded
  [E, stride] host banks plus a new expert_stride_bytes argument threaded
  through the vendored moe_vec launchers (0 = previous dense behaviour)
- moe_vec calls chunked to min(65535, 16384) rows: the kernel indexes experts
  via blockIdx.z (CUDA grid-z cap 65535) and a 16k-token x top-8 prefill chunk
  also overflowed transient VRAM
- q/k/v kept as separate projections (a layer may quantize attn_v differently
  from attn_q/k -- observed on the XS Q4_K_M build)
- deferred GGUF linears materialized from the file's tensor table at conversion
  time, before the engine collects the state dict

Tested on: RTX 5080 (16 GB), 23 GB RAM, NVIDIA 610.62, CUDA 13,
wsl2. Checkpoints: unsloth/Laguna-S-2.1-GGUF (Laguna-S-2.1-UD-IQ1_S.gguf,
S, metadata/tensor coverage only) and poolside/Laguna-XS-2.1-GGUF
(Laguna-XS-2.1-Q4_K_M.gguf) plus a third-party APEX-I-Mini XS build
(Q3_K/Q4_K/Q5_K/Q6_K/IQ2_S) run end to end.

Validation on Laguna-XS-2.1-APEX-I-Mini.gguf:
  ft serve --model <model> --kv-cache-dtype fp8_e4m3 --num-tokens 262144 --kv-reserve-tokens 262144
- NIAH 3/3 at 250,054 tokens (needle at 10%/50%/90% depth, exact passcode),
  ~433 tok/s prefill
- decode 157-162 tok/s at 64k ctx, 21-23 tok/s at ~250k ctx (PCIe-bound)

Not done: S-model e2e (host lacked RAM for its ~37 GiB expert banks), hybrid/cpu
MoE backend for the gguf format, FTW conversion, TP>1. See tasks/laguna-handover.md.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(server): add Poolside V1 reasoning and tool parsers

1 participant