Conectează-te cu noi

Inteligența artificială

Cadrul de inferență Microsoft aduce modele de limbă mari pe 1 bit pentru dispozitivele locale

mm
Înțelegerea LLM-urilor pe 1 bit și a cadrului Microsoft BitNet.cpp

În octombrie 17, 2024, Microsoft a anunțat BitNet.cpp, un cadru de inferență conceput pentru a rula modele de limbaj mari (LLM) cuantificate pe 1 bit. BitNet.cpp este un progres semnificativ în Gen AI, permițând implementarea eficientă a LLM-urilor de 1 bit pe procesoare standard, fără a necesita GPU-uri scumpe. Această dezvoltare democratizează accesul la LLM, făcându-le disponibile pe o gamă largă de dispozitive și oferind noi posibilități în aplicațiile AI pe dispozitiv.

Înțelegerea modelelor de limbaj mari pe 1 bit

Modelele de limbaj mari (LLM) au necesitat în mod tradițional resurse de calcul semnificative datorită utilizării numerelor în virgulă mobilă de înaltă precizie (de obicei FP16 sau BF16) pentru greutățile modelului. Această necesitate a făcut ca implementarea LLM-urilor să fie costisitoare și consumatoare de energie.

În esență, LLM-urile pe 1 bit utilizează tehnici de cuantizare extremă pentru a reprezenta greutățile modelului folosind doar trei valori posibile: -1, 0 și 1, de unde termenul „1.58 biți” (deoarece necesită puțin mai mult de un bit pentru a codifica trei state).

Sistemul de greutate ternar

Conceptul

Cuantizarea pe 1 bit din BitNet.cpp este un sistem de greutate ternar. BitNet funcționează cu doar trei valori posibile pentru fiecare parametru:

  • -1 (negativ)
  • 0 (neutru)
  • 1 (pozitiv)

Acest lucru are ca rezultat o cerință de stocare de aproximativ 1.58 biți per parametru, de unde și numele BitNet b1.58. Această reducere drastică a lățimii de biți a parametrilor duce la o reducere impresionantă a utilizării memoriei și a complexității de calcul, deoarece majoritatea înmulțirilor în virgulă mobilă sunt înlocuite cu simple adunări și scăderi.

Fundamentul matematic

Cuantificarea pe 1 bit implică transformarea greutăților și activărilor în reprezentarea lor ternară prin următorii pași:

1. Binarizarea greutății

Binarizarea greutăților implică centralizarea lor în jurul mediei (α), rezultând o reprezentare ternară. Transformarea este exprimată matematic astfel:

Wf=Semna(W-α)

Unde:

  • W este matricea de greutate inițială.
  • α este media greutăților.
  • Semnează(x) Returnează +1 if x > 0 și -1 in caz contrar.

2. Cuantizare activare

Cuantificarea activărilor asigură că intrările sunt limitate la o lățime de biți specificată:

Unde:

  • Qb = 2(b−1)2^{(b-1)} este nivelul maxim de cuantizare pentru b-lățime de biți.
  • γ este valoarea maximă absolută a x (notat ca ∣∣x∣∣∞).
  • ε este un număr mic pentru a preveni depășirea în timpul calculelor.

3. Operație BitLinear

Stratul BitLinear înlocuiește înmulțirile tradiționale de matrice 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 cuantizare.

Această transformare permite calcule eficiente, păstrând în același timp performanța modelului.

Implicații de performanță

Eficiența memoriei

Sistemul de greutate ternară reduce semnificativ cerințele de memorie:

  • LLM-uri tradiționale: 16 biți pe greutate
  • BitNet.cpp: 1.58 biți pe greutate

Această reducere se traduce printr-o economie de memorie de aproximativ 90% comparativ cu modelele tradiționale pe 16 biți, permițând modelelor mai mari să se încadreze în aceleași constrângeri hardware.

Eficienţă energetică

Viteză de inferență, eficiență energetică (Apple M2)

 

Viteza de inferență: mai rapidă pe ambele procesoare

Viteză de inferență, eficiență energetică (i7-13700H)

1. Viteza de inferență: mai rapidă pe ambele procesoare

Viteza de inferență este reprezentat ca numărul de token-uri procesate pe secundă. Iată o defalcare a observațiilor:

  • Pe Apple M2 Ultra: BitNet.cpp realizează până la 5.07x accelerare pentru modele mai mari (30B) comparativ cu Llama.cpp, cu o viteză de vârf de 593.43 de jetoane pe secundă pentru un model 125M, care este a 1.37x accelerare. Pentru modelele mai mari, cum ar fi 3.8B și 7B, BitNet.cpp menține o viteză de peste 84.77 de jetoane pe secundă, arătându-și eficiența pe scară.
  • Pe Intel i7-13700H: BitNet.cpp realizează îmbunătățiri și mai dramatice ale vitezei. La dimensiunea modelului 7B, BitNet.cpp oferă un accelerare incredibilă de 5.68x comparativ cu Llama.cpp. Pentru modelele mai mici, cum ar fi 125M, procesează 389.08 de jetoane pe secundă, Care este 2.37x mai repede decât Llama.cpp.

