Eszközön belüli inferencia optimalizálása Apple siliconon
Egy egyedi helyi motor, amely javítja az előkitöltési és dekódolási áteresztőképességet.
Ahhoz, hogy ez a munkamegosztás zökkenőmentesnek tűnjön, a helyi inferenciának lépést kell tartania a feladat többi részével. Ehhez olyan motorra van szükség, amely gyorsan képes feldolgozni a promptokat, és fenntartja a magas tokengenerálási rátát.
A Lily, a könnyűsúlyú helyi inferencemotorunk, kifejezetten az Apple siliconhoz és a Qwen3.6-35B-A3B modellhez készült, az előkitöltéshez és a dekódoláshoz külön optimalizációkkal. A motor hamarosan nyílt forráskódúvá válik.
Bevezetés
A Macen futtatható LLM-ek egyik elterjedt módja az MLX, az Apple nyílt forráskódú gépi tanulási keretrendszere az Apple siliconhoz. Kísérőkönyvtára, az MLX-LM hozzáadja azokat a komponenseket, amelyek a nyelvi modellek széles skálájával való betöltéshez és szöveggeneráláshoz szükségesek. Az MLX és az MLX-LM együtt egy azonnal használható, általános célú vermet biztosít a helyi LLM-inferenciához.
A Qwen3.6-35B-A3B egy ritka (sparse), hibrid modell: szakértők keveréke (Mixture-of-Experts, MoE) útválasztást használ, és a rögzített méretű rekurrens állapotokat teljes figyelemmel (attention) kombinálja. Ezek az építészeti döntések csökkentik a szükséges számítások mennyiségét, de egyben szabálytalan munkaterhelést is teremtenek. A tokenek különböző szakértői súlyokhoz irányítódnak, a rekurrens állapotok pedig természetüknél fogva szekvenciálisak.
Az MLX-LM már eleve kiválasztja az optimalizált kerneleket az inferenciafázisokhoz és a gyakori munkaterhelési alakzatokhoz, de újrafelhasználható műveleteinek számos modellarchitektúrát kell támogatniuk. A Qwenre szakosodott motor képes a modell és a futtatókörnyezet szintjén specializálódni, a modell rögzített struktúrája köré hangolva a kerneleket, az adatmozgást és az ütemezést.
A Lily végponttól végpontig egyetlen folyamatban valósítja meg ezt a specializációt. Egy Rust-futtatókörnyezet tölti be a modellt, és kezeli a munkamenet állapotát és a generálási hurkot, egy OpenAI-kompatibilis chat-completions API fogadja a kéréseket és streameli a tokeneket, és egyedi Metal kernelek hajtják végre a Qwen-specifikus műveleteket. Sem a PyTorch, sem az MLX nincs benne a végrehajtási útvonalban.

Az előkitöltési és dekódolási teljesítményt külön-külön mérjük. Az előkitöltési áteresztőképesség azt rögzíti, hogy a motor milyen gyorsan dolgozza fel a promptot; a dekódolási áteresztőképesség azt rögzíti, hogy milyen gyorsan generál kimeneti tokeneket.
A Qwen3.6-35B-A3B modellt egyetlen, 40 magos GPU-val és 128 GB egységesített memóriával rendelkező, M5 Max által hajtott MacBook Pro eszközön benchmarkoltuk. A prefill (előkitöltés) tíz és a dekódolás tíz különböző prompt-, illetve kontextushossza mentén, 256-tól 128 ezer tokenig (K = 1024) terjedő tartományban a motor átlagosan az MLX-LM előkitöltési áteresztőképességének 1,23-szorosát és dekódolási áteresztőképességének 1,35-szorosát hozza. 4K-s prompt és 4K-s dekódolási kontextus mellett az egyedi motor másodpercenként 5749,9 előkitöltési és 186,6 dekódolási tokent ér el, szemben az MLX-LM 4337,5, illetve 140,9 értékével. Többkörös munkamenet során ezek az idómegtakarítások minden egyes további modellhívással növekednek.

Következő lépésként bemutatjuk, hogy a Qwen architektúrája hogyan teremt modellspecifikus optimalizációs lehetőségeket az Apple siliconon. Ezután végigtekintjük az ebből adódó előkitöltési és dekódolási változtatásokat. Kitérünk arra is, hogy hol szűnik meg a további optimalizálás kifizetődősége, majd az MLX-LM-mel szembeni végpontok közötti (end-to-end) összehasonlítással zárjuk a témát.
A Qwenre jellemző optimalizálási lehetőségek Apple siliconon
A Qwen három különböző munkaterhelési alakzatot hoz létre
A Qwen3.6-35B-A3B 35 milliárd paramétert tartalmaz, de tokenenként csak körülbelül 3 milliárdot aktivál. Egy router 256 szakértői alhálózatot pontoz és választ ki nyolcat, egy minden tokent feldolgozó megosztott szakértő mellett. Ez a ritka MoE-kialakítás csökkenti a számítást, de egyenetlen munkát eredményez: a szakértők különböző számú tokent kapnak, és minden egyes token a szakértők különböző kombinációjának súlyait igényli.
A Qwen emellett 10 teljes figyelmi réteget kombinál 30 Gated DeltaNet réteggel. Ez a két rétegtípus különböző módon őrzi meg a korábbi információkat.
A figyelmi rétegek csoportos lekérdezéses figyelmet (grouped-query attention, GQA) használnak. A Qwen 16 lekérdezési fejjel és két kulcs-érték (KV) fejjel rendelkezik, amelyekben nyolc lekérdezési fej osztozik egy KV-fejen. A megosztás kisebbé teszi a KV-gyorsítótárat, és lehetővé teszi a gyorsítótárazott adatok újrafelhasználását a lekérdezési fejek között. A gyorsítótár továbbra is tárol új kulcsokat és értékeket minden egyes tokenhez, így a kontextus növekedésével minden dekódolási lépés több adatot olvas be.
A Gated DeltaNet ehelyett rögzített méretű rekurrens állapotba tömöríti a korábbi információkat. Egy betanult kapu szabályozza, hogy mennyi maradjon meg a meglévő állapotból, míg egy deltafrissítés az aktuális token adatait építi be. A modell rekurrens módon határozza meg ezeket a frissítéseket, így minden token az előző token által előállított állapottól függ. Az előkitöltés során azonban egy motor kétféleképpen is kiértékelheti ugyanezt a számítást. Vagy közvetlenül pásztázhat végig a tokeneken, miközben előreviszi az állapotot, vagy blokkokba szervezheti át a frissítéseket, amelyek több mátrixműveletet és token szintű párhuzamosságot tesznek szabaddá. Hogy melyik megközelítés a gyorsabb, az a modell dimenzióitól, a munkaterheléstől és a hardvertől függ.
Ezek a struktúrák együttesen három számítási mintát hoznak létre: egyenetlen szakértői csoportokat, egy növekedő gyorsítótáron végzett figyelmet (attention), valamint egy rögzített méretű rekurrenciát, amely közvetlenül vagy blokkokban is értékelhető.
Az Apple silicon különböző útvonalakat biztosít a különböző munkaterhelésekhez
Az előkitöltés egyszerre dolgoz fel sok prompttoken-aktivációs sort. Az itt vizsgált helyi munkaterhelés jellemzően egyszerre egy kérést dekódol (batch 1), és lépésenként egy új sort dolgoz fel. Ez a különbség megváltoztatja Ugyanazoknak a modellsúlyoknak a felhasználását. Az előkitöltés képes a súlyok minden egyes blokkját sorok százain vagy ezrein keresztül újra felhasználni. A dekódolás nagyrészt nem, mivel minden új tokenhez újabb áthaladás szükséges a súlyokon.
Az Apple silicon a CPU-t és a GPU-t az egységesített memória mögé helyezi, amely egyetlen fizikai memóriapulult jelent, amely mindkettő számára elérhető. Ez lehetővé teszi, hogy a modell rezidens maradjon anélkül, hogy külön GPU-másolatot kellene fenntartani, de nem teszi ingyenessé az adatmozgást. A súlyok és a köztes értékek olvasása továbbra is memóriasávszélességet fogyaszt, míg a regiszterek és a többi chipen belüli tár gyorsabb, de sokkal kisebb.
Az M5 GPU különféle számítási útvonalakat is biztosít. Az előkitöltés lineáris rétegei általános mátrix-mátrix szorzást (GEMM) használnak, amely egy súlymátrixot alkalmaz egyszerre sok sorra. A kompatibilis GEMM-ek az egyes GPU-magokban található Neural Acceleratort használhatják a Metal 4 tenzorműveleteken keresztül. A batch-1 dekódolás ehelyett általános mátrix-vektor szorzást (GEMV) használ, amely ugyanazokat a súlyokat alkalmazza egy sorra. Csekély súly-újrafelhasználás mellett a GEMV elsősorban a memóriasávszélességtől függ, és jobban illeszkedik a GPU vektoros aritmetikai logikai egységeihez (ALU), mint a nagyobb adatszintű újrafelhasználással járó mátrixműveletekre tervezett Neural Accelerators.
Ezek a végrehajtási útvonalak nem kizárólagosak a Lilyre nézve. Az MLX ugyanezen az egységesített memórián operál, és a munkaterhelési alakzatnak megfelelően választja ki az optimalizált mátrix- és vektorkerneleket. Az MLX-LM Qwen-implementációja már most is csoportosítja a szakértői munkát, fuzionált rekurrens Metal kernellel értékeli ki a Gated DeltaNetet, és GQA-tudatos figyelmet használ. Ezek a képességek jelzik a közös kiindulópontot a hatékony Qwen-inferenciához az Apple siliconon.
Optimalizációs stratégia
A Lily szűkebb hatóköre lehetővé teszi, hogy ezeket a megosztott végrehajtási útvonalakat a Qwen pontos architektúrája és dimenziói köré hangolja. Fázisspecifikus GPU-útvonalakat használ, a Qwen szakértői, rekurrens és figyelmi munkaterhelését úgy képezi le, hogy minimalizálja az adatok mozgását, valamint a mért munkaterhelési alakzat alapján választja ki a kerneleket és az elrendezéseket. A stratégia három részből áll:
- A GPU-útvonal igazítása az inferenciafázishoz. Mátrixorientált végrehajtás használata, amikor az előkitöltés sok soron keresztül tudja újrafelhasználni a súlyokat, és vektororientált végrehajtás, amikor a batch-1 dekódolás egyszerre egy sort dolgoz fel.
- A Qwen struktúrájának leképezése a GPU-ra, minimalizálva az adatmozgást. A súlyok tömörítve tartása a felhasználásukig, a routolt szakértői munka megszervezése a CPU-ra való visszatérés nélkül, a Gated DeltaNet állapot chipen tartása a rekurrens pásztázás során, valamint a csoportos lekérdezéses figyelem által megosztott KV-adatok újrafelhasználása.
- Kernelek igazítása a munkaterhelési alakzathoz. Az egyes fázisokon belül válassza ki a csempeméreteket, a végrehajtási elrendezéseket és a figyelmi útvonalakat a rendelkezésre álló sorszám, a sorok szakértők közötti eloszlása, a művelet dimenziói és az aktuális kontextushossz alapján.
A következő szakaszok elmagyarázzák ezeket a döntéseket. Az M5 Maxen, illesztett ablációkban kiértékelt optimalizációk hatását úgy becsüljük meg, hogy összehasonlítjuk az egyébként azonos motorkonfigurációkat, amelyek csak a vizsgált optimalizációban térnek el egymástól. Mivel ezek a kísértek a motorunk verzióit hasonlítják össze önmagával, inkább a mechanizmusokat magyarázzák, semmint hogy az MLX-LM-mel szembeni végeredményeket bontanák le.
Előkitöltés: súlyok újrafelhasználása és az útválasztás megtartása a GPU-n
Az előkitöltés egyszerre számos tokensort tesz szabaddá, de a Qwen egyenetlenül irányítja át ezeket a sorokat a szakértők között, és a sorozaton keresztül frissíti a rekurrens állapotot. Optimalizációi három csoportba sorolhatók: a ritka szakértői munka megszervezése az útválasztott sorok köré, a Gated DeltaNet pásztázás chipen tartása, valamint a hosszú promptok határolt csonkokra osztása.

