Skip to content

Commit 3e6448d

Browse files
ehsan6shaclaude
andcommitted
runtime: cap max_new_tokens 3072 -> 768 for usable phone-UX latency
Lab observation 2026-05-27: with thinking-mode generating 500-1500 think-tokens plus structured-output tokens, max_new_tokens=3072 allowed turns to run for 7-10 minutes on RK3588 NPU. Phone-app shows 'Thinking...' the whole time with no progress visible until the turn completes (generate() blocks until the full output text is ready). Cap to 768 — about 2-3 minutes per turn at RK3588's ~5-7 tps. Long but bounded enough that the phone UI doesn't appear hung. The synthetic-verdict fallback in run_troubleshoot handles truncated output gracefully. Proper fix later: stream tokens as they arrive via SSE (current generate blocks). Then max_new_tokens can be raised again without hurting perceived latency. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent dec8471 commit 3e6448d

1 file changed

Lines changed: 11 additions & 7 deletions

File tree

src/runtime/rkllm_runtime.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -352,13 +352,17 @@ def init_model(
352352
# If a future conversion bumps the model's limit, raise this
353353
# value in lock-step.
354354
max_context_len: int = 4096,
355-
# max_new_tokens raised to 3072 with the Qwen 3 1.7B + thinking-
356-
# mode swap (advisor catch). Thinking blocks empirically run
357-
# 500-1500 tokens; the structured response adds another 200-500.
358-
# The prior 2048 was tight enough to truncate mid-verdict on
359-
# hard prompts, which manifests as no </think> in the output
360-
# → strip_think returns empty → user sees nothing useful.
361-
max_new_tokens: int = 3072,
355+
# max_new_tokens lowered to 768 (2026-05-27 lab test). On RK3588
356+
# NPU, Qwen 3 1.7B in thinking mode generates ~5-7 tokens/sec.
357+
# 3072 would cap a turn at ~7-10 minutes which exceeds phone-
358+
# app UX timeouts (and even our per-token 90s wait stretches
359+
# the user's perception). 768 caps at ~2-3 minutes — long but
360+
# bounded. The model occasionally truncates verbose verdicts
361+
# at this limit, which the synthetic-verdict fallback handles
362+
# gracefully. Raise back once we have a faster model or a real
363+
# streaming SSE path that emits tokens as they arrive (current
364+
# generate() blocks until the full turn completes).
365+
max_new_tokens: int = 768,
362366
temperature: float = 0.6,
363367
top_k: int = 20,
364368
top_p: float = 0.8,

0 commit comments

Comments
 (0)