Szybki start vLLM: Wysokowydajne obsługiwanie modeli LLM

Szybka inferencja LLM z użyciem API OpenAI

Page content

vLLM to silny, wydajny silnik wdrażania i inferencji dla dużych modeli językowych (LLM), opracowany przez Sky Computing Lab z UC Berkeley.

Z wykorzystaniem rewolucyjnego algorytmu PagedAttention, vLLM osiąga wydajność 14–24 razy większą niż tradycyjne metody wdrażania, stając się najlepszym wyborem do wdrażania LLM w środowiskach produkcyjnych.

vllm logo

Co to jest vLLM?

vLLM (wirtualny LLM) to biblioteka open-source do szybkiej inferencji i wdrażania LLM, która szybko stała się standardem branżowym dla wdrożeń produkcyjnych. Wydana w 2023 roku, wprowadziła PagedAttention, innowacyjną technikę zarządzania pamięcią, która znacząco poprawia wydajność wdrażania.

Kluczowe funkcje

Wysoka wydajność: vLLM zapewnia wydajność 14–24 razy większą niż HuggingFace Transformers przy tej samej konfiguracji sprzętu. Ten ogromny zysk w wydajności pochodzi z ciągłego batchowania, zoptymalizowanych jąder CUDA oraz algorytmu PagedAttention, który eliminuje fragmentację pamięci.

Kompatybilność z API OpenAI: vLLM zawiera wbudowany serwer API, który jest w pełni kompatybilny z formatem OpenAI. To umożliwia płynne przechodzenie z OpenAI na infrastrukturę samowdrażaną bez konieczności zmiany kodu aplikacji. Wystarczy, że wskazasz klienta API na punkt końcowy vLLM i działa on przezroczysto.

Algorytm PagedAttention: Jądro innowacji za wydajnością vLLM to PagedAttention, który stosuje koncepcję wirtualnego paginowania pamięci do mechanizmów uwagi. Zamiast alokować kontynuowane bloki pamięci dla cache’ów KV (co prowadzi do fragmentacji), PagedAttention dzieli pamięć na stałe rozmiary bloków, które mogą być alokowane na żądanie. To zmniejsza marnotrawstwo pamięci aż do 4 razy i umożliwia znacznie większe rozmiary batchów.

Ciągłe batchowanie: Odpowiadając na statyczne batchowanie, gdzie czeka się, aż wszystkie sekwencje zostaną zakończone, vLLM korzysta z ciągłego (rolującego) batchowania. Natychmiast po zakończeniu jednej sekwencji, nowa może zostać dodana do batcha. To maksymalizuje wykorzystanie GPU i minimalizuje opóźnienia dla przychodzących żądań.

Wsparcie dla wielu GPU: vLLM obsługuje tensor parallelism i pipeline parallelism do dystrybucji dużych modeli na wielu GPU. Może skutecznie wdrażać modele, które nie mieszczą się w pamięci pojedynczego GPU, wspierając konfiguracje od 2 do 8+ GPU.

Szeroka obsługa modeli: Kompatybilna z popularnymi architekturami modeli, w tym LLaMA, Mistral, Mixtral, Qwen, Phi, Gemma i wieloma innymi. Obsługuje zarówno modele zoptymalizowane pod kątem instrukcji, jak i podstawowe modele z HuggingFace Hub.

Kiedy używać vLLM

vLLM wyróżnia się w konkretnych scenariuszach, w których jego siły są najbardziej widoczne:

Usługi API produkcyjne: Gdy potrzebujesz wdrażania LLM dla wielu użytkowników jednocześnie poprzez API, vLLM ma najwyższą wydajność i efektywne batchowanie, stając się najlepszym wyborem. Firmy prowadzące chatboty, asystenty kodowe lub usługi generowania treści korzystają z jego możliwości, aby obsługiwać setki żądań na sekundę.

Wysoka wydajność w warunkach wysokiego obciążenia: Jeśli aplikacja ma wielu użytkowników jednocześnie wysyłających żądania, ciągłe batchowanie i PagedAttention w vLLM pozwalają obsłużyć więcej użytkowników przy tej samej konfiguracji sprzętu niż inne narzędzia.

Optymalizacja kosztów: Gdy koszty GPU są krytyczne, wyższa wydajność vLLM oznacza, że możesz obsłużyć ten sam ruch przy mniejszej liczbie GPU, bezpośrednio zmniejszając koszty infrastruktury. 4-krotnie większa wydajność pamięci z PagedAttention pozwala również na użycie mniejszych, tańszych instancji GPU.

Wdrażanie w Kubernetes: Bezstanowa architektura vLLM i przyjazne kontenerom środowisko robocze czynią z niego idealne narzędzie do wdrażania w klastrach Kubernetes. Jego spójna wydajność przy obciążeniu i prostota zarządzania zasobami dobrze współgra z infrastrukturą opartą na chmurze.

Kiedy nie używać vLLM: Dla lokalnego rozwoju, eksperymentowania lub scenariuszy jednoosobowych, narzędzia takie jak Ollama oferują lepsze doświadczenie użytkownika z prostszym ustawieniem. Złożoność vLLM jest uzasadniona, gdy potrzebujesz jego zalet wydajnościowych dla obciążeń produkcyjnych.

Jak zainstalować vLLM

Wymagania wstępne

