Ollama czy vLLM: co wybrać do serwowania modeli LLM?
Porównanie wydajności Ollama i vLLM. Wybierz Ollama dla lokalnego asystenta na CPU lub vLLM dla wysokiej przepustowości na GPU. Sprawdź, kiedy użyć PagedAttention i GGUF.
Ollama a vLLM w jednym akapicie
Ollama to menedżer modeli z wbudowanym serwerem: pobiera skwantyzowane wagi, ładuje je i odpowiada na 127.0.0.1:11434, korzystając z CPU, jeśli serwer nie posiada innego zasobu. vLLM to silnik wysokiej przepustowości: utrzymuje GPU w stanie pełnego obciążenia przy wielu jednoczesnych żądaniach i jest niewłaściwym narzędziem na maszynie bez akceleratora graficznego. Na tym polega główna różnica. Ollama jest przeznaczona dla pojedynczego użytkownika korzystającego z lokalnego asystenta. vLLM jest przeznaczony dla aplikacji obsługującej cały zespół.
Oba rozwiązania udostępniają API HTTP zgodne z OpenAI, więc kod klienta można łatwo przełączać między nimi poprzez zmianę base URL. API nie stanowi różnicy. Różnica polega na sposobie obsługi sytuacji, w której drugie żądanie dociera w momencie, gdy pierwsze wciąż generuje tokeny.
Czym w rzeczywistości jest Ollama
Ollama to warstwa ułatwiająca obsługę modeli. W ramach jednego polecenia instalacyjnego dostarcza rejestr modeli (ollama pull llama3.1:8b), lokalne repozytorium wag, interfejs czatu, usługę systemd oraz API HTTP. Serwowane modele to pliki GGUF, zazwyczaj kwantyzowane do 4 bitów, dzięki czemu model 7B lub 8B zajmuje na dysku około 5 GB zamiast 16 GB. Kwantyzacja jest kluczowa dla umożliwienia inferencji na procesorze (CPU).
Silnik uruchomieniowy oparto na llama.cpp, bibliotece C++ do inferencji, która uczyniła kwantyzację GGUF praktycznym rozwiązaniem na standardowym sprzęcie. Ollama dodała własny silnik dla niektórych nowszych rodzin modeli, jednak llama.cpp pozostaje fundamentem dla większości serwowanych treści. Porównywanie Ollama z llama.cpp jest zatem w dużej mierze zestawieniem warstwy ergonomicznej z narzędziem, które ona opakowuje.
Projekt zakłada obsługę jednego użytkownika. Według stanu na lipiec 2026, domyślna wartość dla OLLAMA_NUM_PARALLEL wynosi 1, co oznacza, że jeden model przetwarza jedno żądanie naraz, a pozostałe oczekują w kolejce mieszczącej domyślnie 512 wpisów (OLLAMA_MAX_QUEUE). Parametr równoległości można zwiększyć, a poniższa sekcja wyjaśnia związane z tym koszty. Jeśli Ollama nie była wcześniej używana, należy rozpocząć od lektury hostowania Ollama na VPS z zamkniętym portem 11434, ponieważ API nie posiada żadnego mechanizmu uwierzytelniania.
Czym w rzeczywistości jest vLLM
vLLM to wyłącznie serwer wnioskowania. Nie zarządza biblioteką modeli, nie posiada interfejsu czatu i nie pobiera modeli na żądanie. Podczas uruchamiania wskazuje się repozytorium Hugging Face, z którego ładowany jest jeden konkretny model, obsługiwany aż do momentu zatrzymania procesu.
W zamian za to ograniczenie uzyskuje się wysoką przepustowość. Za wydajność odpowiadają dwa mechanizmy. PagedAttention przechowuje pamięć podręczną KV (key-value cache, czyli stan uwagi dla każdego tokena, utrzymywany przez model dla każdego aktywnego żądania) w blokach o stałym rozmiarze, podobnie jak system operacyjny stronicuje pamięć. Żądanie nie wymaga już dużej, ciągłej rezerwacji pamięci obliczonej na najgorszy scenariusz, dzięki czemu przestrzeń, która wcześniej pozostawała zarezerwowana i niewykorzystana, staje się dostępna dla większej liczby jednoczesnych żądań. Continuous batching pozwala nowemu żądaniu dołączyć do uruchomionej partii w kolejnym kroku dekodowania, zamiast czekać na zakończenie przetwarzania całej bieżącej partii. Zakończona sekwencja natychmiast opuszcza partię, a zwolnione miejsce jest od razu zajmowane.
Praktyczny rezultat: na pojedynczym GPU przejście od jednego do trzydziestu jednoczesnych użytkowników znacząco zwiększa całkowitą liczbę generowanych tokenów na sekundę, podczas gdy spadek prędkości dla pojedynczego użytkownika jest znacznie mniejszy, niż można by oczekiwać. W domyślnej konfiguracji Ollama, przejście od jednego do trzydziestu użytkowników powoduje jedynie, że dwudziestu dziewięciu z nich musi czekać.
Continuous batching stanowi kluczową różnicę
Wyobraźmy sobie pięć żądań trafiających do serwera w tym samym momencie na identycznym sprzęcie.
Ollama przy ustawieniach domyślnych przetwarza pierwsze żądanie do końca, następnie drugie i tak dalej. Piąty użytkownik czeka na cztery pełne cykle generowania. Całkowita przepustowość jest w przybliżeniu równa prędkości pojedynczego generowania, ponieważ procesor pracuje tylko nad jedną sekwencją.
vLLM dekoduje wszystkie pięć żądań w tym samym przebiegu (forward pass). Wygenerowanie jednego tokena dla pięciu sekwencji kosztuje niewiele więcej niż dla jednej, ponieważ najbardziej kosztownym elementem jest odczyt wag modelu z pamięci, a ten odczyt jest współdzielony w ramach całej partii (batch). Jest to ten sam fakt dotyczący przepustowości pamięci, który sprawia, że wnioskowanie na CPU jest wolne: płaci się za przenoszenie wag, a nie za operacje arytmetyczne.
Można ustawić OLLAMA_NUM_PARALLEL=4 i uzyskać część tych korzyści. Kosztem jest pamięć. Każdy równoległy slot wymaga własnej pamięci podręcznej KV, a Ollama dzieli okno kontekstu pomiędzy sloty. W rezultacie cztery równoległe żądania do modelu skonfigurowanego na 8192 tokeny pozostawiają każdemu żądaniu 2048 tokenów kontekstu. Wartość 8192 jest wyborem, a nie narzuconym ograniczeniem, więc zwiększenie num_ctx i dopasowanie wymaganej pamięci RAM jest krokiem decydującym o tym, czy cztery sloty będą w ogóle użyteczne. Paged cache w vLLM pozwala uniknąć tego kompromisu, ponieważ bloki są przydzielane żądaniu w miarę jego rzeczywistego wzrostu. Tak czy inaczej, limit liczby osób, które pojedyncza maszyna może obsłużyć jednocześnie, zależy od rozmiaru pamięci podręcznej KV, kosztu prefill oraz głębokości kolejki, co jest powodem, dlaczego serwer działający poprawnie dla jednej osoby zwalnia przy pięciu.
Instalacja i udostępnianie za pomocą Ollama
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.1:8b
ollama run --verbose llama3.1:8b "Write two sentences about Linux."Skrypt instalacyjny tworzy użytkownika systemowego ollama, instaluje plik binarny i rejestruje ollama.service powiązany z 127.0.0.1:11434. Wartość eval rate wyświetlona przez --verbose to rzeczywista liczba tokenów na sekundę na danej maszynie. Należy jej ufać bardziej niż jakimkolwiek publikowanym danym. Jeden odczyt z jednego zapytania to punkt wyjścia, a nie wskaźnik wydajności, dlatego pomiar tokenów na sekundę przy zmiennym obciążeniu pozwala ocenić, czy serwer utrzyma oczekiwany ruch oraz czy wynajem GPU jest bardziej opłacalny niż płacenie za każdy token.
Aby zwiększyć współbieżność, należy użyć pliku typu drop-in dla systemd, co zapobiegnie nadpisaniu zmian podczas aktualizacji:
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_KEEP_ALIVE=30m"sudo systemctl restart ollama
ollama psollama ps pokazuje, co jest załadowane, a kolumna PROCESSOR wskazuje rzeczywisty stan. 100% CPU oznacza, że GPU nie jest wykorzystywane, co stanowi prawdziwą przyczynę większości zgłoszeń o wolnym działaniu Ollama. Wiersz OLLAMA_KEEP_ALIVE=30m w pliku drop-in jest równie istotny na maszynach o niskim obciążeniu, ponieważ domyślne ustawienie usuwa model z pamięci po pięciu minutach bezczynności, a utrzymywanie modelu w pamięci między zapytaniami eliminuje konieczność ponownego ładowania modelu przy pierwszym zapytaniu po godzinie bezczynności.
Instalacja i udostępnianie za pomocą vLLM
vLLM wymaga systemu Linux oraz środowiska Python w wersji od 3.10 do 3.13. Należy zainstalować go w odrębnym środowisku wirtualnym, ponieważ wymaga on specyficznej kompilacji PyTorch:
uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm --torch-backend=autoNastępnie należy uruchomić model. Nazwa musi być identyfikatorem repozytorium w serwisie Hugging Face, a nie krótkim tagiem:
vllm serve Qwen/Qwen2.5-1.5B-InstructPierwsze uruchomienie trwa długo, ponieważ system pobiera wagi, a następnie profiluje GPU w celu określenia liczby bloków pamięci podręcznej KV, które zmieszczą się w pamięci. Usługa nasłuchuje na porcie 8000. Należy sprawdzić jej działanie przed napisaniem kodu klienta:
curl http://localhost:8000/v1/models
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "Qwen/Qwen2.5-1.5B-Instruct", "messages": [{"role": "user", "content": "Who won the world series in 2020?"}]}'Jeśli na serwerze zainstalowano Docker, oficjalny obraz pozwala uniknąć problemów z zależnościami CUDA:
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
--env "HF_TOKEN=$HF_TOKEN" \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model Qwen/Qwen3-0.6BFlaga --ipc=host jest wymagana, a nie opcjonalna: PyTorch przesyła tensory między procesami za pomocą pamięci współdzielonej, a domyślny przydział pamięci współdzielonej w Docker jest zbyt mały dla wnioskowania z wykorzystaniem równoległości tensorowej.
Najważniejsze flagi w środowisku produkcyjnym to --max-model-len (okno kontekstowe, które zamierzasz obsługiwać), --gpu-memory-utilization (część pamięci karty, którą vLLM może zająć; domyślnie 0.92 według stanu na lipiec 2026), --tensor-parallel-size służąca do podziału jednego modelu na kilka jednostek GPU oraz --api-key.
Uwierzytelnianie to jedna flaga w vLLM i brak w Ollama
vLLM wymusza użycie tokena bearer, jeśli zostanie on podany:
vllm serve Qwen/Qwen2.5-1.5B-Instruct --api-key token-abc123Tę samą wartość można przekazać za pomocą zmiennej środowiskowej VLLM_API_KEY. Żądanie bez tokena kończy się błędem HTTP 401. Nie jest to wystarczający powód, aby wystawiać port 8000 na publicznym interfejsie, ponieważ vLLM nie posiada mechanizmu ograniczania liczby żądań (rate limiting), a zwykły token HTTP jest czytelny podczas transmisji. Oznacza to jednak, że serwer rozpoznaje tożsamość wywołującego.
Ollama nie posiada takich funkcji. Brak jest klucza, logowania czy listy dozwolonych adresów. Każdy proces, który ma dostęp do portu 11434, może uruchamiać, pobierać lub usuwać modele. Należy utrzymywać usługę na interfejsie loopback i uzyskiwać do niej dostęp przez samodzielnie hostowaną sieć VPN WireGuard lub poprzez uwierzytelniający reverse proxy, który dokonuje terminacji TLS (transport layer security).
Wymagania sprzętowe: co jest potrzebne dla każdego rozwiązania
Ollama działa na procesorze (CPU). Model skwantyzowany do 4-bitów zajmuje około pół gigabajta pamięci RAM na miliard parametrów, plus około gigabajta narzutu na środowisko uruchomieniowe oraz dodatkową pamięć na kontekst. Model 3B wymaga więc około 4 GB wolnej pamięci, a model 8B około 8 GB. Szybkość na współdzielonym vCPU wynosi od kilku do kilkunastu tokenów na sekundę. Wynika to z przepustowości pamięci, a nie z błędnej konfiguracji, więc żadna flaga tego nie naprawi. Aby sprawdzić te obliczenia w praktyce dla konkretnego wydania, zamiast polegać na szacunkach, uruchomienie Nemotron 3.5 Lightning na VPS pozwala precyzyjnie określić tag do pobrania, zajętość pamięci RAM po załadowaniu oraz ocenić, czy wydajność samego CPU jest akceptowalna.
vLLM zakłada użycie GPU. Domyślna ścieżka obsługuje niekwantyzowane wagi w precyzji 16-bitowej, co oznacza około 2 GB na miliard parametrów: model 8B wymaga około 16 GB pamięci wideo na same wagi, jeszcze przed przydzieleniem pamięci na cache KV, która zapewnia współbieżność, dla której zainstalowano vLLM. Na karcie 24 GB pozostawia to użyteczną ilość pamięci na cache. Na karcie 16 GB jest to niemożliwe, więc należy wybrać mniejszy model lub przekazać --quantization z kwantyzowanym punktem kontrolnym (checkpoint). Istnieje backend dla CPU, ale standardowe pakiety nie są dla niego budowane i niweluje to sens używania vLLM.
Kwestia sprzętowa zazwyczaj rozstrzyga wybór oprogramowania. Brak GPU oznacza wybór Ollama. Wynajęte GPU, które wykazuje 5 procent wykorzystania z powodu szeregowania żądań, oznacza potrzebę użycia vLLM.
Wybór rozwiązania dla danego obciążenia
- Jedna osoba, VPS z procesorem CPU, tworzenie szkiców i podsumowań: Ollama. Tempo pracy jest akceptowalne, a prostszego rozwiązania nie ma.
- Asystent programistyczny lub serwer MCP łączący narzędzia z lokalnym modelem, z którego korzystasz tylko Ty: Ollama. Obsługa jednego połączenia jednocześnie to rzeczywiste obciążenie.
- Porównywanie pięciu modeli w tym tygodniu: Ollama. Pobieranie i usuwanie otagowanych modeli to zadanie, w którym to narzędzie sprawdza się najlepiej, podczas gdy vLLM wymaga restartu procesu dla każdego modelu.
- Aplikacja wewnętrzna, produkt typu chat lub potok wyszukiwania z rzeczywistymi użytkownikami: vLLM. To przypadek, w którym przetwarzanie wsadowe uzasadnia koszty GPU.
- Zadanie wsadowe polegające na ocenie stu tysięcy dokumentów w ciągu nocy: vLLM z wysokim parametrem
--max-num-seqs. Przepustowość jest jedyną istotną metryką, a opóźnienie dla pojedynczego dokumentu nie ma znaczenia. - Platforma agentowa, w której kilka samodzielnie hostowanych agentów AI odpytuje model jednocześnie: vLLM, ponieważ ruch generowany przez agentów ma charakter skokowy i z natury jest równoległy.
Tryby awaryjne i odpowiadające im komunikaty
vLLM odmawia uruchomienia z błędem pamięci podręcznej KV. Komunikat zawiera obie wartości liczbowe:
ValueError: The model's max seq len (32768) is larger than the maximum number of tokens that can be stored in KV cache (8192). Try increasing gpu_memory_utilization or decreasing max_model_len when initializing the engine.Model deklaruje okno kontekstowe większe niż ilość pamięci pozostała po załadowaniu wag. Należy je zmniejszyć za pomocą --max-model-len 8192 lub zwiększyć --gpu-memory-utilization, jeśli karta nie jest używana przez inne procesy. Zwiększanie wykorzystania powyżej około 0.95 zazwyczaj prowadzi do zamiany tego błędu startowego na późniejszy błąd CUDA out-of-memory podczas pracy pod obciążeniem, co jest rozwiązaniem mniej korzystnym.
Ollama wyświetla Killed w trakcie generowania. Mechanizm Linux out-of-memory killer zatrzymał proces, ponieważ model wymagał więcej pamięci RAM, niż posiada serwer. Potwierdź to za pomocą sudo dmesg | grep -i oom. Rozwiązaniem jest wybór mniejszego lub mocniej skwantyzowanego modelu, a nie zmiana ustawień.
Ollama odpowiada poprawnie przy pojedynczym zapytaniu, ale zawiesza się pod obciążeniem. W logach nie pojawiają się żadne błędy. Czas odpowiedzi wydłuża się wraz ze wzrostem liczby użytkowników, ponieważ OLLAMA_NUM_PARALLEL=1 szereguje zapytania. Długie odpowiedzi pogarszają sytuację w kolejce, ponieważ jeden użytkownik blokuje jedyny dostępny slot do momentu zakończenia generowania przez model, dlatego ograniczenie odpowiedzi za pomocą num_predict ustala górny limit czasu, przez jaki pojedyncze zapytanie może blokować serwer. Zwiększ ustawienie równoległości i zaakceptuj mniejszy kontekst na zapytanie lub przenieś obciążenie do vLLM.
vLLM zwraca błąd 401 przy każdym wywołaniu. Usługa została uruchomiona z flagą --api-key, a klient nie wysyła nagłówka Authorization. Większość bibliotek klienckich OpenAI wysyła dowolną wartość przekazaną jako klucz, więc należy ustawić go tam, zamiast usuwać flagę.
vLLM zgłasza, że model nie został znaleziony. Ollama pobiera modele na żądanie, vLLM tego nie robi. Pole model w treści zapytania musi być zgodne z identyfikatorem repozytorium, z którym uruchomiono usługę, lub z wartością --served-model-name, jeśli została ustawiona. Dokładny ciąg znaków można zweryfikować za pomocą curl http://localhost:8000/v1/models.
Uruchomienie obu rozwiązań jest uzasadnionym podejściem
Nie wykluczają się one wzajemnie. Typowa konfiguracja obejmuje vLLM na instancji z GPU obsługującej aplikację oraz Ollama na standardowym VPS obok, wykorzystywanym do lokalnych skryptów, zadań cron oraz testowania nowych wydań modeli. Oba punkty końcowe są zgodne z API OpenAI, więc jedna biblioteka kliencka i zmiana base-URL pozwalają na obsługę obu. Kontrola kosztów jest tutaj ważniejsza niż wybór silnika, ponieważ bezczynne GPU generuje takie same opłaty jak obciążone, a utrzymanie przewidywalnych kosztów agentów i wnioskowania to odrębne zagadnienie od wyboru serwera.
FAQ
Czy vLLM jest szybszy niż Ollama?
W przypadku pojedynczego żądania na tym samym GPU różnica jest niewielka, ponieważ obie aplikacje wykonują te same obliczenia. Przy wielu jednoczesnych żądaniach vLLM ma znaczną przewagę, ponieważ ciągłe przetwarzanie wsadowe (continuous batching) dekoduje każdą aktywną sekwencję w jednym przebiegu, podczas gdy domyślna konfiguracja Ollama przetwarza je jedna po drugiej. Na maszynie wyposażonej tylko w CPU pytanie to jest bezprzedmiotowe: Ollama działa w takim środowisku, a vLLM praktycznie nie.
Czy vLLM może działać bez GPU?
Nie w sposób użyteczny. Standardowe pakiety są przeznaczone dla GPU NVIDIA lub AMD, a główny cel istnienia vLLM, czyli utrzymywanie akceleratora w stanie pełnego obciążenia dzięki przetwarzaniu wsadowemu, na CPU traci sens. Backend CPU istnieje wyłącznie do celów programistycznych. Do rzeczywistej inferencji na CPU należy używać bezpośrednio Ollama lub llama.cpp.
Jaka jest różnica między Ollama a llama.cpp?
llama.cpp to biblioteka do inferencji, a GGUF to jej format kwantyzowanych wag. Silnik Ollama jest na niej zbudowany i dodaje elementy, które w llama.cpp trzeba skonfigurować samodzielnie: rejestr modeli, automatyczne pobieranie, działający w tle serwer, jednostkę systemd oraz punkt końcowy zgodny z API OpenAI. Ollama wprowadziła własny silnik dla niektórych nowszych rodzin modeli, więc oba rozwiązania nie są już identyczne pod spodem.
Ile pamięci GPU potrzebuje vLLM dla modelu 8B?
Przy precyzji 16-bitowej same wagi zajmują około 16 GB, czyli w przybliżeniu 2 GB na miliard parametrów, a pamięć podręczna KV wymaga dodatkowego miejsca. Karta 24 GB zapewnia komfort pracy. Karta 16 GB wymaga użycia skwantyzowanego punktu kontrolnego lub mniejszego modelu. vLLM rezerwuje część pamięci karty określoną przez --gpu-memory-utilization, co na lipiec 2026 roku domyślnie wynosi 0.92.
Czy muszę zmieniać kod aplikacji, aby przełączać się między nimi?
Zazwyczaj wystarczy zmienić bazowy URL, klucz API oraz nazwę modelu. Ollama udostępnia interfejs zgodny z OpenAI pod adresem http://127.0.0.1:11434/v1 i ignoruje klucz, podczas gdy vLLM udostępnia http://localhost:8000/v1 i wymusza użycie klucza, jeśli został ustawiony. Nazwy modeli różnią się formatem: llama3.1:8b dla Ollama, a pełny identyfikator repozytorium, taki jak Qwen/Qwen2.5-1.5B-Instruct, dla vLLM.