Optimalisering av enhetsintern inferens for Apple Silicon
En tilpasset lokal motor som forbedrer prefill- og dekodingsgjennomstrømming.
Hybrid beregning på Apple Silicon orkestrerer en oppgave mellom grenseoverskridende intelligens i skyen og en lokal modell på Macen. Sky-modeller håndterer forskning og resonnement, mens en lokal modell arbeider med private filer og apper på Macen.
For at denne arbeidsdeling skal føles sømløs, må lokal inferens holde tritt med resten av oppgaven. Det krever en motor som kan behandle ledetekster raskt og opprettholde en høy token-genereringsrate.
Lily, vår lettvektige lokale inferensmotor, er bygget spesielt for Apple-silisium og Qwen3.6-35B-A3B, med separate optimaliseringer for prefill og dekoding. En frittstående demo er offentlig tilgjengelig på GitHub.
Innledning
En vanlig måte å kjøre LLM-er på en Mac er med MLX, Apples maskinlæringsrammeverk med åpen kildekode for Apple Silicon. Det tilhørende biblioteket, MLX-LM, legger til komponentene som trengs for å laste inn og generere tekst med et bredt spekter av språkmodeller. Sammen gir MLX og MLX-LM en hyllevarebasert, generell stabel for lokal LLM-inferens.
Qwen3.6-35B-A3B er en glissen, hybrid modell: den bruker ekspertblandingsruting (MoE) og kombinerer fast-størrelses resirkulerende tilstander med full oppmerksomhet. Disse arkitektoniske valgene reduserer mengden beregninger som kreves, men de skaper også uregelmessige arbeidsmengder. Token rutes til forskjellige ekspertvekter, og resirkulerende tilstander er sekvensielle av natur.
MLX-LM velger allerede optimaliserte kjerner for inferensfaser og vanlige arbeidsmengdeformer, men de gjenbrukbare operasjonene må støtte mange modellarkitektur. En motor dedikert til Qwen kan spesialisere seg på modell- og kjøretidsnivå, og koordinere kjerner, dataflyt og planlegging rundt modellens faste struktur.
Lily implementerer denne spesialiseringen ende-til-ende i en enkelt prosess. En Rust-kjøretid laster inn modellsjekkpunktet og administrerer økttilstanden og genereringsløkken, et OpenAI-kompatibelt chat-fullførings-API aksepterer forespørsler og strømmer token, og egendefinerte Metal-kjerner utfører Qwen-spesifikke operasjoner. Hverken PyTorch eller MLX er i utførelsesbanen.
Vi måler prefill- og dekodingsytelse separat. Prefill-gjennomstrømming fanger opp hvor raskt motoren behandler ledeteksten; dekodingsgjennomstrømming fanger opp hvor raskt den genererer utdatatoken.
Vi benchmarker Qwen3.6-35B-A3B på en enkelt MacBook Pro drevet av en M5 Max med en 40-kjernet GPU og 128 GB felles minne. På tvers av ti promptlengder for prefill og ti kontekstlengder for decode, fra 256 til 128K tokens (K = 1 024), oppnår motoren i gjennomsnitt 1,22× MLX-LM sin prefill-throughput og 1,32× sin decode-throughput. Ved en prompt på 4K tokens og en decode-kontekst på 4K tokens når den tilpassede motoren 5 749,9 prefill-tokens per sekund og 186,6 decode-tokens per sekund, sammenlignet med 4 737,5 og 140,9 for MLX-LM. Over en økt med flere turer akkumuleres disse tidsbesparelsene for hver ekstra modellkall.
Deretter forklarer vi hvordan Qwens arkitektur skaper modellspesifikke optimaliseringsmuligheter på Apple Silicon. Deretter går vi gjennom de resulterende prefill- og dekodingsendringene. Vi dekker også hvor ytterligere optimalisering slutter å lønne seg før vi avslutter med en ende-til-ende-sammenligning mot MLX-LM.
Qwen-spesifikke optimaliseringsmuligheter på Apple Silicon
Qwen skaper tre distinkte arbeidsmengdeformer
Qwen3.6-35B-A3B inneholder 35 milliarder parametere, men aktiverer bare omtrent 3 milliarder for hvert token. En ruter scorer 256 ekspert-undernettverk og velger åtte, ved siden av én delt ekspert som behandler hvert token. Denne glisne MoE-designen reduserer beregninger, men produserer ujevnt arbeid: eksperter mottar forskjellige antall token, og hvert token krever vekter fra en annen kombinasjon av eksperter.
Qwen kombinerer også 10 lag med full oppmerksomhet med 30 Gated DeltaNet-lag. Disse to lagtypene beholder tidligere informasjon på forskjellige måter.
Oppmerksomhetslagene bruker gruppert-forespørsel-oppmerksomhet (GQA). Qwen har 16 forespørselshoder og to nøkkel-verdi-hoder (KV), der åtte forespørselshoder deler hvert KV-hode. Deling gjør KV-mellomlageret mindre og gjør at bufret data kan gjenbrukes på tvers av forespørselshoder. Mellomlageret lagrer fremdeles nye nøkler og verdier for hvert token, slik at hvert dekodingstrinn leser mer data etter hvert som konteksten vokser.
Gated DeltaNet komprimerer i stedet tidligere informasjon til en resirkulerende tilstand i fast størrelse. En innlært port kontrollerer hvor mye av den eksisterende tilstanden som skal beholdes, mens en delta-oppdatering inkorporerer informasjon fra det gjeldende tokenet. Modellen definerer disse oppdateringene resirkulerende, slik at hvert token avhenger av tilstanden produsert av det foregående tokenet. Under prefill kan imidlertid en motor evaluere den samme beregningen på to måter. Den kan skanne gjennom tokenene direkte samtidig som den bærer tilstanden fremover, eller omorganisere oppdateringene i blokker som eksponerer flere matriseoperasjoner og token-nivå-parallelisme. Hvilken tilnærming som er raskere, avhenger av modelldimensjonene, arbeidsmengden og maskinvaren.
Til sammen skaper disse strukturene tre beregningsmønstre: ujevne ekspertgrupper, oppmerksomhet over et voksende mellomlager, og en fast størrelse på resirkuleringen som kan evalueres direkte eller i blokker.
Apple Silicon tilbyr forskjellige baner for forskjellige arbeidsmengder
Prefill behandler mange ledetekst-token-aktiveringsrader samtidig. Den lokale arbeidsmengden som vurderes her, dekoder typisk én forespørsel om gangen (batch 1) og behandler én ny rad per trinn. Denne forskjellen endrer hvordan de samme modellvektene brukes. Prefill kan gjenbruke hver blokk med vekter på tvers av hundrevis eller tusenvis av rader. Dekoding kan i stor grad ikke det, siden hvert nye token krever en ny gjennomgang av vektene.
Apple Silicon plasserer CPU-en og GPU-en bak enhetlig minne, et enkelt fysisk minnebasseng som er tilgjengelig for begge. Dette gjør at modellen kan forbli bosatt uten å opprettholde en egen GPU-kopi, men det gjør ikke dataflyt gratis. Lesing av vekter og mellomliggende verdier forbruker fremdeles minnebåndbredde, mens registre og annen brikkelagring er raskere, men mye mindre.
M5-GPU-en tilbyr også forskjellige beregningsbaner. Prefills lineære lag bruker generell matrise-matrise-multiplikasjon (GEMM), og bruker en vektmatrise på mange rader samtidig. Kompatible GEMM-er kan bruke den neurale akseleratoren i hver GPU-kjerne gjennom Metal 4-tensoroperasjoner. Batch-1-dekoding bruker i stedet generell matrise-vektor-multiplikasjon (GEMV), og bruker de samme vektene på én rad. Med lite vektgjenbruk er GEMV hovedsakelig begrenset av minnebåndbredde og egner seg bedre til GPU-ens vektor-aritmetikk-logikk-enheter (ALU-er) enn til neurale akseleratorer designet for matriseoperasjoner med større datagjenbruk.
Disse utførelsesbanene er ikke unike for Lily. MLX opererer over det samme enhetlige minnet og velger optimaliserte matrise- og vektorkjerner i henhold til arbeidsmengdens form. MLX-LMs Qwen-implementering grupperer allerede ekspertarbeid, evaluerer Gated DeltaNet med en sammensmeltet resirkulerende Metal-kjerne, og bruker GQA-bevisst oppmerksomhet. Disse evnene er det delte utgangspunktet for effektiv Qwen-inferens på Apple Silicon.
Optimaliseringsstrategi
Lilys smalere omfang gjør at den kan koordinere disse delte utførelsesbanene rundt Qwens nøyaktige arkitektur og dimensjoner. Den bruker fasespesifikke GPU-baner, tilpasser Qwens ekspert-, resirkulerende og oppmerksomhetsarbeidsmengder for å minimere dataflyt, og velger kjerner og oppsett fra den målte arbeidsmengdeformen. Strategien har tre deler:
- Tilpass GPU-banen til inferensfasen. Bruk matriseorientert utførelse når prefill kan gjenbruke vekter på tvers av mange rader, og vektororientert utførelse når batch-1-dekoding behandler én rad av gangen.
- Tilpass Qwens struktur til GPU-en samtidig som dataflyten minimeres. Hold vekter komprimert til de brukes, organiser rutet ekspertarbeid uten å returnere til CPU-en, behør Gated DeltaNet-tilstand på brikken gjennom sin resirkulerende skanning, og gjenbruk KV-dataene som deles av gruppert-forespørsel-oppmerksomhet.
- Tilpass kjerner til arbeidsmengdens form. Velg flisstørrelser, utførelsesoppsett og oppmerksomhetsbaner innenfor hver fase fra det tilgjengelige radantallet, radenes distribusjon på tvers av eksperter, operasjonens dimensjoner og den gjeldende kontekstlengden.
Følgende avsnitt forklarer disse valgene. For optimaliseringer evaluert i matchede ablasjoner på en M5 Max, anslår vi effektene ved å sammenligne ellers identiske motorkonfigurasjoner som bare skiller seg ut i optimaliseringen som studeres. Fordi disse eksperimentene sammenligner versjoner av motoren vår mot seg selv, forklarer de mekanismer i stedet for å dekomponere de endelige resultatene mot MLX-LM.
Prefill: gjenbruk vekter og hold ruting på GPU-en
Prefill eksponerer mange token-rader samtidig, men Qwen ruter disse radene ujevnt på tvers av eksperter og oppdaterer resirkulerende tilstand gjennom sekvensen. Optimaliseringene faller i tre grupper: organiser glisent ekspertarbeid rundt de rutete radene, hold Gated DeltaNet-skanningen på brikken, og del lange ledetekster inn i begrensede klumper.
Optimaliser glissen ekspertberegning
Dekvantiser vekter under matrisemultiplikasjon
Qwen3.6-35B-A3B-sjekkpunktet bruker gruppevis affin 4-bits kvantisering. Hver vekt lagres som en 4-bits heltallskode, mens hver gruppe på 64 vekter deler en bfloat16-skala og -skjevhet som brukes til å gjenoppbygge verdiene dens. Dette reduserer modellen på 35 milliarder parametere fra omtrent 70 GB med bfloat16-vekter til et 19,4 GB sjekkpunkt, noe som gjør det praktisk å holde modellen bosatt på Macen.
Metal 4-tensoroperasjonen som brukes til matrisemultiplikasjon, forbruker bfloat16-operander i stedet for den pakkede 4-bits representasjonen. Før multiplikasjon må GPU-en gjenoppbygge vektene i bfloat16. Den optimaliserte grupperte GEMM-en i Lily utfører denne konverteringen én liten vektflis om gangen og holder resultatet i brikkens trådgruppeminne lenge nok til å multiplisere det med de rutete aktiveringsradene. Akkumulering bruker 32-bits flyttall, og utdataene skrives i bfloat16. Den komplett utvidede vektmatrisen blir aldri opprettet i det enhetlige minnet.
I ablasjonen kjører dekvantisering som en separat operasjon: den utvider 4-bits vektene til en bfloat16-matrise i enhetlig minne, hvorefter matrisekjernen leser den matrisen tilbake. Ved en 512-tokens ledetekst økte flytting av dekvantisering inn i den grupperte GEMM-en ende-til-ende-prefill-gjennomstrømming med 77,4 % ved å eliminere denne midlertidige skrive- og leseoperasjonen.
Hold ekspertruting på GPU-en
Den grupperte GEMM-en krever at aktiveringsradene tilordnet til hver ekspert lagres sammen. Etter å ha valgt åtte eksperter per token, teller et histogram hvor mange tilordninger som gikk til hver ekspert. En prefiks-skanning gjør disse tellingene om til startforskyvninger, et spredningstrinn plasserer rader i ekspertgruppene sine, og et blokk-kart lister opp matriseblokkene med fast størrelse som den grupperte GEMM-en må behandle.
Den optimaliserte banen holder hele denne sekvensen i én kommandobuffer, en ordnet batch med GPU-operasjoner, for hver ledetekstklump. En ablasjon pauses i stedet slik at CPU-en kan inspisere rutingsmellomproduktene og sende inn neste operasjon. Å holde histogrammet og prefiks-skanningen på GPU-en legger til to kjerner, men fjerner CPU-GPU-synkronisering inne i hvert MoE-lag.
Ved en 512-tokens ledetekst økte aktivering av GPU-bosatt ruting ende-til-ende-prefill med 89 %. Dette viser også hvorfor kjerneantallet alene kan være misvisende: den raskere ruten starter flere kjerner, men venter aldri på CPU-en inne i laget.
Tilpass flisstørrelsen til ekspertbelastningen
Ved en 2K-tokens ledetekst produserer ruting av hvert token til åtte av 256 eksperter 16 384 token-ekspert-tilordninger, eller et gjennomsnitt på 64 aktiveringsrader per ekspert. Den faktiske distribusjonen er ujevn: noen eksperter mottar mange rader, mens andre mottar få.
Den grupperte GEMM-en deler hver eksperts utdata inn i fliser, som er små rektangulære blokker av en matrisemultiplikasjons utdata. Hver flis tilordnes én GPU-trådgruppe. På Apple Silicons GPU-er inneholder en trådgruppe én eller flere simd-grupper, som hver består av 32 tråder som utfører instruksjoner i taktsammenheng.
Større fliser sprer oppsettkostnaden over flere rader og eksponerer mer parallelt arbeid, men en del av en stor flis forblir inaktiv når en ekspert bare mottar noen få rader. Flisstørrelse og simd-gruppeantall er derfor koblet sammen.
En ablasjon fastsetter flisen til 16 rader. Mot den kontrollen forbedret aktivering av 32-rads-flisen med fire simd-grupper ende-til-ende-prefill med 13,2 % ved 2K token.
Hold resirkulerende tilstand på brikken
Under prefill skanner hvert Gated DeltaNet-lag ledeteksten i rekkefølge mens den bærer sin resirkulerende tilstand fremover. Med registerbosetting deaktivert, bruker ablasjonen en blokkvis skanning. Ved en 2K-tokens ledetekst flytter den banen 256 MiB (mebibyte) med tilstand per lag og stopper gjentatte ganger samarbeidende tråder ved barrierer, synkroniseringspunkter der alle deltakende tråder må vente på hverandre.
Den resirkulerende tilstanden er en matrise. Den optimaliserte kjernen tilordner hver kolonne til én simd-gruppe. Simd-gruppen deler kolonnen mellom sine tråder, laster inn kolonnen i registre én gang, og fører tilstanden gjennom hele skanningen. Trådene utveksler mellomelementer gjennom simd-gruppeoperasjoner i stedet for trådgruppeminne, som er brikkeminne delt på tvers av en trådgruppe. Den fullførte tilstanden skrives tilbake først etter skanningen.
Tilstanden og porten bruker et 32-bits flyttallsformat fordi små avrundingsfeil samler seg på tvers av sekvensielle oppdateringer. Forespørsels- og nøkkelaktiveringer forblir i bfloat16.
Ved en 2K-tokens ledetekst forbedret aktivering av den registerbosatte skanningen ende-til-ende-prefill med 5,6 %. Ekspert-GEMM-er sto for omtrent 90 % av prefill-tiden. Den sekvensielle skanningen eksponerer ikke nok gjenbrukbart matrisearbeid til å dra nytte av de neurale akseleratorene.
Begrens midlertidig minne med ledetekstklumpinndeling
Kjøretiden behandler en lang ledetekst som en sekvens av begrensede klumper i stedet for å beholde midlertidige data for hvert ledetekst-token i minnet samtidig. Modellvekter forblir bosatt i det enhetlige minnet, mens den resirkulerende tilstanden og KV-mellomlageret fører kontekst fra én klump til den neste. Ingen tidligere kontekst blir kastet.
Uten klumpinndeling vokser midlertidige aktiveringsmatriser med hele ledeteksten og konkurrerer med modellvekter, resirkulerende tilstand og KV-mellomlageret om enhetlig minne. Klumpinndeling holder bare én segments midlertidige verdier i live av gangen, og frigjør eller gjenbruker deretter den lagringen før behandling av neste segment. Dette setter et tak på topp-arbeidsminnet og lar motoren behandle lengre ledetekster uten å endre modellens utdata.
Klumpinndelt prefill er populært i mange motorer og er avgjørende for å betjene lange flerrunders trajektorier i disse minnebegrensede miljøene. Total prefill-tid for oppmerksomhetslag forblir kvadratisk på ledetekstens lengde, med litt ekstra overhead fra gjentatte KV-innlastinger av tidligere klumper.
Dekoding: minimer antall flyttede byte per token
Batch-1-dekoding behandler én ny rad av gangen. Med lite vektgjenbruk avhenger gjennomstrømmingen hovedsakelig av hvor mange byte motoren flytter for hvert token. Dekodingsendringene faller i fire grupper: optimaliser vekstien for én rad, hold hvert trinn på GPU-en, reduser mellomliggende og statlig trafikk, og les oppmerksomhetsmellomlageret effektivt.
Optimaliser vekstien for én rad
MLX utsteder allerede enrads-arbeid til spesialiserte matrise-vektorkjerner. Fordi Lily ikke bruker MLX, må den tilpassede kjøretiden levere den samme grunnleggende strategien. Vår rad-parallelle GEMV er designet for én aktiveringsrad. En simd-gruppe samarbeider om utdataene mens den leser forskjellige deler av vektmatrisen parallelt.
Hold hvert dekodingstrinn på GPU-en
Hold token-overleveringen på GPU-en
Hvert dekodingstrinn avsluttes med å velge neste token; det følgende trinnet begynner med det tokenet som inndata. Å sende utvalget til CPU-en og deretter tilbake til GPU-en legger til et synkroniseringspunkt for hvert token. Kjøretiden vår veksler i stedet mellom to kommandobuffere og to GPU-bosatte token-spor. GPU-en velger tokenet med høyest poengsum og skriver token-ID-en direkte inn i inndatasporet for neste dekodingstrinn, mens CPU-en klargjør etterfølgende arbeid.
Overlapp uavhengig GPU-arbeid
I ett registrert batch-1-dekodingstrinn startet generering av et token 795 GPU-kjerner. Avhengighetene deres dannet 555 sekvensielle stadier, noe som gjorde at noen kjerner kunne kjøre samtidig. Metals serielle utførelsesmodus kjørte likevel hver kjerne i rekkefølge.
Den optimaliserte dekodingsbanen registrerer de faktiske dataavhengighetene i en samtidig Metal-passering. Uavhengige kjerneoppstarter kan kjøre samtidig når GPU-ressurser tillater det. En barriere settes inn bare når senere arbeid krever et tidligere resultat.
Reduser mellomliggende og statlig trafikk
Separate kjerner materialiserer ofte et mellomprodukt: én kjerne skriver et midlertidig resultat til minnet, og den neste leser resultatet tilbake. Den optimaliserte dekodingsbanen smelter sammen fire kjeder: de to ekspert-inndataprojeksjonene med sin gatede aktivering; ekspert-utdataprojeksjonen med sin rutingspoengsum og det delte ekspertresultatet; forespørsels- og nøkkelklargjøring før oppmerksomhet; og den resirkulerende oppdateringen med sin normalisering. Hver sammensmeltede kjerne holder midlertidige verdier i registre i stedet for å sende dem gjennom minnet.
Fusjon forkortet også avhengighetsgrafer: når en midlertidig skriving forsvinner, gjør barrieren som beskyttet forbrukeren det også.
Les oppmerksomhetsmellomlageret effektivt
Slå sammen oppmerksomhetsmellomlagerets lesinger
Oppmerksomhet leser nøkler og verdier fra KV-mellomlageret under hvert dekodingstrinn. I ablasjonen ber ikke alltid nabotradene på GPU-en om naboliggende byte, noe som tvinger minnesystemet til å betjene flere separate transaksjoner. Aktivering av sammensmeltede innlastinger gjør at tilstøtende tråder ber om tilstøtende byte slik at maskinvaren kan kombinere lesingene deres.
På bfloat16-konfigurasjonen økte sammenslåing nøkkelbåndbredden fra 33,8 til 47,9 GB/s, økte verdsbåndbredden fra 42,0 til 61,8 GB/s, og forbedret ende-til-ende-dekoding med 2,1 % ved en 3 840-tokens kontekst.
Pakke forespørselshoder for å gjenbruke KV-rader
Gruppert-forespørsel-oppmerksomhet lar åtte forespørselshoder dele ett KV-hode. I ablasjonen kjører hvert forespørselshode i en separat simd-gruppe, slik at alle åtte uavhengig ber om den samme bufret KV-raden. Den optimaliserte kjernen pakker fire forespørselshoder inn i én trådgruppe, som laster inn hver KV-rad én gang og gjenbruker den på tvers av fire oppmerksomhetsberegninger. En andre trådgruppe håndterer de gjenstående fire hodene.
Denne teknikken, som vanligvis kalles GQA-pakking, utfører den samme aritmetikken og produserer identiske utdatabyte samtidig som den reduserer åtte uavhengige KV-forespørsler til to delte innlastinger. Mot den upakkede ablasjonen forbedret den ende-til-ende-dekodingsgjennomstrømmingen med 23,8 % ved en 32K-tokens kontekst.
Bytt oppmerksomhetsoppsett ved lange kontekster
Hvert dekodingstrinn i et lag med full oppmerksomhet skanner det eksisterende KV-mellomlageret. Et fast blokk-oppsett deler det mellomlageret inn i like deler som GPU-en kan behandle parallelt. Den ekstra planleggingen er ikke verdt det når mellomlageret er lite, men det faste blokk-oppsettet balanserer arbeidet mer jevnt etter hvert som konteksten vokser.
For denne modellen holder kjøretiden den generelle oppmerksomhetsbanen under 32K token og bruker den faste blokk-banen ved 32K eller lengre. Bytteoperasjonen gjelder når hvert hode har 256 verdier og åtte forespørselshoder deler et KV-hode; andre formater forblir på den generelle banen. En ablasjon deaktiverer denne bryteren og bruker alltid den generelle banen. Aktivering av den faste blokk-ruten forbedret ende-til-ende-dekoding med 7,7 % ved 32K, 27,4 % ved 64K og 40,2 % ved 128K.
Grenser for ytterligere optimalisering
Noen endringer forbedret en isolert operasjon, men forbedret ikke ende-til-ende-inferens.
Spekulativ dekoding, som bruker en mindre modell til å foreslå token som hele modellen skal verifisere, gjorde batch-1-dekoding 18 % langsommere. Verifikasjon behandlet grupper på to til fem rader, en ineffektiv form for denne maskinvaren, og radene valgte ofte forskjellige eksperter, noe som økte mengden ekspertvektdata som ble lest. Reduksjon av utdatavokabularet til utkastforfatteren forbedret utkastforfatterens gjennomstrømming med 4,7–5,1 %, men gjorde ikke den komplette spekulative løkken raskere. Dette resultatet er arbeidsmengdespesifikt: vår partiet Qwen-utplassering på Blackwell bruker spekulativ dekoding under forskjellige forhold.
Andre eksperimenter inkluderte å redusere GPU-oppstart, overlappe hele faser, bruke større prefill-fliser, bruke bredere fusjon, akselerere ruteren og kombinere utdataprofilering med token-valg. Ingen forbedret den komplette inferensløkken.
Målinger av maskinvaregrensene viste også liten gjenværende margin i de viktigste prefill- og dekodingsoperasjonene. MoE GEMM-ene og GEMV-ene nådde 97,9 % og 90,3 % av de raskeste vedvarende vektlesehastighetene for sine tilgangsmønstre. Fjerning av aritmetikk fra den glisne GEMV-en endret gjennomstrømmingen med bare 0,2 %, noe som bekrefter at vektlesing i stedet for beregning var den begrensende ressursen. Prefills matrisemultiplikasjon nådde tilsvarende 93 % av den teoretiske matrisegrensen i isolasjon og 80–86 % inne i de testede modellene.
Ende-til-ende-ytelse
Ende-til-ende-sammenligningen laster inn identiske 4-bits sjekkpunktsbyte i begge motorene og kjører én forespørsel om gangen på én 40-kjerners, 128 GB M5 Max. Innenfor hver runde kjører de to motorene i vekslende rekkefølge for å redusere skjevhet fra bakgrunnsbelastning og endringer i brikketemperatur. Vi sammenligner med MLX-LMs raskeste direktogenereringsbane, ikke dens server, slik at målingen fokuserer på modellutførelse i stedet for tjenesteoverhodet.
Sveipet dekker ti ledetekstlengder for prefill og ti kontekstlengder for dekoding, fra 256 til 128K token. Prefill-gjennomstrømmingen stiger først når motoren sprer faste oppsettkostnader over flere token. Prefill topper seg rundt en 4K-tokens ledetekst, faller deretter fordi de ti lagene med full oppmerksomhet utfører mer arbeid etter hvert som ledeteksten vokser. Dekodingen forblir nesten flat ved korte kontekster og synker når lesing av det voksende KV-mellomlageret blir vesentlig. Den tilpassede motoren er raskere ved hver registrerte lengde.
Fordi spesialisert utførelse kan endre rekkefølgen på flyttallsoperasjoner, sjekket vi også numerisk konsistens mot MLX-LM. I en lærertvunget sammenligning forutså begge motorene neste token fra det samme referanseprefikset ved hver av 192 posisjoner, noe som forhindret at tidligere forskjeller påvirket senere inndata. Lilys perplexitet var bare 0,04 % høyere, og den valgte det samme topprangerte tokenet ved 96,35 % av de testede posisjonene.
Bygget for den lokale plattformen
Apple Silicon er ikke en mindre datasenter-GPU. Det er en komplett lokal inferensplattform med egne maskinvare- og programvareegenskaper. Enhetlig minne gir en enkelt node en svært høy grense for hvor mye modell og tilstand den kan holde på. M5 Neurale akseleratorer absorberer det tette matrisearbeidet i prefill. Vektor-ALU-ene håndterer den båndbreddebundne resten med lav gjenbruk i dekoding.
Qwen legger til ytterligere muligheter for spesialisering: hold ekspertruting og resirkulerende tilstand på GPU-en, eliminer unødvendige mellomprodukter, overlapp uavhengig arbeid, gjenbruk delt KV-data, og tilpass kjerner til arbeidsmengdens form.
Med modell- og plattformspesifikk optimalisering kan én Mac kjøre en stor glissen modell effektivt. Fremtidig arbeid vil utvide dekningen på tvers av modeller, brikker og tjenestearbeidsmengder, og gjøre mekanismene som er validert her på en konfigurasjon til mer generell kjøretidspolitikk.
Det bredere prinsippet er å tilpasse motoren til både modellens arkitektur og maskinvarens spesifikke beregnings- og minnebaner. Etter hvert som grenseoverskridende åpne-vekt-modeller og maskinvare utvikler seg, vil lokal ytelsessterk inferens i økende grad avhenge av motorer skreddersydd for begge i stedet for noen som abstraherer bort forskjellene deres.
Sitat
@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}
}