
Ollama ile modelinizi ayağa kaldırdınız, harika çalışıyor. Sonra ekipten on kişi aynı anda bağlandı ve her şey tıkandı. Bu yazıda tam olarak bunun neden olduğunu, vLLM’in hangi numaralarla aynı ekran kartından 20 kat fazla iş çıkardığını ve alternatiflerinin ne zaman daha doğru tercih olduğunu birlikte öğreneceğiz.
Bu yazıya “LLM nedir biliyorum, hatta lokalde model çalıştırdım ama vLLM bana hep ‘ciddi insanların aracı’ gibi göründü” diyerek geldiyseniz doğru yerdesiniz. Sonuna vardığınızda şunları yapabileceksiniz: bir aracın neden 5 kullanıcıda tıkanıp ötekinin 200 kullanıcıyı taşıdığını mimari olarak açıklayabileceksiniz, PagedAttention ve continuous batching’in ne demek olduğunu bir arkadaşınıza anlatabileceksiniz, vLLM’i tek komutla ayağa kaldırıp hangi flag’in ne işe yaradığını bilerek ayar yapabileceksiniz ve — belki en önemlisi — vLLM’in gerekmediği durumları tanıyabileceksiniz.
1. Ollama’nın Yetersiz Olduğu Nokta
Olaya rakamlarla girelim, çünkü bunlar yazının geri kalanını anlamlı kılıyor. 2026’da yayımlanan hakemli bir çalışma; aynı H100 GPU üzerinde aynı modeli (Qwen3-4B) aynı parametrelerle Ollama ve vLLM ile servis edip dört farklı senaryoda ölçtü[5]. Sonuçlar şöyle:
| Ölçüm (100 eşzamanlı kullanıcı) | Ollama | vLLM |
|---|---|---|
| Throughput (istek/saniye) | 0.45 | 15.20 (~22 kat) |
| Ortalama gecikme (latency) | 100+ saniye | 10 saniyenin altı |
| İlk token’a kadar geçen süre (TTFT) | 54–122 saniye | 3 saniyenin altı |
| Başarısız istek oranı | %39.29 | %0 |
| Kırılma noktası | ~10 kullanıcı | 200 kullanıcı ve ötesi |
Çalışmanın toplamında vLLM 99.802 isteğin tamamını hatasız tamamlarken, Ollama senaryolara göre %13–30 arası hata verdi[5]. Kritik nokta şu: başarıyla tamamlanan isteklerde iki aracın cevap kalitesi birbirine denk çıktı. Yani mesele modelin zekâsı değil; mesele tamamen işin nasıl sıraya dizildiği.
Yanlış anlamayalım! Ollama kötü bir araç değil — bambaşka bir iş için tasarlanmış bir araç. Ollama varsayılan olarak model başına tek paralel istek işler (OLLAMA_NUM_PARALLEL ile elle artırılır) ve gerisini kuyruğa alır; kuyruk 512’yi geçince istekleri reddeder[16]. Bu, tek kişilik masaüstü kullanımı için son derece makul bir tasarım tercihidir. Ama “makul tasarım tercihi” ile “yüz kişiyi taşıyan sunucu” arasında bir mimari uçurum var. O uçurumu kapatan şeyin adı vLLM.
2. vLLM Nereden Çıktı?
vLLM, UC Berkeley’deki Sky Computing Lab’da doğdu ve 2023’te SOSP konferansında sunulan “Efficient Memory Management for Large Language Model Serving with PagedAttention” makalesiyle akademik olarak kayda geçti[21][22]. İlk duyuru yazısındaki iddia dönemin şartlarında çarpıcıydı: aynı donanımda Hugging Face Transformers’a göre 24 kata kadar, o zamanın en iyi servis aracı olan Hugging Face TGI’ya göre 3.5 kata kadar daha yüksek throughput[1].
Aradan geçen sürede vLLM bir araştırma projesinden ekosistemin fiili omurgasına dönüştü. Bugün NVIDIA’nın yanında AMD, Intel CPU/GPU, TPU ve Gaudi üzerinde çalışıyor; AWQ, GPTQ, GGUF, FP8, INT4/INT8 gibi bir düzineden fazla quantization formatını destekliyor; LoRA adaptörleri, structured output, tool calling ve çok modlu (multimodal) girdi işleyebiliyor[3]. Geliştirme temposu da buna göre: Ağustos 2026’da çıkan v0.27.0 sürümü tek başına 242 committer’dan gelen 561 commit içeriyordu[18]. Bu dönüşümün en net kanıtı da rakip cepheden geldi. Hugging Face, bir zamanların en güçlü servis aracı olan kendi TGI’ını bakım moduna aldı; deponun ilk satırındaki uyarıda artık yalnızca küçük hata düzeltmelerini kabul ettiklerini, ileriye dönük olarak “vLLM ve SGLang’i, lokal tarafta da llama.cpp ve MLX’i kullanmanızı önerdiklerini ve bu projelere katkı verdiklerini” yazıyorlar[9].
Burada bir şirketin pazar kaybettiği filan yok — hepsi açık kaynak; TGI da Apache 2.0, vLLM de. Açık kaynak dünyasında normal olan şey tam da bu: aynı problemi çözen beş ayrı proje bir süre yarışır, biri kritik kütleye ulaşınca geri kalanların ekipleri kendi kodlarını sürdürmek yerine emeklerini o ortak omurgaya taşır. Hugging Face’in yaptığı bir teslim olma değil, kaynak tahsisi kararı: TGI’ı ayakta tutmaya harcayacağı mühendis saatini vLLM’e katkı olarak vermek. Bizim için önemi şu — vLLM’i öneren taraf, onun en yakın rakibini yazmış olan ekip.
Bir cümlelik tanım: vLLM, bir GPU’daki belleği ve zamanı aynı anda gelen çok sayıda istek arasında olabildiğince az israfla paylaştıran bir inference (çıkarım) motorudur. Tek kullanıcının cevabını hızlandırmaz; aynı donanımdan kaç kullanıcının beslenebileceğini kökten değiştirir.
3. Perde Arkası I — PagedAttention: İşletim Sisteminden Çalınan Fikir
Şimdi asıl meseleye girelim. Bir LLM cevap üretirken, sohbetin o ana kadarki her token’ı için hesapladığı ara değerleri (key ve value tensörleri) bellekte tutar; bu depoya KV cache denir. Amaç her yeni token’da tüm geçmişi baştan hesaplamamaktır. Sorun şu ki bu depo devasadır: Llama-3-70B’de FP16 hassasiyetle her bir token, tüm katmanlar boyunca yaklaşık 160 KB yer kaplar[4].
Klasik yaklaşımda sistem, her istek için “bu istek en fazla 2048 token üretebilir” varsayıp bitişik (contiguous) bir bellek bloğunu baştan rezerve ederdi — 70B model için istek başına ~327 MB[4]. Peki kullanıcı 40 token’lık kısa bir cevap alıp gittiyse? Rezerve edilen alanın neredeyse tamamı boşa gitti. vLLM ekibinin ölçümüne göre bu yaklaşımda belleğin %60–80’i fragmentasyon ve aşırı rezervasyon yüzünden çöpe gidiyordu[1].
PagedAttention’ın fikri şu: işletim sistemleri bu problemi 1960’larda çözdü, adı virtual memory (sanal bellek) ve paging (sayfalama). Nasıl ki bir process belleğe sanal adreslerle erişip arka planda dağınık fiziksel frame’lere yönlendiriliyorsa, vLLM de KV cache’i sabit boyutlu bloklara (nominal varsayılan 16 token; güncel sürümlerde attention backend’i daha büyük bir değer seçebiliyor) böler ve her isteğe bir block table (blok tablosu) verir. İstek büyüdükçe boş blok havuzundan (free_block_queue) blok alır; bittiğinde bırakır. Bloklar bellekte bitişik olmak zorunda değildir[2][4].
Sonuç? İsraf yalnızca her dizinin son bloğunda, ortalama yarım blok kadar olur. Toplam bellek israfı %60-80 bandından %4’ün altına iner[1]. Aynı ekran kartına aynı anda çok daha fazla canlı istek sığar; basitleştirilmiş senaryolarda eşzamanlı istek kapasitesinde ~2.5 katlık artış ölçülüyor[9].

