El cuello de botella no era el modelo: era el contrato | Home Assistant Specialist v0.5
TOOL CALLING // CONTEXT BUDGET // LOCAL SPECIALIST
No queríamos otro chatbot que devolviera bloques de texto o estructuras JSON conversacionales que simulan ser herramientas. Queríamos un motor pequeño, determinista y altamente especializado que entienda el contrato operativo nativo de Home Assistant y produzca llamadas directas que el bus domótico pueda ejecutar sin intermediarios ni rodeos.
El desarrollo de Home Assistant Specialist v0.5 comenzó rompiendo una premisa equivocada: el problema de los modelos pequeños en tareas de control no es su masa de parámetros, sino la naturaleza del contrato que les exigimos aprender.
1. Abandonar la compatibilidad artificial: El contrato nativo
Las versiones anteriores intentaban aproximar el comportamiento de herramientas mediante JSONs incrustados en turnos conversacionales comunes. Esa aproximación genera fricción, alucinaciones de sintaxis y exige al modelo procesar capas de abstracción innecesarias.
En la v0.5 tomamos una decisión radical: romper la compatibilidad conversacional e implementar el protocolo nativo de Qwen3 y las especificaciones de Chat Templating de Hugging Face:
- Estructura rígida de roles:
system,user,assistant(contool_callsexplícitos) y respuestas con roltool. - Definición formal de esquemas en el bloque
toolsdel prompt. - Aplicación de máscara de pérdida (
train_on_turn) para que el optimizador compute gradientes únicamente en las respuestas del asistente, evitando que el modelo memorice la inyección del sistema o las salidas del entorno.
Cuando cambias el contrato, cambias el objeto mismo que estás entrenando. No estás enseñándole a hablar de domótica; estás afinando un relé de ejecución.
2. Dataset V5: La tiranía de los datos limpios
Un modelo especialista vale exactamente lo mismo que el dataset sobre el que se refina. El dataset privado V5 se construyó con un filtrado quirúrgico para eliminar ruido estructural:
- 7,004 ejemplos de entrenamiento (6,779 efectivos tras la tokenización).
- 607 ejemplos de validación (588 efectivos).
- 667 ejemplos en la suite de prueba (test).
- 2,588 ejemplos rechazados categóricamente por inconsistencias en firmas de argumentos o esquemas corruptos.
- Límite controlado de máximo 8 entidades expuestas por conversación.
El filtrado inicial a 8 entidades no busca enmascarar la complejidad de un hogar inteligente, sino establecer un aislamiento de variables. En mi homelab modesto tengo más de 100 entidades activas en Home Assistant. Probar primero que el modelo comprende la sintaxis y los argumentos sobre 8 entidades en la baseline es el requisito de control necesario antes de escalar la densidad del contexto.
3. El presupuesto de contexto: De 2048 a 4096 tokens
La primera intuición técnica fue limitar la longitud máxima de secuencia (MAX_SEQ_LENGTH) a 2048 tokens buscando velocidad de entrenamiento y menor consumo de memoria. Fue un error de medición.
Las firmas de las herramientas nativas (tools) ocupan una porción masiva del prompt de entrada. En secuencias de 2048 tokens, la medición real demostró que las conversaciones válidas requerían entre 2,700 y 3,300 tokens. Al cercenar la secuencia a 2048, se recortaban las llamadas de salida del asistente.
Conclusión operativa: MAX_SEQ_LENGTH=4096 no es un lujo; es el piso mínimo funcional para preservar esquemas, contexto histórico y la llamada de la herramienta completa. Limitar entidades reduce el payload, pero no sustituye la medición real del costo del esquema.
4. Hardware y verificación DDP real en Kaggle
El proceso de entrenamiento distribuido (DDP) se desplegó sobre un entorno de dos GPUs NVIDIA Tesla T4 en Kaggle Notebooks:
HARDWARE T4x2: OK
rank 0: startup RANK=0 LOCAL_RANK=0 WORLD_SIZE=2 | GPU Tesla T4
rank 1: startup RANK=1 LOCAL_RANK=1 WORLD_SIZE=2 | GPU Tesla T4
Un detalle técnico crucial durante el arranque con Unsloth: el motor imprime aisladamente Num GPUs used = 1 por cada proceso worker. Una mirada superficial sugeriría un fallback a Single GPU. La confirmación real del paralelismo proviene del runtime global: WORLD_SIZE=2, LOCAL_RANK activo en ambos procesos y Data Parallel GPUs=2.
La verificación en el smoke test (3 pasos) confirmó la estabilidad de infraestructura:
global_step=3
training_loss=3.9789
train_runtime=203.36 s
5. Economía de cómputo y la regla de 1 época
La configuración inicial para 2 épocas (848 pasos) con QLoRA sobre Qwen3-4B (33M parámetros entrenables de 2.5B totales) arrojó un throughput de 66.6 segundos por paso. Esto proyectaba un tiempo total de ~15.7 horas.
Ante el límite de 12 horas por sesión continua en Kaggle, la corrida de 2 épocas fue cancelada en el paso 14/848. No fue una falla del modelo, sino una decisión consciente de economía de cómputo.
Reconfiguramos el job a NUM_TRAIN_EPOCHS=1 (424 pasos, ~7.85 horas). Para evitar pérdidas por desconexión o interrupción del runtime, establecimos un pipeline de checkpointing remoto que sube pesos de forma autónoma a Hugging Face Hub cada 50 pasos (~55 minutos de cómputo). Si Kaggle corta la sesión, el progreso queda respaldado sin tirar horas de GPU a la basura.
6. La estrategia de hardware local y el rol del micro-modelo
En mi homelab, la ejecución de inferencia está asignada a una NVIDIA Quadro RTX 4000 de 8 GB VRAM, mientras que los embeddings se delegan a un contenedor secundario de Ollama en CPU (puerto 11435).
La elección de Qwen3-4B Q5 permite mantener una ventana de contexto holgada de hasta 16k tokens en 8 GB. La visión a largo plazo, desarrollada en conjunto con Tuxbot (nuestro agente frontera), es usar esta v0.5 como escalón de validación sintáctica para luego descender hacia micro-modelos aún más livianos:
- Qwen3-1.7B Q4: permite extender la ventana de contexto hasta 28k tokens en la RTX 4000.
- Qwen3-0.6B Q4/Q5: permite expandir el contexto hasta 32k tokens sin desbordar un solo megabyte hacia la RAM del sistema.
Reducir el tamaño del modelo no es un retroceso; es ganar capacidad para procesar el estado real de 100+ entidades domésticas sin ahogar la VRAM ni comprometer la latencia.
7. Flujo de trabajo Humano-Agente y estado del proyecto
Este proyecto refleja la dinámica real entre visión de producto e ingeniería de ejecución:
- Humano (Sebastian / tuxevil): Dirección de arquitectura, decisiones de economía de cómputo, restricciones físicas de VRAM (8 GB), diseño de pruebas de densidad de entidades en homelab real.
- Agente (Tuxbot): Construcción del pipeline de entrenamiento, verificación de esquemas de pérdida, configuración de DDP y diseño de la suite de validación/test.
Estado editorial y técnico honesto
- Corrida de 1 época: En ejecución y bajo monitoreo mediante checkpoints en Hugging Face.
- Benchmarks y Quality Gate: Pendientes de evaluación tras concluir la corrida sobre el set de test (667 ejemplos).
- Exportación GGUF y Merge FP16: Pendientes hasta validar la precisión de argumentos y cero alucinaciones en sintaxis nativa.
El progreso técnico real no se mide por la cantidad de parámetros de un modelo, sino por la precisión de su contrato y la disciplina con la que gestionas tus recursos de cómputo.