En una execució recent vaig tenir LLMs locals treballant més de 28 hores, mastegant quatre-cents trenta-set fitxers markdown. El model era qwen3.5:122b, servit via Ollama en dos Mac Studio sobre una xarxa local privada. La tasca, gens glamurosa: llegir un fitxer, retornar un JSON amb un resum de dues frases, les persones esmentades, les etiquetes de temes, les idees clau que el fitxer argumenta. Repetir. Agregar entre fitxers. Escriure els bastiments per entrada.
Si ho intento fer amb claude code em quedo sense tokens en un sospir, i fins i tot pagant proveïdors xinesos de núvol barats acabaré no fent aquesta mena d’optimitzacions del repositori de continguts perquè es pot encarir aviat.
Des de llavors he començat a substituir aquell pipeline per DS4 executant DeepSeek V4 Flash Q4 sobre el mateix maquinari. La latència per crida ha caigut de cent cinquanta segons a uns dotze. Mateixa tasca. Mateixa forma de prompt. Motor diferent, el doble de mida en RAM. Una millora rotunda en rendiment, i fins i tot noto que la màquina Studio funciona més fresca.
Aquest post és la nota d’optimització. El que vull de la flota local és un LLM de qualitat amb cost variable proper a zero, per a tasques per lots — indexació de wikis, auditoria de referències, neteja de transcripcions, classificació en massa. La mena de feina on el coll d’ampolla és la latència i la fiabilitat, no la intel·ligència. Dos motors, dues postures, una compensació que cal anomenar.
El cas d’ús#
Un índex wiki sobre un repositori personal d’escriptura i recerca. Uns quatre-cents fitxers markdown: capítols, esborranys, material de fonts, notes de memòria — fins i tot la meva tesi doctoral sencera hi és dins! Per a cada fitxer vull un petit artefacte estructurat: un resum que l’índex pugui mostrar, entitats anomenades per poblar les facetes de persones/temes/idees-clau, referències creuades entre elles.
Això és extracció massiva. Prompt de sistema reutilitzable; contingut d’usuari variable; sortida JSON estructurada. El model no cal que sigui llest — cal que sigui fiable, predictible i prou disponible per tirar endavant centenars de crides sense trencar-se.
Cridar un LLM en aquest registre és un esport diferent de conversar-hi. La sortida és l’entrada del següent pas del pipeline. Si el vint per cent de les crides tornen buides, és el vint per cent de la wiki que falta. Si dupliques la longitud del context i la qualitat es degrada silenciosament, el corpus que cal trossejar és el teu fitxer més gran. La superfície d’enginyeria que importa és la latència, la previsibilitat i la fallada elegant.
El patró wiki de Karpathy#
A principis d’abril de 2026 Andrej Karpathy va publicar un tuit que es va fer viral: “a large fraction of my recent token throughput is going less into manipulating code, and more into manipulating [knowledge].” Hi esbossava un sistema on les fonts en brut — articles, papers, repositoris, datasets, fins i tot imatges — cauen en un directori raw/, i un agent LLM les compila incrementalment en una wiki estructurada: fitxers markdown interconnectats amb resums, backlinks, pàgines de conceptes. Dos dies després ho va completar amb un idea file — un gist de GitHub que descriu el patró conceptualment, sense codi adjunt, sota la teoria que en l’era dels agents la idea és més útil de compartir que la implementació.
Aquell tuit descriu el projecte que estic construint gairebé paraula per paraula. El repositori que estic indexant són anys d’escriptura — capítols, esborranys, transcripcions de fonts, notes de memòria, tot plegat. El bootstrap que vaig executar és el pas de compilació incremental que Karpathy anomena. Les operacions que esbossa més avall — ingesta, consulta, lint — són el que ve a continuació per a mi. No va inventar el patró, però el va fer llegible: el va anomenar, li va donar forma, el va fer públic en el moment en què les eines per a maquinari local hi havien arribat. Aquest estiu serà a tot arreu.
Versatilitat contra especialització#
Dues postures s’asseuen als extrems de l’espectre dels LLM locals.
Ollama és l’extrem versàtil. Serveix qualsevol model de la seva biblioteca — Qwen, Llama, Mistral, Gemma, Phi, qualsevol que puguis trobar com a GGUF. Una instal·lació, GUI i CLI, una API HTTP, i pots canviar de model per tasca. Si canvies de model cada setmana, Ollama és l’eina correcta: la fricció de provar-ne un de nou és una sola ordre ollama pull.
DS4 és l’extrem especialitzat, el nouvingut. Serveix un model — DeepSeek V4 Flash quantitzat en q2 o q4 — i està dedicat a fer que aquell únic model funcioni tan bé com un Mac Studio permeti. Cache KV resident a disc, kernels conscients de MoE, descodificació especulativa MTP, una API HTTP compatible amb OpenAI a sobre. No pot servir cap altre model. Això no és un bug; és el disseny i la intenció.
La compensació és directa. Si et compromets amb un model i el fas servir intensament — mateix prefix de prompt, centenars de crides al dia, cost de prefill amortitzat sobre milers d’inferències — l’especialització es paga sola de pressa. Si saltes entre models, el motor especialitzat és cost enfonsat. La resposta correcta depèn de quant l’uses de debò.
Ollama + qwen3.5:122b — l’incumbent versàtil#
qwen3.5:122b és un model Mixture-of-Experts potent, 125 mil milions de paràmetres totals, capacitat de sobra. Servit via Ollama és una instal·lació d’una línia i una presència permanent a la LAN. Ha estat el “Tier 1” del meu taller durant mesos: tot el que és mecànic i voluminós i pel qual no vull pagar una API hi va a parar.
Per al bootstrap de la wiki, dues observacions val la pena registrar.
El precipici de context. Vaig limitar cada crida a 12k tokens d’entrada amb un sostre fort de 16k via --num-ctx 16000. Passat el 16k, la qualitat es degrada de manera visible — cues truncades, entitats anomenades perdudes, qualificadors numèrics que cauen. El capítol de 30k, la transcripció de 70k, el fitxer de visió del món de 50k, tots s’havien de trossejar, resumir per tros, i reagregar. Cada tros és una altra crida d’Ollama.
El mode de fallada de sortida buida. Al llarg de l’execució, entre el divuit i el vint per cent de les crides retornaven len=0 — una compleció buida. Ni JSON malformat, ni contingut rebutjat, només res. A través de fitxers de totes les mides; no predit per mida, tipus, ni contingut. Reintentar la mateixa crida sol produir el mateix resultat. La meva mitigació va ser una passada de reintents amb gpt-5-mini via OpenAI — uns vint cèntims per cada cent fitxers. Barat, però no gratis, i no és la qüestió.
DS4 + DeepSeek V4 Flash — la pila especialitzada#
DS4 és un motor d’inferència alpha construït per antirez, dedicat a DeepSeek V4 Flash — un model MoE de 284B totals / 13B actius. L’especificació del model afirma fins a un milió de tokens de context; jo executo el servidor amb --ctx 200000 i he provat fitxers fins a 70k tokens. Exposa una API HTTP compatible amb OpenAI al port 8000 i manté una cache KV SHA1 a disc que persisteix entre reinicis del servidor.
Tres d’aquestes propietats importen per a l’extracció per lots:
La cache KV reutilitza prefixos de prompt. Quan el prompt de sistema és idèntic a cada crida — i en un pipeline d’extracció estructurada sempre ho és — el cost de prefill es paga una vegada, i després queda en cache a disc. De la segona crida endavant veus un cost per crida dràsticament més petit. Al llarg d’una execució llarga això es compon en l’estalvi més gran.
200k de context (el model en reclama més, jo he provat fins aquí). Prou de trossejar els fitxers de 70k. Tot sencer entra, tot sencer surt resumit. Menys lògica d’agregació, menys risc de perdre una secció.
Sensiblement millor en sortida JSON estructurada segons les meves proves inicials. Zero fallades de sortida buida en les primeres execucions.
Rendiment de maquinari sobre l’M3 Ultra: ~38 tokens per segon de prefill, 32 de generació — coherent amb els números documentats per antirez. La latència per crida en el pipeline d’enriquiment en viu és de 6,3 a 25,9 s, mitjana 11,6 s per a una crida de 2k d’entrada i 500 tokens de sortida (últimes 200 crides d’una execució de 1.241). La mateixa forma de crida amb qwen3.5:122b corria a 90–290 s, mitjana 150–200 s. Un ordre de magnitud al temps de rellotge que més importava.
La imatge de fiabilitat és més nítida que la de la latència, i la que decideix si el pipeline és usable en absolut. Zero fallades silencioses en 1.241 crides, contra una de cada cinc amb Qwen. El prompt de sistema li diu al model “si el context és massa prim, mostra INSUFFICIENT_CONTEXT i res més” — DeepSeek V4 Flash obeeix el 15,6 % de les vegades. El bastiment es manté en lloc; res no s’inventa. Qwen, quan fallava, fallava silenciosament.
| Mètrica | DS4 + DeepSeek V4 Flash | Ollama + Qwen3.5:122b |
|---|---|---|
| Latència per crida, mitjana | 11,6 s | 150–200 s |
| Latència per crida, rang | 6,3 – 25,9 s | ~90 – 290 s |
| Fallades silencioses de sortida buida | 0 / 1.241 | ~18–20 % |
| Refusos honestos (bastiment mantingut) | 194 / 1.241 (15,6 %) | n/d |
| Pressupost de context que aguanta qualitat | 200k tokens (provats) | ~16k efectius |
| Reutilització de cache entre crides | SHA1 a disc, persistent | cap |
Una observació poc científica però que val la pena registrar: el Mac Studio funciona més fresc amb DS4 a quasi tota la GPU que amb Ollama+Qwen3.5:122b a càrrega comparable. Sense benchmark, només la temperatura de la carcassa.
No lligat a DS4. El truc de la cache KV a disc no és propietari. llama.cpp pot guardar cache de prefixos en memòria avui mateix i té cache persistent a disc al seu roadmap; Ollama s’hi recolza i ho heretarà. El patró — motor especialitzat, reutilització de prefix de prompt — és portable, i l’optimització s’estendrà a qualsevol model que estiguis servint en cada moment.
Generació en català#
No estic comparant la qualitat de generació d’aquests dos motors en aquest post. Aquesta és una pregunta diferent, i en textos prou llargs i de pes no confiaria que cap dels dos m’escrigui la feina. Per al català en particular, la meva norma vigent és que qualsevol cosa generada per un model local per sota del llindar aproximat de ~250B paràmetres efectius perd l’idioma — el ritme, el vocabulari que no es tradueix. Qwen3.5:122b no passa la prova. DeepSeek V4 Flash, amb tretze mil milions de paràmetres actius en inferència, queda en la mateixa classe efectiva de mida i espero que falli la mateixa prova fins que una tanda real de traducció em digui el contrari.
La traducció amb català com a llengua objectiu, al meu taller, va a Claude o a un model frontera d’OpenAI. La flota local cobreix només granel ES/EN. L’estalvi de cost viu al costat mecànic en granel; la veu i l’idioma no són per estalviar-hi.
Desmonetització, en el sentit de Diamandis#
A Bold (2015), Peter Diamandis i Steven Kotler descriuen sis efectes que segueixen quan una tecnologia es digitalitza: es torna enganyosa, disruptiva, desmonetitzada, desmaterialitzada, democratitzada. La desmonetització és la que importa aquí. Fa un any, indexar quatre-cents fitxers markdown personals amb un LLM no era econòmicament obvi — a preus d’API frontera la factura hauria estat real, els límits de taxa l’haurien estirat al llarg de setmanes. Avui, sobre maquinari que ja posseeixo, la mateixa feina és una sola execució per lots a zero cost variable. La crida marginal és gratuïta.
Quan el cost marginal s’acosta a zero, els casos d’ús que emergeixen són els que no compensaven la factura abans. La indexació wiki d’un corpus personal és un. Neteja de transcripcions a escala, esborranys multilingües per a coses que igualment reescriuràs, cerca semàntica sobre centenars de papers, auditoria de referències, extracció d’ontologies — cadascun era “interessant però no prou interessant” als preus d’API frontera, i cadascun és un projecte secundari ara.
Aquesta és l’optimització que importa. No “Ollama contra DS4” — aquesta decisió és petita, i la resposta canvia a mesura que llama.cpp es posa al dia. L’optimització és trobar els fluxos de treball que només tenen sentit un cop el cost per crida ha desaparegut.
Referència tècnica ràpida#
Si vols provar el camí DS4 en una màquina Apple Silicon amb prou memòria (256–512 GB per al build Q4, 96–192 GB per al Q2):
# 1. Clona + compila (~30 segons)
mkdir -p ~/Code && cd ~/Code
git clone https://github.com/antirez/ds4.git
cd ds4 && make
# 2. Descarrega el model (Q4: 153 GB, Q2: 81 GB) — GGUFs publicats per antirez
./download_model.sh q4 # o `q2` per al build petit
# 3. Engega el servidor
mkdir -p ~/.ds4-kv
./ds4-server \
--ctx 200000 \
--kv-disk-dir ~/.ds4-kv \
--kv-disk-space-mb 32768
# 4. Crida'l com qualsevol endpoint OpenAI
curl -s http://192.168.1.35:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "deepseek-v4-flash",
"messages": [{"role":"user","content":"Hola"}]}'Per defecte el servidor s’hauria d’escoltar a 0.0.0.0:8000, tot i que la versió que vaig compilar s’escoltava a 127.0.0.1:8000 i va caldre reconfigurar-la explícitament per arribar-hi des de la LAN. El --kv-disk-dir és on viu la cache KV SHA1 — manteniu-lo en NVMe intern, no en emmagatzematge extern. La primera crida a un servidor en fred triga deu a seixanta segons a carregar els pesos; les crides següents els reutilitzen.
