Modele i platformy AI

Ramowy framework Microsoft umożliwia uruchamianie 1-bitowych dużych modeli językowych na urządzeniach lokalnych

mm
Dodaj Unite.AI do preferowanych źródeł w Google

17 października 2024 r. Microsoft (MSFT ) ogłosił BitNet.cpp, framework inferencyjny zaprojektowany do uruchamiania 1-bitowych modeli językowych (LLM). BitNet.cpp to znaczący postęp w dziedzinie sztucznej inteligencji, umożliwiający wydajne wdrożenie 1-bitowych LLM na standardowych procesorach, bez konieczności korzystania z drogich kart graficznych. To rozwiązanie demokratyzuje dostęp do LLM, umożliwiając ich uruchamianie na szerokim zakresie urządzeń i dając nowe możliwości w aplikacjach sztucznej inteligencji na urządzeniach.

Poznanie 1-bitowych dużych modeli językowych

Duże modele językowe (LLM) tradycyjnie wymagały znaczących zasobów obliczeniowych ze względu na wykorzystywanie liczb zmiennoprzecinkowych o wysokiej precyzji (zazwyczaj FP16 lub BF16) dla wag modelu. To wymaganie sprawiło, że wdrożenie LLM było drogie i energochłonne.

W swojej istocie 1-bitowe LLM wykorzystują ekstremalne techniki kwantyzacji do reprezentowania wag modelu przy użyciu tylko trzech możliwych wartości: -1, 0 i 1, stąd nazwa “1,58-bit” (ponieważ wymaga nieco ponad jeden bit do zakodowania trzech stanów).

System wag trójwartościowych

Pojęcie

Kwantyzacja 1-bitowa w BitNet.cpp jest systemem wag trójwartościowych. BitNet operuje tylko trzema możliwymi wartościami dla każdego parametru:

  • -1 (ujemna)
  • 0 (neutralna)
  • 1 (dodatnia)

To powoduje, że wymagania dotyczące pamięci wynoszą około 1,58 bita na parametr, stąd nazwa BitNet b1,58. To drastyczne zmniejszenie szerokości bitowej parametrów prowadzi do imponującego zmniejszenia zużycia pamięci i złożoności obliczeniowej, ponieważ większość mnożeń zmiennoprzecinkowych zastępowana jest prostymi dodawaniem i odejmowaniem.

Podstawy matematyczne

Kwantyzacja 1-bitowa obejmuje transformację wag i aktywacji w ich trójwartościową reprezentację za pomocą następujących kroków:

1. Binarzacja wag

Binarzacja wag polega na ich centralizacji wokół średniej (α), co prowadzi do trójwartościowej reprezentacji. Transformacja jest matematycznie wyrażona jako:

Wf​=Sign(W−α)

Gdzie:

  • W to oryginalna macierz wag.
  • α to średnia wag.
  • Sign(x) zwraca +1, jeśli x > 0 i -1 w przeciwnym przypadku.

2. Kwantyzacja aktywacji

Kwantyzacja aktywacji zapewnia, że dane wejściowe są ograniczone do określonej szerokości bitowej:

x^e​=Quant(x)=Clip(γx×Qb​​,−Qb​+ϵ,Qb​−ϵ)

Gdzie:

  • Qb = 2(b−1)2^{(b-1)} jest maksymalnym poziomem kwantyzacji dla b-bitowej szerokości.
  • γ jest maksymalną wartością bezwzględną x (oznaczoną jako ∣∣x∣∣∞).
  • ε jest małą liczbą, która zapobiega przepełnieniu podczas obliczeń.

3. Operacja BitLinear

Warstwa BitLinear zastępuje tradycyjne mnożenia macierzy uproszczoną operacją:

y=Wf​×x^e​×(Qb​βγ​)

Gdzie:

  • β jest czynnikiem skalującym, który minimalizuje błędy aproksymacji.
  • γ skaluje aktywacje.
  • Q_b jest czynnikiem kwantyzacji.

Ta transformacja umożliwia wydajne obliczenia, zachowując przy tym wydajność modelu.

