8 Commits
Author SHA1 Message Date
TheTomandClaude Opus 4.6 3931b3ba97 revert: remove unrelated niah_test.py change
Co-Authored-By: tturney1@gmail.com
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 18:40:36 -05:00
TheTomandClaude Opus 4.6 92d4840cf0 docs: fix MLX section — K+V compression, accurate labels, memory table
Co-Authored-By: tturney1@gmail.com
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 18:39:49 -05:00
bee2625d9c feat: NIAH v2 — Kamradt/RULER industry-standard methodology
Rewrite to follow Kamradt (2023) and NVIDIA RULER (COLM 2024):

Modes:
- single: Kamradt depth sweep (0-100%) x context length heatmap
- multi-key: RULER MK-NIAH with distractor needles
- multi-value: RULER MV-NIAH with same-key multiple values

Changes from v1:
- "The special magic number is: {7-digit}" format (Kamradt style)
- 24 diverse filler paragraphs (science, history, art, etc.)
- Depth sweep as primary variable (0%, 10%, ..., 100%)
- Heatmap output (the classic red/green grid)
- Distractor needle support (multi-key mode)
- Multi-value retrieval scoring
- 7-digit regex scoring from content field only
- Cites methodology sources in script header

101 tests, all passing. No /Users/tom/ paths.

References:
- github.com/gkamradt/LLMTest_NeedleInAHaystack
- github.com/NVIDIA/RULER (arXiv:2404.06654)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 14:56:12 -05:00
TheTom 5c1c50ec6e fix: score from content only (not reasoning_content), 2048 max_tokens, 4K headroom
Qwen3.5 thinking mode puts the answer in content field, but
reasoning_content mentions ALL needle codes from the haystack.
Scoring from reasoning gave false positives. Now only score
from content — if model ran out of tokens during thinking,
it's a legitimate miss.

Also: increased max_tokens to 2048 (model needs room to finish
thinking) and server context headroom to +4096.

TODO: Proper rewrite based on Kamradt/RULER methodology — need
depth sweep, diverse filler, distractor needles.
2026-03-26 14:29:16 -05:00
TheTom bc195fe98e fix: handle Qwen3.5 thinking mode — check reasoning_content + 512 max_tokens 2026-03-26 14:02:35 -05:00
TheTom 2d66fe96f6 fix: disable thinking mode + strip <think> tags in NIAH responses
Qwen3.5 with --jinja uses thinking mode by default, returning empty
content field (thinking goes in a separate field). Fix:
1. Send enable_thinking: false in the API request
2. Strip <think>...</think> tags from response as fallback
3. Increase max_tokens to 64 (thinking models need more room)

Also fixed test assertions for new needle positions (5%-95%)
and server timeout (120s).
2026-03-26 13:58:56 -05:00
TheTom e36048f2a6 fix: add -o shorthand for --output-dir in NIAH script 2026-03-26 13:50:09 -05:00
c8b5d7ba88 feat: NIAH benchmark — needle-in-a-haystack retrieval accuracy test
niah_test.py — standalone NIAH benchmark for TurboQuant:
- Spins up llama-server per config, inserts 6-digit "secret code" needles
  into filler text, queries via /v1/chat/completions, scores exact match
- Tests all combos of depths x needles x cache types
- Needle positions span 5%-95% of context (not just first half)
- Regex-based scoring (exact 6-digit word boundary match, no false positives)
- Configurable: --depths, --needles, --cache-types, --server-timeout,
  --query-timeout, --server-bin, --chars-per-token, --verbose
- Server lifecycle: atexit + signal handlers, stderr captured to temp file
- Deterministic: seed=42, positions logged for reproducibility
- No personal paths in defaults, cross-platform (macOS + Linux)

Hardened per Codex + Roast review:
- Scoring: regex r'\b(\d{6})\b' not substring match (Codex critical)
- Positions: 5%-95% spread not 10%-50% (Roast critical)
- 20 cities (was 10), validates --needles <= city count
- Server timeout 120s (was 60), query timeout 300s (was 120)
- --server-bin flag for ROCm/custom builds
- Server stderr always captured for remote debugging
- Token estimation documented + --chars-per-token override

74 tests, all passing. No /Users/tom/ in any file.

Reference: @jtdavies found TQ 3.5-bit drops to 17-45% of bf16 NIAH
at 128K on MLX. This script lets us measure where we stand on Metal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 13:46:21 -05:00