# ia-modelo-chat — el modelo que contesta en la barra lateral de `atuq` (SDD 26 §6.7). # # ══ QUÉ ES ═════════════════════════════════════════════════════════════════════════════════════ # **Qwen2.5-1.5B-Instruct, cuantizado Q4_K_M**: 1.117.320.736 bytes de GGUF. Es el modelo de chat de # la distro, y entra como los pesos entran en cualquier lado — **fuente pineada por sha256**, no un # build que lo produzca. Nadie entrena nada acá. # # ══ POR QUÉ ÉSTE ═══════════════════════════════════════════════════════════════════════════════ # Tres cosas, y las tres se pueden discutir cambiando un sha256: # # · **licencia Apache-2.0**, que es lo que una distro puede shipear sin letra chica. Las # alternativas obvias (Llama-3.2, Gemma) traen licencias propias con restricciones de uso, y eso # en una imagen que se distribuye no es un detalle; # · **habla español**, que es el idioma de quien va a usar esto. Medido antes de pinearlo, no # supuesto: se le preguntó qué es una distribución de GNU/Linux y contestó dos frases correctas # en español; # · **entra en la imagen y corre en CPU**: 1,04 GiB y **20,1 tokens/s** medidos en el hub sin GPU # (89 tokens en 4,4 s). Un modelo de 7B con la misma licencia daría mejores respuestas y # quintuplicaría el peso, con la mitad de la velocidad. # # ══ POR QUÉ EL TARBALL ES NUESTRO Y LA URL NO RESUELVE ═════════════════════════════════════════ # takana extrae toda fuente con `tar`, y un `.gguf` pelado no es un tar. Así que el objeto pineado es # un tar que envuelve el fichero, publicado en el mirror de fuentes y servido **por sha256** — el # mismo camino que `firefox-pgo-profile`. La URL `.invalid` no resuelve a propósito (ADR 0013: la URL # no entra en `hash_inputs`, sólo el sha256). # # La PROCEDENCIA, para que nadie tenga que confiar en nuestro tar: # upstream https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF # fichero qwen2.5-1.5b-instruct-q4_k_m.gguf # sha256 6a1a2eb6d15622bf3c96857206351ba97e1af16c30d7a74ee38970e434e9407e ← del GGUF, no del tar # Ese sha256 es el que HuggingFace publica como `lfs.oid`, y es el que se verificó al bajarlo. # # ⚠ `strip_components = 0`: el tar lleva el fichero en la raíz. Con el default (1) se recorta lo # único que hay y el install muere con un `cp: cannot stat` que no menciona el recorte. name = "ia-modelo-chat" version = "qwen2.5-1.5b-instruct-q4_k_m" license = "Apache-2.0" [source] tarball = "https://no-hay-upstream.invalid/takana/ia-modelo-chat.tar" sha256 = "2560ee9452a979116ae24278615c51ecced38d2e62288ffe29f4a4bf7ddfc1c6" strip_components = 0 [build] compiler = "zig-cc" [build.phases] configure = "true" compile = "true" install = ''' set -e mkdir -p /out/usr/share/takana/ia cp qwen2.5-1.5b-instruct-q4_k_m.gguf /out/usr/share/takana/ia/modelo.gguf M=/out/usr/share/takana/ia/modelo.gguf # ── GUARDIÁN: QUE SEA UN GGUF, NO UN FICHERO GRANDE ───────────────────────────────────────── # El modo de fallo callado acá es el de siempre: un fichero truncado o un HTML de error de 200 K # renombrado a `.gguf` se instala igual, sella en verde, y lo único que falla es la respuesta — # cuando ya no hay nadie mirando el build. Se comprueban las dos cosas que un GGUF de verdad tiene: # el número mágico `GGUF` en los primeros cuatro bytes, y el tamaño. head -c 4 "$M" | grep -q GGUF || { echo "!! el fichero instalado no empieza con el mágico GGUF" >&2 head -c 64 "$M" | od -c | head -3 >&2 exit 1 } n=$(stat -c%s "$M") test "$n" -gt 900000000 || { echo "!! el GGUF pesa $n bytes: está truncado" >&2; exit 1; } echo "guardián: GGUF válido — $n bytes" '''