Inference Engine'ler

20 min · 1,095 words

What you will be able to do
  • Say what an inference engine does that a provider hides from you
  • Give the three real reasons to run a model yourself
  • Pick an engine for one machine, for a GPU server, or for a cluster
  • Explain why batching decides throughput
  • Put a chat interface in front of a local model

LLM Temelleri modülünde inference engine'lerin adları geçmişti. Oradaki açıklama, bu engine'lere nadiren doğrudan dokunacağını söylüyordu. Bu doğru ve bu yüzden o modül hemen Ollama'ya geçmişti. Bu modül ise engine'lere gerçekten dokunmanın gerektiği durumları anlatıyor.

Bir inference engine, model weight'lerini belleğe yükleyen ve senin token'larını bir sonraki token'a çeviren programdır. Bu programın şu işleri vardır:

  • GPU belleğini yönetir.
  • İstekleri bir batch'te birleştirir.
  • Turlar arasında attention state'ini önbellekte tutar.
  • İşlerin sırasını, yani scheduling'i belirler.

Bir inference provider ise bu engine'lerden birini senin yerine çalıştıran ve senden token başına ücret alan bir başkasıdır. Konunun kendisi, Inference Provider'lar modülünün ana konusudur.

Neden Kendin Çalıştırırsın

Bunu kendin çalıştırmanın üç nedeni var ve yalnızca bu üçü uğraşmaya değer.

Veri dışarı çıkamaz. Sağlık kayıtları, hukuki belgeler ve metnin senin altyapında kalmasını söyleyen bir kuralın kapsamındaki her şey buna örnektir. Bu, diğer ikisinden çok daha sık karşılaşılan en yaygın nedendir. Eğer senin için geçerliyse, karar tek başına bu nedenle verilmiş olur.

Hacim işi ucuzlatır. Token başına fiyatlandırma çok iyidir, ama her hacimde değil. Bir kesişim noktası vardır ve o noktanın ötesinde, bütün gün çalışan kiralık bir GPU, aynı işi token satın alarak yapmaktan çok daha ucuza gelir. Bu noktayı geçtiysen hesap artık yakın değildir, fark büyüktür.

Bir provider'ın vermeyeceği bir şeye ihtiyacın var. Örneğin:

  • Training LLMs modülünde anlatılan şekilde, kendi fine-tune ettiğin bir model
  • Kimsenin barındırmadığı bir model
  • Alışılmadık bir quantization
  • Tam olarak hangi sürümün çalışacağını sen belirlersin, böylece bir güncelleme seni hiç şaşırtmaz

Bunların hiçbiri geçerli değilse, bir provider kullanman en iyisidir. Kendi altyapında barındırmak (self-hosting) gerçek bir operasyon işidir ve ilk ay boyunca çoğunlukla bütçesine koymadığın şeylerle karşılaşırsın.

Problemin Büyüklüğüne Göre Engine'ler

Rendering FIG. 31.1

FIG. 31.1 — Problemin Büyüklüğüne Göre Engine'ler

Kendi makinende sarmalayıcıları (wrapper) kullanmak en doğrusudur. LLM Temelleri modülünde anlatılan Ollama⁠ ve LM Studio⁠ bu durumda doğru seçimdir. İkisi de engine'i gizler ve birkaç dakika içinde çalıştırmanı sağlar; altlarında ise llama.cpp⁠ bulunur. llama.cpp, C ve C++ ile yazılmış bir LLM inference projesidir ve quantize edilmiş bir modelin dizüstü bilgisayarda bile çalışabilmesinin nedeni de budur. llama.cpp'yi doğrudan kullanmak iki durumda mantıklıdır: sarmalayıcının açmadığı bir build flag'ine ihtiyacın olduğunda ya da kimsenin desteklemediği bir donanıma model koyacağın zaman.

Gerçek kullanıcılara hizmet veren bir GPU sunucusunda sarmalayıcılar artık yetmez ve burada bir serving engine'e ihtiyacın olur.

  • vLLM genellikle varsayılan seçimdir. Geniş bir donanım yelpazesini destekler ve iyi bir verimi büyük ölçüde sürekli batching'e borçludur.
  • SGLang⁠, dil ve multimodal modeller için yüksek performanslı bir serving framework'üdür. Özellikle isteklerin uzun ve ortak bir önek (prefix) paylaştığı durumlarda güçlüdür. Her isteğin aynı büyük system prompt'la başladığı bir durumdaysan, tam olarak senin durumun budur.
  • TensorRT-LLM⁠, NVIDIA'dan gelir ve özellikle o donanımdan en fazla verimi çıkarmak için tasarlanmıştır. Modeli önceden optimize edilmiş bir engine'e derlersin. Bunun bir build adımı maliyeti vardır, ama karşılığında daha düşük gecikme (latency) elde edersin.

