Modele și platforme AI
Cadru de inferență Microsoft aduce modelele de limbaj mari de 1 bit pe dispozitive locale
Pe 17 octombrie 2024, Microsoft a anunțat BitNet.cpp (MSFT ), un cadru de inferență proiectat pentru a rula modele de limbaj mari cuantificate la 1 bit. BitNet.cpp reprezintă o progres semnificativ în Gen AI, permițând implementarea eficientă a modelelor de limbaj mari de 1 bit pe procesoare standard, fără a necesita GPU-uri scumpe. Acest lucru democratizează accesul la modelele de limbaj mari, făcându-le disponibile pe o gamă largă de dispozitive și oferind noi posibilități în aplicațiile de inteligență artificială pe dispozitive.
Înțelegerea modelelor de limbaj mari de 1 bit
Modelele de limbaj mari (LLM) au necesitat în mod tradițional resurse computaționale semnificative din cauza utilizării numerelor cu virgulă mobilă de înaltă precizie (în general FP16 sau BF16) pentru greutățile modelului. Această necesitate a făcut implementarea modelelor de limbaj mari scumpă și consumatoare de energie.
În esență, modelele de limbaj mari de 1 bit utilizează tehnici de cuantificare extremă pentru a reprezenta greutățile modelului utilizând numai trei valori posibile: -1, 0 și 1, de unde și termenul de “1,58 bit” (deoarece necesită puțin mai mult de un bit pentru a codifica trei stări).
Sistemul de greutăți ternar
Conceptul
Cuantificarea la 1 bit în BitNet.cpp este un sistem de greutăți ternar. BitNet funcționează cu numai trei valori posibile pentru fiecare parametru:
- -1 (negativ)
- 0 (neutru)
- 1 (pozitiv)
Acest lucru duce la o cerință de stocare de aproximativ 1,58 biți pe parametru, de unde și numele BitNet b1.58. Reducerea drastică a lățimii bitului parametrului conduce la o reducere impresionantă a utilizării memoriei și a complexității computaționale, deoarece majoritatea multiplicărilor cu virgulă mobilă sunt înlocuite cu simple adunări și scăderi.
Baza matematică
Cuantificarea la 1 bit implică transformarea greutăților și a activărilor în reprezentarea lor ternară prin următorii pași:
1. Cuantificarea greutăților
Cuantificarea greutăților implică centralizarea lor în jurul mediei (α), rezultând o reprezentare ternară. Transformarea este exprimată matematic astfel:
Wf=Sign(W−α)
Unde:
- W este matricea de greutăți originală.
- α este media greutăților.
- Sign(x) returnează +1 dacă x > 0 și -1 în caz contrar.
2. Cuantificarea activărilor
Cuantificarea activărilor asigură că intrările sunt limitate la o lățime de bit specificată:
x^e=Quant(x)=Clip(γx×Qb,−Qb+ϵ,Qb−ϵ)
Unde:
- Qb = 2(b−1)2^{(b-1)} este nivelul maxim de cuantificare pentru lățimea de b biți.
- γ este valoarea absolută maximă a lui x (notată cu ∣∣x∣∣∞).
- ε este un număr mic pentru a preveni depășirea în timpul calculelor.
3. Operația BitLinear
Stratul BitLinear înlocuiește multiplicările matriciale tradiționale cu o operație simplificată:
y=Wf×x^e×(Qbβγ)
Unde:
- β este un factor de scalare utilizat pentru a minimiza erorile de aproximare.
- γ scalează activările.
- Q_b este factorul de cuantificare.
Această transformare permite calcule eficiente, păstrând în același timp performanța modelului.
Implicații de performanță
Eficiență de memorie
Sistemul de greutăți ternar reduce semnificativ cerințele de memorie:
- Modelele de limbaj mari tradiționale: 16 biți pe greutate
- BitNet.cpp: 1,58 biți pe greutate
Această reducere se traduce într-o economie de aproximativ 90% a memoriei comparativ cu modelele tradiționale de 16 biți, permițând modele mai mari să se încadreze în aceleași constrângeri de hardware.
1. Viteză de inferență: Mai rapidă pe ambele procesoare
Viteza de inferență este reprezentată ca numărul de tokeni procesați pe secundă. Iată o descriere a observațiilor:
- Pe Apple M2 Ultra: BitNet.cpp atinge până la 5,07x viteza pentru modele mai mari (30B) comparativ cu Llama.cpp, cu o viteză maximă de 593,43 tokeni pe secundă pentru un model de 125M, ceea ce reprezintă o 1,37x viteză. Pentru modele mai mari, cum ar fi cele de 3,8B și 7B, BitNet.cpp menține o viteză de peste 84,77 tokeni pe secundă, demonstrând eficiența sa la scară largă.
- Pe Intel i7-13700H: BitNet.cpp atinge îmbunătățiri și mai dramatice ale vitezei. La dimensiunea modelului de 7B, BitNet.cpp oferă o creștere incredibilă de 5,68x a vitezei comparativ cu Llama.cpp. Pentru modele mai mici, cum ar fi cel de 125M, procesează 389,08 tokeni pe secundă, ceea ce reprezintă o 2,37x viteză mai mare decât Llama.cpp.
2. Eficiență energetică: Un joc schimbat pentru dispozitivele de margine
Graficele furnizate includ, de asemenea, comparații de costuri energetice, care arată o reducere semnificativă a consumului de energie pe token procesat:
- Pe Apple M2 Ultra: Economia de energie a BitNet.cpp este substanțială. Pentru modelul de 700M, consumă 55,4% mai puțină energie pe token comparativ cu Llama.cpp, scăzând de la 0,314 la 0,140. Această tendință continuă pentru modele mai mari, modelul de 70B arătând o reducere de 70,0% a consumului de energie.
- Pe Intel i7-13700H: BitNet.cpp oferă 71,9% economie de energie pentru modelul de 700M, consumul scăzând de la 1,367 la 0,384. Deși datele despre consumul de energie pentru modelul de 70B în Llama.cpp nu sunt disponibile, BitNet.cpp rămâne eficient, cu un consum de energie de 17,33 pentru modelul de 70B.
3. Depășirea baremului de citire umană
Una dintre cele mai interesante observații din aceste grafice este referirea la viteza de citire umană, marcată la 5-7 tokeni pe secundă. Această linie roșie arată că ambele implementări, în special BitNet.cpp, pot depăși cu ușurință viteza de citire umană chiar și pentru cele mai mari modele:
- Pe Apple M2 Ultra, BitNet.cpp depășește viteza de citire umană pentru toate dimensiunile modelului, cea mai mică viteză fiind de 8,67 tokeni pe secundă pentru un model de 70B.
- Pe Intel i7-13700H, modelul de 100B atinge încă 1,70 tokeni pe secundă, aproape atingând gama inferioară a vitezei de citire umană, în timp ce toate modelele mai mici depășesc acest barem.
Considerații de antrenare
Estimatorul Straight-Through (STE)
Deoarece cuantificarea la 1 bit introduce funcții nediferențiate, antrenarea implică o tehnică specializată cunoscută sub numele de Estimatorul Straight-Through (STE). În această abordare, gradientul curge nemodificat prin punctele nediferențiate. Iată o implementare simplificată în Python:
class StraightThroughEstimator(Function): @staticmethod def forward(ctx, input): return input.sign() @staticmethod def backward(ctx, grad_output): return grad_output
Antrenarea cu precizie mixtă
Pentru a menține stabilitatea în timpul antrenării, se utilizează precizie mixtă:
- Greutăți și activări: Cuantificate la precizie de 1 bit.
- Gradient și stări ale optimizatorului: Stocate într-o precizie mai mare.
- Greutăți latente: Menținute într-o precizie ridicată pentru a facilita actualizări precise în timpul antrenării.
Strategia de rată de învățare mare
O provocare unică cu modelele de 1 bit este aceea că actualizările mici nu pot afecta greutățile binarizate. Pentru a contracara acest lucru, rata de învățare este crescută, asigurând o convergență mai rapidă și o optimizare mai bună comparativ cu abordările tradiționale.
Cuantificarea și normalizarea grupului
BitNet.cpp introduce cuantificarea și normalizarea grupului pentru a îmbunătăți paralelismul modelului. În loc de calcularea parametrilor pentru întreaga matrice de greutăți, BitNet împarte greutățile și activările în multiple grupuri (G).
Acest grupare permite procesarea paralelă eficientă fără comunicare suplimentară între grupuri, permițând antrenarea și inferența modelului la scară largă.
Note de implementare și optimizări
Optimizarea CPU
BitNet.cpp utilizează mai multe optimizări de nivel scăzut pentru a atinge performanța maximă a CPU:
- Operații vectorizate: Utilizează instrucțiuni SIMD pentru manipularea eficientă a biților.
- Acces la memorie prietenos cu cache-ul: Structurează datele pentru a minimiza ratele de eroare ale cache-ului.
- Procesare paralelă: Distribuie sarcina de lucru eficient pe multiple nuclee CPU.
Iată un exemplu de funcție cheie care implementează cuantificarea și inferența în BitNet:
Modele suportate
Lansarea curentă a BitNet.cpp suportă următoarele modele de limbaj mari de 1 bit disponibile pe Hugging Face:
- bitnet_b1_58-large (0,7 miliarde de parametri)
- bitnet_b1_58-3B (3,3 miliarde de parametri)
- Llama3-8B-1.58-100B-tokens (8,0 miliarde de parametri)
Aceste modele sunt disponibile public pentru a demonstra capacitățile de inferență ale cadrului. Deși nu au fost antrenate sau lansate oficial de Microsoft, ele ilustrează versatilitatea cadrului.
Ghid de instalare
Pentru a începe cu BitNet.cpp, urmați pașii de mai jos:
Precondiții
- Python >= 3.9
- CMake >= 3.22
- Clang >= 18
- Conda (recomandat)
Pentru utilizatorii Windows, Visual Studio ar trebui să fie instalat cu următoarele componente activate:
- Dezvoltare de birou cu C++
- Unelte C++-CMake pentru Windows
- Git pentru Windows
- Compilator C++-Clang pentru Windows
- Suport MS-Build pentru setul de instrumente LLVM (Clang)
Pentru utilizatorii Debian/Ubuntu, este disponibil un script de instalare automată:
Instalare pas cu pas
- Clonați depozitul:
- Instalați dependențele:
- Construiți și pregătiți proiectul: Puteți descărca direct un model de pe Hugging Face și să-l convertiți într-un format cuantificat:
Alternativ, puteți descărca și converti manual modelul:
Rularea inferenței cu BitNet.cpp
Pentru a rula inferența utilizând cadrul, folosiți următoarea comandă:
Explicație:
-mspecifică calea fișierului model.-pdefinește textul de intrare.-nsetează numărul de tokeni de prezis.-tempajustează aleatoritatea de eșantionare (temperatura) în timpul inferenței.
Exemplu de ieșire
Detalii tehnice ale BitNet.cpp
Stratul BitLinear
BitNet.cpp implementează o arhitectură Transformer modificată, înlocuind multiplicările matriciale standard cu operații BitLinear. Această abordare centralizează greutățile spre zero înainte de cuantificare și le scalează pentru a reduce erorile de aproximare. Funcția de transformare cheie arată astfel:
# Funcție de binarizare pentru greutăți de 1 bit def binarize_weights(W): alpha = W.mean() W_binarized = np.sign(W - alpha) return W_binarized
Combinația greutăților centralizate și a scalării asigură că eroarea de cuantificare rămâne minimă, păstrând astfel performanța.
Impactul în industrie
BitNet.cpp ar putea avea implicații de anvergură pentru implementarea modelelor de limbaj mari:
- Accesibilitate: Permite modelelor de limbaj mari să ruleze pe dispozitive standard, democratizând accesul la inteligența artificială puternică.
- Eficiență costală: Reduce nevoia de GPU-uri scumpe, micșorând bariera pentru adoptare.
- Eficiență energetică: Economisește energie prin utilizarea inferenței pe bază de CPU.
- Inovație: Deschide noi posibilități pentru aplicațiile de inteligență artificială pe dispozitive, cum ar fi traducerea în timp real, asistenți vocali și aplicații cu focus pe confidențialitate fără dependențe de cloud.
Provocări și direcții viitoare
Deși modelele de limbaj mari de 1 bit oferă perspective promițătoare, mai există provocări. Acestea includ dezvoltarea de modele robuste de 1 bit pentru diverse sarcini, optimizarea hardware-ului pentru computația de 1 bit și încurajarea dezvoltatorilor să adopte acest nou paradigma. Explorarea cuantificării de 1 bit pentru sarcini de vedere de computer sau audio reprezintă o direcție viitoare interesantă.
Concluzie
Lansarea BitNet.cpp de către Microsoft reprezintă o avansare semnificativă. Prin permiterea inferenței eficiente de 1 bit pe procesoare standard, BitNet.cpp creează accesibilitatea și durabilitatea inteligenței artificiale. Acest cadru stabilește scena pentru modele de limbaj mari mai portabile și mai rentabile, împingând ceea ce este posibil cu inteligența artificială pe dispozitive.














