Vietinio išvedimo optimizavimas „Apple silicon“ platformai
Pasirinktinis vietinis variklis, pagerinantis išankstinio užpildymo ir dekodavimo pralaidumą.
Hibridiniai skaičiavimai „Apple silicon“ platformoje koordinuoja užduotį tarp pažangaus intelekto danguje (debesyje) ir vietinio modelio „Mac“ kompiuteryje. Debesies modeliai apdoroja tyrimus ir mąstymą, o vietinis modelis dirba su privačiais failais ir programomis „Mac“ kompiuteryje.
Kad šis darbo pasiskirstymas jaustųsi sklandus, vietinis išvedimas turi žengti koja kojon su likusia užduoties dalimi. Tam reikalingas variklis, galintis greitai apdoroti užklausas ir palaikyti didelį tokenų generavimo greitį.
„Lily“ – mūsų lengvas vietinio išvedimo variklis – sukurtas specialiai „Apple silicon“ ir Qwen3.6-35B-A3B, numatant atskirus optimizavimus išankstiniam užpildymui ir dekodavimui. Netrukus variklio kodas bus paskelbtas kaip atvirasis šaltinis.
Įvadas
Įprastas būdas paleisti LLM „Mac“ kompiuteryje yra naudoti MLX – „Apple“ atvirojo kodo mašininio mokymosi sistemą, skirtą „Apple silicon“. Jos papildoma biblioteka MLX-LM prideda komponentus, reikalingus tekstui įkelti ir generuoti naudojant įvairius kalbos modelius. Kartu „MLX“ ir „MLX-LM“ suteikia paruoštą, universalų steką vietiniam LLM išvedimui.
„Qwen3.6-35B-A3B“ yra retas, hibridinis modelis: jame naudojamas ekspertų mišinio (MoE) maršrutizavimas ir derinamos fiksuoto dydžio pasikartojančios būsenos su visapusišku dėmesiu. Šie architektūriniai sprendimai sumažina reikalingų skaičiavimų apimtį, tačiau taip pat sukuria nereguliarius darbo krūvius. Tokenai nukreipiami į skirtingus ekspertų svorius, o pasikartojančios būsenos iš prigimties yra nuoseklios.
„MLX-LM“ jau pasirenka optimizuotus branduolius išvedimo fazėms ir įprastoms darbo krūvio formoms, tačiau jos pakartotinai naudojamos operacijos turi palaikyti daugybę modelio architektūrų. „Qwen“ skirtas variklis gali specializuotis modelio ir vykdymo aplinkos lygmeniu, koordinuodamas branduolius, duomenų judėjimą ir planavimą aplink fiksuotą modelio struktūrą.
„Lily“ įgyvendina šią specializaciją nuo galo iki galo viename procese. „Rust“ vykdymo aplinka įkelia modelio kontrolinį tašką ir valdo sesijos būseną bei generavimo ciklą, su „OpenAI“ suderinama pokalbių užbaigimo API priima užklausas ir srautu siunčia tokenus, o pasirinktiniai „Metal“ branduoliai vykdo „Qwen“ specifines operacijas. Vykdymo kelyje nėra nei „PyTorch“, nei „MLX“.

Išankstinio užpildymo ir dekodavimo našumą matuojame atskirai. Išankstinio užpildymo pralaidumas parodo, kaip greitai variklis apdoroja užklausą; dekodavimo pralaidumas parodo, kaip greitai jis generuoja išvesties tokenus.
Atlikome „Qwen3.6-35B-A3B“ testavimą su vienu „MacBook Pro“, kuriame veikia „M5 Max“ su 40 branduolių GPU ir 128 GB bendrosios atminties. Išbandžius dešimt užklausos ilgių išankstiniam užpildymui ir dešimt konteksto ilgių dekodavimui (nuo 256 iki 128 tūkst. tokenų, kur K = 1024), variklis pasiekė vidutiniškai 1,23 karto didesnį išankstinio užpildymo pralaidumą ir 1,35 karto didesnį dekodavimo pralaidumą nei „MLX-LM“. Naudojant 4 tūkst. tokenų užklausą ir 4 tūkst. tokenų dekodavimo kontekstą, pasirinktinis variklis pasiekia 5 749,9 išankstinio užpildymo tokeno per sekundę ir 186,6 dekodavimo tokeno per sekundę greitį, palyginti su 4 737,5 ir 140,9, kuriuos pasiekia „MLX-LM“. Vykdant kelių žingsnių sesiją, šis laiko sutaupymas sumuojasi su kiekvienu papildomu modelio iškvietimu.

