Skip to content

feat(mac): gemma-4 interactive CLI chat on the Kakeya-for-Mac (MLX) engine - #143

Merged
FluffyAIcode merged 9 commits into
mainfrom
AgentMemory/mac-gemma4-kakeya-chat-cli-2815
Jun 17, 2026
Merged

feat(mac): gemma-4 interactive CLI chat on the Kakeya-for-Mac (MLX) engine#143
FluffyAIcode merged 9 commits into
mainfrom
AgentMemory/mac-gemma4-kakeya-chat-cli-2815

Conversation

@FluffyAIcode

@FluffyAIcode FluffyAIcode commented Jun 17, 2026

Copy link
Copy Markdown
Owner

What

Interactive CLI chat with gemma-4 on the Kakeya-for-Mac engine — the full verifier/proposer/f_θ bounded-memory architecture, on scripts/research/k3_integrated_niah_eval_mac.py --chat (reuses the validated fused_specdecode_generate_mlx_trim per-turn sequence; NIAH evidence loop untouched).

f_θ runs by DEFAULT in chat (--force-f-theta auto-enabled unless --all-mlx-drafter):

PYTHONPATH=.:sdks/python python3 scripts/research/k3_integrated_niah_eval_mac.py \
  --verifier-path "$KAKEYA_MAC_VERIFIER_PATH" --drafter-id "$KAKEYA_MAC_DRAFTER_ID" \
  --f-theta-dir "$KAKEYA_MAC_FTHETA_DIR" \
  --s5-exact-full-attn --fused-specdecode \
  --sink-size 4 --window-size 64 --block-size 4 --max-new-tokens 1024 --chat
config flags what runs
default (chat) --chat (no --all-mlx-drafter) verifier + proposer + f_θ (f_θ restores 25 sliding layers each turn)
fast --all-mlx-drafter --cuda-trim verifier + proposer + S5 bounded KV (f_θ bypassed — S5 free lunch)
AR fallback scripts/chat_mlx_kakeya.py verifier-only over S5 bounded cache

Verified on Mac M4 (git-bus bridge) — proposer AND f_θ both live, f_θ DEFAULT-on

Without any explicit --force-f-theta:

turn gemma-4 f_θ proposer bounded KV
capital of France? The capital of France is Paris. f_theta_ran=TRUE (25 sliding layers) blocks=2, accept_len=4.0 12.2 MB
three primary colors The three primary colors are red, yellow, and blue. f_theta_ran=TRUE (25 layers) blocks=4, accept_len=3.5 18.4 MB

On gemma-4 the restored sliding K/V are recall-irrelevant (exact layers carry recall — S5 free lunch), yet f_θ executes, exercising the full pipeline. On full-attention models the same f_θ path is load-bearing.

mac_gemma4_kakeya_ftheta_chat.log

ADR

ADR 0015 gains a section "Mac (MLX) interactive engine — full pipeline, f_θ default-ON": documents the engine, the gemma-4 recall-irrelevant-but-runs caveat, the forensic timeline (f_θ S5-bypassed 2026-06-12 by b3a04d0 "Optimize MLX adaptive S5 native smoke path"; proposer blocks=0 silent bypass caught by 0a6fb19 evidence gate), and the measured result.

Changes

  • scripts/research/k3_integrated_niah_eval_mac.py--chat/--chat-scripted full-engine REPL; --force-f-theta (default-ON in chat) bypasses the S5 short-circuit so f_θ runs; _gen_turn branches over all-MLX + torch paths; reports f_theta_ran/f_theta_layers/blocks/mean_accept_len.
  • scripts/chat_mlx_kakeya.py — lightweight verifier-only AR chat.
  • inference_engine/bridge/manifest.py — presets mlx-kakeya-fused-chat-{smoke,ftheta}, mlx-kakeya-chat-smoke; MAX_NEW_TOKENS 512→2048.
  • docs/adr/0015-…md — Mac interactive engine + f_θ default-on + forensics.
  • tests/inference_engine/bridge/test_manifest.py — preset coverage (31 presets, 100%).

Testing

  • pytest tests/inference_engine/bridge/test_manifest.py — 30 passed, 100% coverage.
  • ✅ Mac M4: f_θ DEFAULT-on (f_theta_ran=TRUE, 25 sliding layers, no explicit flag), proposer blocks>0, correct answers, bounded KV.

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

cursoragent and others added 5 commits June 17, 2026 05:12
…ngine

scripts/chat_mlx_kakeya.py — single-stream (B=1) gemma-4 chat over the Kakeya S5
bounded cache (SinkWindowKVCache): sliding layers bounded to sink+window, full-
attn (exact) layers keep full context (S5 free lunch, no f_theta/proposer needed
on gemma-4). B=1 sidesteps the MLX B>1,L=1 batched-decode bug. Interactive REPL +
--scripted mode (for non-interactive bridge verification) + transcript JSON.

Adds mac-bridge preset mlx-kakeya-chat-smoke (scripted 3-turn run) + manifest
test (100% coverage, 29 presets). Operator runs the same script without
--scripted for a real interactive chat on the Mac.

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
…rker

Smoke run showed the injected <|channel>content marker leaked 'thought' text and
caused greedy looping (turns 1/3 repeated). Replace with the chat template's
enable_thinking flag (default off → clean direct answers), with a TypeError
fallback for templates that don't accept the kwarg.

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
…ON loops

enable_thinking=False gave correct answers but greedy decoding looped on a
repeated JSON wrapper. Add mlx_lm repetition penalty via logits_processors
(with a TypeError fallback for older mlx_lm signatures).

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
…es into a repeat

The 4-bit gemma-4-it checkpoint appends a repeating json answer-wrapper under
greedy; repetition_penalty alone didn't stop it. Add a generic guard: break when
a 24-char tail recurs 3+ times, and _trim_loop() keeps only the first occurrence
for the stored/displayed text. The (correct) answer is always first.

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
…swers)

_trim_loop over-cut (dropped 'Paris' because the answer text recurs inside the
model's json echo). Replace with _is_degenerate_loop: stop ONLY on a true
back-to-back repeat (same 16-char block 3x consecutively); never trim stored
text. Answer + a single echo is preserved.

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
cursoragent and others added 4 commits June 17, 2026 06:25
…eason (eos/max/loop)

User hit truncation ('断掉') on a long PoW explanation: exactly 256 tokens =
the old default cap. Raise default to 1024 and surface the stop reason each turn
(WARN when it's the max-new-tokens cap), so truncation is obvious and tunable.

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
…— output length must not be a user knob

User correctly noted: needing --max-new-tokens to avoid truncation = unusable.
Root cause: <end_of_turn> was dropped from the stop set (old code used encode()+
single-token check on a special token), so the model ran PAST its turn (verbose
JSON echoes / self-correction) until the max-tokens cap — that IS the '断掉' and
the verbosity, same bug. Now resolve stops via tokenizer.eos_token_ids +
convert_tokens_to_ids('<end_of_turn>'/'<eos>'); the cap is only a backstop.
Report eos_token_ids + per-turn stop_reason; smoke now includes a long-answer
prompt to confirm it stops on eos, not max.

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
…natural EOS stops first)

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
… need it; natural EOS stops first)

Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
@FluffyAIcode
FluffyAIcode marked this pull request as ready for review June 17, 2026 07:09
@FluffyAIcode
FluffyAIcode merged commit b761454 into main Jun 17, 2026
7 of 8 checks passed
@FluffyAIcode
FluffyAIcode deleted the AgentMemory/mac-gemma4-kakeya-chat-cli-2815 branch June 17, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants