Documentación

Viabilidad de ANE: transformaciones equivalentes y un objetivo medible de 10×

Fecha de la investigación: 2026-09-20. Hardware: M3 Max, GPU de 40 núcleos, 128 GiB. Este documento describe hipótesis y cotas matemáticas, no una afirmación de una nueva aceleración medida. El punto de partida son los pesos originales de Laya y el runtime MLX FP16, más rápido. Los experimentos de ingeniería y las mediciones pueden dejar obsoletas las observaciones iniciales que se indican abajo.

El mejor primer experimento es una reescritura de forma fija y channel-first de todo el transformer, seguida de una inspección del plan de ejecución. El objetivo de orden de magnitud más plausible es la energía por decisión completada, siempre que el modelo conserve una latencia y una precisión útiles. Cambiar solo un ajuste de unidad de cómputo de Core ML no es evidencia suficiente de que el Neural Engine ejecutara el modelo.

Los experimentos de ingeniería posteriores implementaron esa reescritura, y el informe medido de velocidad/energía ahora registra los resultados. El candidato sin comprimir mejora la eficiencia pero no ha cumplido el objetivo de 10×. Las hipótesis y el denominador original que se indican abajo se conservan como registro de la investigación; usa la comparación posterior con MLX compilado para las afirmaciones de rendimiento medidas.

Definir el objetivo antes de optimizar

Para las mismas entradas, el mismo checkpoint, la misma política de precisión y el mismo número de decisiones completadas, define:

t = elapsed time / completed decisions
P = average measured power over that same interval
E = integrated energy / completed decisions = P × t

S = t_MLX / t_candidate                    speed gain
R = P_MLX / P_candidate                    power reduction factor
S × R = E_MLX / E_candidate                 energy efficiency gain

Usa la latencia media por bloque, no un percentil de latencia, en esta identidad. Reporta P50 y P95 por separado. Un resultado que es 2× más rápido con un quinto de la potencia es una mejora de energía de 10×. Un resultado que es la mitad de rápido necesita una reducción de potencia de 20× para ofrecer la misma mejora de energía de 10×. Multiplicar la velocidad por una mejora de energía ya calculada cuenta el tiempo transcurrido dos veces.

Hay dos pruebas de potencia distintas:

  1. Inferencia secuencial saturada: mide el rendimiento real, la latencia y los julios por decisión. Un candidato de menor potencia pero más lento no es automáticamente más eficiente.
  2. Carga ofrecida igual, como el mismo ritmo de tick de Snake: ambos candidatos deben terminar el mismo trabajo dentro del plazo. Reporta la potencia media, la energía total del intervalo, los incumplimientos de plazo y las decisiones completadas. Dormir más tiempo o descartar trabajo no es una optimización.

Registra el dominio de potencia medido. La telemetría de CPU + GPU + ANE no es necesariamente la potencia de toda la máquina ni de la batería, y no debe etiquetarse como tal. Reporta la energía bruta y, si es utilizable, la energía emparejada con reposo restado. Cuando carga menos reposo es similar al ruido, conserva la incertidumbre en lugar de recortarla en silencio y reportar una relación enorme. Mantén la tokenización, las copias de entrada, el fallback a CPU y el postprocesamiento dentro del límite de contabilidad del endpoint.

Evidencia inicial y el denominador

El benchmark multilingüe actual de MLX mide una única pregunta de 91 tokens con 7.870 ms P50 / 9.870 ms P95. El benchmark inglés de MLX mide una pregunta de 93 tokens con 13.334 / 13.734 ms. Son mediciones predict de extremo a extremo, que excluyen la carga y el calentamiento del modelo. Una comparación nueva debe reejecutar la ruta MLX más fuerte aplicable, incluidas sus opciones opt-in de compile y caché de prompt allí donde la carga de trabajo lo permita; un resultado eager histórico no es un denominador permanente.

