Wchodzisz na r/LocalLLaMA, ktoś pyta „jaką kartę wziąć pod modele", i pod postem od razu ta sama litania: 3090, 3090, może 4090 jak budżet pozwala, koniecznie NVIDIA, koniecznie CUDA. Człowiek z Radeonem w obudowie albo z MacBookiem na biurku czyta to i po cichu zakłada, że wsiadł nie do tego pociągu — że lokalne LLM-y to zabawa wyłącznie dla posiadaczy zielonych kart, a on ma co najwyżej oglądać z peronu.
I to jest jedno z tych przekonań, które żyje własnym życiem, choć z prawdą ma niewiele
wspólnego. Bo llama.cpp — silnik, na którym stoi pół tego lokalnego światka — od samego
początku był pisany pod jedną obietnicę: odpalać modele „na szerokim zakresie sprzętu",
lokalnie i w chmurze, w czystym C/C++ bez ciężkich zależności.1 CUDA jest w tym
zestawie, jasne. Ale jest jedną z kilkunastu opcji, nie warunkiem wejścia.
Co to w ogóle jest „backend"
Zajrzyj pod maskę llama.cpp, a znajdziesz ggml — bibliotekę, która robi całą matematykę
modelu. I tu wchodzi słowo klucz: backend. To po prostu moduł ggml, który wie, jak
wykonać te wszystkie mnożenia macierzy na konkretnym rodzaju sprzętu. Jeden backend gada
z układem NVIDIA. Inny z GPU Apple. Jeszcze inny z byle czym, co ma sterownik Vulkana.
Domyślnym, zawsze dostępnym backendem jest CPU. Zwykły procesor, ten sam, na którym
odpalasz przeglądarkę. Zbudujesz llama.cpp bez ani jednej flagi akceleracji i model
i tak ruszy — wolniej niż na GPU, ale ruszy.2 To jest ta część, o której cała ta litania
zapomina wspomnieć: żeby cokolwiek pogadało lokalnie, karta graficzna nie jest
ci technicznie potrzebna. Jest ci potrzebna, żeby było szybko. A to już zupełnie inna rozmowa.
Ilu tych backendów w ogóle jest?
Więcej, niż podejrzewasz. Oficjalna tabela w README ciągnie się przez kilkanaście pozycji: Metal, BLAS, SYCL, CUDA, HIP, Vulkan, MUSA, CANN, OpenCL, ZenDNN, WebGPU, IBM zDNN, Hexagon i jeszcze parę egzotów.1 Większości z nich w życiu nie dotkniesz — Ascend NPU czy IBM Z & LinuxONE to sprzęt, którego nie trzymasz pod biurkiem. Ale te, które realnie decydują o tym, czy twój sprzęt załapie się na zabawę, dają się policzyć na palcach:
| Backend | Sprzęt | Flaga przy budowaniu |
|---|---|---|
| CPU | dowolny procesor | żadna (domyślny) |
| CUDA | GPU NVIDIA | -DGGML_CUDA=ON |
| Metal | Apple Silicon (M1–M4) | domyślnie ON na macOS |
| Vulkan | GPU wielu producentów (AMD, Intel, NVIDIA) | -DGGML_VULKAN=ON |
| HIP / ROCm | GPU AMD | -DGGML_HIP=ON -DGPU_TARGETS=… |
| SYCL | GPU Intel | osobna instrukcja |
| BLAS | CPU (przyspieszenie) | -DGGML_BLAS=ON |
Zanim pójdziemy dalej — jedna rzecz, która lubi umykać, a jest w tym wszystkim kluczowa.
Te flagi z -D na przedzie to opcje budowania, czyli kompilacji. llama.cpp bierzesz
w postaci kodu źródłowego i raz zamieniasz go w gotowy program — tym właśnie jest
budowanie, a robi to cmake. I to na tym etapie, przed pierwszym uruchomieniem, mówisz,
jakie backendy wkompilować. Nie podajesz -DGGML_CUDA=ON przy odpalaniu modelu — podajesz
to raz, zanim plik wykonywalny w ogóle powstanie. Potem uruchamiasz już gotową binarkę,
a ona z góry wie, na czym ma liczyć.
Przejdźmy tę listę tak, jak się ją czyta w praktyce — od strony pytania „a co ja mam w obudowie".
Masz NVIDIA? No to CUDA, ta zamknięta platforma obliczeniowa NVIDIA, która działa
tylko na ich kartach. Włączasz ją flagą -DGGML_CUDA=ON przy budowaniu.2 To ta
najbardziej wydeptana ścieżka, o której wszyscy piszą — i faktycznie działa jak trzeba.
Tylko że wydeptana nie znaczy jedyna.
Masz MacBooka na Apple Silicon? Tu jest najlepszy żart całej układanki: nie musisz
robić absolutnie nic. Backend Metal — natywne API GPU Apple — jest na macOS włączony
domyślnie. Budujesz llama.cpp normalnie i twój M2 czy M3 od razu liczy na GPU. Chcesz
go z jakiegoś powodu wyłączyć? Musisz się wręcz postarać: -DGGML_METAL=OFF.2
Zunifikowana pamięć w Makach robi tu robotę, o której właściciele osobnych kart mogą
tylko pomarzyć.
Masz Radeona albo GPU Intela? I tu robi się najciekawiej, bo to dokładnie ci ludzie, których ta litania odprawia z kwitkiem. A mają aż dwie drogi.
Vulkan, czyli furtka dla całej reszty
Gdybym miał wskazać jeden backend, o którym za mało się mówi, to Vulkan. To otwarte,
wieloplatformowe API graficzno-obliczeniowe (ta sama Khronos, co od OpenGL-a), które
obsługuje mnóstwo sterowników GPU — NVIDIA, AMD, Intela. W llama.cpp włączasz je jedną
flagą, -DGGML_VULKAN=ON, i dostajesz akcelerację GPU działającą cross-platform, na
Windowsie, Linuksie i macOS naraz — bez instalowania dedykowanych, ciężkich stosów
producenta.3
I to jest sedno. Bo alternatywą dla AMD jest HIP/ROCm — cały software’owy stos AMD do liczenia na GPU (HIP to interfejs w jego ramach, pozwalający pisać kod zbliżony do CUDA; to nie osobny produkt, tylko część tego samego ekosystemu). Bywa wydajniejszy od Vulkana, ale kosztuje cię więcej zachodu przy konfiguracji i samym budowaniu. Zobacz, jak to wygląda:
HIPCXX="$(hipconfig -l)/clang" HIP_PATH="$(hipconfig -R)" \
cmake -S . -B build -DGGML_HIP=ON -DGPU_TARGETS=gfx1030 -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
gfx1030 to nie ozdobnik — to kod architektury twojego konkretnego układu AMD, który
musisz najpierw poznać i podać ręcznie.4 U Intela jest podobnie: backend SYCL
(otwarty standard programowania heterogenicznego, którym Intel wozi swoje GPU przez oneAPI)
ma na tyle osobną drogę budowania, że w repo doczekał się własnego pliku dokumentacji, obok
głównego build.md.5 Nikt nie mówi, że to zabawa bez łzawienia. Ale że się da — da się.
Dla kogoś bez „zielonej karty" Vulkan bywa najkrótszą drogą do sensownej akceleracji GPU:
jedna flaga -DGGML_VULKAN=ON, sterownik, który i tak masz do grania, i tyle — zamiast
przekopywania się przez cały ROCm czy oneAPI. Nie zawsze wyciśnie z Radeona ostatni token,
ale różnica między „liczę na GPU" a „mielę na samym CPU" jest odczuwalnie większa niż
różnica między dwoma backendami GPU. Najpierw w ogóle wejdź na GPU; to, który z nich
wyciska więcej, dostroisz później.
A jeśli GPU w ogóle nie ma?
Zostaje CPU — i wcale nie jesteś skazany na gołą, referencyjną implementację. Masz BLAS
(np. OpenBLAS), który przyspiesza obliczenia na procesorze i włącza się parą flag
-DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS.2 A jak siedzisz na czymś bardziej
konkretnym, llama.cpp ma nawet backendy skrojone pod rodzinę procesora: ZenDNN pod
serwerowe CPU AMD EPYC i Arm KleidiAI pod układy Arm — obok generycznego CPU.2
Mrówcza robota optymalizacyjna, o której mało kto wie, a która potrafi wycisnąć z krzemu,
który już masz, zaskakująco dużo.
Zrób to sam
Powiedzmy, że budujesz llama.cpp sam (a warto — rozbieraliśmy jego flagi po
kolei, bo to na nich jedzie pół ekosystemu, od Ollamy po
LM Studio). Najprostszy build, sam CPU, bez żadnych ozdobników:
cmake -B build
cmake --build build --config Release
Chcesz akcelerację? Dokładasz jedną flagę pod swój sprzęt — -DGGML_CUDA=ON,
-DGGML_VULKAN=ON, -DGGML_HIP=ON — i tyle. Co więcej, backendy da się łączyć w jednym
buildzie (CUDA i Vulkan naraz to normalka), a którym urządzeniem policzysz, wybierasz już
w locie, przy odpalaniu:
llama-cli --list-devices
llama-cli -m model.gguf --device Vulkan0
llama-cli -m model.gguf --device none
--list-devices pokaże ci wszystkie akceleratory, które build widzi, --device wskaże
ten jeden, a --device none każe liczyć wyłącznie na CPU — wygodne, gdy chcesz zobaczyć,
ile tracisz bez GPU.6 I jedno, co warto rozdzielić w głowie raz na zawsze: wybór
backendu to nie to samo co kwantyzacja modelu. Format GGUF i to, czy bierzesz Q4 czy Q8
(nazwy rozbieraliśmy osobno), to jedna decyzja —
na czym to policzysz to zupełnie druga. Ten sam plik .gguf pojedzie na CUDA, na
Vulkanie i na gołym procesorze. Nie mieszaj tych dwóch pokręteł, bo to niezależne osie.
Cała aktualna prawda o budowaniu siedzi w jednym pliku:
docs/build.md w repo
ggml-org/llama.cpp. Sekcja po sekcji, backend po backendzie.
Bo ta redditowa litania „NVIDIA albo nic" to trochę jak stać przed budynkiem z jednymi oszklonymi drzwiami frontowymi, na które wszyscy się pchają, i nie wiedzieć, że dookoła jest jeszcze pięć wejść — węższych, gorzej oznaczonych, część z lekko zacinającą się klamką, ale prowadzących do tego samego środka. Zielona karta to najwygodniejsze drzwi. Nie jedyne.
ggml-org/llama.cpp— README (deklaracja celu projektu: „a wide range of hardware — locally and in the cloud" i tabela wspieranych backendów, m.in. Metal, BLAS, SYCL, CUDA, HIP, Vulkan, CANN, OpenCL, ZenDNN, IBM zDNN, Hexagon): github.com/ggml-org/llama.cpp. ↩︎ ↩︎ggml-org/llama.cpp— dokumentacja budowania (CPU jako backend domyślny,-DGGML_CUDA=ON, Metal domyślnie ON na macOS z-DGGML_METAL=OFF,-DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS, sekcje ZenDNN i Arm KleidiAI): docs/build.md. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ggml-org/llama.cpp— sekcja Vulkan (flaga-DGGML_VULKAN=ON, wieloplatformowy backend na GPU różnych producentów): docs/build.md#vulkan. ↩︎ggml-org/llama.cpp— sekcja HIP (zmienneHIPCXX/HIP_PATHzhipconfig, flagi-DGGML_HIP=ON -DGPU_TARGETS=gfx1030): docs/build.md#hip. ↩︎ggml-org/llama.cpp— osobna dokumentacja backendu SYCL dla GPU Intel: docs/backend/SYCL.md. ↩︎ggml-org/llama.cpp— definicje flag CLI--list-devices,--device(z obsługą wartościnonewparse_device_list): common/arg.cpp. ↩︎