Skip to content

Commit 3616e33

Browse files
fix(mac chat): stop at gemma's natural turn end (real EOS detection) — 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>
1 parent bd2eaad commit 3616e33

2 files changed

Lines changed: 23 additions & 11 deletions

File tree

inference_engine/bridge/manifest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ def _harness_preset(
668668
"--max-new-tokens", "{max_new_tokens}",
669669
"--scripted",
670670
"What is the capital of France? Answer in one short sentence."
671-
"||Now multiply 6 by 7 and give only the number."
671+
"||Explain how proof-of-work works, step by step."
672672
"||Name three primary colors.",
673673
"--output",
674674
"results/research/k3_mac_bridge_mlx_kakeya_chat.json",

scripts/chat_mlx_kakeya.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,28 @@ def _log(msg: str) -> None:
3737

3838

3939
def _resolve_eos(tok) -> set:
40-
"""gemma stops a turn on <end_of_turn>; also honor the tokenizer EOS."""
41-
eos = set()
40+
"""All token ids that end gemma's turn — so generation stops NATURALLY (the
41+
user must never tune output length). gemma ends a turn on ``<end_of_turn>``
42+
(and ``<eos>``); the previous code used ``encode()`` + a single-token check
43+
which silently DROPPED ``<end_of_turn>`` (it's a special token), so the model
44+
ran past its turn (verbose echoes) until the max-tokens cap — the real bug."""
45+
eos: set = set()
46+
# mlx_lm's TokenizerWrapper exposes the authoritative stop set when present.
47+
ids = getattr(tok, "eos_token_ids", None)
48+
if ids:
49+
eos |= {int(i) for i in ids}
4250
if getattr(tok, "eos_token_id", None) is not None:
4351
eos.add(int(tok.eos_token_id))
52+
# convert_tokens_to_ids is the reliable lookup for a KNOWN special token
53+
# (unlike encode(), which may split it or add specials).
54+
unk = getattr(tok, "unk_token_id", None)
4455
for marker in ("<end_of_turn>", "<eos>"):
4556
try:
46-
ids = tok.encode(marker, add_special_tokens=False)
47-
ids = ids.tolist() if hasattr(ids, "tolist") else list(ids)
48-
if len(ids) == 1:
49-
eos.add(int(ids[0]))
57+
tid = tok.convert_tokens_to_ids(marker)
5058
except Exception:
51-
pass
59+
tid = None
60+
if isinstance(tid, int) and tid >= 0 and tid != unk:
61+
eos.add(int(tid))
5262
return eos
5363

5464

@@ -206,15 +216,17 @@ def _iter():
206216
history.append({"role": "assistant", "content": info["text"]})
207217
transcript.append({"user": user, **info})
208218
_log(f"USER: {user!r}")
209-
_log(f"GEMMA-4: {info['text'][:200]!r} "
210-
f"({info['n_tokens']} tok, {info['decode_tps']} tok/s, "
211-
f"resident_kv={info['resident_kv_bytes']/1e6:.1f}MB)")
219+
_log(f"GEMMA-4: {info['text'][:160]!r} "
220+
f"({info['n_tokens']} tok, stop={info['stop_reason']}, "
221+
f"{info['decode_tps']} tok/s, resident_kv={info['resident_kv_bytes']/1e6:.1f}MB)")
212222
report = {
213223
"kind": "mac_gemma4_kakeya_chat", "schema_version": 1,
214224
"model_path": args.verifier_path,
215225
"engine": "Kakeya-for-Mac (MLX, S5 bounded sink+window, single-stream)",
216226
"sink": args.sink, "window": args.window, "full_window": args.full_window,
217227
"exact_layers": sorted(full_idx), "n_layers": n_layers,
228+
"eos_token_ids": sorted(eos),
229+
"max_new_tokens_cap": args.max_new_tokens,
218230
"turns": transcript,
219231
}
220232
if args.output:

0 commit comments

Comments
 (0)