llama.cpp — kompajliranje iz izvornog koda i pokretanje llama-server

Ollama je udobna dok ti trebaju podrazumevane vrednosti. Onog trenutka kad hoćeš tačno da odrediš koliko slojeva ide na karticu, kako se deli posao između dve kartice ili koji tačno parametri idu u inferenciju — nailaziš na zid, jer Ollama te odluke donosi umesto tebe.

llama.cpp je ono što se ispod nje ionako vrti. Ovaj tekst pokazuje kako se kompajlira sa CUDA podrškom, kako se pokreće llama-server i koji parametri stvarno menjaju ponašanje.

Kada ima smisla

Ollama llama.cpp
Jedna komanda do modela koji radi Kompajliranje, pa podešavanje
Sama bira raspored slojeva Ti određuješ svaki sloj
Podešavanje kroz promenljive okruženja Svaki parametar dostupan iz komandne linije
Sopstvena biblioteka modela Bilo koji GGUF fajl
Nove mogućnosti stižu sa zakašnjenjem Odmah, na dan objave

Konkretni razlozi za prelazak: hoćeš da izvučeš poslednji token iz slabije kartice, radiš sa modelom koji Ollama još ne podržava, treba ti parametar koji ona ne izlaže, ili ti smeta dodatni sloj između tebe i inferencije.

Ako ti ništa od toga nije slučaj, ostani na Ollami — ovaj tekst ti onda služi kao razumevanje onoga što se ispod dešava.

Priprema

Za razliku od Ollame, ovde ti jeste potreban CUDA toolkit, jer se kod kompajlira:

$ nvcc --version
Cuda compilation tools, release 12.8, V12.8.61

Ako komande nema, instalacija je opisana u tekstu o drajverima i CUDA toolkit-u. Toolkit i drajver su dve različite stvari i ovde trebaju obe.

Alati za građenje:

$ sudo apt install -y build-essential cmake git libcurl4-openssl-dev
$ sudo dnf install -y gcc gcc-c++ cmake git libcurl-devel

Paket libcurl nije obavezan, ali bez njega llama-server ne može sam da preuzima modele sa Hugging Face-a.

Kompajliranje

$ git clone https://github.com/ggml-org/llama.cpp
$ cd llama.cpp

Sa CUDA podrškom:

$ cmake -B build -DGGML_CUDA=ON
$ cmake --build build --config Release -j $(nproc)

Traje od nekoliko minuta do pola sata, zavisno od mašine. CUDA deo je najsporiji jer se kod gradi za više arhitektura kartica.

Ako znaš tačno koju karticu imaš, ograniči se na nju i skrati vreme višestruko:

$ cmake -B build -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=86
Kartica Vrednost
RTX 30xx, A100 86, odnosno 80
RTX 40xx, L40 89
RTX 50xx 120
H100 90

Samo procesor

Bez kartice, ili za poređenje:

$ cmake -B build
$ cmake --build build --config Release -j $(nproc)

Podrazumevano se uključuju sve instrukcije koje procesor podržava. Šta je stvarno na raspolaganju:

$ lscpu | grep -o 'avx[0-9_]*' | sort -u

Provera

$ ./build/bin/llama-cli --version
version: 6420 (a1b2c3d4)
built with cc (GCC) 13.2.0 for x86_64-linux-gnu

Da je CUDA stvarno unutra:

$ ./build/bin/llama-server --list-devices
Available devices:
  CUDA0: NVIDIA GeForce RTX 3090 (24576 MiB, 24164 MiB free)

Ako spisak pokazuje samo procesor, GGML_CUDA=ON nije prihvaćen. Obriši build direktorijum i kreni ispočetka — CMake ume da zadrži staru konfiguraciju.

Instalacija u sistem

Binarni fajlovi ostaju u build/bin. Da budu dostupni svuda:

$ sudo cmake --install build --prefix /usr/local

Preuzimanje modela

llama.cpp radi isključivo sa GGUF fajlovima. Ako već koristiš Ollamu, njeni modeli su takođe GGUF, ali su imenovani po heš vrednosti i nezgodni za ručno korišćenje.

Najjednostavnije je pustiti server da sam preuzme:

$ llama-server -hf bartowski/Qwen3-8B-GGUF:Q4_K_M

Fajl završava u ~/.cache/llama.cpp i sledeći put se koristi odatle. Ručno preuzimanje i organizacija fajlova su tema teksta o Hugging Face CLI alatu.

Pokretanje servera

$ llama-server -m ~/models/qwen3-8b-q4_k_m.gguf --port 8080 -ngl 99
$ curl http://localhost:8080/health
{"status":"ok"}

Server ima i ugrađen veb interfejs na istoj adresi, koristan za brzu proveru bez pisanja zahteva.

Parametar koji je najvažniji

