Optimització de la inferència en el dispositiu per a Apple Silicon

Un motor local personalitzat que millora el rendiment del prefill i la decodificació.

AutorsPerplexity Engineering

El còmput híbrid en Apple silicon orquestra una tasca entre la intel·ligència de frontera al núvol i un model local al Mac. Els models del núvol s'encarreguen de la recerca i el raonament, mentre que un model local treballa amb fitxers i aplicacions privades al Mac.

Perquè aquesta divisió de la feina sembli fluid, la inferència local ha de seguir el ritme de la resta de la tasca. Això requereix un motor que pugui processar prompts ràpidament i mantenir una taxa de generació de tokens alta.

Lily, el nostre motor d'inferència local de pes lleuger, està dissenyat específicament per a Apple Silicon i Qwen3.6-35B-A3B, amb optimitzacions separades per al preompliment i la descodificació. Hi ha una demo autònoma disponible públicament a GitHub.

Introducció

Una manera habitual d'executar LLM en un Mac és amb MLX, el marc de treball de codi obert per a l'aprenentatge automàtic d'Apple per a Apple silicon. La seva biblioteca complementària, MLX-LM, afegeix els components necessaris per carregar i generar text amb una àmplia gamma de models de llenguatge. Junts, MLX i MLX-LM proporcionen una pila a punt per utilitzar i de propòsit general per a la inferència local de LLM.

Qwen3.6-35B-A3B és un model híbrid i dispers: utilitza l'encaminament de mescla d'experts (MoE) i combina estats recurrents de mida fixa amb atenció completa. Aquestes opcions arquitectòniques redueixen la quantitat de càlcul necessària, però també generen càrregues de treball irregulars. Els tokens s'encaminen cap a diferents pesos d'experts, i els estats recurrents tenen una naturalesa seqüencial.

MLX-LM ja selecciona nuclis optimitzats per a les fases d'inferència i les formes de càrrega de treball comunes, però les seves operacions reutilitzables han de donar suport a moltes arquitectures de models. Un motor dedicat a Qwen es pot especialitzar a nivell de model i d'entorn d'execució, coordinant nuclis, moviment de dades i planificació al voltant de l'estructura fixa del model.

Lily implementa aquesta especialització de punta a punta en un sol procés. Un entorn d'execució en Rust carrega el punt de control del model i gestiona l'estat de la sessió i el bucle de generació, una API de finalització de xat compatible amb OpenAI accepta sol·licituds i transmet tokens, i els nuclis Metal personalitzats executen operacions específiques de Qwen. Ni PyTorch ni MLX es troben al camí d'execució.

On es troben la generalitat i l'especialització en les dues piles d'inferència. MLX-LM descriu el model com a operacions de matrius MLX composables, les quals MLX programa mitjançant nuclis reutilitzables. En canvi, Lily situa l'estructura del model, els plans d'execució específics de cada fase i la selecció de nuclis en un únic entorn d'execució en Rust creat al voltant de Qwen i Apple silicon.

Mesurem el rendiment del prefill i de la decodificació per separat. El rendiment del prefill captura la rapidesa amb què el motor processa el prompt; el rendiment de la decodificació captura la rapidesa amb què genera tokens de sortida.

Avaluem Qwen3.6-35B-A3B en un únic MacBook Pro amb un M5 Max, una GPU de 40 nuclis i 128 GB de memòria unificada. En deu longituds de prompt per a prefill i deu longituds de context per a decode, de 256 a 128K tokens (K = 1.024), el motor promedia 1,22× el rendiment de prefill de MLX-LM i 1,32× el seu rendiment de decode. Amb un prompt de 4K tokens i un context de decode de 4K tokens, el motor personalitzat arriba a 5.749,9 tokens de prefill per segon i 186,6 tokens de decode per segon, en comparació amb 4.737,5 i 140,9 de MLX-LM. En una sessió multipassada, aquest estalvi de temps s’acumula amb cada crida addicional al model.

