vLLM LLM Inference PagedAttention Continuous Batching Açık Kaynak Yapay Zeka

vLLM Nedir? Açık Kaynak LLM Çıkarım Motoru Rehberi 2026

Orta
person Yapay Zeka Uzmanı

Bir LLM’i dizüstü bilgisayarınızda çalıştırmak ile aynı modeli yüzlerce eş zamanlı kullanıcıya sunmak arasındaki mesafe, birkaç satır koddan ibaret değil. Production ortamında ölçek büyüdükçe GPU belleği tükeniyor, yanıt süreleri uzuyor, kuyrukta bekleyen istekler birikmeye başlıyor.

vLLM tam bu noktada devreye giriyor. Berkeley’deki araştırmacılar tarafından geliştirilen bu açık kaynak inference engine, GPU belleğini çok daha verimli kullanmak için tamamen yeni bir mimari getirdi. Bugün Llama, Mistral, Qwen, Gemma gibi modelleri gerçek trafiğe açan pek çok şirket vLLM üzerinde çalışıyor.

vLLM mimarisi: GPU sunucusunda paralel LLM çıkarım akışları

vLLM nedir?

vLLM (Virtual Large Language Model), açık kaynak büyük dil modellerini GPU üzerinde yüksek verimle çalıştırmaya yarayan bir inference motorudur. İlk sürümü 2023’te UC Berkeley’den Woosuk Kwon ve ekibinin “Efficient Memory Management for Large Language Model Serving with PagedAttention” makalesiyle birlikte yayımlandı. GitHub’da 40.000’i aşan yıldızla bu alandaki en geniş topluluğa sahip proje konumuna geldi.

Temel iddiası basit: aynı GPU’dan daha fazla istek/saniye. Bunu mümkün kılan iki ana teknik var: PagedAttention ve continuous batching. İkisine de aşağıda ayrıntılı bakacağız.

vLLM’in sunduğu OpenAI uyumlu API, mevcut OpenAI SDK kodunu değiştirmeden kendi barındırdığınız modele yönlendirmenizi sağlar. Bu özellik, vendor lock-in’den kaçınmak isteyen ekipler için ciddi bir avantaj.

Projeyi Meta, Microsoft, Google, NVIDIA ve düzinelerce startup aktif olarak katkıda bulunarak geliştiriyor. Yeni model mimarilerinin desteği genellikle birkaç hafta içinde geliyor; bu tempo, topluluğun büyüklüğünün doğrudan bir sonucu.

PagedAttention: bellek atığını kesmek

Transformer tabanlı modellerde her token üretilirken geçmiş token’ların key-value tensörleri saklanır. Buna KV cache denir. Standart yaklaşımda bu önbellek, token sayısı maksimuma ulaşana kadar dolacağı varsayılarak önceden tahsis edilir. Yani 8192 token sığabilecek bir alan, 200 token’lık bir yanıt için bile bloke edilir. Kullanılmayan bu boşluk zayi olur.

PagedAttention bu problemi işletim sistemlerindeki sanal bellek konseptinden uyarlayarak çözdü. KV cache artık önceden sabit blok ayrılmıyor; ihtiyaç doğtukça küçük bloklara (physical blocks) ayrılıyor ve farklı istekler arasında paylaşılabiliyor. Aynı prefix’i paylaşan iki istek, o prefix’in KV cache’ini kopyalamak yerine aynı fiziksel bloğu işaret edebiliyor.

Bu, özellikle sistem prompt’u uzun olan uygulamalarda ciddi fark yaratıyor. Onlarca kullanıcı aynı “Sen bir müşteri destek asistanısın…” açılışını paylaşıyorsa, bu prefix için bellek yalnızca bir kez ayrılıyor; her istek için tekrar hesaplanmıyor.

Pratikte ne anlama geliyor? Aynı GPU’da çok daha fazla isteği eş zamanlı karşılayabiliyorsunuz. Berkeley ekibinin 2023 tarihli makalesine göre vLLM, naive HuggingFace Transformers pipeline’ına kıyasla throughput’u 14 kata kadar artırabildi. Gerçek üretim rakamları workload’a göre değişir, ama bellek verimliliğindeki fark tartışmasız.

# vLLM ile temel inference
from vllm import LLM, SamplingParams

llm = LLM(model="meta-llama/Llama-3.1-8B-Instruct")

params = SamplingParams(temperature=0.7, max_tokens=512)

outputs = llm.generate(
    ["Türkiye'nin başkenti nedir?", "Python'da liste nasıl döngüye girer?"],
    params
)

for output in outputs:
    print(output.outputs[0].text)

Continuous batching: boşta bekleme yok