La exportación multilingüe existente de Core ML mide 11.277 ms P50 con CPU + GPU, 78.037 ms con ALL y 81.336 ms con CPU + NE. Este último plan registra 1,318 operaciones preferidas por CPU y ninguna preferida por NE; 24 operaciones SDPA tienen metadatos de dispositivo desconocidos. Esto no establece ninguna afirmación de ejecución en NE. El plan lista muchas operaciones como NE-supported, lo que es distinto de NE-preferred. Apple describe el uso de dispositivo del plan de cómputo como un uso de dispositivo previsto, así que incluso un plan favorable debería corroborarse con un perfilado en runtime o con actividad de NE observable.

La puerta de regresión FP16 existente es un 100% de acuerdo de argmax en el fixture, salidas deterministas finitas y como máximo 0.02 de deriva absoluta en las probabilidades calibrada y de acción. Es una comprobación de fidelidad de conversión sobre un corpus pequeño. No establece la precisión general en tareas, la competencia en Snake ni la calidad de un modelo comprimido.

Transformaciones equivalentes del grafo

El estudio de despliegue de Transformer de Apple motiva activaciones BC1L tetradimensionales, convoluciones 1×1, dividir la atención en cabezas y reducir las copias de disposición. Su ejemplo publicado de 10× es otro modelo, otro dispositivo y otra línea base; no puede trasladarse a la comparación con MLX de aquí. Trata esas recomendaciones de disposición como candidatas a probar en este sistema operativo y este chip, no como un contrato completo de soporte de hardware actual.

Proyecciones lineales y el MLP con compuerta

Sea X[b,l,i] la activación existente y define U[b,i,0,l] = X[b,l,i]. Para una capa lineal,

Y[b,l,o] = sum_i W[o,i] X[b,l,i] + bias[o]
K[o,i,0,0] = W[o,i]
Conv2D(U,K)[b,o,0,l] = Y[b,l,o]

Esto cambia la disposición y la representación del operador sin cambiar la función de valor real. Mantén esa disposición en todo el codificador y en ambas capas transformer de la cabeza de decisión. Convertir de ida y vuelta alrededor de cada capa lineal puede eliminar el beneficio. QKV puede seguir siendo una única convolución D → 3D; divide su salida de canales en Q, K y V. De igual modo, conserva la proyección fusionada existente del codificador D → 2I, divide los canales en valor y compuerta, aplica el GELU exacto original al valor, multiplica por la compuerta y proyecta I → D.

Para FP16, una anchura de secuencia divisible por 32 también se alinea con la alineación de 64 bytes del último eje descrita en el estudio de Apple. Las formas iniciales son B=1,L=96 para el fixture corto de la API y B=3,L=64 para Snake compacto. Una recomendación de múltiplos de 32 aquí sigue ese modelo de buffer; no es permiso para rellenar cada carga de trabajo a una longitud arbitraria grande. Snake no necesita 96 tokens.

Atención y RoPE

Para cada cabeza, mantén Q y V como (B,d,1,L) y transpón K a (B,L,1,d). Calcula:

score[b,k,0,q] = sum_c Q[b,c,0,q] K[b,k,0,c] / sqrt(d)
weight = softmax(score + additive_mask, axis=key)
out[b,c,0,q] = sum_k weight[b,k,0,q] V[b,c,0,k]

El eje key es el eje 1 en esta representación. Concatena las salidas de las cabezas en el eje de canales. Es la misma función de atención; un eje de softmax equivocado la cambia en silencio. La implementación de atención de referencia de Apple demuestra las dos contracciones tetradimensionales correspondientes. Inspecciona los operadores MIL convertidos: escribir un einsum no garantiza el dispositivo ni el lowering previstos.

Aplica RoPE a los pares de canales de cada cabeza antes de QK. Conserva la convención de mitad dividida del checkpoint, las posiciones originales y la theta por capa. En este checkpoint multilingüe, tanto el RoPE completo como el local usan theta 160000. Dividir la primera y la segunda mitad de todas las cabezas concatenadas juntas es incorrecto; divide dentro de cada cabeza de 64 canales. Una rotación dependiente de la posición no puede plegarse en general en una única matriz de pesos independiente de la posición.