Rendiment mitjà aritmètic a través de deu longituds igualment ponderades de 256 a 128K tokens. Lily promedia 4.135 tokens/s de prefill enfront de 3.383 de MLX-LM (1,22×), i 167,1 tokens/s de decode enfront de 126,9 (1,32×). El prefill varia segons la longitud del prompt; el decode varia segons la longitud del context.

A continuació, expliquem com l'arquitectura de Qwen crea oportunitats d'optimització específiques del model en Apple silicon. Després, repassem els canvis resultants en el prefill i la decodificació. També tractem on l'optimització addicional deixa de ser rendible, abans de concloure amb una comparació de punta a punta amb MLX-LM.

Oportunitats d'optimització específiques de Qwen en Apple silicon

Qwen crea tres formes de càrrega de treball diferents

Qwen3.6-35B-A3B conté 35 milions de paràmetres, però només n'activa uns 3 milions per a cada token. Un encaminador puntua 256 subxarxes d'experts i en selecciona vuit, juntament amb un expert compartit que processa cada token. Aquest disseny de MoE dispers redueix el càlcul, però genera un treball desequilibrat: els experts reben diferents nombres de tokens, i cada token requereix pesos d'una combinació diferent d'experts.

Qwen també combina 10 capes d'atenció completa amb 30 capes de Gated DeltaNet. Aquests dos tipus de capes retenen informació anterior de maneres diferents.

Les capes d'atenció utilitzen atenció de consultes agrupades (GQA). Qwen té 16 capçaleres de consulta i dues capçaleres de clau-valor (KV), amb vuit capçaleres de consulta que comparteixen cada capçalera de KV. Compartir fa que la memòria cau de KV sigui més petita i permet reutilitzar les dades de la memòria cau entre les capçaleres de consulta. La memòria cau encara emmagatzema claus i valors nous per a cada token, de manera que cada pas de decodificació llegeix més dades a mesura que creix el context.

En canvi, Gated DeltaNet comprimeix la informació anterior en un estat recurrent de mida fixa. Una porta apresa controla quanta part de l'estat existent s'ha de retener, mentre que una actualització delta incorpora informació del token actual. El model defineix aquestes actualitzacions de manera recurrent, de manera que cada token depèn de l'estat produït pel token precedent. Durant el prefill, però, un motor pot avaluar el mateix càlcul de dues maneres. Pot explorar els tokens directament mentre transporta l'estat cap endavant, o reorganitzar les actualitzacions en blocs que exposin més operacions de matrius i paral·lelisme a nivell de token. Quin enfocament és més ràpid depèn de les dimensions del model, de la càrrega de treball i del maquinari.

Juntes, aquestes estructures creen tres patrons computacionals: grups d'experts desequilibrats, atenció sobre una memòria cau creixent i una recurrència de mida fixa que es pot avaluar directament o en blocs.

Apple silicon proporciona camins diferents per a diferents càrregues de treball

El prefill processa moltes files d'activació de tokens de prompt alhora. La càrrega de treball local considerada aquí normalment decodifica una sol·licitud a la vegada (lot 1) i processa una fila nova per pas. Aquesta diferència canvia la manera com s'utilitzen els mateixos pesos del model. El prefill pot reutilitzar cada bloc de pesos en centenars o milers de files. La decodificació, en gran manera, no pot fer-ho, ja que cada token nou requereix una altra passada pels pesos.

Apple silicon situa la CPU i la GPU darrere de la memòria unificada, un únic grup de memòria física accessible per a totes dues. Això permet que el model es mantingui resident sense mantenir una còpia de GPU separada, però no fa que el moviment de dades sigui gratuït. Llegir pesos i valors intermedis continua consumint l'amplada de banda de la memòria, mentre que els registres i un altre emmagatzematge en xip són més ràpids, però molt més petits.

