Modele și platforme AI

Cadru de inferență Microsoft aduce modelele de limbaj mari de 1 bit pe dispozitive locale

mm
Adaugă Unite.AI la sursele tale preferate pe Google

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.

Eficiență energetică

Viteză de inferență, eficiență energetică (Apple [securities_stock_price_tag symbol="AAPL" exchange="NASDAQ"] M2)

 

Viteză de inferență: Mai rapidă pe ambele procesoare

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

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 (INTC ) 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:

def bitlinear_forward(input, weight, scale):
# Cuantifică intrarea utilizÃĒnd cuantificarea absmax
input_q = quantize(input)

# Realizează multiplicarea matricială binară
output = binary_matmul(input_q, weight)

# Scalează ieșirea pentru a se potrivi cu precizia originală
return output * scale

def quantize(x):
# Realizează cuantificarea absmax
scale = torch.max(torch.abs(x))
return torch.clamp(x / scale, -1, 1) * scale
[/code]

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

  1. Python >= 3.9
  2. CMake >= 3.22
  3. Clang >= 18
  4. 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ă:

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

Instalare pas cu pas

  1. Clonați depozitul:
    git clone --recursive https://github.com/microsoft/BitNet.git

    cd BitNet
  2. Instalați dependențele:
    # Creați un mediu Conda nou (recomandat)
    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 direct un model de pe Hugging Face și să-l convertiți ÃŪntr-un format cuantificat:
    python setup_env.py --hf-repo HF1BitLLM/Llama3-8B-1.58-100B-tokens -q i2_s

    Alternativ, puteți descărca și converti 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 utilizÃĒnd cadrul, folosiți următoarea comandă:

python run_inference.py -m models/Llama3-8B-1.58-100B-tokens/ggml-model-i2_s.gguf -p "Sandra a călătorit ÃŪn bucătărie. Unde este Sandra?" -n 6 -temp 0.7

Explicație:

  • -m specifică calea fișierului model.
  • -p definește textul de intrare.
  • -n setează numărul de tokeni de prezis.
  • -temp ajustează aleatoritatea de eșantionare (temperatura) ÃŪn timpul inferenței.

Exemplu de ieșire

Sandra a călătorit ÃŪn bucătărie. Unde este Sandra?

Răspuns: Sandra este ÃŪn bucătărie.

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.

Am petrecut ultimii cinci ani scufundÃĒndu-mă ÃŪn lumea fascinantă a Machine Learning și Deep Learning. Pasinea și expertiza mea m-au condus să contribui la peste 50 de proiecte diverse de inginerie software, cu un focus deosebit pe AI/ML. Curiozitatea mea ÃŪn continuare m-a atras și spre Natural Language Processing, un domeniu pe care sunt dornic să ÃŪl explorez mai departe.