Birden fazla makineye yayıldığında sorun artık tek bir sunucu programını iyi çalıştırmak değildir. Sorun, bütün bir makine cluster'ını birlikte yönetmeye dönüşür. llm-d⁠ tam bu iş için tasarlanmıştır ve modern hızlandırıcılarla Kubernetes üzerinde inference çalıştırır. Zamanlamayı ve yönlendirmeyi platform üstlenir, yani her isteği hangi makinenin çalıştıracağına o karar verir. Ayrıca önbellek farkındalıklı yerleştirme (cache-aware placement) yapar: gereken veriyi zaten önbelleğinde tutan bir makineyi tercih eder. Böylece sen bunlarla uğraşmak zorunda kalmazsın.

Sayıları Açıklayan Tek Fikir

Bu modülden yalnızca tek bir mekanizmayı hatırlayacaksan, o batching'dir.

Tek seferde tek istek çalıştıran bir GPU çoğunlukla boştadır, çünkü bir token üretmek çok az hesaplama ama çok büyük bir bellek trafiği gerektirir. Aynı anda birçok isteği birlikte çalıştırırsan, GPU weight'leri bellekten bir kez okur ve gruptaki bütün istekler için kullanır.

İnsanlar bu engine'lerin verimini (throughput) çok sayıda eş zamanlı kullanıcıyla ölçer. Aynı donanımın bazen harika, bazen umutsuz görünmesinin nedeni de budur. Belirleyici olan tek şey, batch'in ne kadar dolu olduğudur.

Pratikte en çok önem taşıyan iyileştirme continuous batching'dir. Engine, bir batch'in bitmesini beklemek yerine eski istekler tamamlandıkça yenilerini batch'e ekler. Böylece GPU hiçbir zaman iş olmadan kalmaz. Aynı nedenle, tek istekle çalıştırdığın kendi benchmark'ın sunucunun neler yapabileceği konusunda seni ciddi biçimde yanıltır.

Batching'in bir de Context Engineering ile bağlantısı var, ama bu sefer öbür yönden. Uzun bir context için attention state'in GPU belleğinde kalması gerekir. Bu yüzden dolu bir context window üzerinde akıl yürütmek daha yavaştır. Üstelik bu bellek, başka bir kullanıcının isteğinin ihtiyaç duyduğu belleği de tutar.

Engine'in Önüne Konan Arayüz

Bir engine sana bir API verir, ama bakabileceğin bir şey vermez. Open WebUI⁠, insanların bir engine'in önüne koyduğu arayüzdür. Ollama'ya ya da OpenAI'ın API biçimini kullanan herhangi bir şeye bağlanan bir chat UI'dır. Hesapları, konuşma geçmişi ve model değiştirme özellikleri vardır. Bazı ekipler kendi donanımlarında çalışan özel bir ChatGPT ister. Onlar için tüm yığın iki parçadan ibarettir: engine ve Open WebUI.

Özet

Bir inference engine, weight'leri gerçekten çalıştıran programdır. Şunların sorumluluğunu üstlenir:

  • GPU belleği
  • batching
  • attention cache'i
  • scheduling

Provider ise bu engine'i senin yerine işleten bir başkasıdır.

Kendi engine'ini üç nedenden biri için çalıştır:

  • Verin senin altyapından çıkamaz.
  • Hacim, GPU kiralamanın token satın almaktan ucuz olduğu noktayı geçti.
  • Kimsenin barındırmadığı bir model ya da sürüme ihtiyacın var.

Bunlardan biri geçerli değilse, bir provider kullan, çünkü self-hosting bir operasyon işidir.

Engine'i problemin büyüklüğüne göre seçmelisin. Kendi makinende, altlarında llama.cpp çalışan Ollama ya da LM Studio'yu kullan. Gerçek kullanıcılara hizmet veren bir GPU sunucusunda ise vLLM, SGLang ya da TensorRT-LLM'den birini seç. SGLang, ortak bir uzun prefix paylaşan istekler için uygundur; TensorRT-LLM ise NVIDIA donanımından en fazla verimi alır. Problem bir cluster'a dönüştüğünde llm-d'ye geçersin.

Batching, bu modüldeki her sayıyı açıklayan fikirdir. Tek bir isteğe hizmet veren bir GPU çoğunlukla boştadır ve continuous batching onu dolu tutar. Bu yüzden tek istekle yapılan bir benchmark, sana neredeyse hiçbir şey söylemez.

Hızlı Kontrol: Kendi altyapında çalıştırdığın modeli her seferinde tek istekle ölçüyorsun ve hızlı görünüyor. Peki elli kullanıcıyla neden çökebilir? Bunun yerine neyi ölçmen gerekirdi?

Kaynaklar

🛠️ Araçlar

🗃️ Repolar

  • llama.cpp⁠: C ve C++ ile yazılmış bir LLM inference projesi. Yerel sarmalayıcıların dayandığı temel budur.
  • SGLang⁠: yüksek performanslı serving. Ortak bir prefix paylaşan isteklerde güçlüdür.
  • TensorRT-LLM⁠: NVIDIA'dan gelir ve daha düşük gecikme için önceden derlenir.
  • llm-d⁠: Kubernetes üzerinde birden fazla makineye yayılmış serving.
  • Open WebUI⁠: bunların herhangi birinin önüne koyabileceğin chat arayüzü.
Want a quick quiz?5 questions on the main points of this module
Question 1 of 5

Bir inference engine ne yapar?