Przed instalacją vLLM upewnij się, że system spełnia wymagania:

  • GPU: NVIDIA GPU z możliwością obliczeniową 7.0+ (V100, T4, A10, A100, H100, RTX 20/30/40 series)
  • CUDA: Wersja 11.8 lub nowsza
  • Python: 3.8 do 3.11
  • VRAM: Minimum 16 GB dla modeli 7B, 24 GB+ dla modeli 13B, 40 GB+ dla większych modeli
  • Sterownik: Sterownik NVIDIA 450.80.02 lub nowszy

Instalacja za pomocą pip

Najprostszym sposobem instalacji jest użycie pip. Działa to na systemach z CUDA 11.8 lub nowszym:

# Utwórz środowisko wirtualne (rekomendowane)
python3 -m venv vllm-env
source vllm-env/bin/activate

# Zainstaluj vLLM
pip install vllm

# Sprawdź instalację
python -c "import vllm; print(vllm.__version__)"

Dla systemów z różnymi wersjami CUDA zainstaluj odpowiedni pakiet:

# Dla CUDA 12.1
pip install vllm==0.4.2+cu121 -f https://github.com/vllm-project/vllm/releases

# Dla CUDA 11.8
pip install vllm==0.4.2+cu118 -f https://github.com/vllm-project/vllm/releases

Instalacja za pomocą Docker

Docker oferuje najbardziej niezawodny sposób wdrażania, szczególnie w środowiskach produkcyjnych:

# Pobierz oficjalny obraz vLLM
docker pull vllm/vllm-openai:latest

# Uruchom vLLM z obsługą GPU
docker run --runtime nvidia --gpus all \
    -v ~/.cache/huggingface:/root/.cache/huggingface \
    -p 8000:8000 \
    --ipc=host \
    vllm/vllm-openai:latest \
    --model mistralai/Mistral-7B-Instruct-v0.2

Flaga --ipc=host jest ważna dla konfiguracji wielu GPU, ponieważ umożliwia poprawną komunikację międzyprocesową.

Instalacja z źródeł

Aby uzyskać najnowsze funkcje lub dostosowania, zainstaluj z źródeł:

git clone https://github.com/vllm-project/vllm.git
cd vllm
pip install -e .

Przewodnik szybkiego startu vLLM

Uruchamianie pierwszego modelu

Uruchom vLLM z modelem za pomocą interfejsu wiersza poleceń:

# Pobierz i uruchom Mistral-7B z API kompatybilnym z OpenAI
python -m vllm.entrypoints.openai.api_server \
    --model mistralai/Mistral-7B-Instruct-v0.2 \
    --port 8000

vLLM automatycznie pobra model z HuggingFace Hub (jeśli nie jest jeszcze w cache’u) i uruchomi serwer. Zobaczysz komunikaty wskazujące, że serwer jest gotowy:

INFO:     Started server process [12345]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000

Wysyłanie żądań API

Po uruchomieniu serwera możesz wysyłać żądania za pomocą klienta Pythona OpenAI lub curl:

Użycie curl:

curl http://localhost:8000/v1/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "mistralai/Mistral-7B-Instruct-v0.2",
        "prompt": "Wyjaśnij, co to jest vLLM w jednym zdaniu:",
        "max_tokens": 100,
        "temperature": 0.7
    }'

Użycie klienta Pythona OpenAI:

from openai import OpenAI

# Wskazanie do serwera vLLM
client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"  # vLLM nie wymaga uwierzytelnienia domyślnie
)

response = client.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    prompt="Wyjaśnij, co to jest vLLM w jednym zdaniu:",
    max_tokens=100,
    temperature=0.7
)

print(response.choices[0].text)

API Chat Completions:

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[
        {"role": "system", "content": "Jesteś pomocnym asystentem."},
        {"role": "user", "content": "Co to jest PagedAttention?"}
    ],
    max_tokens=200
)

print(response.choices[0].message.content)

Zaawansowane konfiguracje

vLLM oferuje wiele parametrów do optymalizacji wydajności:

python -m vllm.entrypoints.openai.api_server \
    --model mistralai/Mistral-7B-Instruct-v0.2 \
    --port 8000 \
    --gpu-memory-utilization 0.95 \  # Użyj 95% pamięci GPU
    --max-model-len 8192 \            # Maksymalna długość sekwencji
    --tensor-parallel-size 2 \        # Użyj 2 GPU z tensor parallelism
    --dtype float16 \                 # Użyj FP16
    --max-num-seqs 256                # Maksymalna liczba sekwencji

Wyjaśnienie kluczowych parametrów:

  • --gpu-memory-utilization: Ile pamięci GPU ma być używane (0.90 = 90%). Wyższe wartości pozwalają na większe batchy, ale pozostawiają mniej marginesu dla wstrząsów pamięci.
  • --max-model-len: Maksymalna długość kontekstu. Zmniejszenie tej wartości oszczędza pamięć na większe batchy.
  • --tensor-parallel-size: Liczba GPU, na które ma być podzielony model.
  • --dtype: Typ danych dla wag (float16, bfloat16 lub float32). FP16 jest zwykle optymalny.
  • --max-num-seqs: Maksymalna liczba sekwencji do przetworzenia w batchu.

Porównanie vLLM i Ollama

Oba vLLM i Ollama są popularnymi narzędziami do lokalnego wdrażania LLM, ale są przeznaczone do różnych przypadków użycia. Zrozumienie, kiedy używać każdego narzędzia, może znacząco wpłynąć na sukces projektu.

Wydajność i przepustowość

vLLM zostało zaprojektowane do maksymalnej przepustowości w scenariuszach wielu użytkowników. Dzięki PagedAttention i ciągłemu batchowaniu umożliwia skuteczne obsługę setek żądań jednocześnie. Testy pokazują, że vLLM osiąga 14–24 razy większą przepustowość niż standardowe implementacje i 2–4 razy większą niż Ollama w warunkach wysokiej przepustowości.

Ollama optymalizuje się pod kątem interaktywnego użycia przez jednego użytkownika, skupiając się na niskim opóźnieniu dla pojedynczych żądań. Choć nie dorównuje vLLM pod względem przepustowości wielu użytkowników, oferuje wspaniałą wydajność dla rozwoju i użycia osobistego z szybszymi czasami startu i niższym zużyciem zasobów w stanie bezczynności.

Łatwość użycia

Ollama wygrywa decydująco pod względem prostoty. Instalacja to jedno polecenie (curl | sh), a uruchamianie modeli jest tak proste jak ollama run llama2. Wchodzi w skład biblioteki modeli z wersjami skwantowanymi zoptymalizowanymi dla różnych konfiguracji sprzętu. Doświadczenie użytkownika przypomina Docker – pobierz, uruchom i gotowe.

vLLM wymaga więcej konfiguracji: zarządzanie środowiskiem Pythona, instalacja CUDA, zrozumienie parametrów wdrażania i ręczna specyfikacja modelu. Krzywa nauki jest stroma, ale otrzymujesz szczegółowe kontrole nad optymalizacją wydajności. Ta złożoność jest uzasadniona w wdrożeniach produkcyjnych, gdzie potrzebujesz maksymalnej wydajności sprzętu.

API i integracja

vLLM oferuje gotowe REST API kompatybilne z OpenAI, co czyni go idealnym zamiennikiem API OpenAI w istniejących aplikacjach. To kluczowe przy migracji usług produkcyjnych z dostawców chmurowych na infrastrukturę samowdrażaną bez konieczności zmian w kodzie.

Ollama oferuje prostsze REST API i dedykowane biblioteki Pythona/JavaScript. Choć funkcjonalne, nie są kompatybilne z formatem OpenAI, wymagając zmian w kodzie przy integracji z aplikacjami oczekującymi na format OpenAI. Jednak projekty społecznościowe takie jak Ollama-OpenAI adaptery wypełniają tę lukę.

Zarządzanie pamięcią

vLLM algorytm PagedAttention oferuje wyższą efektywność pamięci dla żądań wielu użytkowników. Może obsłużyć 2–4 razy więcej użytkowników jednocześnie przy tej samej VRAM niż implementacje proste. To bezpośrednio przekłada się na oszczędności kosztów w wdrożeniach produkcyjnych.

Ollama używa prostszego zarządzania pamięcią odpowiedniego dla scenariuszy jednoosobowych. Automatycznie zarządza ładowaniem i wyjmowaniem modeli na podstawie aktywności, co jest wygodne w rozwoju, ale nie optymalne w warunkach wysokiej przepustowości produkcyjnej.

Wsparcie dla wielu GPU

vLLM wyróżnia się w native tensor parallelism i pipeline parallelism, efektywnie dystrybuując modele na 2–8+ GPU. To jest kluczowe do wdrażania dużych modeli, takich jak LLM z 70B parametrami, które nie mieszczą się w pamięci pojedynczego GPU.

Ollama ma ograniczone wsparcie dla wielu GPU, najlepiej działając z jednym GPU. To czyni go mniej odpowiednim do bardzo dużych modeli wymagających dystrybucyjnej inferencji.

Zalecenia dotyczące przypadków użycia

Wybierz vLLM, gdy:

  • Wdrażasz produkcyjne usługi API dla wielu użytkowników jednocześnie
  • Optymalizujesz koszty na żądanie w wdrożeniach chmurowych
  • Uruchamiasz w Kubernetes lub platformach orchestracji kontenerów
  • Potrzebujesz kompatybilności z API OpenAI dla istniejących aplikacji
  • Wdrażasz duże modele wymagające wsparcia wielu GPU
  • Wydajność i przepustowość są kluczowymi wymaganiami

Wybierz Ollama, gdy:

  • Pracujesz nad lokalnym rozwojem i eksperymentami
  • Używasz interaktywnie przez jednego użytkownika (asystenci, chatboty)
  • Przeprowadzasz szybkie prototypowanie i ocenę modeli
  • Uczy się LLM bez złożoności infrastruktury
  • Uruchamiasz na osobistych komputerach stacjonarnych lub laptopach
  • Prostota i łatwość użycia są priorytetem

Wiele zespołów korzysta z obu: Ollama do rozwoju i eksperymentów, a vLLM do wdrożeń produkcyjnych. To połączenie zapewnia produktywność deweloperów, jednocześnie utrzymując wydajność wdrożeń produkcyjnych.

Porównanie vLLM i Docker Model Runner

Docker niedawno wprowadził Model Runner (wcześniej GenAI Stack) jako oficjalne rozwiązanie do lokalnego wdrażania modeli AI. Jak to porównuje się do vLLM?

Filozofia architektury

Docker Model Runner dąży do być “Dockerem dla AI” – prostym, standardowym sposobem uruchamiania modeli AI lokalnie z tą samą łatwością, jak uruchamianie kontenerów. Abstrahuje złożoność i oferuje spójny interfejs dla różnych modeli i frameworków.

vLLM to specjalizowany silnik inferencji skupiony wyłącznie na wdrażaniu LLM z maksymalną wydajnością. Jest to narzędzie na niższym poziomie, które konteneryzujesz z Dockerem, a nie cała platforma.

Ustawienia i rozpoczęcie

Docker Model Runner instalacja jest prosta dla użytkowników Docker:

docker model pull llama3:8b
docker model run llama3:8b

To podobieństwo do przepływu obrazów Docker czyni to natychmiast znane dla deweloperów korzystających z kontenerów.

vLLM wymaga więcej początkowej konfiguracji (Python, CUDA, zależności) lub użycia gotowych obrazów Docker:

docker pull vllm/vllm-openai:latest
docker run --runtime nvidia --gpus all vllm/vllm-openai:latest --model <model-name>

Charakterystyka wydajności

vLLM dostarcza wyższą przepustowość w scenariuszach wielu użytkowników dzięki PagedAttention i ciągłemu batchowaniu. Dla usług API produkcyjnych obsługujących setki żądań na sekundę, optymalizacje vLLM dają 2–5 razy lepszą przepustowość niż standardowe podejścia do wdrażania.

Docker Model Runner skupia się na łatwości użycia, a nie maksymalnej wydajności. Jest odpowiedni do rozwoju lokalnego, testowania i umiarkowanych obciążeń, ale nie implementuje zaawansowanych optymalizacji, które sprawiają, że vLLM wyróżnia się przy skalowaniu.

Wsparcie dla modeli

Docker Model Runner oferuje wyselekcjonowaną bibliotekę modeli z jednokrotnym dostępem do popularnych modeli. Obsługuje wiele frameworków (nie tylko LLM), w tym Stable Diffusion, Whisper i inne modele AI, czyniąc go bardziej uniwersalnym dla różnych obciążeń AI.

vLLM specjalizuje się w inferencji LLM z głęboką obsługą modeli językowych opartych na transformatorach. Obsługuje każdy LLM kompatybilny z HuggingFace, ale nie rozszerza się na inne typy modeli AI, takie jak generowanie obrazów lub rozpoznawanie mowy.

Wdrażanie w środowisku produkcyjnym

vLLM przetestowany w środowisku produkcyjnym przez firmy takie jak Anthropic, Replicate i wiele innych, obsługujące dziennie miliardy tokenów. Jego charakterystyka wydajności i stabilność przy obciążeniu wysokiego poziomu czynią go standardem de facto dla wdrażania LLM w środowisku produkcyjnym.

Docker Model Runner jest nowszy i pozytuje się bardziej na scenariusze rozwoju i testowania lokalnego. Choć może obsługiwać ruch produkcyjny, brakuje mu udowodnionej wiedzy i optymalizacji wydajności, które wymagają wdrożeń produkcyjnych.

Ekosystem integracji

vLLM integruje się z narzędziami infrastruktury produkcyjnej: operatory Kubernetes, metryki Prometheus, Ray do dystrybucyjnego wdrażania i szerokiej kompatybilności z API OpenAI dla istniejących aplikacji.

Docker Model Runner integruje się naturalnie z ekosystemem Docker i Docker Desktop. Dla zespołów standardowych na Dockerze, ta integracja oferuje spójne doświadczenie, ale mniej specjalistycznych funkcji wdrażania LLM.

Kiedy używać każdego

Użyj vLLM, gdy:

  • Wdrażasz produkcyjne usługi API LLM
  • Wysoka przepustowość, wdrażanie wielu użytkowników
  • Koszty w chmurze są krytyczne, potrzebujesz maksymalnej wydajności
  • Kubernetes i środowiska oparte na chmurze
  • Potrzebujesz udowodnionej skalowalności i wydajności

Użyj Docker Model Runner, gdy:

  • Pracujesz nad lokalnym rozwojem i testowaniem
  • Uruchamiasz różne typy modeli AI (nie tylko LLM)
  • Zespół jest mocno zaangażowany w ekosystem Docker
  • Eksperymentujesz szybko bez konieczności konfiguracji infrastruktury
  • Uczą się i edukacyjne cele

Hybrydowy podejście: Wiele zespołów korzysta z Docker Model Runner lokalnie dla wygody, a potem wdraża z vLLM w środowisku produkcyjnym dla wydajności. Obrazy Docker Model Runner mogą również być używane do uruchamiania kontenerów vLLM, łącząc oba podejścia.

Najlepsze praktyki wdrażania w środowisku produkcyjnym

Wdrażanie za pomocą Docker

Utwórz konfigurację Docker Compose gotową do produkcji:

version: '3.8'

services:
  vllm:
    image: vllm/vllm-openai:latest
    runtime: nvidia
    environment:
      - CUDA_VISIBLE_DEVICES=0,1
    volumes:
      - ~/.cache/huggingface:/root/.cache/huggingface
      - ./logs:/logs
    ports:
      - "8000:800端口
    command: >
      --model mistralai/Mistral-7B-Instruct-v0.2
      --tensor-parallel-size 2
      --gpu-memory-utilization 0.90
      --max-num-seqs 256
      --max-model-len 8192      
    restart: unless-stopped
    shm_size: '16gb'
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 2
              capabilities: [gpu]