İşin güzel tarafı burada bitmiyor. Bloklar paylaşılabilir de. Aynı sistem prompt’uyla gelen yüzlerce istek varsa ya da tek bir prompt’tan paralel olarak birkaç farklı cevap üretiliyorsa, vLLM aynı blokları copy-on-write mantığıyla ortak kullanır. Orijinal ölçümlerde bu paylaşım, karmaşık sampling senaryolarında bellek kullanımını %55’e varan oranda düşürüp throughput’u 2.2 kata kadar artırıyor[1].
4. Perde Arkası II — Continuous Batching: Sırayı Bekletmeyen Kasiyer
İkinci büyük numara için önce bir GPU gerçeğini hatırlayalım: GPU’lar aynı işi çok sayıda veri üzerinde toplu yapmakta harikadır. Bir token üretmek için modelin tüm ağırlıklarını bellekten okumak gerekir; bu okuma masrafını tek bir kullanıcı için ödemek de otuz kullanıcı için ödemek de neredeyse aynıdır. Yani batch (toplu işleme) yapmak sudan ucuz.
Klasik static batching (statik batch’leme) bunu şöyle yapar: N tane isteği toplar, hepsini birlikte çalıştırır, hepsi bitene kadar yeni istek almaz. Sorun ortada: 30 istek 50 token’da bitip 2 istek 500 token’a kadar sürerse, batch’in geri kalanı boş boş dönerken GPU kullanımı %20–40 bandına düşer[4]. Süpermarkette tüm kasaların, en yavaş müşteri işini bitirene kadar kapalı beklemesi gibi.
Continuous batching (sürekli batch’leme) bu kuralı yıkar: batch’i bir “grup” olmaktan çıkarıp akışkan bir havuza çevirir. Her forward pass’ten (ileri geçiş) sonra scheduler devreye girer, biten istekleri havuzdan çıkarır ve boşalan yere bekleyen isteği anında alır. Hiçbir istek bir diğerinin bitmesini beklemez[4][2]

