iris devlog #1 — qwen3.5:9b winner, 25 modeli przetestowane
Dwa dni testów. 25+ modeli LLM od 0.8B do 122B. Cel: znaleźć model do mojej agentki IRIS — polska persona, native tool-calling, dostęp do Obsidian vault. Wynik: qwen3.5:9b z think=True. 28 sekund na pytanie, 7.5/10 jakości, działa na dwóch kartach dających razem 20 GB VRAM.
Hardware
- Dual-socket Xeon E5-2690v3 (24 cores / 48 threads)
- 96 GB DDR4 ECC
- RTX 5070 12 GB (Blackwell) + Tesla P4 8 GB (Pascal)
- Razem 20 GB VRAM dla Ollamy
- Windows 11 Pro PL, sleep S3 po 15 minutach idle
Idea prosta: tani retired hardware z rynku wtórnego (Xeon E5 + Tesla P4 za grosze) plus jedna nowoczesna karta gamingowa. W teorii powinno wystarczyć dla średniej klasy modeli. W praktyce — fascynujące starcie hardware’u z modelami.
Lekcja #1: Dense 70B+ na 20 GB VRAM = RAM-bound śmieć
- llama3.3:70b — 0.9 tok/s, 5 z 16 testów timeout
- deepseek-r1:70b — 0.8 tok/s, 3 timeouty + HTTP 400 native tool
- mixtral:8x22b — 1.4 tok/s, FizzBuzz bug (zła kolejność warunków)
- qwen3-coder-next:80b-A3B — 5.6 tok/s, 0 timeoutów (referencyjny)
Co się stało: dense 70B w Q4 ważą ~40 GB. Mam 20 GB VRAM. Reszta? Trafia do RAM i CPU. Memory bandwidth DDR4 (~50 GB/s) vs VRAM (~600 GB/s na 5070) = ~12× wolniej. Token generation z dużego modelu staje się żółwią karawaną.
Wniosek: active params liczą się więcej niż total params. MoE z 3-10B aktywnymi wygra z dense 30-70B przy ograniczonym VRAM.
Lekcja #2: MoE A3B na pograniczu VRAM = sweet spot
- qwen3.6:35b dense (35B / 35B active) — 10.2 tok/s
- qwen3.5:35b-a3b MoE (35B / 3.6B active) — 9.6 tok/s
- qwen3.5:122b-a10b (122B / 10B active) — 2.6 tok/s (75 GB Q4 = duży spillover)
Niespodzianka: dense 35B wygrało z MoE 35B-A3B. Powód: oba modele po Q4 ważą 22 GB. Mieszczą się prawie w pełni w 20 GB VRAM. Wąskie gardło to memory bandwidth wewnątrz VRAM, nie aktywne parametry.
Lekcja #3: Tool calling NIE jest darmowy
Surowy benchmark tok/s to tylko jedna trzecia historii. Live test z prawdziwym agent loop (8 pytań z vault MCP + math + code):
| Model | Czas/8q | Vault MCP | Math | Code |
|---|---|---|---|---|
| qwen3.6:35b-a3b | 19m54s | ✓ pełna eksploracja | ✓ z sprawdzeniem | ✓ |
| qwen3.6:27b dense | 17m57s | chaotyczne | ✓ | FizzBuzz bug |
| qwen3:14b | 3m31s | Access denied fail | ✓ | generator-in-print |
| qwen3.5:9b | 3m4s | znajduje | ✓ z self-correction | ✓ multi-line |
| qwen3.5:4b | 2m | HALUCYNUJE | ✓ | multi-line zamiast 1-line |
| gemma4:e4b | crash | Access denied | ✓ | nie dotarł |
| ministral-3:14b | 2m40s | ✓ Clarify pattern | błąd arytmetyki | broken slice |
Kluczowe: qwen3:14b był 5.7× szybszy od qwen3.6:35b-a3b, ale tool calling kompletnie padał. „Access denied” dla vault, „skrypt do pobrania kursów działa, sprawdź API” zamiast realnego kodu. Speed bez quality = bezużyteczny dla agenta.
Lekcja #4: Native function calling > silne ale „głupie” modele
Native function calling = model w treningu nauczył się formatu JSON tool calls. Bez tego model zgaduje co zrobić — czasem dobrze, częściej halucynuje ścieżki albo ignoruje tools i odpowiada z wyobraźni.
- Qwen3.5/3.6 — cała rodzina, BFCL ~62-72, polski stabilny
- Mistral / Ministral — native FC OK, ale chinese chars przy truncation
- Nemotron — NVIDIA tuning na BFCL, top reasoning
- Granite 4.1 — BFCL 68.27, ale brak oficjalnego polskiego (disqualifier)
- Gemma 4 — słabsze FC stability, vault MCP fail, halucynacje słów („Sardynegry”)
- Hermes-4-14B GGUF — broken chat template, generuje puste responses
Lekcja #5: Multi-specialist przy 20 GB VRAM = mit
Pomysł wydawał się genialny: zamiast jednego „wszystko-modelu” — kilku specjalistów. Math do Nemotron-3-Nano-4B (AIME 89.1), code do Qwen2.5-Coder-7B (HumanEval 88.4), router qwen3.5:9b.
Problem: każdy specjalista ~3-5 GB Q4 + KV cache ~5 GB. Plus router. Plus aux. Szybko przekraczamy 20 GB VRAM. Ollama zaczyna evict & reload — 30-sekundowe timeouty, 500 errors, swap loop.
GPU available: 0.7 GB ← prawie zero "model requires more gpu memory, evicting" po evict: 10.1 GB free nowy model loaded 500 ERROR (reload nie zdążył w 30s)
Wniosek: multi-specialist ma sens dla datacenter VRAM (80 GB+). Dla 20 GB jeden uniwersalny model z dobrym FC bije pomysł specjalistów.
Lekcja #6: Polski i halucynacje folkloru
Każdy LLM, niezależnie od rozmiaru, ma wspólny problem z polskim: przysłowia są wymyślane.
Pytanie testowe: „Powiedz polskie przysłowie o nie wykluwających się kurach.”
- qwen3.6:35b-a3b — „Kura znosząca jaja nie lęgnie”
- qwen3.5:9b — „Kura, która nie znosi jajek, nie karmi się ziarnem — tylko się gniada”
- qwen3:14b — „Nie wykluwają się kurzyce — nie wykluwają się grzyby”
- gemma4:e4b — „Nie wykluwają się kurzyce — nie wykluwają się grzyby”
- ministral-3:14b — „Z jaj kurczaków bez ogrzewania nie wylęgną się wczesnym rankiem”
Prawdziwe (znane mi) przysłowie to „Nie chwal dnia przed zachodem słońca” albo „Nie licz kurcząt przed wykluciem”. Żaden model tego nie wiedział. Fundamentalna luka w training data dla polskich idiomów.
Jedyny model w stanie obronić się przyznaniem niewiedzy: qwen3.5:9b z think=True i odpowiednio napisaną personą — „nie zmyślam tego czego nie wiem”. Plus uczciwie zaznaczał „myślałem o ALBO” przy wymyślaniu.
Finalny stack
model: qwen3.5:9b # router + aux + heavy
context_length: 262144 # 256K natywny Qwen3.5
kv_cache_type: q4_0 # kompaktowy
think: True # CoT kompensuje 9B capacity
reasoning_effort: medium # balanced
delegation: disabled # jeden model = brak swap
auxiliary_models: same # qwen3.5:9b dla compression/title/curator
VRAM bilans: qwen3.5:9b Q4 ~6 GB + KV cache 256K q4_0 ~10 GB = 16 GB w 20 GB VRAM (4 GB bufor).
Performance: 8 pytań w 3m 4s. 25 pytań w 11m 32s. Vs qwen3.6:35b-a3b (najwyższa jakość) — 5× szybciej.
Quality breakdown (25 testów):
- Math 4/4 (z self-correction przez think=True)
- Wiedza techniczna (CAP, HTTP/2, race condition, GC)
- Code: JS debounce, SQL OFFSET, Bash one-liner (z drobnym bugiem du)
- Vault MCP — znajduje pliki, czyta dzienne notatki
- Memory recall — USER profile + dziennik
- Polskie przysłowia zawsze wymyślane
- Translation czasem niedoskonała („Distributed systems” → „sieciowe”)
- Haiku nie zachowuje 5-7-5
TL;DR dla zniecierpliwionych
| Hardware | Model | Trade-off |
|---|---|---|
| 8 GB VRAM | qwen3.5:4b lub gemma4:e4b | Speed, słaba jakość |
| 12 GB VRAM | qwen3.5:9b z think=True | Sweet spot |
| 20 GB VRAM | qwen3.6:35b-a3b MoE | Maksymalna jakość, wolne |
| 24+ GB VRAM | Heavy MoE z native FC | Datacenter territory |
| 80+ GB VRAM | Multi-specialist sense | Nie domowy use case |
Dla domowego AI agent z polską personą + vault MCP + native tool calling, w 2026 roku, na ~20 GB VRAM: qwen3.5:9b z think=True to wybór.
I jeszcze jedno: nie próbuj 14B base modeli pod agent loop. Są szybkie, ale w testach z prawdziwym agentem zawodzą na rzeczach, gdzie 9B z think=True dobrze sobie radzi. Czasem mniej + thinking > więcej bez.
IRIS żyje. Setup automatyczny — serwer śpi po 15 minutach idle, pamięta o czym rozmawialiśmy, ma polską personę z suchym sarkazmem. Jak prawdziwa agentka.