A ritka szakértői számítás optimalizálása
Súlyok dekvantálása a mátrixszorzás során
A Qwen3.6-35B-A3B ellenőrzőpont csoportos affin 4 bites kvantálást használ. Minden egyes súly 4 bites egész kódként van tárolva, míg a 64 súlyból álló minden egyes csoport osztozik egy bfloat16 skálán és eltoláson (bias), amelyek az értékek rekonstrukciójára szolgálnak. Ez a 35 milliárd paraméteres modellt a bfloat16 súlyok durván 70 GB-os méretéről egy 19,4 GB-os ellenőrzőpontra csökkenti, így a modell Macen történő rezidens tártása megvalósíthatóvá válik.
A mátrixszorzáshoz használt Metal 4 tenzorművelet bfloat16 operandusokat fogyaszt a tömörített 4 bites reprezentáció helyett. Szorzás előtt a GPU-nak bfloat16-ban kell rekonstruálnia a súlyokat. A Lilyben található optimalizált csoportosított GEMM ezt a konverziót egyszerre egy kis súlycsempén végzi el, és a chipen belüli threadgroup memóriában tartja az eredményt addig, amíg meg nem szorozza az útválasztott aktivációs sorokkal. Az akkumuláció 32 bites lebegőpontos értéket használ, a kimenet pedig bfloat16-ban íródik ki. A teljes kibontott súlytömb soha nem jön létre az egységesített memóriában.
Az ablációban a dekvantálás különálló műveletként fut: kibontja a 4 bites súlyokat egy bfloat16 tömbbé az egységesített memóriában, ami után a mátrixkernel visszolvassa ezt a tömböt. 512 tokenes prompt esetén a dekvantálás áthelyezése a csoportosított GEMM-be 77,4%-kal növelte a végpontok közötti előkitöltési áteresztőképességet a köztes írás és olvasás kiküszöbölésével.
A szakértői útválasztás megtartása a GPU-n
A csoportosított GEMM megköveteli, hogy az egyes szakértőkhöz rendelt aktivációs sorok együtt legyenek tárolva. Tokenenként nyolc szakértő kiválasztása után egy hisztogram megszámolja, hogy hány hozzárendelés jutott az egyes szakértőkhöz. Egy prefix pásztázás kezdőeltolásokká alakítja ezeket a darabszámokat, egy scatter lépés a szakértőcsoportjaikba helyezi a sorokat, és egy blokktérkép felsorolja a rögzített méretű mátrixblokkokat, amelyeket a csoportosított GEMM-nek fel kell dolgoznia.
Az optimalizált útvonal ezt az egész sorozatot egyetlen parancspufferben, egy GPU-műveletek rendezett kötegében tartja meg minden egyes promptcsonkhoz. Egy abláció helyette szüneteltet, hogy a CPU ellenőrizhesse az útválasztási köztitermékeket, és elküldhesse a következő műveletet. A hisztogram és a prefix pásztázás GPU-n tartása két kernelt ad hozzá, de eltávolítja a CPU–GPU szinkronizációt az egyes MoE rétegeken belül.
512 tokenes prompt esetén a GPU-rezidens útválasztás engedélyezése 89%-kal növelte a végpontok közötti előkitöltést. Ez azt is mutatja, hogy önmagában a kernelek száma félrevezető lehet: a gyorsabb útvonal több kernelet indít el, de soha nem vár a CPU-ra a rétegen belül.
A csempeméret igazítása a szakértői terheléshez
2K tokenes prompt esetén az összes token 256 szakértő közül nyolchoz történő útválasztása 16 384 token-szakértő hozzárendelést eredményez, ami szakértőként átlagosan 64 aktivációs sort jelent. A tényleges eloszlás egyenetlen: egyes szakértők sok sort kapnak, míg mások keveset.
A csoportosított GEMM az egyes szakértők kimenetét csempékre osztja, amelyek mátrixszorzási kimenetének kis téglalap alakú blokkjai. Minden egyes csempe egyetlen GPU threadgroupnak van hozzárendelve. Az Apple silicon GPU-in a threadgroup egy vagy több simdgroupot tartalmaz, amelyek mindegyike 32 szálból áll, amelyek zárt lépésben (lockstep) hajtják végre a utasításokat.
A nagyobb csempék több soron osztják szét a beállítási költséget, és több párhuzamos munkát tesznek szabaddá, de egy nagy csempe egy része üresen marad, amikor egy szakértő csak néhány sort kap. A csempeméret és a simdgroupok száma ezért szorosan összefügg.
Egy abláció 16 sorban rögzíti a csempét. Ezzel a kontrollal szemben a négy simdgroupot tartalmazó 32 soros csempe engedélyezése 13,2%-kal javította a végpontok közötti előkitöltést 2K token esetén.
A rekurrens állapot chipen tartása
Az előkitöltés során minden egyes Gated DeltaNet réteg sorrendben pásztázza át a promptot, miközben előreviszi a rekurrens állapotát. Kikapcsolt regiszter-rezidencia mellett az abláció blokkonkénti pásztázást használ. 2K tokenes prompt esetén ez az útvonal rétegenként 256 MiB (mebibájt) állapotot mozgat meg, és ismételten megállítja az együttműködő szálakat a gátaknál (barriers), vagyis olyan szinkronizációs pontoknál, ahol minden részt vevő szállal meg kell várni egymást.
A rekurrens állapot egy mátrix. Az optimalizált kernel minden oszlopot egy simdgroupnak rendel hozzá. A simdgroup a szálai között felosztja az oszlopot, egyszer betölti azt a regisztereikbe, és a teljes pásztázás (scan) során viszi tovább az állapotot. A szálak a köztes eredményeket simdgroup-műveleteken keresztül cserélik ki a threadgroup memóriák helyett, amelyek egy threadgroupon belül megosztott chipen belüli tárak. A elkészült állapotot csak a pásztázás után írják vissza.
Az állapot és a kapuja 32 bites lebegőpontos formátumot használ, mivel a kisebb kerekítési hibák összeadódnak a szekvenciális frissítések során. A lekérdezési és kulcsaktivációk bfloat16 formátumban maradnak.
2K tokenes prompt esetén a regiszteralapú pásztázás engedélyezése 5,6%-kal javította a végpontok közötti előkitöltést. A szakértői GEMM-ek tették ki az előkitöltési idő mintegy 90%-át. A szekvenciális pásztázás nem tesz szabaddá elegendő újrafelhasználható mátrixmunkát ahhoz, hogy profitáljon a Neural Accelerators előnyeiből.
Ideiglenes memória korlátozása promptcsonkolással
A futtatókörnyezet a hosszú promptot határolt csonkok sorozataként dolgozza fel ahelyett, hogy az összes prompttoken ideiglenes adatait egyszerre a memóriában tartaná. A modellsúlyok az egységesített memóriában lakoznak, míg a rekurrens állapot és a KV-gyorsítótár az egyik csonkról a másikra viszi át a kontextust. A korábbi kontextusok közül semmi sem vész el.
Csonkolás nélkül az ideiglenes aktivációs tömbök a teljes prompthoz mérten nőnek, és versengenek a modellsúlyokkal, a rekurrens állapottal és a KV-gyorsítótárral az egységesített memóriáért. A csonkolás egyszerre csak egy szegmens ideiglenes értékeit tartja érvényben, majd felszabadítja vagy újra felhasználja ezt a tárhelyet a következő szegmens feldolgozása előtt. Ez korlátozza a csúcsmemória-használatot, és lehetővé teszi a motor számára a hosszabb promptok feldolgozását a modell kimenetének megváltoztatása nélkül.
A csonkolt előkitöltés népszerű sok motorban, és kulcsfontosságú a hosszú, többkörös pályák kiszolgálásához ezekben a memóriakorlátos környezetekben. A figyelmi rétegek teljes előkitöltési ideje a prompt hosszának függvényében négyzetes marad, a korábbi csonkok ismételt KV-betöltéseiből adódó némi többletterheléssel.
Dekódolás: a tokenenkénti bájtmúlatás minimalizálása
A batch-1 dekódolás egyszerre egy új sort dolgoz fel. Csekély súly-újrafelhasználás mellett az áteresztőképessége elsősorban attól függ, hogy a motor hány bájtot mozgat meg tokenenként. A dekódolás változásai négy csoportba sorolhatók: az egysoros súlyútvonal optimalizálása, az egyes lépések megtartása a GPU-n, a köztes és állapotalapú forgalom csökkentése, valamint a figyelmi gyorsítótár hatékony olvasása.