La GPU de l'M5 també proporciona camins de còmput diferents. Les capes lineals del prefill utilitzen la multiplicació general de matrius i matrius (GEMM), aplicant una matriu de pesos a moltes files alhora. Els GEMM compatibles poden utilitzar l'accelerador neuronal de cada nucli de GPU mitjançant operacions de tensor de Metal 4. En canvi, la decodificació de lot 1 utilitza la multiplicació general de matrius i vectors (GEMV), aplicant els mateixos pesos a una fila. Amb una reutilització de pesos mínima, el GEMV està limitat principalment per l'amplada de banda de la memòria i s'adapta millor a les unitats lògiques aritmètiques (ALU) vectorials de la GPU que als acceleradors neuronals dissenyats per a operacions de matrius amb una major reutilització de dades.

Aquests camins d'execució no són exclusius de Lily. MLX opera sobre la mateixa memòria unificada i selecciona nuclis de matrius i vectors optimitzats segons la forma de la càrrega de treball. La implementació de Qwen de MLX-LM ja agrupa el treball dels experts, avalua Gated DeltaNet amb un nucli Metal recurrent fusionat i utilitza l'atenció conscient de GQA. Aquestes capacitats són el punt de partida compartit per a una inferència eficient de Qwen en Apple silicon.

Estratègia d'optimització

L'abast més reduït de Lily li permet coordinar aquests camins d'execució compartits al voltant de l'arquitectura i les dimensions exactes de Qwen. Utilitza camins de GPU específics per a cada fase, assigna les càrregues de treball d'experts, recurrents i d'atenció de Qwen per minimitzar el moviment de dades, i selecciona els nuclis i dissenys segons la forma mesurada de la càrrega de treball. L'estratègia consta de tres parts:

  1. Fer coincidir el camí de la GPU amb la fase d'inferència. Utilitzar l'execució orientada a matrius quan el prefill pot reutilitzar pesos en moltes files, i l'execució orientada a vectors quan la decodificació de lot 1 processa una fila a la vegada.
  2. Assignar l'estructura de Qwen a la GPU alhora que es minimitza el moviment de dades. Mantenir els pesos comprimits fins que s'utilitzin, organitzar el treball dels experts encaminats sense tornar a la CPU, conservar l'estat de Gated DeltaNet al xip a través de la seva exploració recurrent i reutilitzar les dades de KV compartides per l'atenció de consultes agrupades.
  3. Adaptar els nuclis a la forma de la càrrega de treball. Dins de cada fase, seleccionar les mides de les rajoles, els dissenys d'execució i els camins d'atenció a partir del recompte de files disponible, la distribució de les files entre els experts, les dimensions de l'operació i la longitud actual del context.

Les seccions següents expliquen aquestes opcions. Pel que fa a les optimitzacions avaluades en ablacions aparellades en un M5 Max, n'estimem els efectes comparant configuracions del motor altament idèntiques que només difereixen en l'optimització objecte d'estudi. Com que aquests experiments compareixen versions del nostre motor amb ell mateix, expliquen mecanismes en lloc de descompondre els resultats finals enfront de MLX-LM.

Prefill: reutilitzar els pesos i mantenir l'encaminament a la GPU

El prefill exposa moltes files de tokens alhora, però Qwen routeja aquestes files de manera desequilibrada entre els experts i actualitza l'estat recurrent a través de la seqüència. Les seves optimitzacions es divideixen en tres grups: organitzar el treball dels experts dispersos al voltant de les files encaminades, mantenir l'exploració de Gated DeltaNet al xip i dividir els prompts llargs en fragments delimitats.

Execució i residència de dades per a un fragment de prefill delimitat a través d'una capa de Qwen. L'atenció amplia la memòria cau de KV, mentre que Gated DeltaNet transporta el seu estat recurrent de treball als registres. Les metadades d'encaminament d'experts romanen a la GPU, els pesos Q4 es mantenen empaquetats fins que es desquantitzen dins del GEMM agrupat, i les activacions temporals es limiten al fragment actual.

Optimitzar el càlcul d'experts dispersos

Desquantitzar els pesos durant la multiplicació de matrius

El punt de control Qwen3.6-35B-A3B utilitza quantificació afina de 4 bits per grups. Cada pes s'emmagatzema com a codi enter de 4 bits, mentre que cada grup de 64 pesos comparteix una escala i un biaix bfloat16 utilitzats per reconstruir els seus valors. Això redueix el model de 35 milions de paràmetres d'aproximadament 70 GB de pesos bfloat16 a un punt de control de 19,4 GB, fent que sigui pràctic mantenir el model resident al Mac.

L'operació de tensor de Metal 4 utilitzada per a la multiplicació de matrius consumeix operands bfloat16 en lloc de la representació de 4 bits empaquetada. Abans de la multiplicació, la GPU ha de reconstruir els pesos en bfloat16. El GEMM agrupat optimitzat a Lily realitza aquesta conversió una rajoles de pes petita a la vegada i manté el resultat a la memòria de threadgroup del xip just el temps suficient per multiplicar-lo per les files d'activació encaminades. L'acumulació utilitza un punt flotant de 32 bits, i la sortida s'escriu en bfloat16. La matriu de pesos expandida completa no es crea mai a la memòria unificada.

En l'ablació, la desquantització s'executa com una operació separada: expandeix els pesos de 4 bits en una matriu bfloat16 a la memòria unificada, després de la qual cosa el nucli de matrius torna a llegir aquesta matriu. Amb un prompt de 512 tokens, moure la desquantització al GEMM agrupat va augmentar el rendiment del prefill de punta a punta un 77,4 % en eliminar aquesta escriptura i lectura intermèdies.

Mantenir l'encaminament d'experts a la GPU

El GEMM agrupat necessita que les files d'activació assignades a cada expert s'emmagatzemin juntes. Després de seleccionar vuit experts per token, un histograma compta quantes assignacions van anar a cada expert. Una exploració de prefixos converteix aquests recomptes en desplaçaments d'inici, un pas de dispersió col·loca les files als seus grups d'experts, i un mapa de blocs llista els blocs de matrius de mida fixa que el GEMM agrupat ha de processar.

El camí optimitzat manté tota aquesta seqüència en un sol buffer de comandes, un lot ordenat d'operacions de GPU, per a cada fragment de prompt. En canvi, una ablació s'atura perquè la CPU pugui inspeccionar els intermedis d'encaminament i enviar l'operació següent. Mantenir l'histograma i l'exploració de prefixos a la GPU afegeix dos nuclis, però elimina la sincronització entre la CPU i la GPU dins de cada capa de MoE.

Amb un prompt de 512 tokens, habilitar l'encaminament resident a la GPU va augmentar el prefill de punta a punta un 89 %. Això també mostra per què el recompte de nuclis per si sol pot portar a engany: la ruta més ràpida llança més nuclis, però mai espera la CPU dins de la capa.

Fer coincidir la mida de la rajoles amb la càrrega de l'expert

Amb un prompt de 2K tokens, encaminar cada token a vuit de 256 experts produeix 16.384 assignacions de token-expert, o una mitjana de 64 files d'activació per expert. La distribució real és desequilibrada: alguns experts reben moltes files, mentre que d'altres en reben poques.

El GEMM agrupat divideix la sortida de cada expert en rajoles, que són blocs rectangulars petits de la sortida d'una multiplicació de matrius. Cada rajoles s'assigna a un threadgroup de GPU. A les GPU d'Apple silicon, un threadgroup conté un o més simdgrops, cadascun dels quals consta de 32 fils que executen instruccions al pas.

