Capítulos · 13
Core AI Agent Skills: el manual de ANE de Apple, legible por máquinas
Parte de la ANE Knowledge Base. Fuente: el árbol
skills/dereferences/coreai-models(commit85e2f2d) — tres agent skills que Apple distribuye para Claude Code (.claude-plugin/marketplace.json), Codex CLI y Gemini CLI. Son la declaración más explícita de reglas de autoría para ANE que Apple ha publicado jamás — incluyendo hechos de hardware ausentes de los artículos de investigación de 2022/2024 y de las sesiones de la WWDC.
Apple ahora distribuye su experiencia en ML en dispositivo como agent skills: manuales de reglas en markdown + scripts auxiliares probados que un agente de programación carga bajo demanda. Los encabezados de los skills declaran la filosofía: "hard-won empirical knowledge… the rules here are stable across Core AI releases — they reflect hardware behavior, not API shapes." Este documento cataloga lo que enseña cada skill y — lo más importante — lo que añade a los docs 01–07.
1. Los tres skills#
| Skill | Rol | Archivos clave |
|---|---|---|
working-with-coreai |
Orquestador: el pipeline AUTHOR → COMPRESS → EXPORT → COMPILE → RUN, guía de plataforma/dimensionamiento, protocolo de onboarding | SKILL.md, references/guidance.md |
model-authoring |
El manual de reglas de hardware: patrones de autoría por unidad de cómputo, umbrales de verificación, convenciones de KV cache | SKILL.md, references/neural_engine_rules.md (479 líneas), references/gpu_rules.md, references/common_issues.md |
model-compression-exploration |
Un protocolo automatizado de barrido de compresión sobre coreai-opt (~30 configuraciones + refinamientos, JSONL + informe de dispersión) |
SKILL.md, 4 docs de referencia, 2 scripts con pruebas unitarias |
Prescripciones de flujo de trabajo destacables: "Run code, don't read code — running gives ground truth instantly" (descubrimiento de arquitectura vía forward hooks); crear primitivas bottom-up (norm → proyecciones → atención → MLP → bloque), verificando cada una antes de componer; "start with export, add authoring or compression only if needed" — la reescritura es ahora la excepción, no lo predeterminado; y para los agentes, "your first response is always a conversation, not code."
2. Nuevos hechos sobre ANE (no en los docs 01–07 hasta ahora)#
neural_engine_rules.md confirma cada principio que esta KB documentó — BC1S, Conv2d 1×1, último eje de 64 bytes, penalizaciones de relleno de 32×/64×, chunking per-head para residencia en L2, el einsum bchq,bkhc->bkhq — y añade conocimiento de hardware que antes era folclore o desconocido:
| # | Nuevo hecho | Detalle |
|---|---|---|
| 1 | dtypes soportados: fp16, int8, int16 | fp32 en cualquier sitio → fallback a GPU/CPU. Cualquier literal float de Python (x * 1.0) crea un búfer f32; torch.exp promociona a f32; F.silu baja a cast(f32) → mps.swish → cast(f16) (solución: x * torch.sigmoid(x)) |
| 2 | -40000.0, nunca -inf |
"Neural Engine hardware does not handle IEEE -inf correctly in softmax" — primera declaración oficial de por qué existe la convención -1e4 de la KB |
| 3 | La ANE computa K @ Q, transpuesto respecto al Q @ Kᵀ de la GPU |
De ahí la forma de la máscara (1, key_seq, 1, query_seq) — transpuesta vs GPU. La orientación incorrecta es la causa #1 de ~15–30 dB de PSNR |
| 4 | "There is no fused SDPA path" — literal | La atención per-head es "fundamental to Neural Engine hardware", zanjando la cuestión de doc 09 §3.5: el compilador no puede bajar (lower) la SDPA fusionada a la ANE; la forma per-head debe existir en el grafo fuente |
| 5 | Regla de ubicación del softmax | El softmax sobre una dimensión espacial limita la capacidad del compilador de dividir el trabajo espacialmente → coloca el softmax en la dimensión de canal (explica retroactivamente el softmax(dim=1) de 2022) |
| 6 | Reglas de diseño de capa (requieren reentrenamiento) | Los strides de conv deben factorizar en 2s y 3s (4,6,8,9,12,16,24,32); kernels palettizados: stride ≤ 2; descomponer kernels grandes (k_fused = k1+k2−1); fusionar cadenas de conv sin activación; factorizar dilataciones en 2s/3s; stride de pooling solo 2 o 4 |
| 7 | RoPE se queda fuera del grafo | Precalcula cos/sin en Python, pásalos como entradas 4D (1, head_dim, 1, S) — los gathers de tabla 2D dentro del grafo producen una salida 3D que la ANE rechaza |
| 8 | Los embeddings se externalizan | Forma (vocab, 1, hidden), exportados como un programa separado para que se cuanticen de forma independiente (entrypoint gather_embeddings_{N}) |
| 9 | Artefactos multi-entrypoint | Un torch.export dinámico → funciones estáticas especializadas por forma: extend_{ctx}_{len} (decode), prompt_opt_{ctx}_{len} (prefill, no se computan logits), gather_embeddings_{N} |
| 10 | Deriva de fp16 en prefills largos | El prefill secuencial de 1 token acumula redondeo fp16 a lo largo de pasos×capas; más allá de ~50 tokens usa prefill fragmentado (S_q=64) o tensores de caché fp32 del lado del host |
| 11 | Palettization con LUT vectorial | Las generaciones más nuevas de ANE soportan entradas de tabla de consulta con valores vectoriales; las LUT pueden abarcar múltiples canales de salida |
3. La bifurcación del patrón de KV cache (refina los docs 06/09)#
Los skills trazan una clara división de plataforma que nuestra lectura anterior de primitives/ solo insinuaba:
| Neural Engine (iOS) | GPU (macOS) | |
|---|---|---|
| Forma de la caché | [n_layers, B, H_kv·D, 1, max_S] — seq en la dim 4 |
[n_layers, B, H_kv, max_S, D] — seq en la dim 3 |
| Patrón | I/O funcional de solo lectura: el grafo no contiene escrituras de caché; cada llamada recibe la caché pasada completa, hace cat([k_cache, key_rope], dim=-1), y devuelve los nuevos tokens K/V como salidas; el host los escribe en la caché |
Wrapper de exportación con estado: register_buffer + coreai::mutable_slice_update (eager in-place / meta funcional) + mutable_arg_action="hoistToArg" |
| Escollo crítico | Cachea las keys post-RoPE — cachear K pre-RoPE hace que los pasos posteriores atiendan a keys sin rotar, "PSNR collapses to ~20 dB" | No uses APIs de transformación con estado para generación: "state resets between inference calls" |
Nota evolutiva para la KB: la mezcla de máscara one-hot de WhisperKit (doc 06 §4) → MLState (2024) → y ahora dos modismos de Core AI, elegidos por unidad de cómputo. El de ANE es el más cercano en espíritu al de WhisperKit — gestionado por el host, funcional, estático — reivindicando ese diseño.
4. Reglas de GPU que vale la pena registrar (la anti-ANE)#
gpu_rules.md es un mundo especular: layout estándar (B,S,D), nn.Linear, QKV fusionado (una sola proyección — exactamente lo opuesto a las "separate projections for cache residency" de Apple en 2022), SDPA fusionada nativa, máscaras -inf permitidas, intermedios fp32 OK, formas dinámicas bien. Además, técnicas de producción: Q/K-norm+RoPE fusionados sobre el slice QKV empaquetado, ordenar up_proj antes de gate_proj para throughput, MoE vía SwitchLinear/GatherMM (todos los expertos en un solo tensor (sets, experts, out, in), índices uint16), y carga eficiente en memoria de 7B+ (init en meta-device, load_state_dict(assign=True), safetensors transmitidos capa a capa).
La lección que la KB predijo: los consejos de optimización son relativos a la unidad de cómputo. Lo que es obligatorio en ANE (divisiones per-head, proyecciones separadas) es un anti-patrón en GPU, y viceversa — ahora declarado por Apple en dos archivos de reglas paralelos.
5. PSNR como lenguaje de diagnóstico#
Los skills formalizan los números de verificación que esta KB había observado empíricamente ([docs 06](06-case-study-whisperkit.md §8)/11):
| Comprobación | Umbral |
|---|---|
| Reescrito vs fuente (torch) | > 70 dB |
| Layout ANE vs layout GPU (torch) | > 70 dB |
| Compilado vs torch (fp16) | ≥ 40 dB |
| Tras palettization de 4 bits | ≥ 35 dB |
Y, notablemente, firmas de fallo: ~15–30 dB → orientación de la máscara; 20–30 dB → activación incorrecta (SiLU/GELU/QuickGELU no son intercambiables); ~18 dB → discrepancia del patrón M-RoPE; ~20 dB → keys pre-RoPE cacheadas. Rangos de PSNR como una tabla de códigos de error. (Nuestra ejecución de doc 11: TextDecoder compilado 42.5 dB, AudioEncoder 68.9 dB — de lleno en la banda saludable.)
Trampas de runtime catalogadas en common_issues.md: .contiguous() en todo antes de NDArray (el runtime lee memoria en crudo, ignorando los strides); el descriptor de dtype es "si32", no "i32"; filtra las entradas de exportación a los kinds USER_INPUT/BUFFER; tanh → 2·sigmoid(2x)−1 para evitar una op f32; xcrun coreai-build compile --preferred-compute neural-engine — un flag de unidad de cómputo en tiempo AOT que complementa las SpecializationOptions de runtime de doc 12 §3.
6. Guía de plataforma (de guidance.md)#
- iOS: modelos < 2 GB; formas estáticas; poco o ningún control de flujo; palettization (2/4/6/8 bits) o int8/int4 por canal; longitudes variables → fragmentar en múltiples funciones estáticas.
- macOS: deja ≥ 6 GB de RAM de margen; formas dinámicas/control de flujo bien; se recomienda cuantización int4 por bloque.
- Consulta
os_proc_available_memory()antes de cargar; prefiere la especialización.defaulta menos que alinees la representación del modelo con una unidad fija (ANE ↔ palettized/estático; GPU ↔ cuantización lineal/dinámico).
7. El protocolo de barrido de compresión (skill #3, condensado)#
Una versión totalmente procedimentada de la metodología mixed-bit de argmaxtools (doc 07 §3): tres grupos de experimentos (cuantización por canal int8/int4 × 3 esquemas; int4 por bloque × tamaños de bloque 16/32/128; palettization de 4/6/8 bits × tamaños de grupo), ~30 configuraciones barridas con scripts de tamaño/calidad con pruebas unitarias, y luego refinamiento por omisión de capas (primera/última/tipo-de-parámetro-más-pequeño) sembrado a partir de las configuraciones del percentil 95/75, resultados en JSONL + una tabla de frontera de 5 anclas + gráfico de dispersión. Detalles de ingeniería destacables: el overhead de escala por bloque hace que int4/bs=16 ≈ 5 bits efectivos; la divisibilidad omite capas silenciosamente (comprobación previa); entradas reales obligatorias — "random inputs produce meaningless PSNR." El skill incluso prescribe subagentes paralelos por grupo — Apple escribiendo guía de orquestación multi-agente.
8. Metalección#
El conocimiento de optimización de Apple ha recorrido ahora: artículos de investigación (2022) → repos de referencia (2022–23) → toolkits de terceros (2023–24) → compilador + primitivas de plataforma (2026) → agent skills (2026). El estado final es conocimiento empaquetado para que las máquinas lo apliquen — la misma apuesta que hace esta KB. Para este repo, neural_engine_rules.md reemplaza al folclore disperso como la referencia canónica de reglas de ANE; los docs 01–07 explican por qué existen esas reglas.