vLLM — produkciona inferencija sa više paralelnih zahteva
Ollama i llama.cpp su pisani za scenario u kome jedan korisnik čeka jedan odgovor. Kada na isti server krene deset ljudi ili skripta koja obrađuje hiljade zapisa, ta pretpostavka pada — i pada skupo, jer kartica najveći deo vremena stoji.
vLLM je pisan za suprotan slučaj. Ovaj tekst pokazuje kako se instalira, po čemu se razlikuje i kada prelazak zaista ima smisla.
Odakle razlika
Dva mehanizma nose gotovo sve.
Continuous batching. Umesto da čeka da se jedan odgovor završi pa uzme sledeći zahtev, vLLM ubacuje nove zahteve u obradu čim se oslobodi mesto. Pošto je inferencija ograničena propusnošću memorije — kako pokazuje tekst o CPU i GPU inferenciji — težine se ionako čitaju za svaki token. Obraditi osam zahteva u istom prolazu košta jedva više nego obraditi jedan.
PagedAttention. KV keš se ne rezerviše unapred u komadu, nego u blokovima, kao stranice u virtuelnoj memoriji. Nema praznog prostora rezervisanog za kontekst koji možda nikad neće biti iskorišćen, a zajednički deo prompta — recimo isti sistemski prompt kod svih korisnika — čuva se jednom umesto po korisniku.
| Ollama, llama.cpp | vLLM | |
|---|---|---|
| Jedan korisnik | Odlično | Isto ili nešto slabije |
| Deset paralelnih | Red čekanja | Višestruko veća propusnost |
| Format modela | GGUF | safetensors, AWQ, GPTQ, FP8 |
| Rad na procesoru | Podržan | Praktično ne |
| Model mora ceo u VRAM | Ne, preliva se | Da |
| Više modela odjednom | Da | Jedan po procesu |
| Vreme do prvog modela | Minut | Pola sata sa preuzimanjem |
Red o memoriji je onaj koji odlučuje. vLLM nema prelivanje na procesor — ako model ne staje u VRAM, servis se ne pokreće. Nema tihe degradacije kao kod Ollame, ali nema ni popuštanja.
Kada ostati na Ollami
- Jedan korisnik ili nekoliko upita dnevno.
- Model ne staje ceo u karticu.
- Menjaš modele često, ili ih držiš više odjednom.
- Nemaš NVIDIA karticu.
Instalacija
vLLM je Python paket i traži virtuelno okruženje. Sistemski Python nemoj dirati.
$ python3 -m venv ~/.venv/vllm $ source ~/.venv/vllm/bin/activate $ pip install -U vllm
Paket povlači PyTorch i CUDA biblioteke — računaj na nekoliko gigabajta i podosta čekanja. Za brže rešavanje zavisnosti:
$ pip install uv $ uv venv ~/.venv/vllm --python 3.12 $ source ~/.venv/vllm/bin/activate $ uv pip install vllm
Kao i kod Ollame, potreban je samo drajver, ne i CUDA toolkit — biblioteke stižu uz paket.
$ nvidia-smi $ python -c "import torch; print(torch.cuda.is_available())" True
Ako je odgovor False, drajver nije ispravan i dalje nema smisla — pogledaj tekst o drajverima.
$ vllm --version
Prvo pokretanje
$ vllm serve Qwen/Qwen3-8B
Model se preuzima sa Hugging Face-a pri prvom pokretanju, u keš opisan u tekstu o Hugging Face CLI alatu. Za zatvorene modele postavi HF_TOKEN pre pokretanja.
Podizanje traje minut do dva, uz obiman ispis. Dva reda su bitna:
INFO ... Loading model weights took 15.2088 GB INFO ... # GPU blocks: 4823, # CPU blocks: 2048 INFO ... Starting vLLM API server on http://0.0.0.0:8000
Broj GPU blokova govori koliko je memorije ostalo za KV keš. Ako je taj broj mali, model jedva staje i propusnost će biti loša uprkos tome što servis radi.
$ curl http://localhost:8000/v1/models
Podrazumevano sluša na 0.0.0.0, za razliku od Ollame. To znači da je od prvog trenutka dostupan svima na mreži, bez ikakve autentifikacije. Prvo što treba da uradiš:
$ vllm serve Qwen/Qwen3-8B --host 127.0.0.1
Parametri
| Parametar | Šta radi |
|---|---|
--host, --port |
Adresa i port; podrazumevano 0.0.0.0:8000 |
--gpu-memory-utilization |
Udeo VRAM-a koji sme da zauzme; podrazumevano 0.9 |
--max-model-len |
Najveći kontekst; ograniči ga ako memorija ne dozvoljava |
--max-num-seqs |
Najviše zahteva u jednom paketu |
--tensor-parallel-size |
Broj kartica preko kojih se model deli |
--quantization |
Metoda; obično se prepoznaje sama |
--kv-cache-dtype |
Kvantizacija KV keša, npr. fp8 |
--api-key |
Obavezan ključ u zaglavlju |
--served-model-name |
Kraći naziv za API |
--enable-prefix-caching |
Deljenje zajedničkog dela prompta |
--download-dir |
Gde se model preuzima |
gpu-memory-utilization
Ovo je parametar oko koga se najviše vrti. Vrednost 0.9 znači da vLLM uzima devedeset posto memorije kartice, bez obzira na to koliko model stvarno traži — ostatak ide u KV keš i to je namerno.
$ vllm serve Qwen/Qwen3-8B --gpu-memory-utilization 0.85
Spusti je ako kartica gura i ekran ili neki drugi proces. Podizanje iznad 0.95 vodi u pucanje pri opterećenju, jer nema rezerve za skokove u zauzeću.
Nemoj se iznenaditi kad nvidia-smi pokaže punu karticu odmah po pokretanju — memorija se rezerviše unapred, i to je razlika u odnosu na Ollamu, koja je uzima kako treba.
Postavka za karticu od 24 GB
$ vllm serve Qwen/Qwen3-8B-AWQ \
--host 127.0.0.1 --port 8000 \
--served-model-name qwen3 \
--gpu-memory-utilization 0.90 \
--max-model-len 16384 \
--max-num-seqs 16 \
--enable-prefix-caching \
--api-key tajni-kljuc-ovde
Za AWQ i ostale formate pogledaj tekst o kvantizaciji. Ukratko: GGUF ovde ne ide, traži repozitorijum sa -AWQ ili -FP8 u nazivu, ili model u punoj preciznosti ako staje.
Više kartica
$ vllm serve Qwen/Qwen3-32B --tensor-parallel-size 2
Model se deli preko dve kartice, sa svakim slojem rasečenim na pola. Broj mora deliti broj glava pažnje u modelu, pa vrednosti koje nisu stepen dvojke često ne rade.
API
Isključivo OpenAI-kompatibilan, bez sopstvenog puta:
$ curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer tajni-kljuc-ovde" \
-d '{
"model": "qwen3",
"messages": [{"role": "user", "content": "Šta radi komanda ss -tulpn?"}],
"temperature": 0.2,
"max_tokens": 256
}'
Naziv modela mora odgovarati onome pod kojim je servis podignut — otud korist od --served-model-name, jer je puna oznaka sa Hugging Face-a nezgodna za kucanje.
Detaljno o oblicima zahteva ima u tekstu o OpenAI-kompatibilnom API-ju.
Korisne adrese: /health stanje, /v1/models spisak, /metrics metrike u Prometheus formatu — ove poslednje su uključene same od sebe i tema su teksta o monitoringu.
$ curl -s http://localhost:8000/metrics | grep -E 'num_requests|gpu_cache_usage' vllm:num_requests_running 7.0 vllm:num_requests_waiting 2.0 vllm:gpu_cache_usage_perc 0.63
Ova tri broja su najkorisniji pokazatelj stanja. Ako num_requests_waiting stalno raste, kapacitet je premašen. Ako gpu_cache_usage_perc stalno stoji blizu jedinice, zahtevi se odbacuju i vraćaju u red.
Systemd jedinica
$ sudo useradd -r -s /bin/false -m -d /var/lib/vllm vllm
$ sudo tee /etc/systemd/system/vllm.service > /dev/null <<'EOF'
[Unit]
Description=vLLM inference server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=vllm
Group=vllm
Environment="HF_HOME=/var/lib/vllm/huggingface"
EnvironmentFile=-/etc/vllm/env
ExecStart=/var/lib/vllm/.venv/bin/vllm serve Qwen/Qwen3-8B-AWQ \
--host 127.0.0.1 --port 8000 \
--served-model-name qwen3 \
--gpu-memory-utilization 0.90 \
--max-model-len 16384 \
--enable-prefix-caching
Restart=always
RestartSec=10
TimeoutStartSec=600
[Install]
WantedBy=multi-user.target
EOF
TimeoutStartSec je ovde bitan. Podizanje sa preuzimanjem modela ume da premaši podrazumevani rok, pa systemd ubije proces usred posla i onda se sve vrti u krug.
API ključ i HF token idu u zaseban fajl, ne u jedinicu:
$ sudo mkdir -p /etc/vllm $ sudo tee /etc/vllm/env > /dev/null <<'EOF' VLLM_API_KEY=tajni-kljuc-ovde HF_TOKEN=hf_xxxxxxxxxxxxx EOF $ sudo chmod 600 /etc/vllm/env $ sudo chown vllm:vllm /etc/vllm/env
$ sudo systemctl daemon-reload $ sudo systemctl enable --now vllm $ sudo journalctl -u vllm -f
Šta stvarno dobijaš
Poređenje ima smisla samo pod opterećenjem. Sa jednim korisnikom razlika je zanemarljiva, ponekad i u korist llama.cpp.
Model 8B, kartica od 24 GB, kratki odgovori Paralelnih zahteva Ollama vLLM 1 58 t/s 54 t/s 4 61 t/s 190 t/s 16 63 t/s 520 t/s
Brojevi su ilustrativni i zavise od hardvera, ali odnos je onaj koji viđaš u praksi. Ollamin ukupni učinak jedva raste sa brojem korisnika; vLLM raste gotovo linearno dok se kartica ne zasiti.
Pojedinačni korisnik pritom dobija odgovor sporije nego kad je sam — to je cena. Ako ti je bitna latencija jednog korisnika, a ne ukupna propusnost, vLLM ti ne donosi ništa. Kako se ovo meri, pokazuje tekst o benchmarku.
Praktični scenariji
Scenario 1: nema dovoljno memorije pri pokretanju
ValueError: The model's max seq len (40960) is larger than the maximum number of tokens that can be stored in KV cache
Model staje, ali za deklarisani kontekst nema mesta. Spusti --max-model-len na realnu vrednost — retko ti stvarno treba maksimum koji model podržava.
Scenario 2: servis se ne podiže, a model bi trebalo da stane
Proveri da nije GGUF. vLLM traži safetensors, AWQ, GPTQ ili FP8. Proveri i da nešto drugo ne drži karticu:
$ nvidia-smi
Scenario 3: propusnost ne raste sa brojem korisnika
Pogledaj gpu_cache_usage_perc. Ako je blizu jedinice, KV keš je usko grlo — spusti --max-model-len ili podigni --gpu-memory-utilization.
Scenario 4: servis puca posle nekog vremena rada
Vrednost --gpu-memory-utilization je previsoka i nema rezerve za skokove. Spusti na 0.85 i posmatraj.
Scenario 5: podizanje traje predugo i systemd ga ubija
Podigni TimeoutStartSec ili preuzmi model unapred kroz hf download, pa neka servis kreće od gotovog fajla.
Scenario 6: treba ti drugi model
vLLM drži jedan model po procesu. Ili restartuj servis sa drugim modelom, ili podigni drugu jedinicu na drugom portu — uz uslov da oba stanu u memoriju.
Kratka referenca
uv pip install vllm— instalacija u virtuelno okruženjevllm serve organizacija/model— pokretanje--host 127.0.0.1— obavezno, podrazumevano je otvoreno prema mreži--gpu-memory-utilization 0.90— udeo VRAM-a; ispod 0.95--max-model-len— kontekst; prvo mesto za smanjenje--max-num-seqs— zahteva u paketu--tensor-parallel-size 2— deljenje preko kartica--enable-prefix-caching— zajednički deo prompta jednom--served-model-name— kraći naziv za API--api-key— obavezan ključ/v1/chat/completions— jedini API put/metrics—num_requests_waiting,gpu_cache_usage_percTimeoutStartSec=600— inače systemd prekine podizanje- Nema prelivanja na procesor — model staje ili servis ne radi
- Nema GGUF — AWQ, GPTQ, FP8 ili puna preciznost
Vežba
- Instaliraj vLLM u virtuelno okruženje i potvrdi da PyTorch vidi karticu.
- Pokreni model koji staje u tvoju karticu i u ispisu pronađi broj GPU blokova.
- Pošalji isti upit kroz
curli uporedi oblik odgovora sa Ollaminim. - Pusti osam paralelnih zahteva odjednom i prati
/metricstokom obrade. - Izmeri ukupnu propusnost istog modela kroz Ollamu i kroz vLLM pri jednom, pa pri osam paralelnih zahteva.
- Namerno zadaj
--max-model-lenveći nego što memorija dozvoljava i pročitaj grešku do kraja.
Sledeći tekst u serijalu: Ollama u Dockeru sa GPU passthrough-om
Povezano:
- AI na Linux serveru — pregled celog serijala
- Hugging Face CLI — prethodni tekst
- Koliko VRAM-a ti stvarno treba — računica pre nego što servis odbije da se podigne
- Ollama: instalacija na Linux serveru — jednostavnija alternativa
- systemctl — upravljanje servisima
Comments
Post a Comment