Wdrażanie na Kubernetes

Wdrażanie vLLM na Kubernetes dla skalowalności produkcyjnej:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: vllm
  template:
    metadata:
      labels:
        app: vllm
    spec:
      containers:
      - name: vllm
        image: vllm/vllm-openai:latest
        args:
          - --model
          - mistralai/Mistral-7B-Instruct-v0.2
          - --tensor-parallel-size
          - "2"
          - --gpu-memory-utilization
          - "0.90"
        resources:
          limits:
            nvidia.com/gpu: 2
        ports:
        - containerPort: 8000
        volumeMounts:
        - name: cache
          mountPath: /root/.cache/huggingface
      volumes:
      - name: cache
        hostPath:
          path: /mnt/huggingface-cache
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-service
spec:
  selector:
    app: vllm
  ports:
  - port: 80
    targetPort: 8000
  type: LoadBalancer

Monitorowanie i obserwacja

vLLM udostępnia metryki Prometheus do monitorowania:

import requests

# Pobierz metryki
metrics = requests.get("http://localhost:8000/metrics").text
print(metrics)

Kluczowe metryki do monitorowania:

  • vllm:num_requests_running - Aktywne żądania
  • vllm:gpu_cache_usage_perc - Użycie cache’u GPU
  • vllm:time_to_first_token - Metryka opóźnienia
  • vllm:time_per_output_token - Szybkość generowania

Optymalizacja wydajności

Optymalizuj wykorzystanie pamięci GPU: Zaczynaj od --gpu-memory-utilization 0.90 i dostosuj na podstawie obserwowanego zachowania. Wyższe wartości pozwalają na większe batchy, ale ryzykują błędy OOM podczas szczytów ruchu.

Dostosuj maksymalną długość sekwencji: Jeśli Twój scenariusz nie wymaga pełnej długości kontekstu, zmniejsz --max-model-len. To zwalnia pamięć dla większych batchów. Na przykład, jeśli potrzebujesz tylko 4K kontekstu, ustaw --max-model-len 4096 zamiast używania maksymalnej długości modelu (często 8K–32K).

Wybierz odpowiednie kwantyzacje: Dla modeli, które to wspierają, użyj wersji skwantowanych (8-bit, 4-bit), aby zmniejszyć pamięć i zwiększyć przepustowość:

--quantization awq  # Dla modeli skwantowanych AWQ
--quantization gptq # Dla modeli skwantowanych GPTQ

Włącz pamięć cache dla prefiksów: Dla aplikacji z powtarzającymi się promptami (np. chatboty z systemowymi wiadomościami), włącz pamięć cache dla prefiksów:

--enable-prefix-caching

To cacheuje wartości KV dla wspólnych prefiksów, zmniejszając obliczenia dla żądań udostępniających ten sam prefiks promptu.

Rozwiązywanie typowych problemów

Błędy niedostępności pamięci

Objawy: Serwer zawiesza się z błędami CUDA out of memory.

Rozwiązania:

  • Zmniejsz --gpu-memory-utilization do 0,85 lub 0,80
  • Zmniejsz --max-model-len, jeśli Twój scenariusz pozwala
  • Obniż --max-num-seqs, aby zmniejszyć rozmiar batcha
  • Użyj wersji modelu skwantowanej
  • Włącz tensor parallelism, aby rozdzielić na więcej GPU

Niska przepustowość

Objawy: Serwer obsługuje mniej żądań niż przewidywano.

Rozwiązania:

  • Zwiększ --max-num-seqs, aby pozwolić na większe batchy
  • Podnieś --gpu-memory-utilization, jeśli masz margines
  • Sprawdź, czy CPU jest uwięziony z htop – rozważ szybsze CPU
  • Sprawdź wykorzystanie GPU z nvidia-smi – powinno być 95%+
  • Włącz FP16, jeśli używasz FP32: --dtype float16

Wolne pierwsze tokeny

Objawy: Wysokie opóźnienie przed rozpoczęciem generowania.

Rozwiązania:

  • Użyj mniejszych modeli dla aplikacji krytycznych pod względem opóźnienia
  • Włącz pamięć cache dla powtarzających się promptów
  • Zmniejsz --max-num-seqs, aby priorytetyzować opóźnienie nad przepustowością
  • Rozważ dekodowanie speculacyjne dla obsługiwanych modeli
  • Optymalizuj konfigurację tensor parallelism

Błędy ładowania modelu

Objawy: Serwer nie uruchamia się, nie może załadować modelu.

Rozwiązania:

  • Sprawdź, czy nazwa modelu dokładnie odpowiada formatowi HuggingFace
  • Sprawdź połączenie sieciowe z HuggingFace Hub
  • Upewnij się, że jest wystarczająco dużo miejsca na dysku w ~/.cache/huggingface
  • Dla modeli zabezpieczonych, ustaw zmienną środowiskową HF_TOKEN
  • Spróbuj ręcznie pobrać z huggingface-cli download <model>

Zaawansowane funkcje

Dekodowanie speculacyjne