2. Eficiență energetică: un schimbător de jocuri pentru dispozitivele Edge

Graficele furnizate includ și comparații ale costurilor energetice, care arată o reducere semnificativă a consumului de energie per token procesat:

  • Pe Apple M2 Ultra: Economiile de energie ale BitNet.cpp sunt substanțiale. Pentru modelul 700M consuma Cu 55.4% mai puțină energie pe token în comparație cu Llama.cpp, scăzând de la 0.314 la 0.140. Această tendință continuă pentru modelele mai mari, modelul 70B prezentând a Reducere cu 70.0% a consumului de energie.
  • Pe Intel i7-13700H: BitNet.cpp livrează 71.9% economii de energie pentru modelul 700M, cu consumul în scădere de la 1.367 la 0.384. Deși datele de energie pentru modelul 70B din Llama.cpp nu sunt disponibile, BitNet.cpp rămâne eficient, cu consumul de energie la 17.33 pentru modelul 70B.

3. Depășirea standardului de viteză de citire umană

Una dintre cele mai interesante perspective din aceste grafice este referirea la viteza de citire a omului, marcat la 5-7 jetoane pe secundă. Această linie roșie arată că ambele implementări, în special BitNet.cpp, pot depăși confortabil vitezele de citire umane chiar și pentru cele mai mari modele:

  • On Apple M2 Ultra, BitNet.cpp depășește viteza de citire umană pentru toate dimensiunile de model, cea mai mică viteză fiind 8.67 de jetoane pe secundă pentru un model 70B.
  • On Intel i7-13700H, modelul 100B încă realizează 1.70 de jetoane pe secundă, aproape atingând intervalul inferior al vitezei de citire a omului, în timp ce toate modelele mai mici depășesc acest punct de referință.

Considerații de instruire

Estimator direct (STE)

Deoarece cuantizarea pe 1 bit introduce funcții nediferențiabile, antrenamentul implică o tehnică specializată cunoscută sub numele de Estimator direct (STE). În această abordare, gradienții curg nealterați prin puncte nediferențiabile. 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

Antrenament mixt de precizie

Pentru a menține stabilitatea în timpul antrenamentului, precizie mixtă este angajat:

  • Greutăți și activări: Cuantizat la precizie de 1 bit.
  • Gradienți și stări de optimizare: Stocat cu o precizie mai mare.
  • Greutăți latente: Menținut cu precizie ridicată pentru a facilita actualizările precise în timpul antrenamentului.

Strategie pentru rata mare de învățare

O provocare unică cu modelele pe 1 bit este că actualizările mici ar putea să nu afecteze ponderile binarizate. Pentru a atenua acest lucru, rata de învățare este crescută, asigurând o convergență mai rapidă și o optimizare mai bună în comparație cu abordările tradiționale.

Cuantizare și normalizare de grup

BitNet.cpp prezintă Cuantizare și normalizare de grup pentru a spori paralelismul modelului. În loc să calculeze parametrii pentru întreaga matrice de greutate, BitNet împarte greutățile și activările în mai multe grupuri (G).

Această grupare permite procesarea paralelă eficientă fără comunicare suplimentară între grupuri, permițând antrenamentul și inferența modelelor la scară largă.

Note de implementare și optimizări

Optimizarea CPU

BitNet.cpp folosește mai multe optimizări de nivel scăzut pentru a atinge performanța maximă a CPU:

  • Operații vectorizate: Utilizează instrucțiuni SIMD pentru a efectua eficient manipulări de biți.
  • Acces la memorie cache-friendly: Structurează datele pentru a minimiza pierderile de cache.
  • Procesare paralelă: Distribuie eficient sarcina de lucru pe mai multe nuclee CPU.

Iată un exemplu de funcție cheie care implementează cuantizarea și inferența în BitNet:

 
def bitlinear_forward(input, weight, scale):
    # Quantize the input using absmax quantization
    input_q = quantize(input)
    
    # Perform binary matrix multiplication
    output = binary_matmul(input_q, weight)
    
    # Scale the output to match the original precision
    return output * scale

def quantize(x):
    # Perform absmax quantization
    scale = torch.max(torch.abs(x))
    return torch.clamp(x / scale, -1, 1) * scale

Modele acceptate

Versiunea actuală a BitNet.cpp acceptă următoarele LLM-uri pe 1 bit disponibile pe Hugging Face:

  • bitnet_b1_58-large (parametri 0.7B)
  • bitnet_b1_58-3B (parametri 3.3B)
  • Llama3-8B-1.58-100B-jetoane (parametri 8.0B)

Aceste modele sunt disponibile public pentru a demonstra capabilitățile de inferență ale cadrului. Deși nu au fost instruiți sau eliberați oficial de Microsoft, ele ilustrează versatilitatea cadrului.