Toliau paaiškinsime, kaip „Qwen“ architektūra sukuria modelio specifines optimizavimo galimybes „Apple silicon“ platformoje. Tuomet aptarsime iš to kylančius išankstinio užpildymo ir dekodavimo pakeitimus. Taip pat apžvelgsime, kur papildomas optimizavimas nustoja nešti naudą, ir užbaigsim palyginimu su „MLX-LM“.
„Qwen“ specifinės optimizavimo galimybės „Apple silicon“ platformoje
„Qwen“ sukuria tris skirtingas darbo krūvio formas
„Qwen3.6-35B-A3B“ turi 35 milijardus parametrų, tačiau kiekvienam tokenui aktyvuoja tik apie 3 milijardus. Maršrutizatorius įvertina 256 ekspertų subninklus ir išrenka aštuonis, kartu su vienu bendru ekspertu, kuris apdoroja kiekvieną tokeną. Šis retas MoE dizainas sumažina skaičiavimus, tačiau sukuria netolygų darbą: ekspertai gauna skirtingą tokenų skaičių, o kiekvienam tokenui reikalingi svoriai iš skirtingo ekspertų derinio.
„Qwen“ taip pat derina 10 visapusiško dėmesio sluoksnių su 30 Gated DeltaNet sluoksnių. Šie du sluoksnių tipai ankstesnę informaciją išsaugo skirtingais būdais.
Dėmesio sluoksniuose naudojamas grupuoto užklausos dėmesys (GQA). „Qwen“ turi 16 užklausų galvučių ir dvi raktų-reikšmių (KV) galvutes, o aštuonios užklausų galvutės dalijasi kiekviena KV galvute. Dalinimasis sumažina KV talpyklą ir leidžia pakartotinai naudoti talpykloje esančius duomenis tarp užklausų galvučių. Talpykla vis tiek saugo naujus raktus ir reikšmes kiekvienam tokenui, todėl kiekvienas dekodavimo žingsnis nuskaito daugiau duomenų augant kontekstui.
„Gated DeltaNet“ vietoje to suspaudžia ankstesnę informaciją į fiksuoto dydžio pasikartojančią būseną. Išmokti vartai kontroliuoja, kiek esamos būsenos išsaugoti, o deltos atnaujinimas įtraukia informaciją iš dabartinio tokeno. Modelis šiuos atnaujinimus apibrėžia pasikartojančiu būdu, todėl kiekvienas tokenas priklauso nuo būsenos, kurią sugeneravo ankstesnis tokenas. Tačiau išankstinio užpildymo metu variklis gali įvertinti tą patį skaičiavimą dviem būdais. Jis gali tiesiogiai nuskaityti tokenus, perkeldamas būseną į priekį, arba pertvarkyti atnaujinimus į blokus, kurie atveria daugiau matricos operacijų ir tokeno lygio lygiagretumo. Kuris būdas yra greitesnis, priklauso nuo modelio matmenų, darbo krūvio ir aparatūros.
Kartu šios struktūros sukuria tris skaičiavimo šablonus: netolygių ekspertų grupes, dėmesį (angl. attention) augančiai talpyklai ir fiksuoto dydžio pasikartojimą, kurį galima įvertinti tiesiogiai arba blokais.
„Apple silicon“ suteikia skirtingus kelius skirtingiems darbo krūviams
Išankstinis užpildymas vienu metu apdoroja daugybę užklausos tokeno aktyvavimo eilučių. Čia nagrinėjamas vietinis darbo krūvis paprastai dekoduoja po vieną užklausą (1 paketas) ir apdoroja vieną naują eilutę per žingsnį. Šis skirtumas keičia, kaip naudojami tie patys modelio svoriai. Išankstinio užpildymo metu kiekvieną svorių bloką galima pakartotinai naudoti šimtus ar tūkstančius eilučių. Dekodavimas to iš esmės negali padaryti, nes kiekvienam naujam tokenui reikalingas dar vienas praėjimas per svorius.
„Apple silicon“ talpina CPU ir GPU už bendrosios atminties – vienintelio abiem prieinamo fizinio atminties baseino. Tai leidžia modeliui išlikti reziduojančiam be atskiros GPU kopijos, tačiau tai nepadaro duomenų judėjimo nemokamu. Svorių ir tarpinių reikšmių nuskaitymas vis tiek eikvoja atminties pralaidumą, o registrai ir kita lusto atmintis yra greitesnė, bet daug mažesnė.
M5 GPU taip pat suteikia skirtingus skaičiavimo kelius. Išankstinio užpildymo linijiniai sluoksniai naudoja bendrąją matricos ir matricos daugybą (GEMM), pritaikydami svorių matricą daugeliui eilučių vienu metu. Suderinamieji GEMM gali naudoti Neural Accelerator greitintuvą kiekviename GPU branduolyje per Metal 4 tenzoriaus operacijas. 1 paketo dekodavimas vietoje to naudoja bendrąją matricos ir vektoriaus daugybą (GEMV), pritaikydamas tuos pačius svorius vienai eilutei. Esant nedideliam svorių pakartotiniam naudojimui, GEMV daugiausia riboja atminties pralaidumas, todėl jis geriau tinka GPU vektoriniams aritmetiniams loginiams vienetams (ALU), o ne „Neural Accelerators“ greitintuvams, sukurtas matricos operacijoms su didesniu duomenų pakartotiniu naudojimu.
Šie vykdymo keliai nėra išskirtiniai tik „Lily“. „MLX“ veikia per tą pačią bendrąją atmintį ir parenka optimizuotus matricos bei vektoriaus branduolius pagal darbo krūvio formą. „MLX-LM“ Qwen realizacija jau grupuoja ekspertų darbą, vertina „Gated DeltaNet“ naudodama sulietą pasikartojantį „Metal“ branduolį ir naudoja GQA palaikantį dėmesį. Šios galimybės yra bendras atspirties taškas efektyviam „Qwen“ išvedimui „Apple silicon“ platformoje.
Optimizavimo strategija
Siauresnė „Lily“ apimtis leidžia koordinuoti šiuos bendrus vykdymo keliukus atsižvelgiant į tikslią „Qwen“ architektūrą ir matmenis. Joje naudojami fazėms specifiniai GPU keliai, „Qwen“ ekspertų, pasikartojantys ir dėmesio darbo krūviai susiejami taip, kad būtų sumažintas duomenų judėjimas, o branduoliai ir išdėstymai atrenkami pagal išmatuotą darbo krūvio formą. Ši strategija susideda iš trijų dalių:
- Pritaikyti GPU kelią prie išvedimo fazės. Naudoti matrica orientuotą vykdymą, kai išankstinis užpildymas gali pakartotinai naudoti svorius per daugybę eilučių, ir vektoriumi orientuotą vykdymą, kai 1 paketo dekodavimas apdoroja po vieną eilutę.
- Pritaikyti „Qwen“ struktūrą GPU, kartu sumažinant duomenų judėjimą. Laikyti svorius suspaustus, kol jie bus panaudoti, organizuoti nukreiptą ekspertų darbą negrįžtant į CPU, išlaikyti „Gated DeltaNet“ būseną luste per jos pakartotinį nuskaitymą ir pakartotinai naudoti KV duomenis, kuriais dalijasi grupuoto užklausos dėmesys.
- Pritaikyti branduolius pagal darbo krūvio formą. Kiekvienoje fazėje pasirinkite plytelių dydžius, vykdymo išdėstymus ir dėmesio kelius iš galimo eilučių skaičiaus, eilučių pasiskirstymo tarp ekspertų, operacijos matmenų ir dabartinio konteksto ilgio.
Tolimesniuose skyriuose paaiškinami šie pasirinkimai. Optimizavimams, kurie buvo įvertinti atliekant pritaikytas abliacijas su „M5 Max“, jų poveikį apskaičiuojame lyginant kitu atveju identiškas variklio konfigūracijas, kurios skiriasi tik tiriamu optimizavimu. Kadangi šiuose eksperimentuose lyginamos mūsų variklio versijos tarpusavyje, jais paaiškinami mechanizmai, o ne galutiniai rezultatai lyginami su „MLX-LM“.
Išankstinis užpildymas: pakartotinai naudoti svorius ir išlaikyti maršrutizavimą GPU
Išankstinis užpildymas atskleidžia daug tokenų eilučių vienu metu, tačiau „Qwen“ šias eilutes netolygiai paskirsto tarp ekspertų ir visoje sekoje atnaujina pasikartojančią būseną. Jo optimizavimai skirstomi į tris grupes: organizuoti retą ekspertų darbą aplink nukreiptas eilutes, išlaikyti „Gated DeltaNet“ nuskaitymą luste ir padalyti ilgas užklausas į ribotus fragmentus.