Rakamlar: karışık uzunluklu iş yüklerinde continuous batching, static batching’e göre 2–4 kat throughput getiriyor[4]. H100 SXM5 üzerinde Llama 3.3 70B FP8 ile 128 eşzamanlı istekte 1.900 token/s’den 2.380 token/s’ye çıkış ölçülmüş; eşzamanlılık düşükken fark daha da dramatik (4 istekte 290 → 480 token/s)[7]. A100 80GB üzerinde Llama 2 13B ile yapılan bir başka ölçümde ise batch’siz 120 token/s olan hız, continuous batching ile 890’a, PagedAttention eklendiğinde 1.240’a, parametreler optimize edilince 1.580 token/s’ye çıkıyor[17].
Prefill ve decode: iki farklı iş, tek scheduler
Bir ayrıntıya daha girelim, çünkü sonraki bölümleri anlamlı kılıyor. Model bir isteği iki fazda işler. Prefill fazında prompt’un tüm token’ları tek seferde işlenir — bu compute-bound (hesap sınırlı) bir iştir, GPU’nun çarpma gücünü zorlar. Decode fazında ise her adımda tek bir token üretilir — bu memory-bandwidth-bound (bellek bant genişliği sınırlı) bir iştir[2]. vLLM’in V1 scheduler’ı bu iki farklı işi aynı adımda bir arada çalıştırabilir; eski V0’ın ikisini sırayla işleyen yaklaşımına göre ciddi bir kazanç[2].
5. Perde Arkası III — İki Numara Daha: Chunked Prefill ve Prefix Caching
Chunked prefill: uzun prompt’un sırayı kilitlemesini engellemek
Şöyle bir sahne düşünün: siz “merhaba” yazdınız, tam o sırada başka bir kullanıcı 32.000 token’lık bir doküman yapıştırdı. O devasa prefill H100’de 70B model için 200–400 ms boyunca tüm hattı bloke eder ve sizin “merhaba”nız bekler[7]. Buna head-of-line blocking (sıra başı tıkanması) denir.
Chunked prefill, uzun prompt’u parçalara bölüp birden fazla adıma yayar; aralara başka isteklerin işi girer[2]. Ölçülen etki çarpıcı: 32K girdilerde 50 eşzamanlı istekle p95 TTFT 2.800 ms’den 890 ms’ye iniyor — %68 iyileşme. Buna karşılık p50 (medyan) neredeyse hiç değişmiyor[7]. Yani chunked prefill medyan hızı artırmaz; kuyruktaki en talihsiz kullanıcıyı kurtarır. Adalet ile ham medyan hız arasındaki klasik takas.
Prefix caching: aynı sistem prompt’unu bin kere hesaplamamak
Gerçek uygulamalarda istekler birbirine çok benzer başlar: aynı sistem prompt’u, aynı araç (tool) tanımları, RAG’de aynı doküman parçaları, çok turlu sohbette aynı geçmiş. vLLM her 16 token’lık bloğun hash’ini tutar; yeni bir istek geldiğinde hash zinciri tuttuğu yere kadar olan kısmı hiç hesaplamadan hazır KV bloklarından alır[2][14].
Üç pratik not. Birincisi, bu özellik V1 motorunda varsayılan olarak açıktır; çoğu ekip farkında olmadan zaten kullanıyor[14]. İkincisi, eşleşme “benzer metin” değil, blok sınırına kadar token token birebir eşleşmedir — prompt’unuzun başına kullanıcı adı ya da zaman damgası koyarsanız cache’i tamamen öldürürsünüz. Üçüncüsü, gerçek isabet oranınızı tahmin etmeyin, ölçün: vllm:prefix_cache_queries ve vllm:prefix_cache_hits metrikleri tam olarak bunun için var[14]. Çok kiracılı (multi-tenant) bir sistemde ise cache_salt parametresiyle kiracılar arası cache paylaşımını mutlaka kapatın.