Oznaka -ngl govori koliko slojeva ide na karticu. Vrednost 99 znači „svi koji stanu", i to je ono što u većini slučajeva želiš.

llm_load_tensors: offloaded 37/37 layers to GPU
llm_load_tensors:      CUDA0 buffer size =  4685.30 MiB
llm_load_tensors:        CPU buffer size =   292.36 MiB

Prvi red je provera koja je bitna. Ako brojevi nisu jednaki, deo modela radi na procesoru i brzina pada višestruko — razlog je razrađen u tekstu o CPU i GPU inferenciji.

Za razliku od Ollame, ovde možeš da zadaš tačan broj slojeva. Model koji ne staje ceo namerno podeliš:

$ llama-server -m model.gguf -ngl 28

To je korisno kad hoćeš da ostaviš mesta za veliki kontekst umesto za poslednjih nekoliko slojeva.

Ostali parametri

Parametar Šta radi
-m Putanja do GGUF fajla
-ngl Broj slojeva na kartici; 99 za sve
-c Veličina konteksta; 0 uzima maksimum modela
-np Paralelnih tokova; kontekst se deli među njima
-t Niti za procesorski deo; broj fizičkih jezgara
-b, -ub Veličina paketa pri obradi prompta
--host, --port Adresa i port slušanja
--cache-type-k, --cache-type-v Kvantizacija KV keša
-fa Flash attention; manje memorije za keš
--mlock Sprečava ispisivanje modela u swap
-ts Raspodela po karticama, npr. 3,1
--api-key Obavezan ključ u zaglavlju zahteva

Ceo spisak je dugačak i vredi ga jednom pregledati:

$ llama-server --help | less

Postavka za karticu od 24 GB

$ llama-server \
    -m ~/models/qwen3-27b-q4_k_m.gguf \
    --host 127.0.0.1 --port 8080 \
    -ngl 99 \
    -c 16384 \
    --cache-type-k q8_0 --cache-type-v q8_0 \
    -fa \
    -np 2 \
    --mlock

Kvantizovan keš i flash attention idu zajedno — tek zajedno čine kontekst od šesnaest hiljada tokena izvodljivim uz model te veličine. Računica stoji u tekstu o proceni VRAM-a.

Kod parametra -np pazi: zadati kontekst se deli među tokovima. Sa -c 16384 -np 2 svaki tok dobija osam hiljada tokena, a ne šesnaest.

Dve kartice

$ llama-server -m model.gguf -ngl 99 -ts 1,1

Odnos 1,1 deli model na pola. Kod kartica različite veličine odnos prilagodi:

$ llama-server -m model.gguf -ngl 99 -ts 3,1

Ovde je ključna prednost nad Ollamom, koja raspodelu ne prepušta tebi.

API

Server nudi OpenAI-kompatibilan put, isti kao Ollama, pa gotovi alati rade bez izmena:

$ curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [{"role": "user", "content": "Šta radi komanda ss -tulpn?"}],
    "temperature": 0.2
  }'

Model se ne navodi, jer server drži tačno jedan. Postoji i sopstveni put sa nešto više kontrole:

$ curl http://localhost:8080/completion \
  -d '{"prompt": "Nabroj tri komande za pregled diska:", "n_predict": 128}'

Korisne adrese: /health stanje servera, /props podešavanja i veličina konteksta, /metrics metrike u Prometheus formatu — ovo poslednje se uključuje sa --metrics i tema je teksta o monitoringu.

Prosta zaštita, kad server mora da bude dostupan u mreži:

$ llama-server -m model.gguf --api-key tajni-kljuc-ovde
$ curl http://localhost:8080/v1/chat/completions \
  -H "Authorization: Bearer tajni-kljuc-ovde" ...

Ovo je više nego što Ollama nudi, ali i dalje nije dovoljno za izlaganje prema internetu — za to ide proxy sa TLS-om, o čemu govori tekst o zaštiti API-ja.

Systemd jedinica

Za razliku od Ollame, ovde jedinicu pišeš sam:

$ sudo useradd -r -s /bin/false -m -d /var/lib/llamacpp llamacpp
$ sudo tee /etc/systemd/system/llamacpp.service > /dev/null <<'EOF'
[Unit]
Description=llama.cpp server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=llamacpp
Group=llamacpp
ExecStart=/usr/local/bin/llama-server \
    -m /var/lib/llamacpp/models/qwen3-8b-q4_k_m.gguf \
    --host 127.0.0.1 --port 8080 \
    -ngl 99 -c 16384 -fa \
    --cache-type-k q8_0 --cache-type-v q8_0
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now llamacpp
$ systemctl status llamacpp

Ako koristiš --mlock, korisniku treba dozvola za zaključavanje memorije:

LimitMEMLOCK=infinity

Ostali alati

