36 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
TheTomandClaude Opus 4.6 e51e71e1bf fix: add boundary layer protection to MLX quality suite
First/last 2 KV layers stay at FP16 to prevent NaN from extreme
V norms on boundary layers. Matches the production recommendation.

Co-Authored-By: Tom Turney <tturney1@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:19:10 -05:00
TheTomandClaude Opus 4.6 e1d4ff8d23 docs: add NIAH/KLD quality validation — asymmetric mandatory for dense models
Symmetric turbo4 is catastrophic on dense models (KLD=6.86, NIAH 0/15).
Asymmetric K=FP16 fixes everything (KLD=0.003, NIAH 15/15, top-1 98.1%).

Tested on Qwen2.5-7B-Instruct-8bit (28 layers, all KV cache).
Quality test suite added: scripts/mlx_quality_suite.py

Co-Authored-By: Tom Turney <tturney1@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 09:32:30 -05:00
40a8bf46e5 Fix MLX quality suite: hybrid model support, KLD compression threshold
- Detect per-layer cache types so hybrid models (Qwen3.5 linear+attention)
  get TurboKVCache only on KVCache layers, not ArraysCache layers
- Use min_compress_tokens=32 for KLD test so compression actually fires
- Extend KLD text to ~500 tokens for meaningful divergence measurement

Co-Authored-By: Tom Turney <tturney@psyguard.ai>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 09:05:34 -05:00
fe022740c5 Add MLX quality suite for NIAH, KLD, and context scaling tests
New standalone script that tests TurboKVCache quality using mlx-lm
without touching existing llama.cpp test scripts.

Co-Authored-By: Tom Turney <tturney@psyguard.ai>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 09:02:16 -05:00
abcda965a2 scripts: add mlx_lora_to_gguf.sh for MLX LoRA → GGUF conversion
Merges MLX LoRA adapters directly into HF base weights, bypassing
mlx_lm.fuse and its sanitize transforms that break MoE/hybrid
architectures. Supports expert gate_up fusion, SwitchLinear 3D
deltas, optional TQ4_1S Config I compression.

Tested on Qwen3.5-35B-A3B (256-expert MoE + GatedDeltaNet).

Co-Authored-By: tturney@psyguard.ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 22:11:50 -05:00
caee8b9080 fix: quick bench parsing — PPL field 5, decode awk pipe, NIAH table grep
Co-Authored-By: tturney@psyguard.ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:15:53 -05:00
35f3267150 feat: add --no-ref mode to quick bench for unknown models
Reports numbers without pass/fail judgment when reference values
don't apply. Use for testing new models where baseline PPL differs.

Co-Authored-By: tturney@psyguard.ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:15:14 -05:00
57baada4fc feat: add turbo-quick-bench.sh rapid smoke test
5-min per model: PPL + decode + NIAH for q8_0/turbo3/turbo4.
Pass/Warn/Fail thresholds. Codex-reviewed: fixed grep -c abort,
numeric validation, pipefail.

Co-Authored-By: tturney@psyguard.ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:55:41 -05:00
59efd5eddb docs: full long-context validation — direct skip rate + stronger PPL
- Direct skip-rate measurement via output_attentions (9% at 512 → 28% at 4K)
- PPL validation with q8_0 baselines: 8K/20ch, 16K/10ch, 32K/5ch
- ON/OFF delta 0.0000 at all context lengths on clean branch
- turbo3 +1.1-1.4% vs q8_0, consistent and unaffected by sparse V
- Note: PR #4 was reverted (broke turbo3 PPL 6.18 → 181.6)

Co-Authored-By: tturney@psyguard.ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:26:29 -05:00
4a27f20956 Add quality & speed summary section to scripts README
Top-level at-a-glance table with PPL, NIAH, speed ratios across all
tested hardware, compression ratios, and link to decode regression
analysis doc.

