Ollama kao systemd servis

Instalaciona skripta ostavlja servis koji radi, ali sa podrazumevanim vrednostima koje su pisane za desktop. Model se izbacuje iz memorije posle pet minuta, servis sluša samo na lokalnoj adresi, a promenljive okruženja koje ti trebaju nigde nisu postavljene.

Ovaj tekst pokazuje kako se ta jedinica dovodi u stanje upotrebljivo na serveru — trajno, tako da preživi restart i ažuriranje.

Kako jedinica izgleda

Instalaciona skripta pravi ovakav fajl:

$ cat /etc/systemd/system/ollama.service
[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/local/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

[Install]
WantedBy=multi-user.target

Ovaj fajl ne diraj. Sledeće ažuriranje Ollame ga prepisuje i sve tvoje izmene nestaju bez upozorenja. Izmene idu kroz drop-in fajl.

Drop-in izmene

$ sudo systemctl edit ollama

Otvara se prazan fajl u koji upisuješ samo ono što menjaš:

[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_KEEP_ALIVE=-1"

Snimljeno završava u /etc/systemd/system/ollama.service.d/override.conf i ostaje netaknuto kroz ažuriranja.

$ sudo systemctl daemon-reload
$ sudo systemctl restart ollama

Provera šta je stvarno na snazi, sa spojenim vrednostima iz obe datoteke:

$ systemctl cat ollama
$ systemctl show ollama --property=Environment

Ako ti se čini da izmena nije prihvaćena, ova druga komanda ti kaže tačno šta servis vidi. Ista logika važi za svaki systemd servis, o čemu ima više u tekstu o systemctl.

Promenljive okruženja

Ovo je jedini način da se Ollama podesi — konfiguracioni fajl ne postoji.

Promenljiva Podrazumevano Šta radi
OLLAMA_HOST 127.0.0.1:11434 Adresa i port na kojima servis sluša
OLLAMA_MODELS ~/.ollama/models Putanja do fajlova modela
OLLAMA_KEEP_ALIVE 5m Koliko model ostaje u memoriji; -1 trajno
OLLAMA_NUM_PARALLEL automatski Paralelnih zahteva po modelu
OLLAMA_MAX_LOADED_MODELS automatski Koliko različitih modela istovremeno u memoriji
OLLAMA_MAX_QUEUE 512 Dužina reda čekanja pre odbijanja zahteva
OLLAMA_CONTEXT_LENGTH 4096 Podrazumevani kontekst za sve modele
OLLAMA_KV_CACHE_TYPE f16 Kvantizacija KV keša
OLLAMA_FLASH_ATTENTION isključeno Efikasnija pažnja, manje memorije za keš
OLLAMA_ORIGINS lokalno Dozvoljena porekla za pristup iz pregledača
OLLAMA_DEBUG isključeno Opširni logovi
CUDA_VISIBLE_DEVICES sve kartice Koje kartice servis sme da koristi

Svaka ide u zaseban Environment= red. Više vrednosti u jednom redu radi, ali se teže čita i lakše greši.

Mrežni pristup

Podrazumevana vrednost 127.0.0.1 znači da servis vidi samo sama mašina. Za pristup sa drugih računara:

[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"

Ovim si otvorio nezaštićen servis prema mreži. Ollama nema nikakvu autentifikaciju — ko dođe do porta, koristi tvoju karticu, čita spisak modela i šalje šta hoće. Nikad ne izlaži port direktno prema internetu.

Minimum je ograničenje na lokalnu mrežu:

$ sudo ufw allow from 192.168.1.0/24 to any port 11434 proto tcp

Na sistemima sa firewalld:

$ sudo firewall-cmd --permanent --new-zone=ollama
$ sudo firewall-cmd --permanent --zone=ollama --add-source=192.168.1.0/24
$ sudo firewall-cmd --permanent --zone=ollama --add-port=11434/tcp
$ sudo firewall-cmd --reload

Bolje rešenje je vezati servis za lokalnu adresu i ispred njega staviti proxy koji radi TLS i autentifikaciju. To je tema teksta o Nginx reverse proxy postavci i teksta o zaštiti API-ja.

Ako pristupaš samo sa jedne mašine, SSH tunel ne traži nikakvu izmenu servisa:

$ ssh -L 11434:localhost:11434 korisnik@server

Provera odakle se servis vidi

$ sudo ss -tulpn | grep 11434
tcp   LISTEN  0  4096  127.0.0.1:11434  0.0.0.0:*  users:(("ollama",pid=1247,fd=3))

Adresa pre dvotačke govori sve. 127.0.0.1 je samo lokalno, 0.0.0.0 je sve mrežne kartice, konkretna adresa je samo ta.

Držanje modela u memoriji

Podrazumevanih pet minuta znači da posle svake duže pauze prvi upit čeka ponovno učitavanje — kod većeg modela i po desetak sekundi.

[Service]
Environment="OLLAMA_KEEP_ALIVE=-1"

Vrednost -1 drži model trajno. Na serveru koji ima jedan model i dovoljno memorije, to je pravi izbor. Ako deliš karticu sa nečim drugim, uzmi konačnu vrednost:

Environment="OLLAMA_KEEP_ALIVE=2h"

Šta je trenutno učitano i dokle:

$ ollama ps
NAME       ID            SIZE     PROCESSOR    UNTIL
qwen3:8b   a1b2c3d4e5f6  6.2 GB   100% GPU     Forever

Ručno oslobađanje memorije bez restarta servisa:

$ ollama stop qwen3:8b

Paralelni zahtevi

Ollama podrazumevano sama bira koliko zahteva obrađuje istovremeno, na osnovu slobodne memorije. Kad hoćeš da to kontrolišeš:

[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_MAX_LOADED_MODELS=1"

Svaki paralelni tok ima sopstveni KV keš. Četiri paralelna zahteva sa kontekstom od osam hiljada tokena troše četiri puta više memorije za keš nego jedan — računica stoji u tekstu o proceni VRAM-a. Ako podigneš ovaj broj bez rezerve u memoriji, model se prelije na procesor i sve postane sporije nego pre.

Vrednost OLLAMA_MAX_LOADED_MODELS=1 je razumna na jednoj kartici: sprečava da drugi model bude učitan pored prvog i da oba završe delimično na procesoru.

Za desetine paralelnih korisnika Ollama nije pravi alat, jer ne deli zajednički deo konteksta među zahtevima. Tu se prelazi na vLLM.

Kontekst i memorija

Podrazumevani kontekst od 4096 tokena je mali za ozbiljan rad, ali svako podizanje direktno jede VRAM:

[Service]
Environment="OLLAMA_CONTEXT_LENGTH=16384"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
Environment="OLLAMA_FLASH_ATTENTION=1"

Ove tri idu zajedno. Kvantizovan KV keš prepolovi njegovo zauzeće uz gubitak koji se ne primećuje, a flash attention dodatno smanjuje potrošnju — što tek zajedno čini veći kontekst izvodljivim. Više o samoj kvantizaciji ima u tekstu o GGUF formatu.

Posle svake ovakve izmene proveri da model i dalje ceo stoji na kartici:

$ ollama ps

Izbor kartice

Na mašini sa više kartica servis podrazumevano vidi sve. Da ostaviš jednu za nešto drugo:

$ nvidia-smi -L
GPU 0: NVIDIA GeForce RTX 3090 (UUID: GPU-a1b2...)
GPU 1: NVIDIA GeForce RTX 3090 (UUID: GPU-c3d4...)
[Service]
Environment="CUDA_VISIBLE_DEVICES=0"

Ako se karticama menjaju redni brojevi između podizanja sistema, koristi UUID umesto broja:

Environment="CUDA_VISIBLE_DEVICES=GPU-a1b2..."

Kompletan primer

Postavka za server sa jednom karticom od 24 GB, dostupan u lokalnoj mreži:

$ sudo systemctl edit ollama
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_MODELS=/data/ollama/models"
Environment="OLLAMA_KEEP_ALIVE=-1"
Environment="OLLAMA_NUM_PARALLEL=2"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_CONTEXT_LENGTH=16384"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
Environment="OLLAMA_FLASH_ATTENTION=1"
$ sudo systemctl daemon-reload
$ sudo systemctl restart ollama
$ systemctl show ollama --property=Environment
$ ollama ps

Zavisnost od drajvera

Na sporijim mašinama servis ume da se podigne pre nego što je kartica spremna i tiho ode na procesor. Ako ti se to dešava:

[Unit]
After=network-online.target nvidia-persistenced.service
Wants=nvidia-persistenced.service

Uz to uključi trajni režim kartice, kako je opisano u tekstu o drajverima:

$ sudo systemctl enable --now nvidia-persistenced

Logovi

Ollama piše u journal, kao svaki systemd servis:

$ sudo journalctl -u ollama -f
$ sudo journalctl -u ollama --since "1 hour ago" --no-pager

Kod problema sa učitavanjem modela uključi opširnije logovanje:

[Service]
Environment="OLLAMA_DEBUG=1"

U tom režimu vidiš koliko je slojeva otišlo na karticu, a koliko je ostalo na procesoru — najkorisniji podatak kada brzina nije ono što očekuješ. Vrati ga na isključeno kada završiš, jer logovi rastu brzo. Rad sa journalom detaljno pokriva tekst o journalctl.

Ograničenje veličine logova, ako servis radi neprekidno:

$ sudo journalctl --vacuum-size=500M

Praktični scenariji

Scenario 1: izmena ne deluje

$ systemctl show ollama --property=Environment

Ako promenljive nema u ispisu, izostao je daemon-reload ili je fajl završio na pogrešnom mestu. Proveri systemctl cat ollama.

Scenario 2: posle ažuriranja nestala podešavanja

Menjao si glavni fajl umesto drop-in fajla. Prebaci sve u systemctl edit i ubuduće glavni ne diraj.

Scenario 3: servis se stalno restartuje

$ sudo journalctl -u ollama -n 100 --no-pager

Uz Restart=always servis se diže u petlji i kad ne može da radi. Najčešće je zauzet port ili nedostaju prava nad direktorijumom modela.

Scenario 4: sa drugog računara nema pristupa

Redom: ss -tulpn | grep 11434 za adresu slušanja, pa firewall, pa mreža. Prve dve stavke pokrivaju gotovo sve slučajeve.

Scenario 5: dodat je drugi model i sve je usporilo

Oba modela su u memoriji i bar jedan se preliva na procesor. Postavi OLLAMA_MAX_LOADED_MODELS=1.

Scenario 6: nedovoljno memorije posle podizanja konteksta

Uključi OLLAMA_KV_CACHE_TYPE=q8_0 i flash attention. Ako i dalje ne staje, spusti kontekst ili uzmi manji model.

Kratka referenca

  • systemctl edit ollama — drop-in izmene, jedini ispravan način
  • systemctl cat ollama — spojen prikaz svih fajlova
  • systemctl show ollama --property=Environment — šta je stvarno na snazi
  • systemctl daemon-reload — obavezno posle svake izmene
  • OLLAMA_HOST — adresa slušanja; 0.0.0.0 otvara servis prema mreži
  • OLLAMA_KEEP_ALIVE=-1 — model trajno u memoriji
  • OLLAMA_NUM_PARALLEL — svaki tok troši sopstveni KV keš
  • OLLAMA_MAX_LOADED_MODELS=1 — razumno na jednoj kartici
  • OLLAMA_CONTEXT_LENGTH — podrazumevani kontekst za sve modele
  • OLLAMA_KV_CACHE_TYPE=q8_0 — polovi keš
  • OLLAMA_FLASH_ATTENTION=1 — dodatna ušteda memorije
  • CUDA_VISIBLE_DEVICES — izbor kartica
  • OLLAMA_DEBUG=1 — raspored slojeva u logovima
  • ss -tulpn | grep 11434 — odakle je servis vidljiv
  • journalctl -u ollama -f — praćenje logova
  • Ollama nema autentifikaciju — port nikad ne izlaži prema internetu

Vežba

  1. Napravi drop-in fajl koji drži model trajno u memoriji, pa potvrdi kroz ollama ps da kolona UNTIL pokazuje Forever.
  2. Proveri gde servis sluša, pa ga otvori prema lokalnoj mreži i ograniči pravilom u firewallu.
  3. Podigni kontekst na 16384 i izmeri zauzeće kartice pre i posle izmene.
  4. Uključi kvantizovan KV keš i uporedi zauzeće sa prethodnim merenjem.
  5. Uključi OLLAMA_DEBUG i u logovima pronađi koliko je slojeva otišlo na karticu.
  6. Namerno postavi OLLAMA_NUM_PARALLEL previsoko i posmatraj kada model počne da se preliva na procesor.

Sledeći tekst u serijalu: llama.cpp — kompajliranje iz izvornog koda i pokretanje llama-server

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