"""Werkzeugfaehige Modelle. Nur Eintraege, deren GGUF-Vorlage Werkzeuge kennt. Geprueft am 16.10.2026 ueber den GGUF-Kopf (HTTP-Bereichsabruf, keine Miete): `tools` kommt in tokenizer.chat_template vor. Herausgefallen: glm-53 (keine Vorlage, 460 GB), r1-distill-32b, mistral-small-24b-abliterated, cydonia-24b (Vorlage ohne Werkzeuge). Die Vorlage ist die halbe Wahrheit - Ollama muss sie auch als werkzeugfaehig erkennen. Das prueft karte.py nach dem Laden ueber /api/show (`capabilities` enthaelt "tools") und gibt die Karte sonst zurueck. "kontext" bei den Coding-Modellen stammt aus einer KV-Rechnung (nicht gemessen). Bei den uebrigen ist er hier gesetzt und ebenfalls **nicht gemessen**; karte.py prueft nach dem Aufwaermen, ob alles im Grafikspeicher liegt. 8192 bei den 70B auf 48 GB ist fuer Agentenarbeit knapp. """ MODELLE: dict[str, dict] = { # --- fuers Programmieren gebaut "qwen3-coder-30b": { "name": "Qwen3-Coder 30B A3B", "hf": "hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M", "gb": 18.6, "vram": 24, "kontext": 24576, "denkt": False, "code": True, "notiz": "Arbeitspferd, schnell (3 Mrd. aktiv), Original von Alibaba", }, "qwen3-coder-30b-heretic": { "name": "Qwen3-Coder 30B A3B heretic", "hf": "hf.co/mradermacher/Qwen3-Coder-30B-A3B-Instruct-Heretic-GGUF:Q4_K_M", "gb": 18.6, "vram": 24, "kontext": 24576, "denkt": False, "code": True, "notiz": "wie oben, enthemmt", }, "qwen3-coder-next": { "name": "Qwen3-Coder-Next 80B A3B", "hf": "hf.co/unsloth/Qwen3-Coder-Next-GGUF:Q4_K_M", "gb": 48.5, "vram": 80, "kontext": 65536, "denkt": False, "code": True, "notiz": "stärkstes Coding-Modell hier, langer Kontext, 80-GB-Karte", }, "qwen3-coder-next-heretic": { "name": "Qwen3-Coder-Next 80B heretic", "hf": "hf.co/mradermacher/Qwen3-Coder-Next-Uncensored-Heretic-GGUF:Q4_K_M", "gb": 48.5, "vram": 80, "kontext": 65536, "denkt": False, "code": True, "notiz": "wie oben, enthemmt", }, # 17.10.2026: grosse heretic-Modelle, die denken. Vorlage per GGUF-Kopf # geprueft (tools + Denkteil), beide Einzeldateien. Kontext geschaetzt, # nicht gemessen: beide haben kleinen KV-Speicher (gpt-oss: halbe # Schichten Gleitfenster, Qwen3.5: 3/4 lineare Aufmerksamkeit). "gpt-oss-120b-heretic": { "name": "gpt-oss 120B heretic v2", "hf": "hf.co/llmfan46/gpt-oss-120b-heretic-v2-GGUF:MXFP4", "gb": 65.4, "vram": 80, "kontext": 32768, "denkt": True, "code": True, "notiz": "denkt, groß, 5 Mrd. aktiv und damit flott, 80-GB-Karte", }, "qwen35-122b-heretic": { "name": "Qwen 3.5 122B A10B heretic v2", "hf": "hf.co/mradermacher/Qwen3.5-122B-A10B-heretic-v2-GGUF:IQ4_XS", "gb": 66.0, "vram": 80, "kontext": 32768, "denkt": True, "code": True, "notiz": "denkt, größtes Modell im Katalog, 80-GB-Karte", }, "devstral-small-2": { "name": "Devstral Small 2 24B", "hf": "hf.co/unsloth/Devstral-Small-2-24B-Instruct-2512-GGUF:Q4_K_M", "gb": 14.3, "vram": 24, "kontext": 32768, "denkt": False, "code": True, "notiz": "von Mistral für Agenten-Coding trainiert", }, "devstral-small-2-abliterated": { "name": "Devstral Small 2 24B abliterated", "hf": "hf.co/mradermacher/Huihui-Devstral-Small-2-24B-Instruct-2512-abliterated-GGUF:Q4_K_M", "gb": 14.3, "vram": 24, "kontext": 32768, "denkt": False, "code": True, "notiz": "wie oben, enthemmt", }, "glm47-flash": { "name": "GLM-4.7-Flash 30B A3B", "hf": "hf.co/unsloth/GLM-4.7-Flash-GGUF:Q4_K_M", "gb": 18.3, "vram": 24, "kontext": 32768, "denkt": True, "code": True, "notiz": "denkt vor der Antwort, schnell", }, "glm47-flash-heretic": { "name": "GLM-4.7-Flash heretic", "hf": "hf.co/mradermacher/GLM-4.7-Flash-heretic-1.2.0-GGUF:Q4_K_M", "gb": 18.1, "vram": 24, "kontext": 32768, "denkt": True, "code": True, "notiz": "wie oben, enthemmt", }, "qwen25-coder-32b": { "name": "Qwen 2.5 Coder 32B abliterated", "hf": "hf.co/mradermacher/Qwen2.5-Coder-32B-Instruct-abliterated-GGUF:Q4_K_M", "gb": 19.9, "vram": 24, "kontext": 16384, "denkt": False, "code": True, "notiz": "ältere Generation, dicht und damit langsamer", }, # --- allgemeine Modelle mit Werkzeugvorlage "gemma4-31b-heretic": { "name": "Gemma 4 31B heretic", "hf": "hf.co/mradermacher/gemma-4-31B-it-heretic-GGUF:Q4_K_M", "gb": 18.7, "vram": 24, "kontext": 16384, "denkt": False, "code": False, "notiz": "klügstes Allround-Modell im Katalog", }, "qwen36-35b-a3b-heretic": { "name": "Qwen 3.6 35B A3B heretic", "hf": "hf.co/mradermacher/Qwen3.6-35B-A3B-uncensored-heretic-GGUF:Q4_K_M", "gb": 21.2, "vram": 24, "kontext": 16384, "denkt": True, "code": False, "notiz": "schnelles Denkmodell", }, "qwen3-30b-a3b-abliterated": { "name": "Qwen 3 30B A3B abliterated", "hf": "hf.co/mradermacher/Qwen3-30B-A3B-abliterated-GGUF:Q4_K_M", "gb": 18.6, "vram": 24, "kontext": 16384, "denkt": True, "code": False, "notiz": "denkt und ist trotzdem schnell", }, "qwen3-32b-abliterated": { "name": "Qwen 3 32B abliterated", "hf": "hf.co/mradermacher/Qwen3-32B-abliterated-GGUF:Q4_K_M", "gb": 19.8, "vram": 24, "kontext": 16384, "denkt": True, "code": False, "notiz": "dicht, langsam beim Denken", }, "qwq-32b-abliterated": { "name": "QwQ 32B abliterated", "hf": "hf.co/mradermacher/QwQ-32B-abliterated-GGUF:Q4_K_M", "gb": 19.9, "vram": 24, "kontext": 16384, "denkt": True, "code": False, "notiz": "denkt immer lange", }, "qwen25-72b-abliterated": { "name": "Qwen 2.5 72B abliterated", "hf": "hf.co/mradermacher/Qwen2.5-72B-Instruct-abliterated-GGUF:Q4_K_M", "gb": 47.4, "vram": 80, "kontext": 32768, "denkt": False, "code": False, "notiz": "groß und gemächlich, 80-GB-Karte", }, "llama33-70b-abliterated": { "name": "Llama 3.3 70B abliterated", "hf": "hf.co/mradermacher/Llama-3.3-70B-Instruct-abliterated-GGUF:Q4_K_M", "gb": 42.5, "vram": 48, "kontext": 8192, "denkt": False, "code": False, "notiz": "gemächlich, Kontext knapp", }, "llama31-70b-lorablated": { "name": "Llama 3.1 70B lorablated", "hf": "hf.co/bartowski/Llama-3.1-70B-Instruct-lorablated-GGUF:Q4_K_M", "gb": 42.5, "vram": 48, "kontext": 8192, "denkt": False, "code": False, "notiz": "gemächlich, Kontext knapp", }, "anubis-70b": { "name": "Anubis 70B v1.1", "hf": "hf.co/bartowski/TheDrummer_Anubis-70B-v1.1-GGUF:Q4_K_M", "gb": 42.5, "vram": 48, "kontext": 8192, "denkt": False, "code": False, "notiz": "Rollenspielmodell, für Code kaum geeignet", }, "llama31-8b-lexi": { "name": "Llama 3.1 8B Lexi", "hf": "hf.co/bartowski/Llama-3.1-8B-Lexi-Uncensored-V2-GGUF:Q4_K_M", "gb": 4.9, "vram": 16, "kontext": 16384, "denkt": False, "code": False, "notiz": "sehr schnell und billig, zum Ausprobieren", }, } STANDARD_MODELL = "qwen3-coder-30b-heretic" def finden(text: str) -> str | None: """Kennung, Nummer aus der Liste oder eindeutiger Namensteil.""" text = text.strip().lower() if text in MODELLE: return text if text.isdigit(): liste = list(MODELLE) n = int(text) return liste[n - 1] if 1 <= n <= len(liste) else None treffer = [k for k, m in MODELLE.items() if text in k or text in m["name"].lower()] return treffer[0] if len(treffer) == 1 else None # Zum Testen gegen ein festes Ollama (KODE_BASIS): beliebiges Modell dort. import os as _os # noqa: E402 if _os.getenv("KODE_BASIS") and _os.getenv("KODE_LOKAL_MODELL"): MODELLE["lokal"] = { "name": f"lokal: {_os.environ['KODE_LOKAL_MODELL']}", "hf": _os.environ["KODE_LOKAL_MODELL"], "gb": 0, "vram": 0, "kontext": int(_os.getenv("KODE_LOKAL_KONTEXT", "8192")), "denkt": _os.getenv("KODE_LOKAL_DENKT") == "1", "code": True, "notiz": "fester Endpunkt, nichts gemietet", }