Optimizuoti retų ekspertų skaičiavimus
Dekiokuoti svorius matricos daugybos metu
„Qwen3.6-35B-A3B“ kontrolinis taškas naudoja grupėmis taikomą afinine 4 bitų kvantavimą. Kiekvienas svoris saugomas kaip 4 bitų sveikojo skaičiaus kodas, o kiekvienos 64 svorių grupės dalijasi „bfloat16“ skale ir poslinkiu, naudojamu reikšmėms atkurti. Tai sumažina 35 milijardų parametrų modelį nuo maždaug 70 GB „bfloat16“ svorių iki 19,4 GB kontrolinio taško, todėl modelį praktiškai lengva išlaikyti reziduojantį „Mac“ kompiuterio atmintyje.
Matricos daugybai naudojama „Metal 4“ tenzoriaus operacija vartoja „bfloat16“ operandus, o ne supakuotą 4 bitų vaizdavimą. Prieš daugybą GPU turi atkurti svorius „bfloat16“ formatu. Optimizuotas grupuotas GEMM „Lily“ variklyje šį konvertavimą atlieka po vieną mažą svorio plytelę ir laiko rezultatą luste esančioje gijų grupės atmintyje tik tiek, kiek reikia jam padauginti iš nukreiptų aktyvavimo eilučių. Kaupimui naudojamas 32 bitų slankiojantis kablelis, o išvestis įrašoma „bfloat16“ formatu. Pilnas išplėstas svorių masyvas bendrojoje atmintyje niekada nesukuriamas.
Atliekant abliaciją, dekvantavimas vyksta kaip atskira operacija: ji išplečia 4 bitų svorius į „bfloat16“ masyvą bendrojoje atmintyje, po kurio matricos branduolys nuskaito šį masyvą atgal. Esant 512 tokenų užklausai, dekvantavimo perkėlimas į grupuotą GEMM pagerino bendrą išankstinio užpildymo pralaidumą 77,4 %, pašalinant šį tarpinį įrašymą ir nuskaitymą.
Palikti ekspertų maršrutizavimą GPU
Grupuotam GEMM reikia, kad kiekvienam ekspertui priskirtos aktyvavimo eilutės būtų saugomos kartu. Pasirinkus aštuonis ekspertus vienam tokenui, histograma suskaičiuoja, kiek priskirimų teko kiekvienam ekspertui. Prefikso nuskaitymas paverčia šiuos skaičiavimus pradiniais poslinkiais, išbarstymo žingsnis įrašo eilutes į jų ekspertų grupes, o blokų žemėlapis išvardija fiksuoto dydžio matricos blokus, kuriuos grupuotas GEMM privalo apdoroti.
Optimizuotas kelias išlaiko visą šią seką viename komandų buferyje (surūšiuotame GPU operacijų pakete) kiekvienam užklausos fragmentui. Vietoj to, taikant abliaciją, daroma pauzė, kad CPU galėtų patikrinti maršrutizavimo tarpinius rezultatus ir pateikti kitą operaciją. Histogramos ir prefikso nuskaitymo palaikymas GPU prideda du branduolius, bet pašalina CPU ir GPU sinchronizaciją kiekviename MoE sluoksnyje.
Esant 512 tokenų užklausai, GPU reziduojančio maršrutizavimo įjungimas padidino bendrą išankstinį užpildymą 89 %. Tai taip pat parodo, kodėl vien branduolių skaičius gali klaidinti: greitesnis kelias paleidžia daugiau branduolių, bet niekada nelaukia CPU sluoksnio viduje.
Pritaikyti plytelės dydį pagal ekspertų apkrovą
Esant 2 tūkst. tokenų užklausai, kiekvieną tokeną nukreipiant į aštuonis iš 256 ekspertų, sukuriami 16 384 tokenų ir ekspertų priskirimai arba vidutiniškai 64 aktyvavimo eilutės kiekvienam ekspertui. Tikrasis pasiskirstymas yra netolygus: kai kurie ekspertai gauna daug eilučių, o kiti – mažai.
Grupuotas GEMM padalija kiekvieno eksperto išvestį į plyteles – mažus stačiakampius matricos daugybės išvesties blokus. Kiekviena plytelė priskiriama vienai GPU gijų grupei. „Apple silicon“ GPU gijų grupuotėje yra viena ar daugiau „simdgroup“ grupių, kurių kiekvieną sudaro 32 gijos, vykdujícíos instrukcijas sinchroniškai.
Didesnės plytelės paskirsto sąrankos išlaidas didesniam eilučių skaičiui ir sukuria daugiau lygiagretaus darbo, tačiau dalis didelės plytelės lieka laisva, kai ekspertas gauna tik kelias eilutes. Todėl plytelės dydis ir „simdgroup“ grupių skaičius yra tarpusavyje susiję.
Atliekant abliaciją, plytelė fiksuojama ties 16 eilučių. Lyginant su šiuo kontroline, 32 eilučių plytelės su keturiomis „simdgroup“ grupėmis įjungimas pagerino bendrą išankstinį užpildymą 13,2 % prie 2 tūkst. tokenų.
Išsaugoti pasikartojančią būseną luste
Išankstinio užpildymo metu kiekvienas „Gated DeltaNet“ sluoksnis nuosekliai nuskaito užklausą, kartu perkeldamas savo pasikartojančią būseną į priekį. Kai registro rezidavimas išjungtas, atliekant abliaciją naudojamas blokinis nuskaitymas. Esant 2 tūkst. tokenų užklausai, šis kelias perkelia 256 MiB (mebibaitų) būsenos vienam sluoksniui ir pakartotinai sustabdo bendradarbiaujančias gijas ties barjerais – sinchronizacijos taškais, kur visi dalyvaujantys srautai turi laukti vienas kito.
Pasikartojanti būsena yra matrica. Optimizuotas branduolys priskiria kiekvieną stulpelį vienai „simdgroup“ grupei. „Simdgroup“ grupė padalija stulpelį tarp savo gijų, vieną kartą įkelia stulpelį į jų registrus ir perkelia būseną per visą nuskaitymą. Gijos keičiasi tarpiniais rezultatais per „simdgroup“ operacijas, o ne per gijų grupės atmintį – lusto viduje esančią saugyklą, kuria dalijasi visa gijų grupė. Užbaigta būsena įrašoma atgal tik po nuskaitymo.
Būsenai ir jos vartams naudojamas 32 bitų slankiojojo kablelio formatas, nes nedidelės apvalinimo klaidos kaupiasi atliekant nuoseklius atnaujinimus. Užklausos ir rakto aktyvavimai lieka „bfloat16“ formate.
Esant 2 tūkst. tokenų užklausai, registre reziduojančio nuskaitymo įjungimas pagreitino bendrą išankstinį užpildymą 5,6 %. Ekspertų GEMM operacijos sudarė apie 90 % išankstinio užpildymo laiko. Nuoseklus nuskaitymas nesukuria pakankamai pakartotinai naudojamo matricos darbo, kad būtų galima pasinaudoti „Neural Accelerators“ greitintuvų privalumais.
Apriboti laikinąją atmintį dalijant užklausą į fragmentus
Vykdymo aplinka ilgą užklausą apdoroja kaip apribotų fragmentų seką, o ne laiko atmintyje visus laikinus duomenis kiekvienam užklausos tokenui vienu metu. Modelio svoriai lieka bendrojoje atmintyje, o pasikartojanti būsena ir KV talpykla perkelia kontekstą iš vieno fragmento į kitą. Joks ankstesnis kontekstas nėra išmetamas.
Be fragmentavimo laikinieji aktyvavimo masyvai auga kartu su visa užklausai ir konkuruoja su modelio svoriais, pasikartojančia būsena bei KV talpykla dėl bendrosios atminties. Fragmentavimas leidžia vienu metu laikyti gyvais tik vieno segmento laikinąsias reikšmes, o po to atlaisvina arba pakartotinai panaudoja šią saugyklą prieš apdorojant kitą segmentą. Tai apriboja didžiausią darbinę atmintį ir leidžia varikliui apdoroti ilgesnes užklausas nekeičiant modelio išvesties.
Fragmentuotas išankstinis užpildymas yra populiarus daugelyje variklių ir yra gyvybiškai svarbus ilgų kelių posūkių trajektorijoms aptarnauti šiose atminties apribotose aplinkose. Bendras išankstinio užpildymo laikas dėmesio sluoksniams išlieka kvadratinis priklausomai nuo užklausos ilgio, su tam tikromis papildomomis išlaidomis dėl pakartotinių ankstesnių fragmentų KV įkėlimų.
Dekodavimas: sumažinti perkeliamų baitų kiekį vienam tokenui
1 paketo dekodavimas apdoroja po vieną naują eilutę. Esant nedideliam svorių pakartotiniam naudojimui, jo pralaidumas daugiausia priklauso nuo to, kiek baitų variklis perkelia kiekvienam tokenui. Dekodavimo pakeitimai skirstomi į keturias grupes: optimizuoti vienos eilutės svorio kelią, išlaikyti kiekvieną žingsnį GPU, sumažinti tarpinį ir būsenos srautą bei efektyviai nuskaityti dėmesio talpyklą.