La regla local es bidireccional abs(q-k) <= 64, inclusive. Conserva el padding de keys y la regla existente de consultas rellenadas. Las partes constantes dependientes de la posición pueden calcularse antes del trazado para formas fijas; cambiar el padding de muestra debe seguir afectando a la máscara de keys. Sustituir la exclusión matemática por una máscara negativa grande y finita es una aproximación numérica, a menos que coincida con el comportamiento de precisión finita de la implementación original; verifica entradas adversarias y rellenadas.

LayerNorm no es intercambiable con otras normalizaciones

Para cada (b,l), reduce solo a lo largo de los canales:

mu = mean_c U
v = mean_c (U-mu)^2
normalized = (U-mu) / sqrt(v + epsilon)
output = normalized * gamma + beta

Conserva el epsilon original, el orden afín, la varianza poblacional, la normalización identidad de la primera capa, el GELU exacto y el orden residual. La LayerNorm de referencia de Apple usa un orden afín distinto; su adaptador para DistilBERT lo compensa transformando el sesgo. Copiar directamente esa clase y cargar el state dict de Laya sería incorrecto para sesgos distintos de cero. Una expresión afín explícita con el orden original también evita dividir por una gamma posiblemente cero.

Recortar las activaciones, cambiar GELU por tanh o reemplazar LayerNorm por RMSNorm cambia la función. Si los valores al cuadrado desbordan, un reescalado positivo es una opción matemáticamente equivalente:

normalize(x/a, epsilon/a^2) = normalize(x, epsilon), for a > 0

La acumulación en precisión finita sigue necesitando pruebas de paridad. Las reducciones en FP32 pueden costar copias o un fallback a CPU, así que inspecciona el plan en lugar de relajar en silencio el comportamiento numérico.

Mover el trabajo no admitido a los límites del modelo

Si la búsqueda de embeddings, el gather dinámico de marcadores o la cola de acción impiden una región NE contigua, crea un candidato aparte con esta partición:

CPU: tokenizer → selected embedding rows → embedding LayerNorm
NE candidate: all encoder layers → type embedding addition → both heavy head layers
CPU: marker/CLS selection → small scorer → raw-probability features → action head

Solo los extremos cruzan motores. No descargues la atención ni la LayerNorm de todas las capas a la CPU. En multilingüe B=1,L=96, un tensor de embedding FP16 es de 147,456 bytes; en B=3,L=64 es de 294,912 bytes. Incluye estas copias y cualquier copia de salida del estado oculto completo en la medición de extremo a extremo.

La tabla de tokens multilingüe tiene 196,608,000 parámetros, pero cada solicitud reúne solo sus filas de tokens. No es necesario enviarla a un subgrafo transformer de ANE, y no debe contarse como una lectura completa de la tabla en cada predicción. Su LayerNorm no tiene dependencia de posición, así que la prenormalización offline de las filas de la tabla es equivalente en aritmética real. Puede cambiar el redondeo y la precisión de almacenamiento, lo que requiere su propia prueba de paridad. La cabeza de acción consume probabilidades de los logits de marcador brutos, antes de la calibración de temperatura; reconstruir sus características a partir de las probabilidades calibradas públicas cambia el comportamiento del checkpoint.

Límites aritméticos de una afirmación de latencia de 10×

Sea D la anchura oculta, I la anchura intermedia con compuerta del codificador, N las capas del codificador y H=2 las capas de la cabeza de decisión. El recuento principal de parámetros matriciales por token y la aritmética densa son:

A = N(4D^2 + 3DI) + 12HD^2
F_dense(B,L) = 2BLA + 4B(N+H)L^2D

Multiplica y suma cuentan por separado. Estas ecuaciones excluyen normas, activaciones, embeddings, scoring, máscaras, copias y overhead del runtime. No son un perfilador. Modelan el cómputo de atención densa actual incluso para capas locales enmascaradas.

Checkpoint D / I / N A Bytes de la matriz principal FP16 Trabajo denso con B=1,L=96 Cómputo efectivo requerido para 10× por debajo del P50 actual de MLX
Multilingüe 768 / 1152 / 22 124,452,864 248.91 MB 24.574 GFLOP 31.23 TFLOP/s en 0.787 ms
Inglés / arquitectura typed 1024 / 2624 / 28 368,312,320 736.62 MB 71.848 GFLOP 53.89 TFLOP/s en 1.333 ms, usando la línea base inglesa