Les rajoles més grans reparteixen el cost de configuració entre més files i exposen més treball en paral·lel, però una part d'una rajoles gran roman inactiva quan un expert rep només unes poques files. Per tant, la mida de la rajoles i el recompte de simdgrops estan vinculats.

Una ablació fixa la rajoles a 16 files. En comparació amb aquest control, habilitar la rajoles de 32 files amb quatre simdgrops va millorar el prefill de punta a punta un 13,2 % amb 2K tokens.

Mantenir l'estat recurrent al xip

Durant el prefill, cada capa de Gated DeltaNet explora el prompt en ordre mentre transporta el seu estat recurrent cap endavant. Amb la residència de registres desactivada, l'ablació utilitza una exploració per blocs. Amb un prompt de 2K tokens, aquest camí mou 256 MiB (mebibytes) d'estat per capa i atura repetidament els fils que cooperen a les barreres, punts de sincronització on tots els fils participants han d'esperar-se els uns als altres.

L'estat recurrent és una matriu. El nucli optimitzat assigna cada columna a un simdgroup. El simdgroup divideix la columna entre els seus fils, carrega la columna als seus registres una sola vegada i transporta l'estat al llarg de tota l'exploració. Els fils intercanvien resultats intermedis mitjançant operacions de simdgroup en lloc de memòria de threadgroup, un emmagatzematge en xip compartit entre un threadgroup. L'estat completat només es torna a escriure un cop finalitzada l'exploració.

L'estat i la seva porta utilitzen un format d'“floating-point” de 32 bits perquè els errors d'arrodoniment petits s'acumulen al llarg de les actualitzacions seqüencials. Les activacions de consulta i clau es mantenen en bfloat16.

Amb un prompt de 2K tokens, habilitar l'exploració resident en registres va millorar el prefill de punta a punta un 5,6 %. Els GEMM d'experts van representar aproximadament el 90 % del temps de prefill. L'exploració seqüencial no exposa prou treball de matrius reutilitzable com per beneficiar-se dels acceleradors neuronals.

Limitar la memòria temporal amb la fragmentació de prompts

L'entorn d'execució processa un prompt llarg com a seqüència de fragments delimitats en lloc de mantenir dades temporals per a cada token de prompt a la memòria alhora. Els pesos del model romanen residents a la memòria unificada, mentre que l'estat recurrent i la memòria cau de KV transporten el context d'un fragment al següent. No es descarta cap context anterior.

Sense fragmentació, les matrius d'activació temporal creixen amb el prompt complet i competeixen amb els pesos del model, l'estat recurrent i la memòria cau de KV per la memòria unificada. La fragmentació manté actius només els valors temporals d'un segment a la vegada, i després allibera o reutilitza aquest emmagatzematge abans de processar el segment següent. Això limita el pic de memòria de treball i permet que el motor processi prompts més llargs sense canviar la sortida del model.

El prefill fragmentat és popular en molts motors i és crucial per servir trajectòries llargues de múltiples torns en aquests entorns amb restriccions de memòria. El temps total de prefill per a les capes d'atenció continua sent quadràtic respecte a la longitud del prompt, amb una mica de sobrecàrrega addicional de les càrregues de KV repetides dels fragments anteriors.

Decodificació: minimitzar els bytes moguts per token

La decodificació de lot 1 processa una fila nova cada vegada. Amb una reutilització de pesos mínima, el seu rendiment depèn principalment de quants bytes mou el motor per a cada token. Els canvis en la decodificació es divideixen en quatre grups: optimitzar el camí de pesos d'una sola fila, mantenir cada pas a la GPU, reduir el trànsit intermedi i d'estat, i llegir la memòria cau d'atenció de manera eficient.