Optimizuoti vienos eilutės svorio kelią
„MLX“ jau paskirsto vienos eilutės darbą specializuotiems matricos ir vektoriaus branduoliams. Kadangi „Lily“ nenaudoja „MLX“, pasirinktinis variklis privalo suteikti tą pačią pagrindinę strategiją. Mūsų eilučių lygiagretus GEMV yra skirtas vienai aktyvavimo eilutei. „Simdgroup“ grupė bendradarbiauja prie išvesties, tuo metu lygiagrečiai skaitydama skirtingas svorių matricos dalis.
Išsaugoti kiekvieną dekodavimo žingsnį GPU
Išsaugoti tokeno perdavimą GPU
Kiekvienas dekodavimo žingsnis baigiasi kito tokeno pasirinkimu; po jo einantis žingsnis prasideda tuo tokenu kaip įvestimi. Siunčiant pasirinkimą į CPU ir vėl atgal į GPU, prie kiekvieno tokeno pridedamas sinchronizacijos taškas. Mūsų vykdymo aplinka vietoj to kaitalioja du komandų buferius ir du GPU reziduojančius tokenų lizdus. GPU išrenka aukščiausią įvertinimą gavusį tokeną ir įrašo jo tokeno ID tiesiai į kito dekodavimo žingsnio įvesties lizdą, kol CPU ruošia vėlesnį darbą.
Vykdyti nepriklausomą GPU darbą lygiagrečiai
Viename užfiksuotame 1 paketo dekodavimo žingsnyje tokeno generavimas paleido 795 GPU branduolius. Jų priklausomybės suformavo 555 nuoseklius etapus, leidžiančius kai kuriems branduoliams veikti vienu metu. Nepaisant to, „Metal“ nuoseklaus vykdymo režimas paleidome kiekvieną branduolį iš eilės.
Optimizuotas dekodavimo kelias įrašo faktines duomenų priklausomybes lygiagrečiame „Metal“ praėjime. Nepriklausomi branduolių paleidimai gali veikti tuo metu, kai GPU ištekliai tai leidžia. Barjeras įterpiamas tik tada, kai vėlesniam darbui reikalingas ankstesnis rezultatas.
Sumažinti tarpinį ir būsenos srautą
Atskiri branduoliai dažnai sukuria tarpinį rezultatą: vienas branduolys įrašo laikiną rezultatą į atmintį, o kitas jį nuskaito atgal. Optimizuotas dekodavimo kelias sulieja keturias grandines: dviejų ekspertų įvesties proskynos su jų valdomu aktyvavimu; ekspertų išvesties proskynos su jų maršrutizavimo įverčiu ir bendro eksperto rezultatu; užklausos ir rakto paruošimas prieš dėmesį; bei pasikartojantis atnaujinimas su jo normalizavimu. Kiekvienas sulietas branduolys laikinąsias reikšmes saugo registruose, o ne siunčia jas per atmintį.
Suliejimas taip pat sutrumpina priklausomybių grafiką: išnykus tarpiniam įrašui, išnyksta ir barjeras, apsaugojęs jo vartotoją.
Efektyviai nuskaityti dėmesio talpyklą
Sujungti dėmesio talpyklos nuskaitymus į vieną srautą
Dėmesys nuskaito raktus ir reikšmes iš KV talpyklos kiekvieno dekodavimo žingsnio metu. Atliekant abliaciją, kaimyninės GPU gijos ne visada prašo kaimyninių baitų, priversdamos atminties sistemą aptarnauti daugiau atskirų operacijų. Sujungtų įkėlimų įjungimas verčia gretimas gijas prašyti gretimų baitų, kad aparatūra galėtų sujungti jų nuskaitymus.
Naudojant „bfloat16“ konfigūraciją, suliejimas pagerino raktų pralaidumą nuo 33,8 iki 47,9 GB/s, reikšmių pralaidumą nuo 42,0 iki 61,8 GB/s ir pagerino galutinį dekodavimą 2,1 % esant 3 840 tokenų kontekstui.
Supakuoti užklausos galvutes, kad būtų pakartotinai naudojamos KV eilutės
Grupuoto užklausos dėmesio mechanizmas leidžia aštuonioms užklausų galvutėms dalintis viena KV galvute. Atliekant abliaciją, kiekviena užklausos galvutė veikia atskiroje „simdgroup“ grupėje, todėl visos aštuonios nepriklausomai prašo to paties talpykloje esančio KV eilutės elemento. Optimizuotas branduolys sugrupuoja keturias užklausų galvutes į vieną gijų grupę („threadgroup“), kuri įkelia kiekvieną KV eilutę vieną kartą ir pakartotinai ją naudoja atliekant keturis dėmesio skaičiavimus. Antroji gijų grupė apdoroja likusias keturias galvutes.
Šis metodas, dažnai vadinamas GQA pakavimu, atlieka tą pačią aritmetiką ir sukuria identiškus išvesties baitus, kartu sumažindamas aštuonias nepriklausomas KV užklausas iki dviejų bendrų įkėlimų. Palyginus su nesupakuota abliacija, tai pagerino galutinio dekodavimo pralaidumą 23,8 % esant 32 tūkst. tokenų kontekstui.
Perjungti dėmesio išdėstymus esant ilgesniam kontekstui
Kiekvienas dekodavimo žingsnis visapusiško dėmesio sluoksnyje nuskaito esamą KV talpyklą. Fiksuotų blokų išdėstymas padalija šią talpyklą į vienodas dalis, kurias GPU gali apdoroti lygiagrečiai. Papildomas planavimas neatsiperka, kai talpykla yra maža, tačiau fiksuotų blokų išdėstymas tolygiau paskirsto darbą augant kontekstui.
Šiam modeliui vykdymo aplinka palaiko bendrą dėmesio kelią iki 32 tūkst. tokenų, o esant 32 tūkst. ar daugiau tokenų naudoja fiksuoto bloko kelią. Perjungimas įvyksta, kai kiekviena galvutė turi 256 reikšmes ir aštuonios užklausų galvutės dalijasi KV galvute; kitos formos lieka bendrajame kelyje. Atliekant abliaciją, šis perjungimas išjungiamas ir visada naudojamas bendrasis kelias. Fiksuoto bloko maršruto įjungimas pagerino galutinį dekodavimą 7,7 % prie 32 tūkst., 27,4 % prie 64 tūkst. ir 40,2 % prie 128 tūkst. tokenų.
Tolesnes optimizacijos ribos
Kai kurie pakeitimai pagerino atskirą operaciją, bet nepagerino galutinio išvedimo.
Spėjamasis dekodavimas, kuris naudoja mažesnį modelį tokenams pasiūlyti visam modeliui patvirtinti, padarė 1 paketo dekodavimą 18 % lėtesniu. Patvirtinimas apdorojo nuo dviejų iki penkių eilučių grupes – neefektyvią formą šiai aparatūrai, be to, eilutės dažnai pasirinkdavo skirtingus ekspertus, taip padidindamos nuskaitytų ekspertų svorių duomenų kiekį. Juodraščio kūrėjo išvesties žodyno sumažinimas pagerino jo pralaidumą 4,7–5,1 %, tačiau nepadarė viso spėjamojo ciklo greitesniu. Šis rezultatas priklauso nuo darbo krūvio: mūsų sugrupuotas „Qwen“ diegimas „Blackwell“ platformoje naudoja spėjamąjį dekodavimą kitomis sąlygomis.
Kiti eksperimentai apėmė GPU paleidimų skaičiaus mažinimą, viso fazių persidengimo užtikrinimą, didesnių išankstinio užpildymo plytelių naudojimą, platesnį suliejimą, maršrutizatoriaus pagreitinimą ir išvesties projekcijos sujungimą su tokeno parinkimu. Nė vienas iš jų nepagerino pilno išvedimo ciklo.
Aparatūros ribų matavimai taip pat parodė, kad pagrindinėse išankstinio užpildymo ir dekodavimo operacijose beveik neliko rezervo. MoE GEMM ir GEMV pasiekė atitinkamai 97,9 % ir 90,3 % greičiausio pastovaus svorių nuskaitymo greičio jų prieigos šablonams. Aritmetikos pašalinimas iš retos GEMV operacijos pralaidumą pakeitė tik 0,2 %, patvirtindamas, kad ribojantis išteklius buvo svorių nuskaitymas, o ne skaičiavimai. Išankstinio užpildymo matricos daugyba panašiai pasiekė 93 % teorinės matricos ribos atskirai ir 80–86 % testuojamų modelių viduje.
Galutinis našumas
Galutinis palyginimas įkelia identiškus 4 bitų kontrolinio taško baitus į abu variklius ir paleidžia po vieną užklausą vienu metu viename 40 branduolių, 128 GB „M5 Max“. Kiekvieno raundo metu abu varikliai veikia pakaitomis, siekiant sumažinti iškraipymus dėl foninės apkrovos ir lusto temperatūros pokyčių. Lyginame su greičiausiu „MLX-LM“ tiesioginio generavimo keliu, o ne jo serveriu, todėl matavimas orientuotas į modelio vykdymą, o ne į aptarnavimo pridėtines išlaidas.
Peržiūra apima dešimt užklausos ilgių išankstiniam užpildymui ir dešimt konteksto ilgių dekodavimui (nuo 256 iki 128 tūkst. tokenų). Išankstinio užpildymo pralaidumas iš pradžių auga, nes variklis paskirsto fiksuotas sąrankos išlaidas didesniam tokenų skaičiui. Išankstinis užpildymas pasiekia piką ties 4 tūkst. tokenų užklausos, o tada krenta, nes dešimt visapusiško dėmesio sluoksnių atlieka daugiau darbo augant užklausai. Dekodavimas išlieka beveik plokščias esant trumpam kontekstui ir sumažėja, kai augančios KV talpyklos nuskaitymas tampa reikšmingu. Pasirinktinis variklis yra greitesnis prie bet kurio užfiksuoto ilgio.
Kadangi specializuotas vykdymas gali pakeisti slankiojojo kablelio operacijų eiliškumą, mes taip pat patikrinome skaitinį nuoseklumą lyginant su „MLX-LM“. Mokytojo prievarta atlikto palyginimo metu abu varikliai nuspėjo kitą tokeną iš to paties etaloninio prefikso kiekvienoje iš 192 pozicijų, neleisdami ankstesniems skirtumams paveikti vėlesnių įvesčių. „Lily“ klaidinimo rodiklis (perplexity) buvo tik 0,04 % aukštesnis, ir ji pasirinko tą patį aukščiausią reitingą turintį tokeną 96,35 % ištestuotų pozicijų.