Son tasas alcanzadas requeridas, no especificaciones de pico de ANE afirmadas. Una reescritura de disposición elimina overhead pero no elimina esas proyecciones densas. El hardware también debe ejecutar una cadena secuencial de 24 o 30 bloques de atención/MLP.

Un modelo de streaming optimista da otra cota inferior condicional:

t >= max(F / effective_compute, bytes_from_DRAM / effective_bandwidth)

El M3 Max de 40 núcleos de GPU está especificado con 400 GB/s de ancho de banda de memoria unificada. Si cada matriz principal FP16 se obtiene de la DRAM una vez por solicitud, incluso el acceso completo a ese ancho de banda cuesta al menos 0.622 ms para multilingüe y 1.842 ms para inglés. El acceso real al ancho de banda de ANE puede ser menor, y los pesos en caché o comprimidos cambian la suposición. No es una cota inferior física incondicional. Muestra por qué 10× de latencia en inglés es especialmente exigente con streaming sin comprimir, y por qué medir la energía es útil incluso cuando la latencia mejora modestamente.

Para una fracción medida f del tiempo de extremo a extremo mejorada por un factor s, la ley de Amdahl da S = 1 / (1-f+f/s). Ni siquiera una aceleración infinita de una región puede alcanzar 10× a menos que ocupe al menos el 90% de la latencia original. La cota análoga usa la fracción de energía medida, no de FLOPs, cuando el objetivo son julios por decisión. La optimización de consultas seleccionadas de la cabeza final elimina solo unos pocos por ciento de la aritmética del modelo; la dispersión de la atención local también es despreciable con L<=64, donde la ventana local cubre todas las posiciones. Ninguna ofrece una ruta creíble de 10× por sí sola.

La compresión y los cambios arquitectónicos tienen contratos distintos

Candidato ¿Misma función de checkpoint de valor real? Qué puede cambiar de forma realista
Disposición BC1L, proyecciones 1×1, posiciones/máscaras estáticas, división en cabezas Sí, cuando se preservan las ecuaciones y las entradas Planificación, localidad, partición del compilador, copias de memoria
Partición de extremos en CPU, norma de embeddings offline, consultas seleccionadas en la cabeza final Sí en aritmética real; valida el redondeo Operaciones no admitidas, huella del paquete, algo de trabajo no usado
Paletización de 8/6/4 bits o cuantización de pesos Generalmente no Tráfico/almacenamiento de pesos y posiblemente energía/latencia de inferencia
Poda de pesos aprendidos distintos de cero o factorización de bajo rango No, salvo que exista estructura algebraicamente exacta Aritmética matricial y tráfico tras recuperación/calibración
Salida temprana, poda de tokens, menos capas, estudiante más estrecho No Ahorros potencialmente grandes; modelo y contrato de calidad nuevos
Reutilización de estados ocultos entre preguntas arbitrarias No para este codificador bidireccional Atajo inválido; los estados contextuales dependen de la pregunta
Almacenar en caché respuestas completas idénticas Exacto para aciertos de caché Característica de carga de trabajo; no velocidad de inferencia sin caché

La descripción general de optimización actual de Apple apunta a la paletización para ganancias de memoria/latencia en NE e identifica la ruta de cómputo W8A8 más nueva con A17 Pro/M4. No extrapoles esa aceleración de hardware más nueva a este M3 Max. La guía de rendimiento de cuantización también advierte de que la desquantización de activaciones puede ralentizar la ejecución en CPU/GPU. Primero obtén una línea base residente en NE y luego prueba la paletización de pesos de 8 bits hacia abajo, conservando las normas/scorers sensibles según corresponda.