Az egysoros súlyútvonal optimalizálása
Az MLX már most is kiszervezi az egysoros munkát a speciális mátrix-vektor kernelekre. Mivel a Lily nem használ MLX-et, az egyedi futtatókörnyezetnek kell biztosítania ugyanezt az alapvető stratégiát. Soros párhuzamos GEMV-nk egyetlen aktivációs sorra lett tervezve. Egy simdgroup működik együtt a kimeneten, miközben párhuzamosan olvassa a súlymátrix különböző részeit.
Minden egyes dekódolási lépés megtartása a GPU-n
A tokenebcsere megtartása a GPU-n
Minden egyes dekódolási lépés a következő token kiválasztásával ér véget; a következő lépés azzal a tokennel mint bemenettel kezdődik. A kiválasztás elküldése a CPU-nak, majd vissza a GPU-ra minden egyes tokenhez hozzáad egy szinkronizációs pontot. Ehelyett a futtatókörnyezetünk két parancspuffer és két GPU-rezidens tokennyílás között váltakozik. A GPU kiválasztja a legmagasabb pontszámot elért tokent, és a tokenazonosítóját közvetlenül a következő dekódolási lépés bemeneti nyílásába írja, miközben a CPU előkészíti a későbbi munkát.
Független GPU-munka átfedése
Egy rögzített batch-1 dekódolási lépésben egy token generálása 795 GPU-kernelet indított el. Függőségeik 555 szekvenciális szakaszba rendeződtek, így egyes kernelek szabadon futhattak egyidejűleg. A Metal soros végrehajtási módja ennek ellenére minden kernelt sorban futtatott le.
Az optimalizált dekódolási útvonal egy párhuzamos Metal-menetben rögzíti a tényleges adatfüggőségeket. A független kernelindítások egyszerre futhatnak, amikor a GPU-erőforrások ezt lehetővé teszik. Egy akadály csak akkor kerül beillesztésre, ha a későbbi munka korábbi eredményt igényel.
A köztes és az állapotalapú forgalom csökkentése
A különálló kernelek gyakran materializálnak egy köztiterméket: az egyik kernel ideiglenes eredményt ír a memóriába, a következő pedig visszolvassa azt. Az optimalizált dekódolási útvonal négy láncot fuzionál: a két szakértői bemeneti vetítést a kapuzott aktiválásukkal; a szakértői kimeneti vetítést az útválasztási pontszámával és a megosztott szakértő eredményével; a lekérdezés és kulcs előkészítését a figyelem előtt; valamint a rekurrens frissítést a normalizálásával. Mindegyik fuzionált kernel regiszterekben tartja az ideiglenes értékeket ahelyett, hogy a memórián keresztül küldené el azokat.
A fúzió ráadásul lerövidíti a függőségi gráfot is: ha egy köztes írás eltűnik, eltűnik a fogyasztóját védő akadály is.
A figyelmi gyorsítótár hatékony olvasása
A figyelmi gyorsítótár olvasásainak összevonása (coalescing)
A figyelem kulcsokat és értékeket olvas ki a KV-gyorsítótárból minden egyes dekódolási lépés során. Az ablációban a szomszédos GPU-szálak nem mindig kérnek szomszédos bájtokat, ami arra kényszeríti a memóriarendszert, hogy több különálló tranzakciót szolgáljon ki. Az összevont betöltések (coalesced loads) engedélyezése arra készteti a szomszédos szálakat, hogy szomszédos bájtokat kérjenek, így a hardver képes kombinálni az olvasásaikat.
A bfloat16 konfiguráción az összevonás (coalescing) a kulcssávszélességet 33,8-ról 47,9 GB/s-ra, az értéksávszélességet 42,0-ről 61,8 GB/s-ra növelte, és 3840 tokenes kontextus mellett 2,1%-kal javította a végpontok közötti dekódolást.
Lekérdezési fejek csomagolása KV-sorok újrafelhasználásához
A csoportos lekérdezéses figyelem (grouped-query attention) lehetővé teszi, hogy nyolc lekérdezési fej (query head) osztozzon egy KV-fejen. Az abláció során minden egyes lekérdezési fej külön simdgroupban fut, így mind a nyolc egymástól függetlenül kéri le ugyanazt a gyorsítótárazott KV-sort. Az optimalizált kernel négy lekérdezési fejet csomagol egyetlen threadgroupba, amely minden KV-sort egyszer tölt be, és azt négy figyelmi számítás során újra felhasználja. Egy második threadgroup kezeli a fennmaradó négy fejet.
Ez a technikát, amelyet általában GQA-csomagolásnak neveznek, ugyanazt a számítást hajtja végre, és azonos kimeneti bájtokat hoz létre, miközben nyolc független KV-kérést két megosztott betöltésre csökkent. A ki nem csomagolt ablációhoz képest 32K tokenes kontextus mellett 23,8%-kal javította a végpontok közötti dekódolási áteresztőképességet.
Figyelmi elrendezések váltása hosszú kontextusok esetén
A teljes figyelmi (full-attention) réteg minden egyes dekódolási lépése átvizsgálja a meglévő KV-gyorsítótárat. Egy rögzített blokkos elrendezés egyenlő részekre osztja ezt a gyorsítótárat, amelyeket a GPU párhuzamosan tud feldolgozni. Az extra ütemezés nem éri meg, ha a gyorsítótár kicsi, de a rögzített blokkos elrendezés egyenletesebben osztja el a munkát a kontextus növekedésével.
Ehhez a modellhez a futtatókörnyezet 32K token alatt tartja az általános figyelmi útvonalat, és 32K vagy annál hosszabb esetben a rögzített blokkos útvonalat használja. A váltás akkor történik meg, amikor mindegyik fej 256 értékkel rendelkezik, és nyolc lekérdezési fej osztozik egy KV-fejen; a többi alakzat az általános útvonalon marad. Egy abláció letiltja ezt a váltást, és mindig az általános útvonalat használja. A rögzített blokkos útvonal engedélyezése 32K-nál 7,7%-kal, 64K-nál 27,4%-kal, 128K-nál pedig 40,2%-kal javította a végpontok közötti dekódolást.
A további optimalizálás határai
Egyes változtatások egy elszigetelt műveletet javítottak, de nem javították a végpontok közötti inferenciát.
A spekulatív dekódolás, amely kisebb modellt használ a teljes modell által ellenőrizendő tokenek javaslatára, 18%-kal lassabbá tette a batch-1 dekódolást. Az ellenőrzés kettőtől öt sorból álló csoportokat dolgozott fel, ami nem hatékony alakzat ehhez a hardverhez, és a sorok gyakran különböző szakértőket választottak ki, növelve a beolvasott szakértői súlyadatok mennyiségét. A tervezetkészítő kimeneti szókincsének csökkentése 4,7–5,1%-kal javította a tervezetkészítő áteresztőképességét, de nem tette gyorsabbá a teljes spekulatív hurkot. Ez az eredmény munkaterhelés-specifikus: a Blackwellen futó, kötegelt Qwen-alapú üzembe helyezésünk eltérő feltételek mellett használ spekulatív dekódolást.
Más kísértek magukban foglalták a GPU-indítások csökkentését, a teljes fázisok átfedését, nagyobb előkitöltési csemék használatát, szélesebb körű fúzió alkalmazását, a router felgyorsítását, valamint a kimeneti vetítés kombinálását a tokenkiválasztással. Ezek egyike sem javította a teljes inferenciahurkot.
A hardverkorlátok mérései azt is mutatták, hogy a fő előkitöltési és dekódolási műveletekben kevés fennmaradó tartalék maradt. Az MoE GEMM-ek és GEMV-ek elérték a hozzáférési mintáik leggyorsabb fenntartható súlyolvasási sebességének 97,9%-át és 90,3%-át. A számtani műveletek eltávolítása a ritka GEMV-ből mindössze 0,2%-kal változtatta meg az áteresztőképességet, ami megerősíti, hogy a korlátozó erőforrás a számítás helyett a súlyok olvasása volt. Az előkitöltés mátrixszorzása hasonló módon érte el az elméleti mátrixkorlát 93%-át önállóan, és 80–86%-át a tesztelt modelleken belül.
Végpontok közötti teljesítmény
A végpontok közötti összehasonlítás azonos, 4 bites ellenőrzőpont-bájtokat tölt be mindkét motorban, és egyszerre egy kérést futtat egyetlen 40 magos, 128 GB-os M5 Maxen. Az egyes körökön belül a két motor váltakozó sorrendben fut, hogy csökkentse a háttérterhelésből és a chip hőmérsékletének változásából eredő torzítást. Az MLX-LM leggyorsabb közvetlen generálási útvonalával hasonlítunk össze, nem a kiszolgálójával, így a mérés a modell végrehajtására fókuszál a kiszolgálási többletterhelés helyett.
A sweep (pásztázás) tíz prompt- és tíz kontextushosszt fed le az előkitöltéshez és a dekódoláshoz, 256-tól 128K tokenig. Az előkitöltési áteresztőképesség először növekszik, ahogy a motor több tokenen osztja szét a rögzített beállítási költségeket. Az előkitöltés egy 4K-s prompt körül éri el a csúcsát, majd csökken, mert a tíz teljes figyelmi réteg több munkát végez a prompt növekedésével. A dekódolás rövid kontextusoknál szinte lapos marad, és csökkenni kezd, amint a növő KV-gyorsítótár olvasása jelentőségessé válik. Az egyedi motor minden rögzített hossznál gyorsabb.
Mivel a specializált végrehajtás megváltoztathatja a lebegőpontos műveletek sorrendjét, az MLX-LM-hez képest a numerikus konzisztenciát is ellenőriztük. Egy tanárok által vezérelt (teacher-forced) összehasonlításban mindkét motor megjósolta a következő tokent ugyanabból a referenciaprefixből 192 pozíció mindegyikénél, megakadályozva, hogy a korábbi különbségek befolyásolják a későbbi bemeneteket. A Lily perplexitása mindössze 0,04%-kal volt magasabb, és a tesztelt pozíciók 96,35%-ánál ugyanazt a legmagasabb rangú tokent választotta ki.

