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:

BackendSprzętFlaga przy budowaniu
CPUdowolny procesorżadna (domyślny)
CUDAGPU NVIDIA-DGGML_CUDA=ON
MetalApple Silicon (M1–M4)domyślnie ON na macOS
VulkanGPU wielu producentów (AMD, Intel, NVIDIA)-DGGML_VULKAN=ON
HIP / ROCmGPU AMD-DGGML_HIP=ON -DGPU_TARGETS=…
SYCLGPU Intelosobna instrukcja
BLASCPU (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ę.

Dlaczego to ważne dla lokalnego LLM

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.


  1. 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↩︎ ↩︎

  2. 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↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  3. ggml-org/llama.cpp — sekcja Vulkan (flaga -DGGML_VULKAN=ON, wieloplatformowy backend na GPU różnych producentów): docs/build.md#vulkan↩︎

  4. ggml-org/llama.cpp — sekcja HIP (zmienne HIPCXX/HIP_PATH z hipconfig, flagi -DGGML_HIP=ON -DGPU_TARGETS=gfx1030): docs/build.md#hip↩︎

  5. ggml-org/llama.cpp — osobna dokumentacja backendu SYCL dla GPU Intel: docs/backend/SYCL.md↩︎

  6. ggml-org/llama.cpp — definicje flag CLI --list-devices, --device (z obsługą wartości none w parse_device_list): common/arg.cpp↩︎