- Die Konfiguration eines lokalen Coding-Agenten ermöglicht es, Modelle unter macOS auch bei Internetausfällen über eine OpenAI-kompatible API auszuführen und in Pi Text- und Bildeingaben zu verarbeiten
- Verwendet wurden llama.cpp Metal und das Modell Gemma 4 26B-A4B GGUF auf einem Apple M1 Max mit 64 GB und macOS 15.7.7; die Basis-Generierungsgeschwindigkeit lag bei 58.2 tok/s
- Nach dem Hinzufügen eines MTP draft model und der Anpassung auf
--spec-draft-n-max 3stieg die Generierungsgeschwindigkeit auf 72.2 tok/s, also um rund 24 % - Damit Bildeingaben wie Screenshots übertragen werden, muss
mmproj-BF16.ggufmit--mmprojgeladen und die Modelleingabe in Pi auf["text", "image"]gesetzt werden - Die endgültige Konfiguration betreibt den llama.cpp-Server unter
127.0.0.1:8080/v1, den Pi als lokalen Provider nutzt; Qwen3.6 35B-A3B zeigte zwar bessere Benchmarks für Coding-Agenten, war in diesem Test mit 55 tok/s jedoch langsamer
Ziel der lokalen Coding-Agent-Konfiguration
- Mehrere Internetausfälle, durch die der Coding-Agent nicht nutzbar war, gaben den Anstoß, eine lokale Ausführungskonfiguration auszuprobieren
- Die gewünschte Konfiguration sollte auf dem Mac schnell genug für den praktischen Einsatz sein und über eine OpenAI-kompatible API auch in anderen Tools nutzbar sein
- Außerdem sollte sie bei Bedarf Screenshots oder Bilder verarbeiten können, damit vom Agenten erzeugte Ergebnisse wieder als Eingabe verwendet werden können
- Die endgültige Konfiguration besteht aus
llama.cpp, Gemma 4 26B-A4B GGUF, einem Q8 MTP draft model, dem Gemma-4-Multimodal-Projector und dem terminalbasierten Coding-Agenten Pi - Die Testumgebung war ein Apple M1 Max mit 64 GB Unified Memory und macOS 15.7.7
Modell
- Das Hauptmodell war
gemma-4-26B-A4B-it-UD-Q4_K_XL.ggufund liegt im Hugging-Face-Repositoryunsloth-gemma-4-26B-A4B-it-GGUF - Die Datei ist etwa 16 GB groß; zusammen mit MTP draft head und Multimodal-Projector umfasst der Modellordner rund 17 GB
- Der Benchmark-Prompt lautete
Write a compact Python function that parses a unified diff and returns the changed file paths. Then explain two edge cases. - Jeder Benchmark erzeugte etwa 128 Token
Basislauf: llama.cpp + Metal
- Das Hauptmodell wurde direkt mit
llama.cppund Metal-Beschleunigung ausgeführt - Der Startbefehl setzte bei
llama-cliden Modellpfad sowie-ngl 999,-fa on,-c 4096und-n 128 - In der Basiskonfiguration lagen Prompt-Verarbeitung und Generierung bei 298.0 tok/s beziehungsweise 58.2 tok/s
- 58 tok/s ist nicht besonders schnell, aber nutzbar; bei Coding-Agent-Aufgaben ist wegen der vielen Tool-Aufrufe jedoch möglichst hohe Geschwindigkeit wichtig
MTP draft model hinzufügen
- Für Gemma 4 wird ein MTP draft model in der Form
MTP/gemma-4-26B-A4B-it-Q8_0-MTP.ggufbereitgestellt - In
llama.cppwird es für spekulatives Dekodieren über--model-draft,--spec-type draft-mtpund--spec-draft-n-maxgeladen - Der erste Lauf mit MTP erreichte bei 4 Draft-Token 69.2 tok/s
- Die Unsloth-Dokumentation empfiehlt
--spec-draft-n-max 2als Ausgangspunkt, rät aber dazu, je nach Hardware Werte von 1 bis 6 zu testen und den schnellsten zu verwenden - Nach dem Tuning von
--spec-draft-n-maxwar der Wert 3 mit 72.2 tok/s bei der Generierung am schnellsten - Das Hauptmodell allein erreichte 58.2 tok/s, die Konfiguration mit Q8 MTP draft model 72.2 tok/s
- Die Prompt-Verarbeitung blieb nahezu unverändert, die Generierung verbesserte sich um etwa 24 %
Ergebnisse des MTP-Tunings
- Getestet wurden
--spec-draft-n-max-Werte von 1 bis 6 - Bei Wert 1 lagen die Werte bei 295.5 tok/s für Prompts und 68.4 tok/s für Generierung
- Bei Wert 2 waren es 299.1 tok/s für Prompts und 72.0 tok/s für Generierung
- Bei Wert 3 wurden mit 295.6 tok/s für Prompts und 72.2 tok/s für Generierung die besten Werte erreicht
- Bei Wert 4 sank die Generierung auf 70.7 tok/s, bei Wert 5 auf 63.7 tok/s und bei Wert 6 auf 61.2 tok/s
- Auf dem M1 Max war
3am schnellsten,2lag aber sehr nahe daran
Vergleich mit MLX
- Um eine schnellere Methode zum Ausführen des Modells auf dem Mac zu prüfen, wurden auch MLX-Modelle auf Basis von
mlx-lmgetestet llama.cpp Metal + MTPerreichte mit der Kombination aus Unsloth GGUF Q4 und Q8 MTP 72.2 tok/sllama.cpp Metalallein erreichte mit Unsloth GGUF Q4 58.2 tok/sMLX-LMerreichte mit Unsloth UD MLX 4-bit 45.8 tok/sMLX-LMerreichte mitmlx-community 4-bit43.9 tok/s und mitmlx-community OptiQ 4-bit38.1 tok/s- In dieser speziellen Konfiguration war llama.cpp schneller als MLX, und llama.cpp mit MTP war die beste Wahl
- Ein Versuch mit
gemma-4-swift-mlx, auch Gemma 4 MTP zu nutzen, wurde abgebrochen, weil der getestete 26B-4-bit-MLX-Checkpoint nicht zu den vom Loader erwarteten Weight-Keys passte und kein neues Modell heruntergeladen und angepasst werden sollte
Bildunterstützung hinzufügen
- Damit sich in Pi Screenshots anhängen lassen, darf die Modelleingabe nicht nur Text unterstützen
- Der lokale Modelleintrag war ursprünglich auf
"input": ["text"]gesetzt; in diesem Fall konnte Pi die Ausgabe des Bild-Tools nicht korrekt an das Modell übergeben - Auch der
llama.cpp-Server benötigt für Multimodalität den Gemma-4-Multimodal-Projectormmproj-BF16.gguf - Wird der Projector mit
--mmprojgeladen, meldetllama.cppMultimodal-Unterstützung, sodass Pi Bilder senden kann - Ein Testlauf von
llama.cpp Metal + MTPohne Projector ergab 120.3 tok/s für Prompts und 71.4 tok/s für Generierung - Der endgültige Lauf mit geladenem
mmproj-BF16.gguferreichte 297.4 tok/s für Prompts und 72.2 tok/s für Generierung - Beim endgültigen Lauf mit geladenem Projector zeigte sich kein Rückgang der Textgenerierungsgeschwindigkeit
Installation von llama.cpp
- Als Abhängigkeiten wurden per Homebrew
cmake,git,tmuxundpython@3.11installiert - Es wurde der Pfad
~/Developer/ML-Models/Gemma4/reposangelegt und das Repositoryggml-org/llama.cppnachrepos/llama.cppgeklont - Der Build wurde mit
cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_METAL=ON -DGGML_ACCELERATE=ONkonfiguriert - Anschließend wurde mit
cmake --build build --config Release -jein Release-Build ausgeführt - Der getestete Build verwendete die Einstellungen
GGML_METAL=ON,GGML_ACCELERATE=ON,GGML_BLAS=ON,GGML_BLAS_VENDOR=Apple
Modelldateien herunterladen
- Es wurde eine Python-3.11-Virtualenv erstellt und
huggingface_hubsowiehf_xetinstalliert - Mit
huggingface-cli downloadwurden das Gemma-4-Hauptmodell,mmproj-BF16.ggufund das MTP draft model heruntergeladen - Die heruntergeladenen Zieldateien waren
gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf,mmproj-BF16.ggufundMTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf - Der endgültige Modellordner unter
models/unsloth-gemma-4-26B-A4B-it-GGUF/enthält diese drei Dateien
Lokalen Server starten
- Der endgültige Server wird mit
llama-servergestartet, wobei Hauptmodell, MTP draft model und Multimodal-Projector gemeinsam angegeben werden - Wichtige Optionen sind
--spec-type draft-mtp,--spec-draft-n-max 3,-ngl 999,-fa on,-c 65536,--parallel 1 - Der Server wird mit
--host 127.0.0.1 --port 8080ausgeführt - Der OpenAI-kompatible Endpunkt lautet
http://127.0.0.1:8080/v1 - Das Wrapper-Skript
start_server.shstartet den Server in einertmux-Session und schreibt Logs nachlogs/llama-server-mtp.log - Nach
chmod +x start_server.shwird der Server mit./start_server.shgestartet - Ob der Server läuft, lässt sich mit
curl http://127.0.0.1:8080/v1/modelsprüfen
Pi-Konfiguration
- Pi liest die Modellanbieter-Konfiguration aus
~/.pi/agent/models.json - Die
baseUrldes lokalen Providersgemma4-localzeigt aufhttp://127.0.0.1:8080/v1 apiistopenai-completions, und da es sich um einen lokalen Server handelt, bleibtauthHeaderauffalse- Als Modell-ID wird
gemma-4-26B-A4B-it-UD-Q4_K_XL.ggufgesetzt, als NameGemma 4 26B-A4B Q4 + MTP inputmuss auf["text", "image"]stehen, sonst behandelt Pi das Modell als reines Textmodell- Das Kontextfenster wird auf 65536, die maximale Tokenzahl auf 8192 gesetzt
- Falls nötig, können in
~/.pi/agent/settings.jsondefaultProvideraufgemma4-localunddefaultModelauf den betreffenden GGUF-Dateinamen gesetzt werden - Bei
pi --offline --list-models gemmasollte für die Bildunterstützungyesangezeigt werden - Das lokale Modell wird mit
pi --provider gemma4-local --model gemma-4-26B-A4B-it-UD-Q4_K_XL.ggufausgeführt - Nicht-interaktive Ausführung erfolgt in der Form
pi -p --provider gemma4-local --model gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf "Explain what this repository does" - Ein Screenshot als Eingabe wird in der Form
pi -p @"/path/to/screenshot.png" "Describe this image and point out anything relevant to the UI"übergeben
Endgültige Konfiguration
- Die endgültige Inferenz-Laufzeit ist
llama.cpp - Die Beschleunigung unter macOS erfolgt über die Kombination Metal + Accelerate
- Das Hauptmodell ist
gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf - Das Draft-Modell ist
gemma-4-26B-A4B-it-Q8_0-MTP.gguf - Die MTP-Einstellung ist
--spec-draft-n-max 3 - Der Multimodal-Projector ist
mmproj-BF16.gguf - Der Server ist
llama-serverauf127.0.0.1:8080 - Die API ist das OpenAI-kompatible
/v1 - Der Coding-Agent ist Pi, und die Pi-Modelleingabe ist
["text", "image"] - Das MTP draft model erhöhte in dieser Umgebung die Generierungsgeschwindigkeit von Gemma 4 von 58.2 tok/s auf 72.2 tok/s, und die Konfiguration ist einfach genug, um als lokaler OpenAI-kompatibler Server zu laufen
Alternative: Qwen3.6 35B-A3B
- Einige schlagen vor, statt
Gemma 4 26B-A4BlieberQwen3.6 35B-A3Bzu verwenden - Nach nachvollziehbaren Benchmarks wird Qwen als deutlich besserer Coding-Agent als Gemma 4 bewertet
- Die Qwen-Konfiguration war jedoch langsamer und erreichte mit
Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf,unsloth-Qwen3.6-35B-A3B-MTP-GGUFundmmproj-BF16.gguf55 tok/s - 55 tok/s statt 72 tok/s macht für wartende Nutzer einen spürbaren Unterschied
- Für den Download des Qwen-Modells werden aus
unsloth/Qwen3.6-35B-A3B-MTP-GGUFQwen3.6-35B-A3B-UD-Q4_K_XL.ggufundmmproj-BF16.ggufbezogen - Der Qwen-Server verwendet ebenfalls
llama-server, läuft aber mit--port 8081 - In der Pi-Konfiguration heißt der Qwen-Provider
qwen36-local, mitbaseUrlaufhttp://127.0.0.1:8081/v1 - Die Qwen-Modellkonfiguration verwendet
reasoning: true,input: ["text", "image"],contextWindow: 65536,maxTokens: 8192
1 Kommentare
Hacker-News-Kommentare
Wenn der Benchmark-Prompt lautete, „schreibe eine knappe Python-Funktion, die einen unified diff parst und die Pfade der geänderten Dateien zurückgibt, und erkläre zwei Edge Cases“, und jeder Benchmark dabei etwa 128 Token erzeugt hat, dann wirken 128 Token für ein gutes Ergebnis viel zu wenig
Die MTP-Beschleunigung hängt davon ab, wie oft vorhergesagte Token übernommen werden; erfahrungsgemäß ist die Übernahmerate am Anfang der Ausgabe höher, sodass kurze Tests eine falsch positive Beschleunigung erzeugen können
In llama.cpp gibt es ein spezielles Benchmark-Tool, das Parameter durchläuft, ohne dass man den Server neu starten und einen Prompt senden muss: https://github.com/ggml-org/llama.cpp/blob/master/tools/llam...
Im Abschnitt zum Herunterladen von Modellen hätte auch erwähnt werden sollen, dass das
-hf-Argument von llama.cpp das Modell stattdessen für einen herunterlädt. Danke, dass der Autor seine Erfahrungen geteilt hat, aber für Einsteiger ist das vielleicht nicht die beste AnleitungNachdem ich die Ankündigung von Unclothe zu „2x Geschwindigkeit“ gesehen hatte, wollte ich wissen: „Wird das damit in der Praxis schnell genug, um es wirklich zu benutzen?“ und habe es selbst eingerichtet
Letztes Jahr habe ich auch mit so etwas wie Devstral getestet, aber das war so langsam und so dumm, dass ich es nicht weiter benutzen wollte; diesmal habe ich endlich das Gefühl erreicht, dass es sowohl bei der Geschwindigkeit als auch bei der Intelligenz brauchbar ist
llama.cpp hat dafür ein Tool, und um sauber zu messen, muss man vor der Token-Generierung ein Prefill einfügen. Es wird auch immer wichtiger, die Token-Generierungsgeschwindigkeit bei langen Kontexten wie 32k oder 64k zu messen
Ich habe früher mit ollama und opencode schon einmal einen ähnlichen Beitrag geschrieben: https://blog.kulman.sk/running-local-llm-coding-server/
Verbraucht opencode mit seinem System-Prompt nicht zu viel Kontext? Lokale Modelle haben starke Kontextbeschränkungen, und wenn ich mich richtig erinnere, nutzt opencode dafür etwa 10k oder eine ähnliche Größenordnung
Wenn man nur llama.cpp nutzt, braucht man
huggingface-clioffenbar nicht zwingend, um etwas herunterzuladen. Übergibt man-hf ..., lädt es das Modell herunterWenn man den Download-Ort ändern will, setzt man
LLAMA_CACHE:LLAMA_CACHE="models" ./llama-server \-hf unsloth/gemma-4-31B-it-GGUF:UD-Q4_K_XL \...-hfdverwendenWenn der Unified-Memory-RAM groß ist, aber Teraflops und Bandbreite in GB/s nur mittelmäßig oder schlechter sind, ist in der Regel MoE am vielversprechendsten. In meiner Umgebung mit einem M2 Max 96GB ist derzeit nach
(Intelligenz, tok/s, Kontexttiefe)die Nummer 1 DeepSeek-V4-Flash REAP25<65gb gguf+ ds4-server + pi agentNatürlich ist das nicht besser als eine Cloud-API, aber bei Bedarf ist es brauchbar genug, dass ich den Kompromiss eingehe. Selbst auf einem vierstündigen Flug ohne Internet hat ein lokales LLM mit 60 W genug Akkulaufzeit gehabt
Der ds4-Branch mit REAP-Unterstützung ist hier: https://github.com/ljubomirj/ds4/tree/reap-compact-support
Dass DS4F erst bei 784K Kontext auf unter 10 tok/s und damit auf ein unbrauchbares Niveau fällt, macht einen großen Unterschied
Ich frage mich, ob solche lokalen Modelle wirklich auch Nutzern helfen können, die keine Experten in einer bestimmten Programmiersprache sind, echte Probleme zu lösen
Über Inline-Autovervollständigung oder die Implementierung einzelner Einheiten hinaus bin ich nicht sicher, ob sie tatsächlich funktionierende technische Spezifikationen entwerfen und zusammensetzen können
Mit llama.cpp/server ein lokales LLM zu starten und es zusammen mit Claude Code oder Codex-CLI zu verwenden, ist relativ einfach
Da die nötigen Einstellungen für llama server oft verstreut sind, pflege ich hier Hinweise für einige populäre offene LLMs: https://pchalasani.github.io/claude-code-tools/integrations/...
Mit omlx.ai habe ich ziemlich erfolgreich verschiedene MLX-Modelle heruntergeladen, die zu meiner Hardware passen, und mit diesen Modellen Open-Source- und geschlossene Harnesses (Claude Code, Codex) automatisch ausgeführt
Das geht sowohl in einer Web- als auch in einer Desktop-UI, daher braucht man meiner Meinung nach mit omlx dem Blogpost gar nicht zu folgen
Die Gemma-4-MLX-Builds, die ich bisher gefunden habe, waren bei gleicher Quantisierung langsamer und mit MTP sogar deutlich langsamer
Wenn man sich einmal für ein Modell entschieden hat, ist die eingebaute Web-UI von llama.cpp ziemlich gut, und für etwas Herumprobieren ist auch LM Studio okay
Gemma-4 und Qwen 3.6 brauchen den großen allgemeinen opencode-System-Prompt-Block überhaupt nicht; es ist besser, ihn wegzulassen
DeepSeek v4 Flash mit antirez’ ds4 war ziemlich beeindruckend
Beim „gespeicherten Wissen“ fühlt es sich wie ein Modell auf GPT-4-Niveau an, aber bei Tool-Calls in langen Abläufen macht es das besser als GPT-4-Klasse-Modelle
Auf einem 128GB MBP M4 Max bekomme ich etwa 24 t/s bei der Generierung und etwa 200 t/s beim Prefill. Ich dachte, es würde langsam sein, und bei Aufgaben wie Code-Generierung ist es das auch tatsächlich, aber als Maschinen-Orchestrator für einfache Aufgaben ist es überraschend nützlich
Für nicht-agentische Anwendungsfälle ist es auch als Gesprächsmodell völlig ordentlich, und es hat den Vorteil, vollständig selbstbetrieben und privat zu sein
[0]https://github.com/antirez/ds4
Wenn man es maximal faul angehen will, öffnet man einfach Claude Code im Terminal, zeigt auf diesen Beitrag und sagt nur: „Mach das“
Claude dagegen erledigt es auf einmal oder mit nur sehr wenig Nacharbeit sofort
Das Tor zu Wissen und Ausführung ist jetzt das LLM, und Google Search wirkt wie ein Dinosaurier
Es fühlt sich sogar noch beeindruckender an als das Smartphone, als wäre man ungefähr ein Jahrhundert in der Zukunft angekommen