A helyi platformra építve
Az Apple silicon nem egy kisebb adatközponti GPU. Ez egy teljes körű helyi inferenciaplatform, amely saját hardveres és szoftveres jellemzőkkel bír. Az egységesített memória nagyon magas felső határt biztosít egyetlen csomópont számára abban, hogy mennyi modellt és állapotot képes tárolni. Az M5 Neural Accelerators elnyeli a sűrű mátrixmunkát az előkitöltés során. A vektoros ALU-k kezelik a sávszélesség-korlátos, alacsony újrafelhasználású maradékot a dekódolásban.
A Qwen további lehetőségeket teremt a specializációra: a szakértői útválasztás és a rekurrens állapot GPU-n tartása, a felesleges köztitermékek megszüntetése, a független munka átfedése, a megosztott KV-adatok újrafelhasználása, valamint a kernelek igazítása a munkaterhelési alakzathoz.
A modell- és platformspecifikus optimalizációval egyetlen Mac hatékonyan képes futtatni egy nagy ritka modellt. A jövőbeli munka kiterjeszti a lefedettséget a modellekre, chipekre és kiszolgálási munkaterhelésekre, és az itt egyetlen konfiguráción érvényesített mechanizmusokat általánosabb futtatókörnyezeti házirenddé alakítja.
A tágabb elv az, hogy a motort hozzá kell igazítani mind a modell architektúrájához, mind a hardver specifikus számítási és memóriájú útvonalaihoz. Ahogy a határok megnyitásán alapuló (open-weight) modellek és a hardver fejlődnek, a nagy teljesítményű helyi inferencia egyre inkább olyan motorokra fog támaszkodni, amelyek mindkettőhöz idomulnak, ahelyett, hogy elvonatkoztatnának a különbségeiktől.