Flux de dades per a un pas de decodificació de lot 1 i dos mecanismes que redueixen el temps d'inactivitat i el trànsit de la memòria cau. (A) La GPU transmet els pesos Q4 i l'estat del model a través de l'atenció, Gated DeltaNet, l'encaminament i els nuclis d'experts fusionats, i després escriu el token seleccionat directament a la ranura d'entrada del pas següent alhora que n'envia una còpia a la CPU. (B) La planificació conscient de les dependències permet que els nuclis independents se superposin. (C) L'empaquetat GQA permet que quatre capçaleres de consulta comparteixin cada càrrega de files de KV, reduint vuit sol·licituds independents a dues càrregues compartides.

Optimitzar el camí de pesos d'una sola fila

MLX ja despatxa el treball d'una sola fila a nuclis especialitzats de matrius i vectors. Com que Lily no utilitza MLX, l'entorn d'execució personalitzat ha de proporcionar la mateixa estratègia bàsica. El nostre GEMV paral·lel per files està dissenyat per a una fila d'activació. Un simdgroup coopera en la sortida mentre llegeix diferents parts de la matriu de pesos en paral·lel.

Mantenir cada pas de decodificació a la GPU

Mantenir el traspàs de tokens a la GPU

Cada pas de decodificació acaba seleccionant el token següent; el pas següent comença amb aquest token com a entrada. Enviar la selecció a la CPU i després tornar-la a enviar a la GPU afegeix un punt de sincronització a cada token. En canvi, el nostre entorn d'execució alterna entre dos buffers de comandes i dues ranures de tokens residents a la GPU. La GPU selecciona el token amb la puntuació més alta i escriu el seu ID de token directament a la ranura d'entrada per al pas de decodificació següent, mentre la CPU prepara el treball posterior.

Superposar treball independent de la GPU

En un pas de decodificació de lot 1 enregistrat, generar un token va llançar 795 nuclis de GPU. Les seves dependències van formar 555 etapes seqüencials, deixant alguns nuclis lliures per executar-se de manera concurrent. No obstant això, el mode d'execució sèrie de Metal va executar cada nucli en ordre.

El camí de decodificació optimitzat registra les dependències reals de les dades en una passada de Metal concurrent. Els llançaments de nuclis independents es poden executar al mateix temps quan els recursos de la GPU ho permeten. S'insereix una barrera només quan el treball posterior requereix un resultat anterior.

Reduir el trànsit intermedi i d'estat

Sovint, els nuclis separats materialitzen un intermedi: un nucli escriu un resultat temporal a la memòria, i el següent torna a llegir el resultat. El camí de decodificació optimitzat fusiona quatre cadenes: les dues projeccions d'entrada d'experts amb la seva activació amb porta; la projecció de sortida d'experts amb la seva puntuació d'encaminament i el resultat de l'expert compartit; la preparació de consultes i claus abans de l'atenció; i l'actualització recurrent amb la seva normalització. Cada nucli fusionat manté els valors temporals als registres en lloc d'enviar-los a través de la memòria.

La fusió també escurça el graf de dependències: quan una escriptura intermèdia desapareix, també ho fa la barrera que protegia el seu consumidor.

Llegir la memòria cau d'atenció de manera eficient

Coalescer les lectures de la memòria cau d'atenció

L'atenció llegeix claus i valors de la memòria cau de KV durant cada pas de decodificació. En l'ablació, els fils de GPU veïns no sempre sol·liciten bytes veïns, la qual cosa obliga el sistema de memòria a atendre més transaccions separades. Habilitar les càrregues coalescides fa que els fils adjacents sol·licitin bytes adjacents perquè el maquinari pugui combinar les seves lectures.

En la configuració bfloat16, la coalescència va augmentar l'amplada de banda de les claus de 33,8 a 47,9 GB/s, va incrementar l'amplada de banda dels valors de 42,0 a 61,8 GB/s i va millorar la decodificació de punta a punta un 2,1 % amb un context de 3.840 tokens.

Empaquetar les capçaleres de consulta per reutilitzar les files de KV