Bu arada bir rakibin farkını da burada görelim: SGLang’ın RadixAttention‘ı aynı problemi radix ağacı ile çözer; vLLM düz bir hash tablosu kullanıp eviction (tahliye) politikasıyla ağaç davranışını yaklaşık olarak taklit eder[14]. Ortak prefix’in çok yoğun olduğu agent döngülerinde SGLang’ın veri yapısı hâlâ bir adım önde[30].
6. Elimizi Kirletelim: vLLM’i Ayağa Kaldırmak
Teori bu kadar; şimdi çalıştıralım. vLLM’in iki kullanım modu var ve ikisini de bilmekte fayda var.
Mod 1: Offline batch inference (sunucu yok, sadece Python)
Elinizde 10.000 doküman var ve hepsini özetlemek istiyorsunuz. Sunucuya gerek yok:
pip install vllm
# ozet.py
from vllm import LLM, SamplingParams
prompts = ["Şu metni özetle: ...", "Bunu da özetle: ...", ...]
params = SamplingParams(temperature=0.3, top_p=0.9, max_tokens=512)
llm = LLM(model="Qwen/Qwen3-8B", gpu_memory_utilization=0.90)
for out in llm.generate(prompts, params):
print(out.outputs[0].text)
Bu mod, vLLM’in en az bilinen ama en çok kazandıran kullanımıdır: listeyi verirsiniz, motor continuous batching’i kendi içinde uygular ve GPU’yu ağzına kadar doldurur. Aynı işi tek tek API çağrısıyla yapmaya kıyasla fark katlarla ölçülür.
Mod 2: OpenAI uyumlu sunucu
vllm serve Qwen/Qwen3-8B \
--host 0.0.0.0 --port 8000 \
--max-model-len 16384 \
--gpu-memory-utilization 0.90 \
--max-num-seqs 256
Sunucu ayağa kalktığında elinizde /v1/chat/completions uçlu, OpenAI SDK’sının olduğu gibi konuşabildiği bir servis olur. Yani kodunuzda değişecek tek şey base URL:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"Qwen/Qwen3-8B",
"messages":[{"role":"user","content":"Merhaba, ayakta mısın?"}],
"max_tokens":50}'
Docker ile: prod’a giden yol
docker run --gpus all --ipc=host -p 8000:8000 \
-e HUGGING_FACE_HUB_TOKEN=... \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.3-70B-Instruct \
--dtype fp8 \
--tensor-parallel-size 2 \
--max-model-len 16384 \
--gpu-memory-utilization 0.92 \
--max-num-seqs 512 \
--max-num-batched-tokens 65536 \
--enable-chunked-prefill \
--kv-cache-dtype fp8
En sık yapılan hata:
--ipc=hostflag’ini unutmak. vLLM arka planda PyTorch’un paylaşımlı bellek (shared memory) mekanizmasını kullanır — özellikle tensor parallel çalışırken. Container’ın varsayılan küçük shm alanı yetmezse sistem yük altında anlaşılmaz hatalarla çöker.--ipc=hostyerine yeterince büyük bir--shm-sizevermek de aynı işi görür[8].
Ve prod’da gözünüzü ayırmayacağınız üç metrik (/metrics ucundan Prometheus formatında gelir)[8]:
curl http://localhost:8000/metrics | grep vllm:
vllm:num_requests_waiting # kuyruk derinliği — sürekli artıyorsa kapasiteniz yetmiyor
vllm:kv_cache_usage_perc # KV cache doluluğu — %100'e dayanınca preemption başlar
vllm:time_to_first_token_seconds # kullanıcının hissettiği gecikme
7. Ayar Odası: Hangi Vida Ne İşe Yarar?
vLLM’in onlarca flag’i (komut satırı seçeneği) var ama pratikte hayatınızı belirleyen bir avuç tanesi. Tabloyu ezberlemeyin, mantığını anlayın:
| Flag | Ne yapar | Pratik öneri |
|---|---|---|
--gpu-memory-utilization | GPU belleğinin ne kadarını vLLM’e ayırdığınız (güncel varsayılan 0.92) | Bare-metal’de 0.95’e kadar çıkın; kartı başka iş paylaşıyorsa 0.85’te kalın[7] |
--max-model-len | İzin verilen maksimum context uzunluğu | Gerçekten ihtiyacınız olan değeri yazın. Gereksiz büyütmek KV cache’i şişirir ve eşzamanlı kullanıcı sayınızı düşürür |
--max-num-seqs | Aynı anda batch’te tutulacak maksimum istek sayısı | Yüksek eşzamanlılıklı API’lerde 512–2048; düşük gecikme istiyorsanız düşük tutun[7] |
--max-num-batched-tokens | Bir adımda işlenecek toplam token bütçesi | Throughput odaklıysa 16K–64K; düşük gecikme odaklıysa 8K civarı[7][17] |
--kv-cache-dtype fp8 | KV cache’i 8 bitte tutar | Bellek ihtiyacını yarıya indirir; context bütçenizi bir hamlede ikiye katlar[8] |
--tensor-parallel-size | Modeli kaç GPU’ya bölecek | Model tek karta sığmıyorsa şart. Kart sayınıza eşitleyin[29] |
--enable-chunked-prefill | Uzun prompt’ları parçalara böler | Girdi uzunlukları çok değişkense açın; hepsi kısa ve benzerse gereksiz[7] |
--quantization / --dtype fp8 | Ağırlıkları düşük hassasiyette tutar | 70B FP16 ≈ 140 GB (2× H100), FP8 ≈ 70 GB (tek H100). Sığdırma matematiğinin can simidi[8] |
Bir de “OOM (out of memory) hatası aldım, ne yapayım” refleksi olsun: sırasıyla --max-model-len‘i düşürün, --max-num-seqs‘i kısın, --kv-cache-dtype fp8 açın, quantize edilmiş bir model ağırlığına geçin, hâlâ olmuyorsa --tensor-parallel-size ile ikinci karta yayın[19].
Bunun karşılığı sadece hız değil, doğrudan para: bir vaka çalışmasında varsayılan ayarlardan optimize ayarlara geçiş, aynı throughput’u %40 yerine %85 GPU kullanımıyla sağlayarak aylık maliyeti 5.789 dolardan 2.894 dolara indiriyor[7].
8. Kıyas Zamanı I: Ollama, llama.cpp, LM Studio ve Docker Model Runner
Şimdi kafa karışıklığının en yoğun olduğu yere gelelim. Sık sorulan “Ollama mı vLLM mi?” sorusunun dürüst cevabı: bu ikisi aynı ligde değil. Ollama, llama.cpp ve LM Studio tek kullanıcıyı mutlu etmek için tasarlandı; vLLM bir GPU filosundan maksimum iş çıkarmak için. Kıyaslamak, bisiklet ile şehirlerarası otobüs kıyaslamak gibi — ikisi de doğru, mesele nereye gittiğiniz.
| Ollama / LM Studio | llama.cpp | Docker Model Runner | vLLM | |
|---|---|---|---|---|
| Hedef | Tek kullanıcı, masaüstü | Gömülü / taşınabilir çalışma zamanı | Geliştirici iş akışı, tek API | Çok kullanıcılı servis, prod |
| Model formatı | GGUF | GGUF | GGUF + safetensors (OCI paketi) | Safetensors (GGUF de destekli) |
| Donanım | CPU, Mac, her türlü GPU | Her yerde — CPU dahil | NVIDIA / AMD / Apple Silicon | Ağırlıklı NVIDIA; AMD, TPU, CPU, Gaudi |
| Eşzamanlılık | Varsayılan 1; elle artırılır[16] | Sınırlı, elle ayarlanır | Arka uca göre değişir | Yüzlerce |
| Başlangıç süresi | Saniyeler | Saniyeler | Saniyeler | ~60 saniye[6] |
| Kurulum yükü | Tek komut | Derleme / flag bilgisi | Docker varsa yok | Ciddi; GPU sürücüsü, bellek planı |
Peki Docker Model Runner tam olarak nedir?
Bu, listedeki en yeni ve en çok yanlış anlaşılan isim. Docker Model Runner (DMR) bir inference motoru değil; motorların üzerine geçen bir yönetim ve dağıtım katmanı. Modelleri OCI artifact’ı olarak — yani container image’ları gibi — Docker Hub, herhangi bir OCI registry’si ya da Hugging Face üzerinden çeker, tek bir OpenAI uyumlu API sunar ve arkada üç farklı motoru koşturabilir: yerel geliştirme için llama.cpp, görsel üretim için Diffusers ve yüksek throughput için vLLM[10][23].
# vLLM arka ucunu kur (Linux + NVIDIA)
docker model install-runner --backend vllm --gpu cuda
# modeli çek ve çalıştır — API yine OpenAI uyumlu
docker model run ai/smollm2-vllm "Beni duyuyor musun?"
Buradaki asıl fikir şu: aynı iş akışı içinde llama.cpp ile lokalde prototip yapıp, tek satır değiştirerek vLLM ile prod’a ölçeklemek[11]. Modeli container gibi versiyonlayıp registry’de tutabilmek de kurumsal tarafta ciddi bir kolaylık. Sınırlar da net: vLLM arka ucu Linux ve WSL2 üzerinde NVIDIA GPU ister, model kayıt/başlatma sırasında llama.cpp’den yavaştır ve API’nin kimlik doğrulaması yoktur — servise erişebilen herkes model çalıştırabilir[10][11].
Mac tarafında güzel bir gelişme de var: Docker ve vLLM ekibinin birlikte geliştirdiği vllm-metal arka ucu, MLX ile PyTorch’u tek bir yolda birleştirip Apple Silicon’ın unified memory’sini sıfır kopyayla kullanıyor. Docker Desktop 4.62+ ile docker model install-runner --backend vllm deyip MLX formatındaki modelleri çalıştırabiliyorsunuz[12][13]. Beklentiyi doğru ayarlayalım ama: aynı ölçümlerde llama.cpp hâlâ ~1.2–1.3 kat daha hızlı; vllm-metal’in avantajı uzun çıktılarda daha iyi ölçeklenmesi[12].
9. Kıyas Zamanı II: vLLM’in Gerçek Rakipleri
vLLM’in asıl rakipleri Ollama değil, aynı problemi çözen diğer prod servis motorları. Sahne bugün üç isimden ibaret: SGLang, TensorRT-LLM ve azalan bir üçüncü, TGI.
Mart 2026’da H100 SXM5 üzerinde Llama 3.3 70B Instruct FP8 ile, 200 benzersiz prompt kullanılarak yapılan bir ölçüm şöyle[6][9]:
| Eşzamanlılık | vLLM | SGLang | TensorRT-LLM |
|---|---|---|---|
| 1 istek | 120 tok/s | 125 tok/s | 130 tok/s |
| 50 istek | 1.850 tok/s | 1.920 tok/s | 2.100 tok/s |
| 100 istek | 2.400 tok/s | 2.460 tok/s | 2.780 tok/s |
| TTFT p50 (10 istek) | 120 ms | 112 ms | 105 ms |
| Soğuk başlangıç | ~62 sn | ~58 sn | ~28 dakika (derleme) |
Tabloyu okurken iki şeye dikkat edelim. Birincisi, aradaki farklar sandığınızdan küçük — üçü de aynı büyüklük mertebesinde. İkincisi ve daha önemlisi: bu test benzersiz prompt’larla yapıldı, yani prefix caching’in hiç devreye girmediği en kötü senaryoydu. Gerçek trafiğinizde aynı sistem prompt’u tekrar ediyorsa sıralama pekâlâ değişebilir[9].
SGLang, RadixAttention’ı sayesinde ortak prefix’in yoğun olduğu işlerde — sohbet, RAG, few-shot, agent döngüleri — vLLM’e göre daha iyi TTFT verir[6][30]. TensorRT-LLM ham hızın zirvesidir ama bedeli ağırdır: yalnızca NVIDIA, dar model desteği ve modeli önceden derleme zorunluluğu. Haftada bir model değiştiren bir ekip için 28 dakikalık derleme süresi tek başına caydırıcıdır[6][20]. TGI ise artık bakım modunda; Hugging Face yeni işler için kullanıcıları vLLM, SGLang, llama.cpp ve MLX’e yönlendiriyor[9].
Pratikte karar şuna geliyor: çoğu ekip için gerçek seçim vLLM ile SGLang arasındadır[6]. vLLM’i öne çıkaran şey ham hız değil, en geniş model desteği, derleme gerektirmeyen esneklik ve en olgun operasyon ekosistemi. Yeni bir model çıktığında ilk gün destekleyen genelde vLLM olur.
Benchmark okuma kılavuzu: Sürüm kayması gerçek bir sorundur. TensorRT-LLM v1.2 derlemeli, v1.3 PyTorch tabanlıdır; ikisini karşılaştırmak motor kabiliyetini değil sürüm etkisini ölçer[9]. Kendi bake-off’unuzu yaparken üç ayrı trafik şekli deneyin — benzersiz prompt’lar, tekrar eden prefix’ler ve gerçek prod karışımınız — ve başarısız istekleri de raporlayın, sadece başarılıların ortalamasını değil.
10. vLLM’i Ne Zaman Seçmemeli?
Bir aracı gerçekten anlamak, sınırlarını bilmekle olur. vLLM’den uzak durmanız gereken durumlar:
Tek kullanıcıysanız. vLLM’in tüm sihri paylaşımda. Kendi başınıza sohbet ediyorsanız Ollama ya da LM Studio hem daha hızlı kurulur hem daha hızlı başlar. ~60 saniyelik soğuk başlangıcı her seferinde ödemenin anlamı yok[6][27][28].
Mac’teyseniz (çoğunlukla). vllm-metal umut verici ama topluluk tarafından sürdürülüyor, arm64 Python 3.12 ve Xcode Command Line Tools istiyor ve kaynaktan derleniyor[13]. Apple Silicon’da hâlâ pratik cevap MLX ya da llama.cpp.
VRAM’iniz darsa. vLLM belleği baştan rezerve edip yönetir; llama.cpp’nin “katmanların bir kısmını CPU’ya taşı” esnekliği yoktur. GGUF ile 8 GB’lık bir kartta 30B model koşturma numaraları vLLM’in dünyasına ait değil.
Model desteği doğrulanmadıysa. “Mimariyi destekliyor” ile “prod’a hazır” aynı şey değil. Ciddi model kartları artık hangi motor sürümüyle hangi komutla çalıştırılacağını açıkça yazıyor; oradan başlayın, sürümleri sabitleyin, sonra kendi GPU’nuzda yük, tool çağrısı ve throughput testi yapın[9].
11. Ufuk: Tek Sunucudan Dağıtık Servise
Son olarak nereye gittiğimize bakalım, çünkü bu yön vLLM’in gelecekteki rolünü belirliyor. İki büyük kavram öne çıkıyor.
KV offloading: vLLM 0.11.0 ile gelen KV offloading connector, GPU belleği dolduğunda KV değerlerini atıp sonra yeniden hesaplamak yerine CPU RAM’ine asenkron olarak taşıyor. Llama-3.1-8B ile H100’de tek istekte TTFT’de 2–22 kat, 10.000 istekli testte throughput’ta 9 kata varan iyileşme raporlanıyor; 0.12.0’daki bellek yerleşimi optimizasyonuyla bunun üstüne 4 kat TTFT ve 5 kat throughput daha ekleniyor[15]. Son sürümlerde bu, katmanlı ikincil depolamayı da kapsayacak şekilde genişledi[18].
Disaggregated serving (ayrıştırılmış servis): Hatırlayın, prefill compute-bound, decode memory-bound bir işti. Neden ikisini aynı GPU’da yapalım? Yeni mimari bu iki fazı ayrı GPU havuzlarına dağıtıp KV cache’i aralarında transfer ediyor. Kubernetes üzerinde llm-d, NVIDIA Dynamo ve KServe gibi projeler tam olarak bu deseni operasyonel hale getiriyor[24][25][26]. Bu katmanların çoğunda motor olarak yine vLLM koşuyor — yani vLLM giderek “tek sunucu aracı” olmaktan çıkıp dağıtık bir servis katmanının çekirdeğine dönüşüyor.
Kapanış: Karar Sizde
Toparlayalım. vLLM’in bütün hikâyesi üç cümleye sığıyor. PagedAttention belleği kurtarır — KV cache’i işletim sistemi sayfaları gibi yönetip israfı %60-80’den %4’ün altına indirir. Continuous batching zamanı kurtarır — kimse kimseyi beklemez, GPU boş dönmez. Ve bu ikisi yalnızca paylaşımda anlam kazanır — tek kullanıcıysanız vLLM size bir şey kazandırmaz, sadece kurulum zahmeti verir.
Karar ağacınız bu kadar basit: kendinize çalıştırıyorsanız Ollama ya da LM Studio; taşınabilirlik ve tam kontrol istiyorsanız llama.cpp; aynı iş akışında hem prototip hem prod istiyorsanız Docker Model Runner; başkalarına servis ediyorsanız vLLM; prefix’i çok ağır agent yükleriniz varsa yanına SGLang’ı da tartın; tek modeli yıllarca sabit koşturacaksanız TensorRT-LLM’i değerlendirin.
Ve en önemlisi: bu yazıdaki hiçbir sayıyı olduğu gibi kabul etmeyin. Kendi modelinizle, kendi prompt dağılımınızla, kendi kartınızda ölçün. İyi haber şu ki artık neyi ölçeceğinizi ve çıkan sayının neden o çıktığını biliyorsunuz. Kolay gelsin — GPU’nuz dolu, kuyruğunuz boş olsun!
Kaynaklar
- vLLM Blog — vLLM: Easy, Fast, and Cheap LLM Serving with PagedAttention
- vLLM Blog — Inside vLLM: Anatomy of a High-Throughput LLM Inference System
- vLLM — Official Documentation
- Runpod — vLLM Explained: PagedAttention and Continuous Batching
- Applied Sciences (MDPI) — Benchmarking Ollama and vLLM for Concurrent LLM Serving: A Multi-Scenario Evaluation
- Spheron — vLLM vs TensorRT-LLM vs SGLang: Which Is Fastest? (H100 Benchmarks, 2026)
- Spheron — LLM Serving Optimization: Continuous Batching, PagedAttention and Chunked Prefill on H100
- Spheron — vLLM Production Deployment 2026: Multi-GPU Tensor Parallel + FP8 Docker Setup
- LeetLLM — vLLM vs SGLang vs TensorRT-LLM vs Ollama: Choosing an Inference Engine in 2026
- Docker Docs — Docker Model Runner
- vLLM Blog — Docker Model Runner Integrates vLLM for High-Throughput Inferencing
- Docker Blog — Docker Model Runner Adds vLLM Support on macOS
- vllm-metal — Community Hardware Plugin for vLLM on Apple Silicon (GitHub)
- packet.ai — vLLM Prefix Caching Explained
- vLLM Blog — Inside vLLM’s New KV Offloading Connector
- Ollama — Official FAQ (Concurrency & Environment Variables)
- EaseCloud — vLLM Throughput Guide: PagedAttention and Batching Tips (2026)
- vLLM — Releases (GitHub)
- vLLM Docs — Optimization and Tuning
- Runpod — vLLM vs TensorRT-LLM vs SGLang: Which Inference Engine to Deploy
- UC Berkeley Sky Computing Lab — vLLM Project Page
- Efficient Memory Management for Large Language Model Serving with PagedAttention (arXiv 2309.06180)
- Docker Docs — Model Runner Inference Engines
- Spheron — llm-d on Kubernetes: Disaggregated LLM Inference Deployment Guide
- NVIDIA Technical Blog — Deploying Disaggregated LLM Inference Workloads on Kubernetes
- vLLM Docs — Disaggregated Prefilling
- Rost Glukhov — Ollama vs vLLM vs LM Studio: Best Way to Run LLMs Locally in 2026
- Codersera — vLLM vs Ollama vs LM Studio: The 2026 Production Self-Host Benchmark
- vLLM Docs — Parallelism and Scaling
- Spheron — vLLM vs SGLang 2026: RadixAttention vs PagedAttention Benchmarks
- Kapak Görseli: Photo by Klara Kulikova on Unsplash