Uz server se dobija još nekoliko korisnih binarnih fajlova.

$ llama-cli -m model.gguf -p "Objasni šta radi umask" -n 128

Merenje brzine, bez ikakvog servera između:

$ llama-bench -m model.gguf -ngl 99
| model          | test   |    t/s |
| -------------- | ------ | ------ |
| qwen3 8B Q4_K_M| pp512  | 3421.5 |
| qwen3 8B Q4_K_M| tg128  |   58.3 |

Oznaka pp je obrada prompta, tg generisanje. Razlika među njima objašnjena je u tekstu o CPU i GPU inferenciji, a poređenje postavki u tekstu o benchmarku.

Pravljenje sopstvene kvantizacije, kao u tekstu o kvantizaciji:

$ llama-quantize model-f16.gguf model-q4_k_m.gguf Q4_K_M

Merenje gubitka kvaliteta između varijanti:

$ llama-perplexity -m model-q4_k_m.gguf -f test.txt

Ažuriranje

Projekat se menja brzo, sa objavama gotovo svakodnevno:

$ cd llama.cpp
$ git pull
$ cmake --build build --config Release -j $(nproc)

Ponovno građenje je inkrementalno i traje kraće od prvog. Ako se javе čudne greške posle povlačenja izmena, obriši build i kreni ispočetka.

Format GGUF se povremeno menja. Vrlo stari fajlovi na novoj verziji ne rade i traže ponovno preuzimanje — to je cena praćenja projekta koji se ovako brzo razvija.

Praktični scenariji

Scenario 1: kompajliranje puca na CUDA delu

nvcc fatal   : Unsupported gpu architecture

Zadata arhitektura ne odgovara ni kartici ni verziji toolkit-a. Izostavi CMAKE_CUDA_ARCHITECTURES i pusti da se gradi za sve.

Scenario 2: server radi, ali sporo

Pogledaj red offloaded X/Y layers pri pokretanju. Ako brojevi nisu jednaki, spusti kontekst ili uzmi nižu kvantizaciju.

Scenario 3: nedovoljno memorije pri učitavanju

CUDA error: out of memory

Redom: uključi -fa, kvantizuj keš na q8_0, spusti -c, pa tek onda smanjuj -ngl.

Scenario 4: model odgovara besmisleno

Verovatno je base umesto instruct verzija, ili je predložak za sklapanje prompta pogrešno prepoznat. Pogledaj šta je server javio pri učitavanju:

$ llama-server -m model.gguf 2>&1 | grep -i 'chat template'

Scenario 5: dve kartice, radi samo jedna

Bez -ts raspodela ne mora biti ono što očekuješ. Proveri --list-devices, pa zadaj odnos izričito.

Scenario 6: sve je radilo, pa posle git pull prestalo

Ili je format modela zastareo, ili je stari build direktorijum u sukobu sa novom konfiguracijom. Prvo obriši build, pa ako ne pomogne, preuzmi model ponovo.

Kratka referenca

  • cmake -B build -DGGML_CUDA=ON — konfiguracija sa CUDA podrškom
  • cmake --build build --config Release -j $(nproc) — građenje
  • -DCMAKE_CUDA_ARCHITECTURES=86 — samo za svoju karticu, brže
  • llama-server --list-devices — provera da je CUDA unutra
  • -ngl 99 — svi slojevi na karticu
  • offloaded X/Y layers — brojevi moraju biti jednaki
  • -c — kontekst; sa -np se deli među tokovima
  • --cache-type-k q8_0 — kvantizovan KV keš
  • -fa — flash attention
  • -ts 3,1 — raspodela po karticama
  • --api-key — obavezan ključ u zaglavlju
  • --mlock — model ostaje van swapa
  • /v1/chat/completions — OpenAI-kompatibilan put
  • llama-bench — merenje brzine
  • llama-quantize — sopstvena kvantizacija
  • llama-perplexity — merenje gubitka kvaliteta

Vežba

  1. Kompajliraj llama.cpp sa CUDA podrškom i potvrdi karticu kroz --list-devices.
  2. Pokreni server sa -ngl 99 i u ispisu pronađi red o rasporedu slojeva.
  3. Namerno spusti -ngl na polovinu slojeva i izmeri razliku u brzini.
  4. Uporedi rezultat komande llama-bench sa istim modelom pokrenutim kroz Ollamu.
  5. Pokreni server sa -c 16384 -np 2, pa kroz /props proveri koliki kontekst dobija jedan tok.
  6. Napravi systemd jedinicu i potvrdi da server radi posle restarta mašine.

Sledeći tekst u serijalu: Hugging Face CLI — preuzimanje modela i organizacija na disku

Povezano:

Comments

Popular posts from this blog

Početak u Linuxu — šta je i zašto se uči

Konverzija tipova podataka u Pythonu

groupadd