A/B-Ergebnis: Qwen3.5-4B verliert, Qwen3-4B bleibt produktiv

Qwen3.5-4B ist auf der RK3588-NPU 21-45% langsamer und haelt die
JSON-Vorgabe nicht durch: von 61 extrahierten Todos ueber drei
Gespraeche blieben 2 uebrig, dazu 13 Parse-Fehler mit Wiederholungen.
Die Prosa war nicht schlechter, teils genauer -- ausschlaggebend ist
die Formatdisziplin. Modell-Drop-in zurueckgesetzt, Originalanalysen
per restore wiederhergestellt.

rkllm_server.cpp: neuer Schalter RKLLM_SUPPRESS_THINK=1 haengt einen
leeren Denkblock an das Chat-Template. Ohne ihn antwortet Qwen3.5 mit
Gedankengang statt JSON; RKLLMInput.enable_thinking reicht dafuer
nicht. Ohne die Variable bleibt das Template unveraendert.

Doku: Changelog 2026-09-29 (3) mit Messwerten, Bewertung und der
Einschaetzung zu rknn-llm v1.3.1 (fuer uns wirkungslos, weil wir
keep_history=0 fahren), plus Kapitel 05.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017A91sWU5aWrqZ2DWNTLVph
This commit is contained in:
2026-09-29 17:19:47 +02:00
co-authored by Claude Opus 5
parent e9ba48224e
commit 9e9958fb01
3 changed files with 86 additions and 1 deletions
+59
View File
@@ -3,6 +3,65 @@
Chronik der Entwicklungsschritte. **Regel: jede zukünftige Änderung bekommt hier einen Eintrag** (Datum,
Was, Warum, betroffene Dateien/Backups).
## 2026-09-29 (3) — A/B-Ergebnis: Qwen3.5-4B verliert, Qwen3-4B bleibt produktiv
**Durchgeführt:** Qwen3.5-4B selbst konvertiert (RTX 3090, rkllm-toolkit 1.3.0 im Container,
`w8a8_g128`, `max_context 16384`, 3 NPU-Kerne — identisch zum produktiven Modell), 5,53 GB, Konvertierung
308 s. Übertragung aufs Board per md5 verifiziert. Danach beide Modelle über `lab/ab-llm.mjs` gegen
dieselben drei Aufnahmen.
| Aufnahme | Zeichen | Qwen3-4B | Qwen3.5-4B | Tempo | Summary | Todos |
|---|---|---|---|---|---|---|
| #86 | 8 390 | 10,5 min | 13,1 min | **+25 %** | 2 896 → 848 | 6 → **0** |
| #123 | 19 275 | 24,5 min | 29,7 min | **+21 %** | 6 071 → 3 064 | 18 → **2** |
| #114 | 34 843 | 41,8 min | 60,8 min | **+45 %** | 9 288 → 2 292 | 37 → **0** |
**Urteil: Qwen3-4B-Instruct-2507 bleibt.** Qwen3.5 ist auf unserer NPU durchgängig langsamer, und der
Ausschlag ist nicht das Tempo, sondern die **Todos**: von 61 extrahierten Aufgaben über die drei Gespräche
bleiben 2 übrig. Die Aufgabenliste ist eine Kernfunktion — damit ist das Modell für uns unbrauchbar,
unabhängig von Benchmark-Werten (Artificial-Analysis-Index 27 vs. 18).
**Fair gegenüber Qwen3.5:** die *Prosa* ist nicht schlechter, eher dichter. Bei #123 nennt Qwen3.5 Philipp
korrekt als neues Mitglied, während Qwen3 ihn zur „neuen Teilnehmerin" macht. Das Modell scheitert nicht
am Verstehen, sondern an der **Formatdisziplin**: 13 JSON-Parse-Fehler mit Wiederholungen während der
Läufe (`chunk 12 unparseable -> retry 3`), im Ergebnis leere `todos`-Arrays, und die Zeilenumbrüche landen
teils als literales `\n` im Text.
### Neu: `RKLLM_SUPPRESS_THINK` in `rkllm_server.cpp`
Erster Versuch scheiterte komplett: Qwen3.5 antwortete mit Gedankengang statt JSON
(`llm: combined JSON unparseable`, Auszug: „Wait, looking at line …"), Analyse brach ab.
**`RKLLMInput.enable_thinking = false` reicht bei diesem Modell NICHT.** Das Denken schaltet erst ab,
wenn der Assistenten-Zug mit einem **leeren Denkblock** vorbefüllt wird — so macht es das
`chat_template.jinja` des Modells (Zeile 149-152): `{{- '<think>\n\n</think>\n\n' }}`.
`rkllm_server.cpp` hängt diesen Block jetzt an das Chat-Template an, wenn `RKLLM_SUPPRESS_THINK=1` in der
Umgebung steht; ohne die Variable bleibt das Template unverändert (Qwen3, Gemma3, Qwen2.5 brauchen es
nicht). Neu übersetzt auf dem Board:
`g++ -O2 -std=c++17 -o rkllm_server rkllm_server.cpp -I/usr/include -L/lib -lrkllmrt`.
Backups: `rkllm_server.cpp.bak-think`, `rkllm_server.bak-think`. **Diese Änderung bleibt** — sie kostet
nichts und macht jeden künftigen Denk-Modell-Test möglich.
### Zur Frage rknn-llm v1.3.1 (erschienen am selben Tag)
Enthält u. a. eine *linear attention cache reuse strategy*, die auf Issue #519 zielt (unter 1.3.0 meldet
RKLLM bei Qwen3.5 „Current model does not support kv cache reuse"). **Für uns wirkungslos:** unser Server
fährt bewusst `keep_history = 0` und ruft `rkllm_clear_kv_cache()` vor jedem Lauf, damit kein Kontext
zwischen Aufnahmen durchsickert — es gibt nichts wiederzuverwenden, und die Warnung taucht in unserem
Journal gar nicht auf. Der gemessene Rückstand liegt zudem beim Decode (weniger Text in mehr Zeit), nicht
beim Prefill, den ein Cache-Reuse entlasten würde. Update daher nicht durchgeführt.
### Zustand nach dem Test
Modell-Drop-in auf `qwen3-4b-w8a8g128-16k.rkllm` zurückgesetzt, `restore` hat die Originalanalysen von
#86, #112, #114 und #123 zurückgeschrieben (geprüft: 19,4 min / 7 Todos, 58,5 min / 32 Todos,
38,4 min / 16 Todos). Das konvertierte `qwen35-4b-w8a8g128-16k.rkllm` (5,9 GB) bleibt unter
`/opt/rkllm-models/` liegen — für einen späteren Versuch mit angepasstem Prompt oder neuerer Runtime.
**GOTCHA für künftige Läufe:** `lab/ab-llm.mjs` hat ein Zeitlimit von 45 Min pro Aufnahme; #114 brauchte
60,8 Min und wurde deshalb in `run-qwen35.json` als `pending` eingefroren, obwohl die Analyse später sauber
durchlief. Die echten Werte standen in der DB. Bei langen Gesprächen `TIMEOUT_MS` hochsetzen.
## 2026-09-29 (2) — A/B-Aufbau Qwen3.5-4B (Sicherung, Messstrecke, Konvertierungs-Kit)
**Anlass:** Recherche zur Frage, ob es inzwischen ein besseres LLM gibt als das produktive