vLLM obsługuje dekodowanie speculacyjne, gdzie mniejszy model wstępny sugeruje tokeny, które weryfikuje większy model docelowy. Może przyspieszyć generowanie o 1,5–2 razy:

python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-70b-chat-hf \
    --speculative-model meta-llama/Llama-2-7b-chat-hf \
    --num-speculative-tokens 5

Adapter LoRA

Służy do obsługi wielu adapterów LoRA na podstawie modelu bez ładowania wielu pełnych modeli:

python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-7b-hf \
    --enable-lora \
    --lora-modules sql-lora=./path/to/sql-adapter \
                   code-lora=./path/to/code-adapter

Następnie określ, który adapter użyć na żądanie:

response = client.completions.create(
    model="sql-lora",  # Użyj adaptera SQL
    prompt="Przekształć to na SQL: Pokaż wszystkich użytkowników utworzonych w tym miesiącu"
)

Wdrażanie wielu LoRA

vLLM obsługuje wdrażanie wielu adapterów LoRA z minimalnymi kosztami pamięci. To idealne do obsługi wielu wersji modeli zoptymalizowanych pod kryteria klienta lub zadania:

# Żądanie z konkretnym adapterem LoRA
response = client.chat.completions.create(
    model="meta-llama/Llama-2-7b-hf",
    messages=[{"role": "user", "content": "Napisz zapytanie SQL"}],
    extra_body={"lora_name": "sql-lora"}
)

Pamięć cache dla prefiksów

Włącz automatyczne cacheowanie prefiksów, aby uniknąć ponownego obliczania cache’u KV dla powtarzających się prefiksów promptów:

--enable-prefix-caching

To szczególnie skuteczne dla:

  • Chatbotów z ustalonymi promptami systemowymi
  • Aplikacji RAG z konsystentnymi szablonami kontekstu
  • Promptów z kilkoma przykładami powtarzanych w żądaniach

Cacheowanie prefiksów może zmniejszyć czas do pierwszego tokena o 50–80% dla żądań udostępniających prefiksy promptów.

Przykłady integracji

Integracja z LangChain

from langchain.llms import VLLMOpenAI

llm = VLLMOpenAI(
    openai_api_key="EMPTY",
    openai_api_base="http://localhost:8000/v1",
    model_name="mistralai/Mistral-7B-Instruct-v0.2",
    max_tokens=512,
    temperature=0.7,
)

response = llm("Wyjaśnij PagedAttention w prostych słowach")
print(response)

Integracja z LlamaIndex

from llama_index.llms import VLLMServer

llm = VLLMServer(
    api_url="http://localhost:8000/v1",
    model="mistralai/Mistral-7B-Instruct-v0.2",
    temperature=0.7,
    max_tokens=512
)

response = llm.complete("Co to jest vLLM?")
print(response)

Aplikacja FastAPI

from fastapi import FastAPI
from openai import AsyncOpenAI

app = FastAPI()
client = AsyncOpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

@app.post("/generate")
async def generate(prompt: str):
    response = await client.completions.create(
        model="mistralai/Mistral-7B-Instruct-v0.2",
        prompt=prompt,
        max_tokens=200
    )
    return {"result": response.choices[0].text}

Przykładowe wyniki testów wydajności

Dane rzeczywistej wydajności pomagają ilustrować zalety vLLM:

Porównanie przepustowości (Mistral-7B na GPU A100):

  • vLLM: ~3 500 tokenów/sekunda z 64 użytkownikami jednocześnie
  • HuggingFace Transformers: ~250 tokenów/sekunda przy tej samej koncurencji
  • Ollama: ~1 200 tokenów/sekundy przy tej samej koncurencji
  • Wynik: vLLM dostarcza 14-krotny zysk w porównaniu do podstawowych implementacji

Efektywność pamięci (LLaMA-2-13B):

  • Standardowa implementacja: 24 GB VRAM, 32 sekwencje jednocześnie
  • vLLM z PagedAttention: 24 GB VRAM, 128 sekwencji jednocześnie
  • Wynik: 4-krotnie więcej jednoczesnych żądań przy tej samej pamięci

Opóźnienie pod obciążeniem (Mixtral-8x7B na 2xA100):

  • vLLM: P50 opóźnienia 180 ms, P99 opóźnienia 420 ms przy 100 żądaniach/sekundę
  • Standardowe wdrażanie: P50 opóźnienia 650 ms, P99 opóźnienia 3 200 ms przy 100 żądaniach/sekundę
  • Wynik: vLLM utrzymuje spójne opóźnienie pod wysokim obciążeniem

Te testy pokazują, dlaczego vLLM stał się standardem de facto dla wdrażania LLM w środowisku produkcyjnym, gdzie ważna jest wydajność.

Analiza kosztów

Zrozumienie implikacji kosztowych wyboru vLLM:

Przypadek: Obsługa 1 miliona żądań/dzień

Z użyciem standardowego wdrażania:

  • Wymagane: 8x A100 GPU (80 GB)
  • Koszt na AWS: ~32 złotych/godzina × 24 × 30 = 23 040 złotych/miesiąc
  • Koszt na 1 milion tokenów: ~0,75 złotych

Z użyciem vLLM:

  • Wymagane: 2x A100 GPU (80 GB)
  • Koszt na AWS: ~8 złotych/godzina × 24 × 30 = 5 760 złotych/miesiąc
  • Koszt na 1 milion tokenów: ~0,19 złotych
  • Oszczędności: 17 280 złotych/miesiąc (75% zmniejszenie)