Sukurta vietinei platformai
„Apple silicon“ nėra mažesnis duomenų centro GPU. Tai pilnavertė vietinio išvedimo platforma su savais aparatinės ir programinės įrangos ypatumais. Bendroji atmintis suteikia vienam mazgui labai dideles galimybes talpinti modelį ir būseną. „M5 Neural Accelerators“ greitintuvai apdoroja tankios matricos darbą išankstinio užpildymo metu. Vektoriniai ALU valdo pralaidumo ribojamą, mažo pakartotinio naudojimo likutį dekodavimo metu.
„Qwen“ suteikia papildomų galimybių specializacijai: išlaikyti ekspertų maršrutizavimą ir pasikartojančią būseną GPU, pašalinti nereikalingus tarpinius rezultatus, daryti nepriklausomą darbą lygiagrečiai, pakartotinai naudoti bendrus KV duomenis ir pritaikyti branduolius prie darbo krūvio formos.
Atliekant modelio ir platformos specifinį optimizavimą, vienas „Mac“ kompiuteris gali efektyviai paleisti didelį retą modelį. Būsimas darbas išplės palaikymą tarp modelių, lustų ir aptarnavimo užduočių bei paverstims čia patvirtintus mechanizmus bendresne vykdymo aplinkos politika.
Platesnis principas yra pritaikyti variklį tiek prie modelio architektūros, tiek prie specifinių aparatūros skaičiavimo bei atminties kelių. Tobulėjant pažangiems atvirojo svorio modeliams ir aparatūrai, našus vietinis išvedimas vis labiau priklausys nuo variklių, pritaikytų abiem šiems aspektams, o ne nuo tokių, kurie abstrakčiai slepia jų skirtumus.