Klasik batch inference şöyle çalışır: bir grup isteği topla, hepsini GPU’ya gönder, hepsi bittiğinde sonuçları döndür. Bu yaklaşımda bir istek 10 token’da, bir diğeri 500 token’da tamamlanabilir. 500 token beklerken GPU’nun kapasitesi büyük ölçüde boşa gider.

Continuous batching (ya da iteration-level scheduling), tamamlanan istekleri beklemeksizin yeni isteklerle değiştirir. Her token üretim adımında kuyruktaki yeni istekler aktif batch’e eklenir. GPU sürekli dolu çalışır.

Bu fark gerçek trafikte hissediliyor. Chatbot gibi uygulamalarda kullanıcıların sorduğu sorular çok farklı uzunluklarda oluyor: birisi tek cümleyle yanıt alırken bir diğeri uzun bir analiz bekliyor. Klasik batch’lemede kısa yanıtlı istekler uzun olanları beklemek zorunda; continuous batching’de kısa biten anında yerini bir sonrakine bırakıyor.

İkisi birlikte çalışınca vLLM, idle süreyi azaltan ve belleği verimli kullanan bir motor haline geliyor.

Klasik batching vs continuous batching: GPU kullanım karşılaştırması

OpenAI uyumlu API sunucusu

vLLM’in en pratik özelliklerinden biri, OpenAI API formatında bir sunucu başlatabilmesi. Tek komutla:

python -m vllm.entrypoints.openai.api_server \
    --model mistralai/Mistral-7B-Instruct-v0.3 \
    --host 0.0.0.0 \
    --port 8000

Artık http://localhost:8000/v1 adresinde OpenAI uyumlu bir endpoint var. Mevcut kodunuzu tek satır değiştirip test edebilirsiniz:

from openai import OpenAI

# API anahtarı gerekmez; vllm sunucusu yerel çalışıyor
client = OpenAI(api_key="dummy", base_url="http://localhost:8000/v1")

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.3",
    messages=[{"role": "user", "content": "Makine öğrenmesi nedir?"}],
    max_tokens=300,
)

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

Streaming, function calling ve logprobs da destekleniyor. OpenAI SDK’yı kullanan uygulamalar base_url parametresini değiştirerek kendi barındırdığınız modellere geçebiliyor; geri kalanı aynı kalıyor.

Bu uyumluluk özellikle maliyet ve gizlilik gerektiren durumlarda değerli. Hassas verilerin üçüncü taraf API’lara gitmemesi gerektiğinde vLLM, mevcut kod tabanını bozmadan kendi altyapınızda çalışmanızı sağlar.

Kurulum

vLLM’i kurmak için CUDA destekli bir GPU ve Python 3.8+ gerekiyor. En basit yol pip:

pip install vllm

Docker ile de çalıştırabilirsiniz; bu yaklaşım ortam çakışmalarını önler:

docker run --runtime nvidia --gpus all \
    -v ~/.cache/huggingface:/root/.cache/huggingface \
    -p 8000:8000 \
    vllm/vllm-openai:latest \
    --model meta-llama/Llama-3.1-8B-Instruct

Modeller ilk çalıştırmada HuggingFace Hub’dan indirilir; yerel bir cache klasörü bağlamak indirme süresini tekrar tekrar yaşamanın önüne geçer.

Donanım gereksinimleri

vLLM, NVIDIA GPU’lar için tasarlandı. AMD ROCm desteği de var, ama NVIDIA üzerindeki kadar olgun değil. CPU-only mod mevcut ama production için uygun performans sunmuyor. Google Cloud TPU desteği 2025 itibarıyla deneysel olarak eklendi; stabil olmaktan henüz uzak.

Model BoyutuMinimum VRAMÖnerilen
7B (bf16)14 GBA10G / RTX 3090
13B (bf16)26 GBA100 40GB
70B (bf16)140 GB2x A100 80GB
7B (AWQ 4-bit)~5 GBRTX 3080

Quantization ile bellek gereksinimini önemli ölçüde azaltmak mümkün.

Quantization desteği

vLLM, AWQ, GPTQ ve FP8 formatlarındaki quantize edilmiş modelleri doğrudan destekler. Quantize model kullanmak için --quantization bayrağını eklemek yeterli:

python -m vllm.entrypoints.openai.api_server \
    --model TheBloke/Mistral-7B-Instruct-v0.2-AWQ \
    --quantization awq \
    --max-model-len 4096