L'atenció de consultes agrupades permet que vuit capes de consultes comparteixin una capçalera de clau-valor (KV). En l'ablació, cada capçalera de consulta s'executa en un simdgroup separat, de manera que les vuit sol·liciten de manera independent la mateixa fila de KV de la memòria cau. El nucli optimitzat agrupa quatre capçaleres de consulta en un mateix threadgroup, el qual carrega cada fila de KV una sola vegada i la reutilitza en quatre càlculs d'atenció. Un segon threadgroup s'encarrega de les quatre capçaleres restants.

Aquesta tècnica, anomenada habitualment empaquetat GQA, realitza la mateixa aritmètica i produeix bytes de sortida idèntics alhora que redueix vuit sol·licituds de KV independents a dues càrregues compartides. En comparació amb l'ablació no empaquetada, va millorar el rendiment de la decodificació de punta a punta un 23,8 % amb un context de 32K tokens.

Canviar els dissenys d'atenció en contextos llargs

Cada pas de decodificació en una capa d'atenció completa explora la memòria cau de KV existent. Un disseny de blocs fixos divideix aquesta memòria cau en parts iguals que la GPU pot processar en paral·lel. La seva planificació addicional no val la pena quan la memòria cau és petita, però el disseny de blocs fixos equilibra la feina de manera més uniformada a mesura que creix el context.

Per a aquest model, l'entorn d'execució manté el camí d'atenció general per sota dels 32K tokens i utilitza el camí de blocs fixos a 32K o més. El canvi s'aplica quan cada capçalera té 256 valors i vuit capçaleres de consulta comparteixen una capçalera de KV; altres formes es mantenen al camí general. Una ablació desactiva aquest canvi i utilitza sempre el camí general. Habilitar la ruta de blocs fixos va millorar la decodificació de punta a punta un 7,7 % a 32K, un 27,4 % a 64K i un 40,2 % a 128K.

Límits de la futar optimització

Alguns canvis van millorar una operació isolada, però no van millorar la inferència de punta a punta.

La decodificació especulativa, que utilitza un model més petit per proposar tokens perquè el model complet els verifiqui, va fer que la decodificació de lot 1 anés un 18 % més lenta. La verificació va processar grups de dos a cinc files, una forma ineficient per a aquest maquinari, i les files sovint seleccionaven experts diferents, augmentant la quantitat de dades de pesos d'experts llegides. Reduir el vocabulari de sortida de l'escriptor va millorar el rendiment de l'escriptor un 4,7-5,1 %, però no va accelerar el bucle especulatiu complet. Aquest resultat és específic de la càrrega de treball: el nostre desplegament de Qwen per lots a Blackwell utilitza la decodificació especulativa en condicions diferents.

Altres experiments van incloure reduir els llançaments de la GPU, superposar fases senceres, utilitzar rajoles de prefill més grans, aplicar una fusió més àmplia, accelerar l'encaminador i combinar la projecció de sortida amb la selecció de tokens. Cap va millorar el bucle d'inferència complet.

Les mesures dels límits del maquinari també van mostrar un marge de millora mínim en les operacions principals de prefill i decodificació. Els GEMM i GEMV de MoE van assolir el 97,9 % i el 90,3 % de les taxes de lectura de pesos sostingudes més ràpides per als seus patrons d'accés. Eliminar l'aritmètica del GEMV dispers només va variar el rendiment un 0,2 %, la qual cosa confirma que les lectures de pesos, en lloc del càlcul, eren el recurs limitant. De manera similar, la multiplicació de matrius de prefill va aconseguir el 93 % del límit teòric de matrius de manera isolada i un 80-86 % dins dels models provats.

Rendiment de punta a punta

La comparació de punta a punta carrega bytes de punts de control de 4 bits idèntics en ambdós motors i executa una sol·licitud a la vegada en un sol M5 Max de 40 nuclis i 128 GB. Dins de cada ronda, els dos motors s'executen en ordre altern per reduir el biaix de la càrrega de fons i els canvis en la temperatura del xip. Comparem amb el camí de generació directa més ràpid de MLX-LM, no amb el seu servidor, de manera que la mesura se centra en l'execució del model en lloc de la sobrecàrrega del servei.