Wnioski dotyczące wydajności

Wydajność pamięci

System wag trójwartościowych znacznie redukuje wymagania dotyczące pamięci:

  • Tradycyjne LLM: 16 bitów na wagę
  • BitNet.cpp: 1,58 bita na wagę

To zmniejszenie przekłada się na oszczędność pamięci rzędu 90% w porównaniu z tradycyjnymi modelami 16-bitowymi, co pozwala na umieszczenie większych modeli w ramach tych samych ograniczeń sprzętowych.

Energia

Prędkość inferencji, energia (Apple M2)

 

Prędkość inferencji: Szybciej na obu procesorach

Prędkość inferencji, energia (i7-13700H)

1. Prędkość inferencji: Szybciej na obu procesorach

Prędkość inferencji jest reprezentowana jako liczba tokenów przetwarzanych na sekundę. Oto podsumowanie obserwacji:

  • Na Apple M2 Ultra: BitNet.cpp osiąga nawet 5,07-krotny wzrost prędkości dla większych modeli (30B) w porównaniu z Llama.cpp, z maksymalną prędkością 593,43 tokenów na sekundę dla modelu 125M, co stanowi 1,37-krotny wzrost prędkości. Dla większych modeli, takich jak 3,8B i 7B, BitNet.cpp utrzymuje prędkość powyżej 84,77 tokenów na sekundę, pokazując swoją wydajność na różnych skalach.
  • Na Intel i7-13700H: BitNet.cpp osiąga jeszcze bardziej dramatyczne wzrosty prędkości. Dla modelu 7B BitNet.cpp dostarcza 5,68-krotny wzrost prędkości w porównaniu z Llama.cpp. Dla mniejszych modeli, takich jak 125M, przetwarza 389,08 tokenów na sekundę, co jest 2,37-krotnym wzrostem prędkości w porównaniu z Llama.cpp.

2. Energia: Grająca rolę w urządzeniach brzegowych

Podane wykresy obejmują również porównania kosztów energetycznych, które pokazują znaczne zmniejszenie zużycia energii na token:

  • Na Apple M2 Ultra: BitNet.cpp oferuje znaczne oszczędności energii. Dla modelu 700M zużywa 55,4% mniej energii na token w porównaniu z Llama.cpp, spadając z 0,314 do 0,140. Ten trend kontynuuje się dla większych modeli, a model 70B pokazuje 70,0% redukcję zużycia energii.
  • Na Intel i7-13700H: BitNet.cpp dostarcza 71,9% oszczędności energii dla modelu 700M, z zużyciem spadającym z 1,367 do 0,384. Chociaż dane dotyczące energii dla modelu 70B w Llama.cpp są niedostępne, BitNet.cpp pozostaje wydajny, z zużyciem energii na poziomie 17,33 dla modelu 70B.

3. Przekroczenie benchmarku prędkości czytania ludzi

Jednym z najbardziej interesujących spostrzeżeń z tych wykresów jest odniesienie do prędkości czytania ludzi, oznaczonej na 5-7 tokenów na sekundę. Ta czerwona linia pokazuje, że oba wdrożenia, szczególnie BitNet.cpp, mogą komfortowo przekroczyć prędkość czytania ludzi nawet dla największych modeli:

  • Na Apple M2 Ultra: BitNet.cpp przekracza prędkość czytania ludzi dla wszystkich rozmiarów modeli, z najniższą prędkością 8,67 tokenów na sekundę dla modelu 70B.
  • Na Intel i7-13700H: model 100B osiąga 1,70 tokena na sekundę, prawie dotykając dolnego zakresu prędkości czytania ludzi, podczas gdy wszystkie mniejsze modele przekraczają ten benchmark.

Uwagi dotyczące szkolenia

Estymator prosty (STE)

Ponieważ kwantyzacja 1-bitowa wprowadza niediferencjalne funkcje, szkolenie obejmuje specjalistyczną technikę zwaną Estymatorem prostym (STE). W tym podejściu gradienty płyną niezmienione przez punkty niediferencjalne. Oto uproszczona implementacja w Pythonie:

class StraightThroughEstimator(Function):
@staticmethod
def forward(ctx, input):
return input.sign()

@staticmethod
def backward(ctx, grad_output):
return grad_output

Szkolenie o mieszanej precyzji

Aby utrzymać stabilność podczas szkolenia, mieszana precyzja jest zastosowana:

  • Wagi i aktywacje: Zkwantyzowane do precyzji 1-bitowej.
  • Gradienty i stany optymalizatora: Przechowywane w wyższej precyzji.
  • Wagi ukryte: Utrzymywane w wysokiej precyzji w celu zapewnienia dokładnych aktualizacji podczas szkolenia.

Strategia dużej stopy uczenia

Jednym z unikalnych wyzwań w przypadku modeli 1-bitowych jest to, że małe aktualizacje mogą nie wpływać na zbinaryzowane wagi. Aby temu przeciwdziałać, zwiększa się stopę uczenia, co zapewnia szybsze zbieżność i lepszą optymalizację w porównaniu z tradycyjnymi podejściami.

Kwantyzacja i normalizacja grupowa

BitNet.cpp wprowadza kwantyzację i normalizację grupową w celu zwiększenia równoległości modelu. Zamiast obliczania parametrów dla całej macierzy wag, BitNet dzieli wagi i aktywacje na wiele grup (G).

To grupowanie umożliwia wydajne przetwarzanie równoległe bez dodatkowej komunikacji międzygrupowej, co pozwala na szkolenie i inferencję dużych modeli.

Uwagi dotyczące implementacji i optymalizacji

Optymalizacja procesora

BitNet.cpp wykorzystuje kilka niskopoziomowych optymalizacji, aby osiągnąć maksymalną wydajność procesora:

  • Operacje wektorowe: Wykorzystuje instrukcje SIMD do efektywnego manipulowania bitami.
  • Dostęp do pamięci przyjazny dla cache: Organizuje dane w celu minimalizacji niepowodzeń cache.
  • Przetwarzanie równoległe: Rozdziela obciążenie na wiele rdzeni procesora.

Oto przykład kluczowej funkcji, która implementuje kwantyzację i inferencję w BitNet:

def bitlinear_forward(input, weight, scale):
# Zkwantyzuj dane wejściowe przy użyciu kwantyzacji absmax
input_q = quantize(input)

# Wykonaj mnożenie macierzy binarnej
output = binary_matmul(input_q, weight)

# Skaluj wyjście, aby dopasować oryginalną precyzję
return output * scale

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

Obsługiwane modele

Aktualna wersja BitNet.cpp obsługuje następujące 1-bitowe LLM dostępne na Hugging Face:

  • bitnet_b1_58-large (0,7 mld parametrów)
  • bitnet_b1_58-3B (3,3 mld parametrów)
  • Llama3-8B-1.58-100B-tokens (8,0 mld parametrów)

Te modele są publicznie dostępne, aby zademonstrować możliwości inferencyjne frameworka. Chociaż nie zostały oficjalnie przeszkolone ani wydane przez Microsoft, ilustrują wszechstronność frameworka.

Przewodnik instalacji

Aby rozpocząć pracę z BitNet.cpp, postępuj zgodnie z poniższymi krokami:

Wymagania wstępne

  1. Python >= 3.9
  2. CMake >= 3.22
  3. Clang >= 18
  4. Conda (bardzo zalecane)

Dla użytkowników systemu Windows zalecane jest zainstalowanie Visual Studio z następującymi składnikami:

  • Desktop Development with C++
  • C++-CMake Tools for Windows
  • Git for Windows
  • C++-Clang Compiler for Windows
  • MS-Build Support for LLVM Toolset (Clang)

Dla użytkowników Debian/Ubuntu dostępny jest skrypt instalacji automatycznej:

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