AWQ (Activation-aware Weight Quantization), ağırlıkları 4 bite indirirken aktivasyonları yüksek hassasiyette tutar. Bellek kullanımını yarıya yakın düşürürken kalite kaybı genellikle küçük kalır. Mistral 7B için AWQ versiyonu yaklaşık 4 GB VRAM tutarken bf16 versiyonu 14 GB istiyor; bu fark tüketici GPU’larında modeli çalıştırmayı mümkün kılıyor.

GPTQ, post-training quantization için farklı bir yaklaşım kullanır. AWQ kadar popüler olmasa da geniş model seçeneğiyle, özellikle TheBloke gibi topluluğun quantize ettiği modellerde yaygın karşılaşılan bir format.

FP8 (8-bit floating point), NVIDIA Hopper (H100) ailesinde donanım hızlanmasından faydalanır. Hassasiyeti INT8’den iyi korurken benzer bellek tasarrufu sunar. H100 cluster’ında çalışıyorsanız tercih edilecek ilk format bu.

Desteklenen modeller

vLLM, HuggingFace Hub üzerindeki büyük bir model yelpazesini destekler. En yaygın kullanılanlar:

  • Llama ailesi: Meta Llama 3.1, 3.2, 3.3 (8B, 70B, 405B)
  • Mistral / Mixtral: Mistral 7B, Mixtral 8x7B, Mistral Large
  • Qwen: Qwen2.5 (0.5B → 72B), Qwen2.5-Coder
  • Google: Gemma 2 (2B, 9B, 27B)
  • Microsoft: Phi-3, Phi-4
  • DeepSeek: DeepSeek-V2, DeepSeek-R1 (tam ve damıtılmış versiyonlar)

Yeni mimarilerin desteği genellikle modelin yayımlanmasından birkaç hafta içinde geliyor. Resmi desteklenen modeller listesi güncel tutuluyor.

vLLM ile Ollama arasındaki fark

Bu iki araç farklı kullanım senaryoları için tasarlandı.

Ollama, geliştirici deneyimini ön plana koyar. Tek komutla model indirip çalıştırabilirsiniz, Mac ve Windows’ta sorunsuz çalışır, CPU-only modda da kullanılabilir. Laptop’ınızda hızlıca bir model denemek için ideal.

vLLM ise production ortamları için optimize edildi. Çoklu GPU, tensor parallelism, yüksek concurrent request, düşük latency gereksinimlerini karşılamak üzere tasarlandı. Ollama’nın sunmadığı PagedAttention ve continuous batching, yüksek trafikte throughput farkını belirginleştirir.

ÖzellikOllamavLLM
Kurulum kolaylığıÇok kolayOrta
CPU desteğiEvetKısıtlı
Mac / WindowsEvetHayır (Linux/CUDA)
PagedAttentionHayırEvet
Concurrent req.DüşükYüksek
Production uygunluğuKısıtlıYüksek
OpenAI uyumlu APIEvetEvet

Kural basit: geliştirirken Ollama, production’a çıkarken vLLM.

Ollama vs vLLM: geliştirme ortamı ile production sunucu karşılaştırması

Çoklu GPU ve tensor parallelism

Büyük modeller tek GPU’ya sığmayabilir. vLLM tensor parallelism ile modeli birden fazla GPU’ya böler:

python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4 \
    --dtype bfloat16

Bu komut 70B modeli 4 GPU’ya dağıtır. Her GPU modelin bir bölümünü tutar; çıkarım GPU’lar arasında koordineli yürür.

Pipeline parallelism de destekleniyor: model katmanları farklı GPU’lara atanır. Tensor parallelism latency’yi düşürürken pipeline parallelism throughput’u artırır. Büyük cluster deployment’larında ikisi birlikte kullanılabilir.

Bellek yönetimi: pratik ipuçları

--max-model-len

Modelin desteklediği maksimum context uzunluğu GPU belleğinde doğrudan yer kaplar. KV cache boyutu context length ile doğrusal orantılı büyür. Uygulamanız 8192 token’dan uzun yanıt üretmiyorsa:

--max-model-len 8192

Bu parametreyle gereksiz bellek rezervasyonunu önleyebilirsiniz.

--gpu-memory-utilization

vLLM varsayılan olarak GPU VRAM’inin %90’ını kullanır. Aynı sunucuda başka processler çalışıyorsa bu değeri düşürmek gerekebilir:

--gpu-memory-utilization 0.75

Prefix caching

Aynı sistem prompt’u kullanan çok sayıda isteğiniz varsa prefix caching bellek ve hesaplamayı önemli ölçüde azaltır:

--enable-prefix-caching

Monitoring ve observability

