Documentação

Viabilidade do ANE: transformações equivalentes e uma meta mensurável de 10×

Data da pesquisa: 2026-09-20. Hardware: M3 Max, GPU de 40 núcleos, 128 GiB. Este documento descreve hipóteses e limites matemáticos, não uma afirmação de uma nova aceleração medida. O ponto de partida são os pesos originais do Laya e o runtime MLX FP16 mais rápido. Os experimentos de engenharia e as medições podem substituir as observações iniciais abaixo.

O melhor primeiro experimento é uma reescrita de forma fixa e channel-first de todo o transformer, seguida por uma inspeção do plano de execução. A meta de ordem de magnitude mais plausível é energia por decisão concluída, desde que o modelo mantenha latência e acurácia úteis. Mudar apenas uma configuração de compute-unit do Core ML não é evidência suficiente de que o Neural Engine executou o modelo.

Os experimentos de engenharia subsequentes implementaram essa reescrita, e o relatório de velocidade/energia medido agora registra os resultados. O candidato não comprimido melhora a eficiência, mas não atingiu a meta de 10×. As hipóteses e o denominador original abaixo são mantidos como registro de pesquisa; use a comparação posterior com o MLX compilado para afirmações de desempenho medido.

Defina a meta antes de otimizar

Para as mesmas entradas, checkpoint, política de precisão e número de decisões concluídas, defina:

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

Use a latência média de bloco, não um percentil de latência, nesta identidade. Relate P50 e P95 separadamente. Um resultado 2× mais rápido com um quinto da potência é uma melhoria de energia de 10×. Um resultado duas vezes mais lento precisa de uma redução de potência de 20× para entregar a mesma melhoria de energia de 10×. Multiplicar a velocidade por uma melhoria de energia já calculada conta o tempo decorrido duas vezes.

Há dois testes de potência distintos:

  1. Inferência sequencial saturada: meça o throughput, a latência e os joules reais por decisão. Um candidato de menor potência mas mais lento não é automaticamente mais eficiente.
  2. Carga oferecida igual, como a mesma taxa de tick do Snake: ambos os candidatos devem terminar o mesmo trabalho dentro do prazo. Relate potência média, energia total do intervalo, prazos perdidos e decisões concluídas. Dormir por mais tempo ou descartar trabalho não é uma otimização.

Registre o domínio de potência medido. A telemetria de CPU + GPU + ANE não é necessariamente a potência da máquina inteira nem da bateria, e não deve ser rotulada como tal. Relate a energia bruta e, se utilizável, a energia pareada com idle subtraído. Quando carga menos idle é semelhante ao ruído, preserve a incerteza em vez de limitá-la silenciosamente e relatar uma razão enorme. Mantenha tokenização, cópias de entrada, fallback para CPU e pós-processamento dentro da fronteira de contabilização do endpoint.

Evidência inicial e o denominador

O atual benchmark multilíngue do MLX mede uma única pergunta de 91 tokens em 7.870 ms de P50 / 9.870 ms de P95. O benchmark em inglês do MLX mede uma pergunta de 93 tokens em 13.334 / 13.734 ms. Essas são medições de predict ponta a ponta, excluindo carregamento do modelo e aquecimento. Uma nova comparação deve reexecutar o caminho MLX mais forte aplicável, incluindo suas configurações opt-in de compile e de cache de prompt onde a carga de trabalho permitir; um resultado histórico em modo eager não é um denominador permanente.

A exportação multilíngue atual do Core ML mede 11.277 ms de P50 com CPU + GPU, 78.037 ms com ALL, e 81.336 ms com CPU + NE. O último plano registra 1,318 operações preferidas por CPU e nenhuma operação preferida por NE; 24 operações SDPA têm metadados de dispositivo desconhecidos. Isso não estabelece nenhuma afirmação de execução no NE. O plano lista muitas operações como NE-suportadas, o que é diferente de NE-preferidas. A Apple descreve o uso de dispositivo do compute-plan como uso previsto de dispositivo, então mesmo um plano favorável deve ser corroborado por profiling em tempo de execução ou atividade NE observável.

O portão de regressão FP16 existente é 100% de concordância de argmax da fixture, saídas determinísticas finitas e no máximo 0.02 de desvio absoluto em probabilidades calibradas e de ação. Essa é uma verificação de fidelidade de conversão em um pequeno corpus. Ela não estabelece acurácia geral de tarefa, competência no Snake nem a qualidade de um modelo comprimido.

Transformações equivalentes de grafo

O estudo de implantação de Transformer da Apple motiva ativações BC1L quadridimensionais, convoluções 1×1, a divisão da atenção em cabeças e a redução de cópias de layout. Seu exemplo publicado de 10× é um modelo, dispositivo e linha de base diferentes; ele não pode ser transferido para a comparação com o MLX aqui. Trate essas recomendações de layout como candidatas a testar neste sistema operacional e neste chip, não como um contrato completo de suporte de hardware atual.

Projeções lineares e o MLP com gate

Seja X[b,l,i] a ativação existente e defina U[b,i,0,l] = X[b,l,i]. Para uma camada linear,

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]

Isso muda o layout e a representação de operadores sem mudar a função de valor real. Mantenha esse layout ao longo de todo o encoder e das duas camadas transformer da decision head. Converter para ele e de volta ao redor de cada camada linear pode apagar o benefício. O QKV pode continuar sendo uma única convolução D → 3D; divida sua saída de canais em Q, K e V. Da mesma forma, preserve a projeção fundida existente D → 2I do encoder, divida os canais em valor e gate, aplique o GELU exato original ao valor, multiplique pelo gate e projete I → D.

Para FP16, uma largura de sequência divisível por 32 também se alinha ao alinhamento de 64 bytes do último eixo descrito no estudo da Apple. As formas iniciais são B=1,L=96 para a fixture curta da API e B=3,L=64 para o Snake compacto. Uma recomendação de múltiplo de 32 aqui segue esse modelo de buffer; não é permissão para preencher toda carga de trabalho até um comprimento arbitrário grande. O Snake não precisa de 96 tokens.

Atenção e RoPE

Para cada cabeça, mantenha Q e V como (B,d,1,L) e transponha K para (B,L,1,d). Calcule:

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]

O eixo key é o eixo 1 nesta representação. Concatene as saídas das cabeças no eixo dos canais. Esta é a mesma função de atenção; um eixo de softmax errado a altera silenciosamente. A implementação de atenção de referência da Apple demonstra as duas contrações quadridimensionais correspondentes. Inspecione os operadores MIL convertidos: escrever um einsum não garante o dispositivo nem o lowering pretendidos.

Aplique RoPE aos pares de canais de cada cabeça antes do QK. Preserve a convenção de metades divididas do checkpoint, as posições originais e o theta por camada. Neste checkpoint multilíngue, tanto o RoPE completo quanto o local usam theta 160000. Dividir a primeira e a segunda metade de todas as cabeças concatenadas juntas é incorreto; divida dentro de cada cabeça de 64 canais. Uma rotação dependente de posição geralmente não pode ser dobrada em uma única matriz de pesos independente de posição.

A regra local é bidirecional abs(q-k) <= 64, inclusive. Preserve o preenchimento de chaves e a regra existente de query com preenchimento. Partes constantes dependentes de posição podem ser computadas antes do tracing para formas fixas; mudar o preenchimento das amostras ainda deve afetar a máscara de chaves. Substituir a exclusão matemática por uma máscara negativa grande e finita é uma aproximação numérica, a menos que corresponda ao comportamento de precisão finita da implementação original; verifique entradas adversariais e com preenchimento.

LayerNorm não é intercambiável com outras normalizações

Para cada (b,l), reduza apenas ao longo dos canais:

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

Mantenha o epsilon original, a ordem afim, a variância populacional, a normalização identidade da primeira camada, o GELU exato e a ordem residual. O LayerNorm de referência da Apple usa uma ordem afim diferente; seu adapter DistilBERT compensa transformando o viés. Copiar diretamente essa classe e carregar o state dict do Laya seria incorreto para vieses diferentes de zero. Uma expressão afim explícita na ordem original também evita dividir por um gamma possivelmente zero.

Limitar ativações, trocar o GELU por tanh ou substituir o LayerNorm pelo RMSNorm muda a função. Se os valores ao quadrado estouram, uma reescalonagem positiva é uma opção matematicamente equivalente:

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

A acumulação em precisão finita ainda precisa de testes de paridade. Reduções em FP32 podem custar cópias ou fallback para CPU, então inspecione o plano em vez de relaxar silenciosamente o comportamento numérico.

Mova o trabalho não suportado para as fronteiras do modelo

Se o lookup de embedding, o gather dinâmico de marcadores ou a cauda de ação impedir uma região NE contígua, faça um candidato separado com esta partição:

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

Apenas os endpoints cruzam engines. Não transfira a atenção nem o LayerNorm de cada camada para a CPU. Em multilíngue B=1,L=96, um tensor de embedding FP16 tem 147,456 bytes; em B=3,L=64 ele tem 294,912 bytes. Inclua essas cópias e qualquer cópia de saída de hidden-state completo na medição ponta a ponta.

A tabela de tokens multilíngue tem 196,608,000 parâmetros, mas cada requisição reúne apenas suas linhas de token. Ela não precisa ser enviada para um subgrafo transformer do ANE, e não deve ser contada como uma leitura de tabela completa a cada predição. Seu LayerNorm não tem dependência de posição, então a pré-normalização offline das linhas da tabela é equivalente em aritmética real. Ela pode mudar o arredondamento e a precisão de armazenamento, exigindo sua própria verificação de paridade. A action head consome probabilidades de logits de marcador brutos, antes da calibração de temperatura; reconstruir seus recursos a partir de probabilidades calibradas públicas altera o comportamento do checkpoint.

Limites aritméticos de uma afirmação de latência de 10×

Seja D a largura oculta, I a largura intermediária do encoder com gate, N as camadas do encoder e H=2 as camadas da decision head. A principal contagem de parâmetros de matriz por token e a aritmética densa são:

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

Multiplicação e adição contam separadamente. Essas equações excluem normas, ativações, embeddings, pontuação, máscaras, cópias e sobrecarga de runtime. Elas não são um profiler. Elas modelam a computação de atenção densa atual mesmo para camadas locais mascaradas.

Checkpoint D / I / N A Bytes da matriz principal FP16 Trabalho denso em B=1,L=96 Computação efetiva requerida para 10× abaixo do P50 atual do MLX
Multilíngue 768 / 1152 / 22 124,452,864 248.91 MB 24.574 GFLOP 31.23 TFLOP/s em até 0.787 ms
Inglês / arquitetura tipada 1024 / 2624 / 28 368,312,320 736.62 MB 71.848 GFLOP 53.89 TFLOP/s em até 1.333 ms, usando a linha de base em inglês

Essas são taxas alcançadas requeridas, não especificações de pico do ANE afirmadas. Uma reescrita de layout remove sobrecarga, mas não remove essas projeções densas. O hardware também deve executar uma cadeia sequencial de 24 ou 30 blocos de atenção/MLP.

Um modelo de streaming otimista dá outro piso condicional:

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

O M3 Max de 40 núcleos de GPU é especificado com banda de memória unificada de 400 GB/s. Se cada matriz principal FP16 for buscada da DRAM uma vez por requisição, mesmo o acesso total a essa banda custa pelo menos 0.622 ms para multilíngue e 1.842 ms para inglês. O acesso real à banda do ANE pode ser menor, e pesos em cache ou comprimidos mudam a suposição. Este não é um limite físico incondicional. Ele mostra por que a latência de 10× em inglês é particularmente exigente sob streaming não comprimido, e por que medir energia é útil mesmo quando a latência melhora modestamente.

Para uma fração medida f do tempo ponta a ponta melhorada por um fator s, a lei de Amdahl dá S = 1 / (1-f+f/s). Mesmo a aceleração infinita de uma região não pode atingir 10×, a menos que ela ocupe pelo menos 90% da latência original. O limite análogo usa a fração da energia medida, não de FLOPs, ao mirar joules por decisão. A otimização de query selecionada na cabeça final remove apenas alguns por cento da aritmética do modelo; a esparsidade da atenção local também é desprezível em L<=64, onde a janela local cobre todas as posições. Nenhuma das duas fornece uma rota de 10× independente crível.

Compressão e mudanças arquiteturais têm contratos diferentes

Candidato Mesma função de checkpoint de valor real? O que ele pode realisticamente mudar
Layout BC1L, projeções 1×1, posições/máscaras estáticas, divisão de cabeças Sim, quando equações e entradas são preservadas Escalonamento, localidade, particionamento do compilador, cópias de memória
Partição de endpoint na CPU, norma de embedding offline, queries selecionadas na cabeça final Sim em aritmética real; valide o arredondamento Operações não suportadas, footprint do pacote, algum trabalho não usado
Paletização de 8/6/4 bits ou quantização de pesos Geralmente não Tráfego/armazenamento de pesos e possivelmente energia/latência de inferência
Poda de pesos aprendidos diferentes de zero ou fatoração de posto baixo Não, a menos que exista estrutura algebricamente exata Aritmética de matriz e tráfego após recuperação/calibração
Saída antecipada, poda de tokens, menos camadas, student mais estreito Não Economia potencialmente grande; novo modelo e contrato de qualidade
Reúso de hidden-state entre perguntas arbitrárias Não para este encoder bidirecional Atalho inválido; estados contextuais dependem da pergunta
Cache de respostas idênticas de entrada inteira Exato para acertos de cache Recurso de carga de trabalho; não é velocidade de inferência sem cache

A atual visão geral de otimização da Apple aponta para a paletização para ganhos de memória/latência no NE e identifica o caminho de computação mais novo W8A8 com A17 Pro/M4. Não extrapole essa aceleração de hardware mais novo para este M3 Max. O guia de desempenho de quantização também alerta que a desquantização de ativação pode tornar a execução em CPU/GPU mais lenta. Primeiro obtenha uma linha de base residente no NE, depois teste a paletização de pesos de 8 bits para baixo, preservando normas/scorers sensíveis conforme apropriado.

Empacotar pesos FP16 em oito ou quatro bits dá uma razão ideal de armazenamento de pesos de 2× ou 4× antes dos metadados. Isso não é um multiplicador de latência igual: descompressão, movimentação de ativação e computação permanecem. A poda só ajuda o runtime se a representação escolhida de fato explorar os zeros. Remover cabeças/camadas arbitrárias ou realizar truncamento de posto baixo exige recuperação de qualidade e não pode manter a identidade do modelo original sem qualificação.

Para um limite de erro de logit por entrada ||z'-z||_infinity <= delta, um certificado de argmax suficiente é top1(z)-top2(z) > 2delta. Com temperatura de calibração positiva idêntica T, o limite de Lipschitz da norma infinito do softmax dá ||p'-p||_infinity <= delta/(2T). Esses são diagnósticos úteis em entradas avaliadas, não um certificado global para quantização. Preserve fatias separadas de avaliação de margem estreita e multilíngue; exemplos saturados podem esconder grandes erros de logit.

Três experimentos e portões de aceitação

  1. Grafo NE equivalente de forma fixa. Exporte multilíngue B=1,L=96,K=4 e Snake B=3,L=64,K=4 com projeções BC1L, RoPE correto por cabeça, atenção explícita e LayerNorm/GELU originais. Compare arrays de entrada e saídas de camadas individuais com o grafo original. Inspecione quais projeções principais e blocos de atenção são preferidos por NE, depois verifique a atividade NE real em tempo de execução. Apenas uma contagem de operadores suportados não é sucesso. Reexecute a linha de base MLX otimizada correspondente em blocos alternados.
  2. Uma ilha transformer contígua. Se o primeiro grafo se fragmentar, mova o embedding e a pequena cauda final para fronteiras de CPU. Compare isso com o candidato de grafo completo sob a mesma medição de potência. Mantenha um candidato apenas se predições completas melhorarem a latência ou a energia além da variação observada entre execuções. Inclua todas as cópias; um encoder isolado rápido é insuficiente.
  3. Compressão focada em energia depois que o posicionamento funciona. Triagem de paletização de 8 bits, depois 6/4 bits como variantes aproximadas separadas. Execute o portão inalterado da fixture, tarefas choice/score/noul em held-out, entradas multilíngues, empates próximos e trajetórias do Snake. Publique acurácia, desvio de probabilidade e calibração junto com o desempenho. Compressão agressiva ou destilação pertence a um modelo nomeado separadamente se mudar o comportamento aprendido.

Antes de uma afirmação de lançamento, use os mesmos hashes de checkpoint/entrada e uma ordem alternada de linha de base/candidato; exclua a compilação a frio, mas relate-a separadamente. Use pelo menos cinco blocos sustentados por finalista e retenha amostras brutas de latência, chamadas concluídas e potência. Exija a concordância da fixture original e as tolerâncias de probabilidade existentes sem afrouxá-las para o candidato passar, além de saídas finitas estáveis e memória limitada. Meça entradas longas e de fronteira de forma separadamente das demos curtas de forma fixa.

Declare 10× apenas quando a velocidade, a potência sob carga igual ou a razão de energia relevante for de pelo menos dez com uma incerteza que sustente a afirmação, cumprindo ao mesmo tempo os limites declarados de latência e qualidade de tarefa. Se o limite inferior da incerteza não chegar a dez, relate a razão medida. Um ganho menor de energia com execução no NE verificada continua sendo evidência útil; não é um resultado de ordem de magnitude.

Proveniência da documentação

Usei o fluxo de trabalho exigido da CLI Context7: resolvi Core ML Tools para /apple/coremltools, depois consultei o lowering de operadores/layout de transformer e o comportamento de compressão do NE (três comandos no total). Verifiquei o artigo de pesquisa da Apple, o código de referência, a documentação atual de otimização do Core ML, a documentação de compute-plan e a especificação de dispositivo linkada acima. As equações do modelo, as contagens de parâmetros e as medições iniciais foram derivadas deste repositório e de seu irmão MLX. Nenhum benchmark concorrente de GPU/ANE foi executado por este ramo de pesquisa.