Ten przewaga kosztowa rośnie wraz z skalą. Organizacje obsługujące miliardy tokenów miesięcznie oszczędzają setki tysięcy złotych, korzystając z zoptymalizowanego wdrażania vLLM zamiast podstawowych implementacji.

Rozważania bezpieczeństwa

Uwierzytelnienie

vLLM nie zawiera uwierzytelnienia domyślnie. Dla środowisk produkcyjnych zaimplementuj uwierzytelnienie na poziomie odwrotnej proxy:

# Konfiguracja Nginx
location /v1/ {
    auth_request /auth;
    proxy_pass http://vllm-backend:8000;
}

location /auth {
    proxy_pass http://auth-service:8080/verify;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}

Lub użyj API gateway takich jak Kong, Traefik lub AWS API Gateway dla wdrożeń na poziomie przedsiębiorstwa z uwierzytelnieniem i ograniczaniem przepustowości.

Izolacja sieciowa

Uruchamiaj vLLM w prywatnych sieciach, nie bezpośrednio wystawiając na internet:

# Przykład NetworkPolicy w Kubernetes
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: vllm-access
spec:
  podSelector:
    matchLabels:
      app: vllm
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: api-gateway
    ports:
    - protocol: TCP
      port: 8000

Ograniczanie przepustowości

Zaimplementuj ograniczanie przepustowości, aby zapobiec nadużyciu:

# Przykład z użyciem Redis do ograniczania przepustowości
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import redis
from datetime import datetime, timedelta

app = FastAPI()
redis_client = redis.Redis(host='localhost', port=6379)

@app.middleware("http")
async def rate_limit_middleware(request, call_next):
    client_ip = request.client.host
    key = f"rate_limit:{client_ip}"
    
    requests = redis_client.incr(key)
    if requests == 1:
        redis_client.expire(key, 60)  # Okno czasowe 60 sekund
    
    if requests > 60:  # 60 żądań na minutę
        raise HTTPException(status_code=429, detail="Przekroczono limit przepustowości")
    
    return await call_next(request)

Kontrola dostępu do modeli

Dla wdrożeń wielu użytkowników, kontroluj, którzy użytkownicy mogą uzyskać dostęp do jakich modeli:

ALLOWED_MODELS = {
    "user_tier_1": ["mistralai/Mistral-7B-Instruct-v0.2"],
    "user_tier_2": ["mistralai/Mistral-7B-Instruct-v0.2", "meta-llama/Llama-2-13b-chat-hf"],
    "admin": ["*"]  # Wszystkie modele
}

def verify_model_access(user_tier: str, model: str) -> bool:
    allowed = ALLOWED_MODELS.get(user_tier, [])
    return "*" in allowed or model in allowed

Przewodnik migracji

Z OpenAI do vLLM

Migracja z OpenAI do samowdrażanej vLLM jest prosta dzięki kompatybilności API:

Przed (OpenAI):

from openai import OpenAI

client = OpenAI(api_key="sk-. ..")
response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "Cześć"}]
)

Po (vLLM):

from openai import OpenAI

client = OpenAI(
    base_url="https://your-vllm-server.com/v1",
    api_key="your-internal-key"  # Jeśli dodałeś uwierzytelnienie
)
response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "Cześć"}]
)

Tylko dwie zmiany są konieczne: zaktualizuj base_url i nazwę modelu. Reszta kodu pozostaje identyczna.

Z Ollama do vLLM

Ollama korzysta z innego formatu API. Oto konwersja:

API Ollama:

import requests

response = requests.post('http://localhost:11434/api/generate',
    json={
        'model': 'llama2',
        'prompt': 'Dlaczego niebo jest niebieskie?'
    })

Ekwiwalent vLLM:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
response = client.completions.create(
    model="meta-llama/Llama-2-7b-chat-hf",
    prompt="Dlaczego niebo jest niebieskie?"
)

Musisz zaktualizować wywołania API w całym kodzie, ale biblioteki klienta OpenAI oferują lepsze zarządzanie błędami i funkcje.

Z HuggingFace Transformers do vLLM

Migracja bezpośredniego użycia Pythona:

HuggingFace:

from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2")
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2")

inputs = tokenizer("Cześć", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=100)
result = tokenizer.decode(outputs[0])

vLLM:

from vllm import LLM, SamplingParams

llm = LLM(model="mistralai/Mistral-7B-Instruct-v0.2")
sampling_params = SamplingParams(max_tokens=100)

outputs = llm.generate("Cześć", sampling_params)
result = outputs[0].outputs[0].text

API Pythona vLLM jest prostsze i znacznie szybsze dla inferencji w batchu.

Przyszłość vLLM

vLLM nadal rozwija się dynamicznie z ekscytującymi funkcjami na trasie:

Rozdzielone wdrażanie: Oddzielanie prefill (przetwarzanie promptu) i dekodowanie (generowanie tokenów) na różne GPU, aby zoptymalizować wykorzystanie zasobów. Prefill jest obliczeniowo ograniczony, a dekodowanie jest ograniczone pod względem pamięci, więc uruchamianie ich na specjalistycznym sprzęcie poprawia wydajność.