L'exploració abasta deu longituds de prompt per al prefill i deu longituds de context per a la decodificació, des de 256 fins a 128K tokens. El rendiment del prefill primer puja a mesura que el motor reparteix els costos fixos de configuració entre més tokens. El prefill arriba al seu pic al voltant d'un prompt de 4K tokens, i després cau perquè les deu capes d'atenció completa fan més feina a mesura que creix el prompt. La decodificació es mantenia gairebé plana en contextos curts i disminueix un cop la lectura de la memòria cau de KV creixent esdevé significativa. El motor personalitzat és més ràpid en totes les longituds registrades.

Com que l'execució especialitzada pot canviar l'ordre de les operacions de punt flotant, també hem comprovat la consistència numèrica en comparació amb MLX-LM. En una comparació forçada pel professor, ambdós motors van predir el token següent a partir del mateix prefix de referència en cadascuna de les 192 posicions, evitant que les diferències anteriors afectessin les entrades posteriors. La perplexitat de Lily només va ser un 0,04 % superior, i va seleccionar el mateix token millor valorat en el 96,35 % de les posicions provades.

Rendiment de prefill segons la longitud del prompt i rendiment de decode segons la longitud del context per a Qwen3.6-35B-A3B Q4, lot 1, en un sol M5 Max de 40 nuclis i 128 GB. En deu longituds de 256 a 128K tokens, Lily és més ràpid a cada punt registrat: 1,13–1,50× el rendiment de prefill de MLX-LM i 1,26–1,34× el seu rendiment de decode. La comparació utilitza el camí de generació directa més ràpid de MLX-LM. Tots dos eixos horitzontals utilitzen escales logarítmiques; cap eix vertical comença a zero.

Creat per a la plataforma local

Apple silicon no és una GPU de centre de dades més petita. És una plataforma d'inferència local completa amb les seves pròpies característiques de maquinari i programari. La memòria unificada ofereix a un sol node un límit superior molt elevat quant a la quantitat de model i estat que pot contenir. Els acceleradors neuronals de l'M5 absorbeixen el treball de matrius denses en el prefill. Les ALU vectorials s'encarreguen de la resta, limitada per l'amplada de banda i de baixa reutilització, en la decodificació.

Qwen afegeix més oportunitats d'especialització: mantenir l'encaminament d'experts i l'estat recurrent a la GPU, eliminar intermedis innecessaris, superposar el treball independent, reutilitzar dades de KV compartides i adaptar els nuclis a la forma de la càrrega de treball.

Amb l'optimització específica del model i de la plataforma, un sol Mac pot executar un model dispers gran de manera eficient. El treball futur ampliarà la cobertura entre models, xips i càrregues de treball de servei, i convertirà els mecanismes validats aquí en una sola configuració en una política d'entorn d'execució més general.

El principi general és fer coincidir el motor tant amb l'arquitectura del model com amb els camins específics de còmput i memòria del maquinari. A mesura que evo-lucionin els models de pesos oberts de frontera i el maquinari, la inferència local d'alt rendiment dependrà cada cop més de motors adaptats a tots dos en lloc de d'altres que n'abstreguin les diferències.

Citació

BibTeX
@online{perplexity2026OptimizingOnDeviceInferenceForAppleSilicon,
  author = {{Perplexity} and Yibo Wu and Lequn Chen and Kevin Hu and Phi Hoang and Claire Beamer and Jeremy Yang and Denis Yarats},
  title = {{Optimizing on-device inference for Apple Silicon}},
  date = {2026-09-01},
  url = {https://www.perplexity.ai/hub/blog/optimizing-on-device-inference-for-apple-silicon}
}