Ghid de instalare

Pentru a începe cu BitNet.cpp, urmați pașii de mai jos:

Cerințe preliminare

  1. Piton > = 3.9
  2. CMake > = 3.22
  3. Zăngăni > = 18
  4. Conda (foarte recomandat)

Pentru ferestre din utilizatorilor, Visual Studio ar trebui să fie instalat cu următoarele componente activate:

  • Dezvoltare desktop cu C++
  • Instrumente C++-CMake pentru Windows
  • Git pentru Windows
  • C++-Clang Compiler pentru Windows
  • Suport MS-Build pentru setul de instrumente LLVM (Clang)

Pentru Debian / Ubuntu utilizatorilor, este disponibil un script de instalare automată:

bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"

Instalare pas cu pas

  1. Clonează depozitul:
    git clone --recursive https://github.com/microsoft/BitNet.git

    cd BitNet
  2. Instalați dependențele:
    # Create a new Conda environment (recommended)
    conda create -n bitnet-cpp python=3.9
    conda activate bitnet-cpp


    pip install -r requirements.txt
  3. Construiți și pregătiți proiectul: Puteți descărca un model direct din Hugging Face și îl puteți converti într-un format cuantificat:
    python setup_env.py --hf-repo HF1BitLLM/Llama3-8B-1.58-100B-tokens -q i2_s

    Alternativ, descărcați și convertiți manual modelul:

    huggingface-cli download HF1BitLLM/Llama3-8B-1.58-100B-tokens --local-dir models/Llama3-8B-1.58-100B-tokens

    python setup_env.py -md models/Llama3-8B-1.58-100B-tokens -q i2_s

Rularea inferenței cu BitNet.cpp

Pentru a rula inferența folosind cadrul, utilizați următoarea comandă:

python run_inference.py -m models/Llama3-8B-1.58-100B-tokens/ggml-model-i2_s.gguf -p "Sandra journeyed to the kitchen. Where is Sandra?" -n 6 -temp 0.7

Explicaţie:

  • -m specifică calea fișierului model.
  • -p definește textul prompt.
  • -n stabilește numărul de jetoane de prezis.
  • -temp ajustează aleatoritatea eșantionării (temperatura) în timpul inferenței.

Exemplu de ieșire

Sandra journeyed to the kitchen. Where is Sandra?

Answer: Sandra is in the kitchen.

Detalii tehnice ale BitNet.cpp

Stratul BitLinear

BitNet.cpp implementează o arhitectură Transformer modificată, înlocuind înmulțirile matrice standard cu BitLinear operațiuni. Această abordare centralizează ponderile la zero înainte de cuantificare și le scalează pentru a reduce erorile de aproximare. Funcția de transformare cheie arată astfel:

# Binarization function for 1-bit weights
def binarize_weights(W):
    alpha = W.mean()
    W_binarized = np.sign(W - alpha)
    return W_binarized

Combinația dintre ponderi centralizate și scalare asigură că eroarea de cuantizare rămâne minimă, păstrând astfel performanța.

Impactul industriei

BitNet.cpp ar putea avea implicații de amploare pentru implementarea LLM-urilor:

  • Accesibilitate: Permite LLM să ruleze pe dispozitive standard, democratizând accesul la IA puternică.
  • Cost-eficiență: Reduce nevoia de GPU-uri scumpe, reducând bariera pentru adoptare.
  • Eficienţă energetică: Economisește energie utilizând inferența standard bazată pe CPU.
  • Inovație: Deschide noi posibilități pentru AI pe dispozitiv, cum ar fi traducerea în timp real a limbii, asistenții vocali și aplicațiile axate pe confidențialitate fără dependențe de cloud.

Provocări și direcții viitoare

În timp ce LLM-urile pe 1 bit sunt promițătoare, rămân mai multe provocări. Acestea includ dezvoltarea de modele robuste pe 1 bit pentru diverse sarcini, optimizarea hardware-ului pentru calculul pe 1 bit și încurajarea dezvoltatorilor să adopte această nouă paradigmă. În plus, explorarea cuantizării pe 1 bit pentru viziune computerizată sau sarcini audio reprezintă o direcție viitoare interesantă.

Concluzie

Lansarea BitNet.cpp de către Microsoft este un progres semnificativ. Permițând inferența eficientă pe 1 bit pe procesoarele standard, BitNet.cpp creează accesibilitatea și sustenabilitatea AI. Acest cadru pregătește scena pentru LLM-uri mai portabile și mai rentabile, promovând ceea ce este posibil cu AI pe dispozitiv.

Mi-am petrecut ultimii cinci ani scufundându-mă în lumea fascinantă a învățării automate și a învățării profunde. Pasiunea și expertiza mea m-au determinat să contribui la peste 50 de proiecte diverse de inginerie software, cu un accent deosebit pe AI/ML. Curiozitatea mea continuă m-a atras și către Procesarea limbajului natural, un domeniu pe care sunt dornic să îl explorez în continuare.