Wdrażanie w wielu węzłach: Dystrybucja bardzo dużych modeli (100B+ parametrów) na wiele maszyn, umożliwiając wdrażanie modeli zbyt dużych dla konfiguracji jednowęzłowych.

Zwiększone kwantyzacje: Wsparcie dla nowych formatów kwantyzacji, takich jak GGUF (używane przez llama.cpp) i poprawione integracje AWQ/GPTQ dla lepszej wydajności modeli skwantowanych.

Ulepszenia dekodowania speculacyjnego: Efektywniejsze modele wstępne i adaptacyjne strategie speculacji, aby osiągnąć wyższe przyspieszenie bez utraty dokładności.

Optymalizacje uwagi: FlashAttention 3, uwaga pierścieniowa dla bardzo długich kontekstów (100K+ tokenów) i inne najnowsze mechanizmy uwagi.

Lepsze wsparcie dla modeli: Rozszerzenie wsparcia do modeli multimodalnych (modeli językowo-wizualnych), modeli audio i specjalistycznych architektur, gdy pojawią się.

Projekt vLLM utrzymuje aktywne rozwijanie z udziałem UC Berkeley, Anyscale i szerszej społeczności open-source. W miarę, jak wdrażanie LLM staje się coraz bardziej krytyczne dla systemów produkcyjnych, rola vLLM jako standardu wydajności nadal rośnie.

Przydatne linki

Powiązane artykuły na tym serwisie

  • Lokalne hostowanie LLM: Kompletny przewodnik 2025 – Ollama, vLLM, LocalAI, Jan, LM Studio i inne – Kompletny porówanie 12+ narzędzi do lokalnego hostowania LLM, w tym szczegółowa analiza vLLM wraz z Ollama, LocalAI, Jan, LM Studio i innymi. Porównuje dojrzałość API, wsparcie wywoływania narzędzi, kompatybilność GGUF oraz wyniki testów wydajności, aby pomóc wybrać odpowiednie rozwiązanie.

  • Ollama – cheat sheet – Kompletny przewodnik z poleceń i cheat sheet Ollama obejmujący instalację, zarządzanie modelami, użycie API oraz najlepsze praktyki wdrażania lokalnych LLM. Niezwykle przydatny dla deweloperów korzystających z Ollama wraz z vLLM lub zamiast niego.

  • Docker Model Runner vs Ollama: Który wybrać? – Szczegółowe porównanie Model Runnera od Dockera i Ollama w kontekście lokalnego hostowania LLM, analizujące wydajność, wsparcie GPU, kompatybilność API i przypadki użycia. Pomaga zrozumieć konkurencyjny świat vLLM.

  • Docker Model Runner – cheat sheet: polecenia i przykłady – Praktyczny cheat sheet Docker Model Runner z poleceniami i przykładami wdrażania modeli AI. Przydatny dla zespołów porównujących podejście Dockera z specjalistycznymi możliwościami serwowania LLM od vLLM.

Zewnętrzne zasoby i dokumentacja

  • Repozytorium vLLM na GitHub – Oficjalne repozytorium vLLM z kodem źródłowym, kompleksową dokumentacją, przewodnikami instalacyjnymi i aktywnymi dyskusjami społecznościowymi. Niezwykle ważny zasób pozwalający na śledzenie najnowszych funkcji i rozwiązywanie problemów.

  • Dokumentacja vLLM – Oficjalna dokumentacja obejmująca wszystkie aspekty vLLM, od podstawowej konfiguracji po zaawansowane ustawienia. Zawiera referencje API, przewodniki dotyczące optymalizacji wydajności oraz najlepsze praktyki wdrażania.

  • Artykuł PagedAttention – Akademicki artykuł przedstawiający algorytm PagedAttention, który stanowi podstawę wydajności vLLM. Niezwykle ważna lektura pozwalająca zrozumieć techniczne innowacje stojące za zaletami wydajności vLLM.

  • Blog vLLM – Oficjalny blog vLLM z ogłoszeniami o nowych wersjach, wynikami testów, analizami technicznymi oraz przypadkami użycia z wdrożeń produkcyjnych.

  • HuggingFace Model Hub – Kompleksowa repozytorium modeli open source kompatybilnych z vLLM. Możliwość wyszukiwania modeli według rozmiaru, zadania, licencji i cech wydajnościowych, aby znaleźć odpowiedni model do konkretnego przypadku użycia.

  • Dokumentacja Ray Serve – Dokumentacja ramki Ray Serve do budowania skalowalnych, rozproszonych wdrożeń vLLM. Ray oferuje zaawansowane funkcje takie jak automatyczne skalowanie, serwowanie wielu modeli i zarządzanie zasobami dla systemów produkcyjnych.

  • NVIDIA TensorRT-LLM – Biblioteka TensorRT-LLM od NVIDIA do bardzo optymalizowanej inferencji na GPU NVIDIA. Alternatywa dla vLLM z innymi strategiami optymalizacji, przydatna do porównań i zrozumienia krajobrazu optymalizacji inferencji.

  • Dokumentacja API OpenAI – Oficjalna dokumentacja API OpenAI, z którą jest kompatybilny API vLLM. Warto odnieść się do niej przy tworzeniu aplikacji wymagających pracy z obiema wersjami API OpenAI i lokalnymi punktami końcowymi vLLM.