Krok po kroku instalacji

  1. Klonuj repozytorium:
    git clone --recursive https://github.com/microsoft/BitNet.git

    cd BitNet
  2. Zainstaluj zależności:
    # Utwórz nowe środowisko Conda (zalecane)
    conda create -n bitnet-cpp python=3.9
    conda activate bitnet-cpp


    pip install -r requirements.txt
  3. Zbuduj i przygotuj projekt: Możesz pobrać model bezpośrednio z Hugging Face i przekonwertować go do formatu zkwantyzowanego:
    python setup_env.py --hf-repo HF1BitLLM/Llama3-8B-1.58-100B-tokens -q i2_s

    Alternatywnie, pobierz i przekonwertuj model ręcznie:

    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

Uruchamianie inferencji z BitNet.cpp

Aby uruchomić inferencję przy użyciu frameworka, użyj następującej komendy:

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

Wyjaśnienie:

  • -m określa ścieżkę pliku modelu.
  • -p definiuje tekst wprowadzania.
  • -n ustawia liczbę tokenów do przewidzenia.
  • -temp dostosowuje losowość próbkowania (temperaturę) podczas inferencji.

Przykład wyjścia

Sandra journeyed to the kitchen. Where is Sandra?

Odpowiedź: Sandra jest w kuchni.

Szczegóły techniczne BitNet.cpp

Warstwa BitLinear

BitNet.cpp implementuje zmodyfikowaną architekturę Transformer, zastępując standardowe mnożenia macierzy uproszczoną operacją BitLinear. To podejście centralizuje wagi do zera przed kwantyzacją i skaluje je, aby zmniejszyć błędy aproksymacji. Kluczowa funkcja transformacji wygląda następująco:

# Funkcja binarzacji wag 1-bitowych
def binarize_weights(W):
alpha = W.mean()
W_binarized = np.sign(W - alpha)
return W_binarized

Połączenie scentralizowanych wag i skalowania zapewnia, że błąd kwantyzacji pozostaje minimalny, co pozwala zachować wydajność.

Wpływ na przemysł

BitNet.cpp może mieć daleko idące konsekwencje dla wdrożenia LLM:

  • Dostępność: Pozwala na uruchamianie LLM na standardowych urządzeniach, demokratyzując dostęp do potężnej sztucznej inteligencji.
  • Efektywność kosztowa: Redukuje potrzebę drogich kart graficznych, obniżając barierę dla adopcji.
  • Efektywność energetyczna: Oszczędza energię, wykorzystując inferencję opartą na procesorze.
  • Innowacje: Otwiera nowe możliwości dla aplikacji sztucznej inteligencji na urządzeniach, takich jak tłumaczenie w czasie rzeczywistym, asystenci głosowi i aplikacje zorientowane na prywatność bez zależności od chmury.

Wyzwania i kierunki przyszłego rozwoju

Chociaż LLM 1-bitowe mają wiele obietnic, pozostają jeszcze pewne wyzwania. Obejmują one rozwój solidnych modeli 1-bitowych dla różnych zadań, optymalizację sprzętu do obliczeń 1-bitowych oraz zachęcanie deweloperów do przyjęcia tego nowego paradygmatu. Ponadto, eksploracja kwantyzacji 1-bitowej dla zadań związanych z widzeniem komputeryjnym lub dźwiękiem reprezentuje interesujący kierunek przyszłego rozwoju.

Podsumowanie

Wydanie BitNet.cpp przez Microsoft to znaczący krok naprzód. Umożliwiając wydajną inferencję 1-bitową na standardowych procesorach, BitNet.cpp tworzy dostępność i zrównoważoność sztucznej inteligencji. Ten framework otwiera drogę do bardziej przenośnych i efektywnych kosztowo LLM, poszerzając granice możliwości sztucznej inteligencji na urządzeniach.

Przez ostatnie pięć lat zanurzałem się w fascynującym świecie Machine Learning i Deep Learning. Moja pasja i ekspertyza doprowadziły mnie do udziału w ponad 50 różnorodnych projektach inżynierii oprogramowania, ze szczególnym uwzględnieniem AI/ML. Moja nieustanna ciekawość również skierowała mnie w stronę Natural Language Processing, dziedziny, którą chcę dalej eksplorować.