Co-Authored-By: tturney@psyguard.ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:43:52 -05:00
TheTom 9674c9bf4a fix: gitignore venv and test result dirs (accidentally committed) 2026-03-26 18:26:30 -05:00
94f87fe0ad docs: comprehensive experiment status update — all 2026-03-26 results
Updated turboquant-plus-experiments.md with:
- Temporal decay: IMPLEMENTED (zero overhead, NIAH preserved, 30-34% savings)
- Rotation-free outlier channeling: DEAD (kurtosis 8-50, not Gaussian)
- Register LUT: FAILED on Metal (spills, CUDA-only)
- Norm correction: MERGED (PPL +1.6% → +1.1%, zero cost)
- 4 new key learnings (#7-10)
- Overall TurboQuant+ status summary
- Updated priority list (3 of 5 items done)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 18:25:59 -05:00
d456030799 docs: add M1 Max and M2 Pro community diagnostic results
First community diagnostic from @Ambisphaeric (M1 Max 64GB):
- Prefill: 93-98% of q8_0 (excellent, flat curve)
- Decode: 84% short → 39% at 32K (M1 constant LUT issue)

M2 Pro Mac Mini partial results (in progress, noisy from workloads).

Co-Authored-By: tturney@psyguard.ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 17:17:34 -05:00
22180a19f1 fix: scrub home directory from diagnostic output before zipping
Replaces /Users/username (or /home/username) with ~ in all output
files (log, JSON profile, monitor CSV) before packaging into the
zip. Prevents accidental PII leak when users share diagnostic results.

Reported by community tester who noticed their Mac username in
command paths logged by llama-bench output.

Co-Authored-By: tturney@psyguard.ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 17:08:47 -05:00
TheTom a3a335d4a9 docs: add AMD/ROCm experimental warning — untested, FA broken on RDNA 2 2026-03-26 17:08:42 -05:00
8533410eb1 docs: add fork table for NVIDIA/AMD — point to spiritbuun's CUDA fork
Community testers need to know which fork to build. Apple Silicon
uses our Metal fork, NVIDIA/AMD uses spiritbuun's CUDA fork.
Also added flash attention requirement warning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 16:58:26 -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
TheTom ce7af8b3f9 docs: add 'plug in charger' warning — battery throttling observed on M5 Max 2026-03-26 12:26:45 -05:00
TheTom f37f639ebd docs: add clone step to README quick start 2026-03-26 12:09:15 -05:00
5bf0aef9d1 fix: 5 Codex blockers — zip safety, exit codes, multi-GPU, PII, skip-ppl
1. Zip failure no longer deletes raw artifacts — preserves data if zip fails
2. main() returns 1 on unhandled exception (was always returning 0)
3. --skip-ppl no longer requires llama-perplexity binary
4. Multi-GPU nvidia-smi: sum memory/util, max temp across all GPUs
5. Model path logged as basename only (was leaking full path with username)
6. Build instructions now platform-aware (Metal vs CUDA)
7. Sharing instructions: GitHub issues + @no_stp_on_snek DM
8. Removed legacy bash diagnostic script (superseded by Python v5)

253 tests, 100% coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 11:58:17 -05:00
69b33b7bf7 feat: 97% coverage (233 tests), SSD detection, comprehensive failure logging
Coverage: 66% → 97% (127 new tests)
Failure logging: 7 → 60 log points — every except block now describes
what it was trying to do and includes the exception detail.

New features:
- detect_storage_type() — SSD/HDD detection (macOS diskutil + Linux rotational flag)
- [STORAGE] tag in diagnostic output
- HDD warning if model is on spinning disk

New test classes: TestDetectStorageType, TestFindModel, TestDiagLogExtended,
TestBackgroundMonitorExtended, TestLiveDisplayExtended, TestAnomalyDetectorExtended,
TestCaptureLoad, TestSectionsExtended, TestBuildJsonProfileExtended,
TestPackageResultsExtended, TestMainFunction, TestRunCmd, TestSubprocessRunner,
TestLinuxHardwareDetection, TestExceptPaths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 11:35:59 -05:00
bb8a04b6a7 fix: Codex review — thread safety, crash paths, signal handling
1. BackgroundMonitor: add threading.Lock for _samples/_sample_count
2. Fix UnboundLocalError: initialize hw={} and gpu_init="" before try block
3. SIGINT handler: use _interrupted flag to prevent writing to closed log
4. Monitor errors tracked instead of silently swallowed
5. Guard finally block against interrupted state

Also added outlandish detection (both directions):
- turbo3 faster than q8_0 → [INVESTIGATE]
- Excellent decode ratio at long context → [NOTABLE]
- Decode improving at deeper context → [INVESTIGATE]
- PPL better than q8_0 → [INVESTIGATE]
- 10 new tests for notable/investigate flags

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 10:47:44 -05:00
8c9d6d4726 feat: Python diagnostic tool v5 + venv launcher + README
turbo_hardware_diag.py (2270 lines, stdlib-only core):
- 13 diagnostic sections matching bash v4 output format
- Cross-platform: macOS (Metal/Apple Silicon) + Linux (NVIDIA/AMD)
- Background monitor thread polling every 10s (CSV output)
- Real-time terminal: rich Live tables or ASCII fallback
- Anomaly detection (bad): decode degradation, thermal throttle, swap growth
- Notable detection (good): excellent ratios, near-parity at long context
- Outlandish detection (investigate): turbo3 faster than q8_0, PPL better
  than baseline, decode improving at deeper context
- Every probe wrapped in try/except — warnings, never crashes
- Output: .txt log, .json profile, .csv monitor, .zip package
- Tag format compatible with hw_replay.py parse_diag_output()
- Full argparse: --help, --model, --skip-ppl, --skip-stress, --verbose

turbo-diag launcher:
- Auto-creates isolated venv (.turbo-diag-venv/)
- Installs rich for terminal UI
- Never pollutes user's Python environment
- Falls back to plain Python if venv creation fails

scripts/README.md:
- Quick start, output format, how-to-read guide
- M5 Max baselines, anomaly flags explained
- Hardware replay system usage
- Troubleshooting, privacy statement

106 tests, 66% line coverage (main() integration path is the gap).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 10:43:12 -05:00
88af7838d0 feat: v4 — continuous background monitoring + GPU/mmap diagnostics
Background monitor (10s polling CSV):
- CPU load, memory pressure %, swap MB, GPU temp, CPU speed limit
- NVIDIA GPU memory used + utilization % (Linux)
- Runs entire duration, included in zip package

New diagnostic sections:
- GPU-using processes (detect Chrome/video interference)
- Model mmap check (SSD detection, size vs free RAM)

Monitor CSV enables post-hoc analysis of thermal throttling,
memory pressure spikes, and GPU contention during benchmarks.

TODO: Rewrite diagnostic in Python (stdlib only) for v5.
Bash is getting fragile with cross-platform edge cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 10:06:42 -05:00
693a391333 fix: address Codex + Gemini review findings
Codex fixes:
- wall_ms → wall_sec (BSD date doesn't support %3N milliseconds)
- Linux physical cores: use 'core id' count instead of processor count
- Remove unused $JSONFILE variable (caused crash on unset -u)
- Fix Metal shader comment accuracy (signs can mix per element)

Gemini/doc review fixes:
- Add inflection point detection (find_decode_inflection)
- Add 1K context measurement flagging (flag_unreliable_measurements)
- Add has_tensor impact to prediction model (+30% penalty)
- Use exponential cache fraction model (matches real data better)
- 4 new tests: inflection detection, unreliable measurement flagging

255 total tests passing (144 core + 71 diag + 40 replay).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 09:34:29 -05:00
31be9fb167 feat: comprehensive hardware diagnostic script + 71 tests
turbo-hardware-diag.sh v3:
- 13 test sections: hardware inventory, GPU caps, model info, prefill,
  decode, stress test, PPL, memory breakdown, load monitoring
- Cross-platform: macOS (Metal) + Linux (CUDA)
- No PII collected — only hardware specs, load stats, benchmarks
- Machine-parseable tags ([HW], [BENCH_START], [LOAD_SNAPSHOT], etc.)
- Zip packaging with hardware profile JSON for replay testing
- Load snapshots at 7 points to detect thermal throttling

71 Python tests covering:
- Script syntax, permissions, structure
- Full mock-binary integration test
- All 13 sections produce non-empty output
- Tag format validation (key=value, ISO 8601 timestamps)
- Error handling (missing model, missing binaries, missing wikitext)
- No PII verification
- Benchmark coverage (all cache types, all depths)
- Load monitoring at all checkpoint points

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-26 09:03:59 -05:00
c11cd3f8ee ci: real-world PDF benchmark script (Mario's 70-page fitness PDF test)
Tests decode speed at realistic context depths with actual document content.
Compares turbo3 vs q8_0 using llama-server API.

Usage: bash scripts/turbo-realworld-bench.sh [path-to-pdf]
PDF not included in repo — testers provide their own.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-25 22:02:33 -05:00
eed5a6310e ci: quality+speed gate — checks PPL + context scaling before push
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-25 20:22:52 -05:00
445a3dc4c7 docs: move engineering docs here from llama.cpp fork
These belong in our repo, not in a fork of someone else's project.

Added:
- docs/quality-benchmarks.md — perplexity validation, bisection log, top-of-tree table
- docs/turbo-speed-investigation.md — Metal gotchas, fp16 WHT, optimization history
- docs/pre-rotate-queries-investigation.md — WHT/RoPE commutativity issue
- docs/pre-rotate-queries-plan.md — original optimization plan
- scripts/turbo-quality-gate.sh — pre-push perplexity check

README links updated to point locally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: tturney@psyguard.ai
2026-03-25 16:16:58 -05:00