Production’da vLLM’i gözlemlemek için Prometheus metrikleri /metrics endpoint’inde sunuluyor. Temel metrikler:

  • vllm:num_requests_running: aktif istek sayısı
  • vllm:gpu_cache_usage_perc: KV cache doluluk oranı
  • vllm:request_success_total: başarılı istek sayısı
  • vllm:time_to_first_token_seconds: ilk token latency

Bu metrikleri Grafana’ya bağlayarak throughput, latency ve bellek kullanımını gerçek zamanlı izleyebilirsiniz.

Dikkat etmesi gereken iki metrik var. gpu_cache_usage_perc sürekli %95’in üzerinde kalıyorsa yeni istekler kuyrukta bekliyor demektir; bu durumda --max-model-len değerini düşürmek ya da GPU eklemek gerekir. time_to_first_token_seconds ise kullanıcı deneyimini doğrudan etkiler: bu değer yükseliyorsa batch boyutu büyümüş ya da KV cache dolu olduğu için preemption başlamış olabilir.

vLLM ayrıca OpenTelemetry ile de entegre çalışıyor. Distributed tracing isteyen sistemler için her isteğin span’larını doğrudan trace backend’e göndermek mümkün.

Structured output ve JSON mode

vLLM, Outlines kütüphanesiyle entegre çalışarak JSON schema’ya uyan yanıtlar üretebiliyor. LLM çıktısını ayrıştırıp doğrulamaya gerek kalmıyor:

from openai import OpenAI
import json

client = OpenAI(api_key="dummy", base_url="http://localhost:8000/v1")

schema = {
    "type": "object",
    "properties": {
        "isim": {"type": "string"},
        "yas": {"type": "integer"},
        "sehir": {"type": "string"}
    },
    "required": ["isim", "yas", "sehir"]
}

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.3",
    messages=[
        {"role": "user", "content": "Ahmet, 32 yaşında, İstanbul'dan bir yazılım geliştirici."}
    ],
    extra_body={"guided_json": json.dumps(schema)},
    max_tokens=200,
)

data = json.loads(response.choices[0].message.content)
print(data)  # {'isim': 'Ahmet', 'yas': 32, 'sehir': 'İstanbul'}

Ne zaman vLLM, ne zaman başka bir şey?

vLLM her senaryo için doğru araç değil:

vLLM iyi seçim:

  • Saniyede 10’dan fazla eş zamanlı istek bekliyorsanız
  • GPU kiraları yüksek ve bellek verimliliği kritik
  • OpenAI API uyumluluğuna ihtiyacınız var
  • Llama, Mistral gibi açık kaynak modelleri production’da çalıştırıyorsunuz

Başka seçenekler:

  • Geliştirme ortamı veya prototyping → Ollama
  • Özel model mimarisi veya training entegrasyonu → HuggingFace TGI
  • Küçük model, az trafik → doğrudan transformers pipeline
  • Sadece OpenAI modellerini kullanıyorsanız → vLLM’e gerek yok

LoRA adapter desteği

vLLM, LoRA ile fine-tune edilmiş modelleri de çalıştırabiliyor. Aynı base modelin üzerine farklı LoRA adapter’larını dinamik olarak yüklemek mümkün; bu özellik, tek bir GPU’da birden fazla özelleştirilmiş model çalıştırmanın verimli bir yolu.

python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-8B-Instruct \
    --enable-lora \
    --max-loras 4

API isteğinde hangi LoRA adapter’ını kullanacağınızı model parametresiyle belirtiyorsunuz. Bu yaklaşım özellikle farklı müşteriler veya görevler için ayrı fine-tuned versiyonlar çalıştırmanız gerektiğinde belleği önemli ölçüde kısıtlıyor: her adapter için tam model yerine yalnızca delta ağırlıklar yükleniyor.

Bir adım sonrası

vLLM tek başına bir inference motoru; deployment için daha geniş bir stacke ihtiyaç var. LiteLLM gibi bir proxy katmanı, vLLM’i birden fazla model veya provider’la birleştirmeyi kolaylaştırır. Kubernetes üzerinde scale-out için vLLM Production Stack veya Ray Serve entegrasyonları başlangıç noktası.

Türkçe LLM servisi kurmayı düşünüyorsanız Qwen2.5 7B veya Llama 3.1 8B ile AWQ quantization kombinasyonu makul bir giriş noktası: tek A100’de saniyede 30-50 istek, düşük gecikme. Trafik arttığında tensor parallelism ile aynı kod tabanını 2 veya 4 GPU’ya taşımak neredeyse parametre değişikliğiyle oluyor. Başlangıçta küçük tutup ölçeği talebe göre büyütmek, sabit maliyet yerine kullanım odaklı bir deployment stratejisi için en sağlıklı yaklaşım.