Empaquetar pesos FP16 a ocho o cuatro bits da una relación ideal de almacenamiento de pesos de 2× o 4× antes de los metadatos. Eso no es un multiplicador de latencia igual: la descompresión, el movimiento de activaciones y el cómputo siguen ahí. La poda solo ayuda al runtime si la representación elegida explota realmente los ceros. Eliminar cabezas/capas arbitrarias o hacer truncamiento de bajo rango requiere recuperación de calidad y no puede conservar la identidad del modelo original sin matices.

Para una cota de error de logits por entrada ||z'-z||_infinity <= delta, un certificado de argmax suficiente es top1(z)-top2(z) > 2delta. Con una temperatura de calibración positiva idéntica T, la cota de Lipschitz en norma infinito del softmax da ||p'-p||_infinity <= delta/(2T). Son diagnósticos útiles sobre entradas evaluadas, no un certificado global para la cuantización. Conserva por separado las rebanadas de evaluación de margen estrecho y multilingües; los ejemplos saturados pueden ocultar grandes errores de logits.

Tres experimentos y puertas de aceptación

  1. Grafo NE equivalente de forma fija. Exporta multilingüe B=1,L=96,K=4 y Snake B=3,L=64,K=4 con proyecciones BC1L, RoPE correcto por cabeza, atención explícita y LayerNorm/GELU originales. Compara los arrays de entrada y las salidas de capas individuales contra el grafo original. Inspecciona qué proyecciones principales y bloques de atención son preferidos por NE y luego comprueba la actividad real de NE en runtime. Un recuento de operaciones admitidas por sí solo no es éxito. Reejecuta la línea base MLX optimizada correspondiente en bloques alternos.
  2. Una única isla transformer contigua. Si el primer grafo se fragmenta, mueve el embedding y la pequeña cola final a los límites de la CPU. Compara esto con el candidato de grafo completo bajo la misma medición de potencia. Conserva un candidato solo si las predicciones completas mejoran la latencia o la energía más allá de la variación observada entre ejecuciones. Incluye todas las copias; un codificador aislado rápido es insuficiente.
  3. Compresión centrada en energía después de que funcione la colocación. Criba la paletización de 8 bits y luego 6/4 bits como variantes aproximadas aparte. Ejecuta la puerta de fixture sin cambios, tareas choice/score/noul reservadas, entradas multilingües, empates cercanos y trayectorias de Snake. Publica la precisión, la deriva de probabilidad y la calibración junto con el rendimiento. La compresión agresiva o la destilación pertenecen a un modelo con nombre aparte si cambian el comportamiento aprendido.

Antes de una afirmación de lanzamiento, usa los mismos hashes de checkpoint/entrada y un orden alterno de línea base/candidato; excluye la compilación en frío pero repórtala por separado. Usa al menos cinco bloques sostenidos por finalista y conserva muestras sin procesar de latencia, llamadas completadas y potencia. Exige el acuerdo del fixture original y las tolerancias de probabilidad existentes sin relajarlas para que pase el candidato, además de salidas finitas estables y memoria acotada. Mide entradas largas y de límite de forma por separado de las demos cortas de forma fija.

Declara 10× solo cuando la velocidad, la potencia con carga igual o la relación de energía relevantes sean al menos diez, con una incertidumbre que respalde la afirmación, y cumpliendo los límites de latencia y calidad de tareas indicados. Si la cota inferior de incertidumbre no llega a diez, reporta la relación medida. Una ganancia de energía menor con ejecución verificada en NE sigue siendo evidencia útil; no es un resultado de orden de magnitud.

Procedencia de la documentación

Se usó el flujo de trabajo requerido de Context7 CLI: se resolvió Core ML Tools a /apple/coremltools y luego se consultaron el lowering de operadores/disposición de transformer y el comportamiento de compresión de NE (tres comandos en total). Se revisaron el artículo de investigación de Apple, el código de referencia, la documentación actual de optimización de Core ML, la documentación del plan de cómputo y la especificación del dispositivo enlazada arriba. Las ecuaciones del modelo, los recuentos de parámetros y las mediciones iniciales se derivaron de este repositorio y de su proyecto hermano MLX. Ninguna rama de esta investigación ejecutó un benchmark competidor de GPU/ANE.