Ollama num_ctx ayarı ile bağlam uzunluğunu artırma
Ollama varsayılan num_ctx değeri uzun istemleri kesebilir. Modelfile veya API isteği üzerinden bellek kapasitenize uygun KV cache boyutunu nasıl yapılandıracağınızı öğrenin.
num_ctx ne işe yarar ve uzun isteminiz neden kesildi
Ollama bağlam uzunluğu (context length), yüklenen bir modelin aynı anda bellekte tutabileceği token sayısıdır ve bunu belirleyen seçenek num_ctx parametresidir. Ollama, modelin desteklediği maksimum değerin çok altında bir varsayılan değer seçer; bu nedenle uzun bir istem, model tarafından okunmadan önce kesilir. Yanıt içerisinde bu durumun gerçekleştiğine dair herhangi bir uyarı yer almaz.
Llama 3.1 8B, Ollama model kütüphanesinde 128k bağlam penceresi ile listelenir. Standart bir sunucu size bu değeri doğrudan sağlamaz. Ollama'nın kendi belgeleri farklı sayfalarda farklı varsayılan değerler sunar: SSS bölümü 4096 token değerini belirtirken, Modelfile referansı num_ctx değerinin varsayılan olarak 2048 olduğunu ifade eder. Bağlam uzunluğu sayfası ise varsayılan değerin mevcut VRAM (video RAM) miktarına göre belirlendiğini belirtir: 24 GiB altı için 4k, 24 ile 48 GiB arası için 32k ve üzeri için 256k. Bu değerlerin her biri farklı sürümlerde geçerli olmuştur. Buradaki çelişki önemli bir ders niteliğindedir: Herhangi bir sayfaya veya bu belgeye güvenmek yerine, değeri doğrudan çalışan sunucunuzdan kontrol edin.
Kesilme işlemi sessizce gerçekleşir çünkü model yine de yanıt verir ve yanıt akıcı görünür. Yanıt, girdiğiniz metnin son kısmından oluşturulmuştur. Bir belgenin ilk yarısını içermeyen bir özet, modelin yetersiz olduğu izlenimini yaratır. Bu durum genellikle küçük bir bağlam penceresinden kaynaklanır.
Sunucunuzun fiilen uyguladığı Ollama bağlam uzunluğunu denetleyin
Her sürümde çalışan denetim prompt_eval_count komutudur; bu komut, sunucunun işlediğini bildirdiği istem belirteçlerinin (prompt tokens) sayısını verir. Bağlam kapasitesinden daha fazla veri gönderdiğinizde, bu sayı sınırda durur.
sudo apt update && sudo apt install -y jq
LONG=$(python3 -c "print('the quick brown fox jumps over the lazy dog. ' * 2000)")
jq -n --arg p "$LONG" '{model:"llama3.1:8b", prompt:$p, stream:false, options:{num_ctx:4096}}' |
curl -s http://localhost:11434/api/generate -d @- |
jq '{prompt_eval_count, prompt_eval_duration}'Bu istem yaklaşık 18.000 kelimedir, yani 4096 belirteçten çok daha fazladır. prompt_eval_count çıktısı, sunucu geri kalanını kırptığı için gerçek belirteç sayısı yerine 4096 değerine yakın bir sonuç döndürür. Komutu "num_ctx":16384 ile tekrar çalıştırdığınızda sayı yükselir. Eğer sürümünüz kırpma yerine hata döndürüyorsa, bu durum aynı bulgunun daha belirgin bir göstergesidir.
ollama psCONTEXT sütunu, bunu yazdıran sürümlerde, yüklü modelin o an hangi bağlam uzunluğuyla çalıştığını gösterir. Yanındaki PROCESSOR sütunu ise modelin nerede konumlandığını belirtir. 100% CPU, GPU bulunmayan bir VPS üzerinde normaldir. GPU içeren bir sunucuda 30%/70% CPU/GPU gibi bir bölünme, ağırlıkların ve önbelleğin artık VRAM'e sığmadığı anlamına gelir; bunun yaygın nedeni ise yükseltilmiş bir num_ctx değeridir.
journalctl -u ollama --no-pager | grep -i n_ctx | tail -n 5Çıkarım çalıştırıcısı (inference runner), bağlam boyutunu n_ctx içeren bir satırda yazdırır. Tam ifade sürümler arasında değişiklik gösterebilir, bu nedenle satırın eksik olması durumunda bunu bir kanıt olarak değil, yeniden adlandırma olarak değerlendirin.
num_ctx ayarının yapılabileceği dört yer
İstek içerisinde. "options": {"num_ctx": 16384} değerini /api/generate veya /api/chat parametresine gönderin. Bu yöntem diğer tüm ayarları geçersiz kılar ve yalnızca ilgili çağrı için geçerli olur. Eğer değer, yüklü modelin mevcut çalışma değerinden farklıysa, sunucu önce modeli yeniden yükler; bunu yanıt içerisindeki load_duration değerinde görebilirsiniz: değer sıfıra yakınken aniden tam saniyelere çıkar. Aynı bekleme süresi, model boşta kalıp bellekten atıldığında da oluşur; bu nedenle bir bağlam boyutu belirlediğinizde keep_alive ile modeli bellekte tutmak faydalıdır.
Etkileşimli oturumda. ollama run içerisinde /set parameter num_ctx 16384 komutunu yazın. Bu ayar sadece o oturum süresince geçerli kalır.
Modelfile içerisinde. Bu yöntem, değeri isimlendirilmiş bir modele sabitler; böylece istemci tarafında herhangi bir değişiklik yapılmasına gerek kalmadan her istemci bu değeri kullanır.
FROM llama3.1:8b
PARAMETER num_ctx 16384ollama create llama3.1-16k -f ./Modelfile
ollama run llama3.1-16kSunucu üzerinde. OLLAMA_CONTEXT_LENGTH, kendi num_ctx değerini taşımayan her istek için varsayılanı belirler. systemd altında, birim dosyasını (unit file) düzenlemek yerine bir drop-in dosyası ekleyin.
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_CONTEXT_LENGTH=16384"sudo systemctl daemon-reload
sudo systemctl restart ollama
ollama psÖncelik sırası, özellikle başka birinin istemcisinde hata ayıklarken önem kazanır. num_ctx içeren bir istek, sunucu varsayılanını geçersiz kılar; bu nedenle kendi küçük değerini gönderen bir sohbet arayüzü veya bir aracı, sizin systemd üzerinde yaptığınız değişikliği sessizce etkisiz hale getirebilir. Bir kodlama aracını Ollama sunucunuza yönlendirdiğinizde, sunucuyu suçlamadan önce istemcinin ne gönderdiğini kontrol edin.
Neden num_ctx değerini doğrudan modelin maksimum değerine ayarlayamazsınız
Dikkat mekanizması (attention), her bir token'ın kendisinden önceki tüm token'ları incelemesini sağlar. Önceki token'lar için hesaplanan anahtar (key) ve değer (value) verileri, her yeni token için tekrar hesaplanmamaları adına saklanır; bu depolama alanına KV cache (anahtar/değer önbelleği) denir. Bu alan, model yüklendiğinde tüm num_ctx için ayrılır, konuşma ilerledikçe büyümez. Bu nedenle, tek satırlık bir komut girişi için bile büyük bir bağlam (context) boyutu, ciddi miktarda bellek tüketir.
DigitalOcean'ın çıkarım maliyeti eğitimi, bu aritmetiği tek bir satırda özetler:
kv_bytes_per_token = 2 * layers * kv_heads * head_dim * bytes_per_valueBuradaki 2 sayısı, anahtarları ve değerleri ayrı ayrı sayar. Diğer sayıları kendi modelinizin özelliklerinden okuyabilirsiniz.
curl -s http://localhost:11434/api/show -d '{"model":"llama3.1:8b"}' |
jq '.model_info | {ctx: ."llama.context_length", layers: ."llama.block_count", heads: ."llama.attention.head_count", kv_heads: ."llama.attention.head_count_kv", embed: ."llama.embedding_length"}'Llama 3.1 8B modeli 32 katman ve 8 anahtar/değer başlığı (head) bildirir. Başlık boyutu, embed değerinin heads değerine bölünmesiyle bulunur; yani burada 4096 / 32 = 128 eder. Bazı modeller bunu doğrudan llama.attention.key_length olarak yayınlar. Varsayılan önbellek f16 değerlerini tutar, bu yüzden bytes_per_value değeri 2'dir. 2 32 8 128 2 işlemi 131.072 bayt sonucunu verir. Bu, bağlamdaki her bir token için 128 KiB önbellek demektir. Bunu bağlam uzunluğu ile çarptığınızda, maliyet soyut bir kavram olmaktan çıkar.
The data behind this chart
[
{
"label": "4k",
"kv_cache_gib": 0.5,
"total_ram_gib": 5.1
},
{
"label": "8k",
"kv_cache_gib": 1,
"total_ram_gib": 5.6
},
{
"label": "16k",
"kv_cache_gib": 2,
"total_ram_gib": 6.6
},
{
"label": "32k",
"kv_cache_gib": 4,
"total_ram_gib": 8.6
},
{
"label": "64k",
"kv_cache_gib": 8,
"total_ram_gib": 12.6
},
{
"label": "128k",
"kv_cache_gib": 16,
"total_ram_gib": 20.6
}
]6 satırındaki değerler, yukarıdaki formülün aritmetik sonucudur, ölçüm değildir. Toplam sütunu, Ollama kütüphanesinin Ağustos 2026'da llama3.1:8b için listelediği 4,9 GB'lık (yani 4,6 GiB) indirme boyutunu ekler; ancak hesaplama tamponlarını (compute buffers) ve sunucu sürecinin kendisini dahil etmez. Bu değerleri minimum bir eşik olarak kabul edin.
Önemli olan şekildir. 8k bağlam boyutunda önbellek 1 GiB maliyet oluşturur; bu, ağırlıkların yanında ihmal edilebilir bir değerdir. Modelin tam 128k kapasitesinde ise 16 GiB maliyet oluşur ki bu, ağırlıkların üç katından fazladır ve toplamda 20.6 GiB civarına ulaşır. Dolayısıyla 4 GB RAM'e sahip bir VPS, bu modeli hiçbir işlevsel bağlam boyutunda yükleyemez. 8 GB RAM'li bir VPS, 8k bağlam boyutunda rahat çalışır. 16 GB RAM'li bir VPS ise sunucunun geri kalanına yer bırakarak 32k seviyesine ulaşabilir. Bu eşiklerin her biri, model ağırlıklarıyla birlikte yukarı doğru kayar. Eğer daha büyük bir modeli bu 8B modeliyle kıyaslıyorsanız, Qwen 27B modelinin sadece CPU kullanan bir VPS üzerinde çalıştırılması için yapılan hesaplamalar, 8 ile 64 GB RAM arasında ağırlıkların bağlam için ne kadar az yer bıraktığını göstermektedir.
KV önbelleği sığmadığında ne olur
Sadece CPU kullanılan bir VPS üzerinde süreç basitçe büyür. Model yüklenirken ve uzun bir istek çalışırken süreci izleyin.
free -m
ps -eo rss,comm --sort=-rss | head -n 5RSS (resident set size) değeri kilobayt cinsinden yazdırılır. Eğer free -m içindeki swap kullanımı artmaya başlarsa, bağlam (context) boyutunu düşürün. Swap üzerinde tutulan bir KV önbelleği, her yeni token tüm önbelleği okuduğu için üretim sürecinin token başına saniyelerce duraksamasına neden olur.
Eğer sunucunun belleği tamamen tükenirse, çekirdek en büyük süreci seçer ve sonlandırır.
sudo dmesg | grep -i "killed process"Out of memory: Killed process 1234 (ollama) ifadesini içeren bir satır, talep ettiğiniz bağlamın sığmadığı anlamına gelir. Ollama genellikle bu noktaya gelmeden reddeder ve istek, talep edilen bellek miktarı ile boş bellek miktarını belirten bir mesajla başarısız olur.
GPU bulunan bir sunucuda hata daha sessiz gerçekleşir. Katmanlar sistem RAM'ine taşar, ollama ps CPU ve GPU dağılımını gösterir ve iş hacmi (throughput) keskin bir şekilde düşer. Düşüşün ne kadar keskin olacağı donanımınıza bağlıdır; bu nedenle başka bir makineye ait verilere güvenmek yerine kendi sunucunuzda saniye başına düşen token sayısını ölçün ve her bağlam ayarı için bunu tekrarlayın.
Prefill süresi, istemden daha hızlı artar
Prefill, ilk çıktı token'ı görünmeden önce girdiğiniz üzerinde yapılan işlemdir. Her istem token'ı, kendisinden önceki tüm token'lara odaklandığından, toplam iş yükü girdi uzunluğunun karesiyle orantılı olarak artar. İstem uzunluğunu iki katına çıkarmak, ilk token için bekleme süresini iki kattan fazla artırır.
Yanıt ölçümü içerdiğinden, buna güvenmek zorunda kalmazsınız.
jq -n --arg p "$LONG" '{model:"llama3.1:8b", prompt:$p, stream:false, options:{num_ctx:16384}}' |
curl -s http://localhost:11434/api/generate -d @- |
jq '{tokens: .prompt_eval_count, prefill_seconds: (.prompt_eval_duration/1000000000)}'Bunu önce kısa bir istemle, ardından uzun bir istemle çalıştırın. Her iki durumda da token sayısını saniyeye bölün. Yalnızca CPU kullanan bir VPS'de prefill işlemi genellikle uzun bağlamlı bir isteğin en yavaş kısmıdır. Kısa bir istemden elde edilen saniye başına token değeri, uzun istemin performansını öngörmez. Önündeki herhangi bir zaman aşımını aşan bir prefill işlemi, uzun bir istemin yanıt yerine genellikle bağlam süresi aşıldı hatası döndürmesine neden olur. Bu nedenle bağlamı kısaltmadan önce hangi katmanın işlemi sonlandırdığını belirleyin.
Eşzamanlılık, bu durumun en çok hissedildiği alandır. Hizmet verilen her isteğin kendi önbelleğine ihtiyacı vardır; bu nedenle yukarıdaki grafikteki bellek sunucu başına değil, istek başınadır ve uzun bir istek, kısa istekler arkasında kuyrukta beklerken sunucuyu meşgul edebilir. OLLAMA_NUM_PARALLEL değerini bilinçli olarak ayarlayın ve her iki sayıyı birlikte artırmadan önce kendi kendine barındırılan bir LLM'in kaç eşzamanlı kullanıcıya hizmet verebileceği konusunu okuyun.
Daha küçük bir önbellek ile bağlamı geri kazanma
Formüldeki bytes_per_value, kontrol edebileceğiniz bir ayardır. Ollama'nın SSS bölümü OLLAMA_KV_CACHE_TYPE'yı belgeler; burada f16 2 baytlık varsayılan değerdir, buna ek olarak q8_0 1 bayt ve q4_0 bunun altındaki değerlerdir. q8_0 değerine geçmek önbelleği yarıya indirir, böylece 32k satırı 4 GiB yerine 2 GiB maliyet oluşturur. Ağırlıkların kuantize edilmesi, aynı bütçenin diğer tarafında bellek açar ve bir VPS'e gerçekten sığan GLM etiketi, eğer tercih ettiğiniz takas buysa, kuantizasyon üzerinden kuantizasyon ile işlenir. Aynı SSS, bazı yapıların kuantize edilmiş bir önbelleğin etkili olması için ihtiyaç duyduğu OLLAMA_FLASH_ATTENTION=1 değerini de belgeler.
[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"Varsaymak yerine doğrulayın: servisi yeniden başlatın, modeli daha öncekiyle aynı num_ctx değerinde yükleyin ve RSS değerini karşılaştırın. Destek, modele ve arka uca bağlıdır; bu nedenle hiçbir şeyi değiştirmeyen bir ayar, kombinasyonunuzun desteklenmediği anlamına gelir. Belgeler bu seçenekleri kaliteli bir sonuç vaat etmeden listeler, bu yüzden onlara güvenmeden önce q4_0 değerini kendi istemlerinizle test edin. Eğer buraya gelmenizin nedeni bu ayarlar ise, Ollama ve llama.cpp bunları farklı şekilde sunar.
num_ctx değerini belirleme yöntemi
- Modelin maksimum bağlam (context) kapasitesini, katman sayısını ve anahtar/değer (key/value) başlık sayısını
/api/showüzerinden okuyun. - Token başına düşen bayt miktarını formülle hesaplayın ve hedeflediğiniz bağlam boyutuyla çarpın.
- Ağırlık boyutunu ekleyin, boş RAM miktarıyla karşılaştırın ve sistemin geri kalanı için en az 1 GiB boş alan bırakın.
- Değeri ayarlayın, modeli yükleyin ve
ollama psileprompt_eval_countkullanarak uygulanan ayarı doğrulayın. - Gerçek iş yükünüzü çalıştırırken
free -müzerinden izleme yapın; eğer swap kullanımı başlarsa bağlam boyutunu yarıya indirin.
Çoğu iş, insanların atadığından daha az bağlama ihtiyaç duyar. Uzun bir raporu özetlemek 16k içinde rahatlıkla sığar. Beş belge parçasını yapıştıran bir getirme (retrieval) arayüzü nadiren 8k değerini aşar. Tüm dosyaları okuyan bir kodlama ajanı, gerçekten 64k veya daha fazlasına ihtiyaç duyan durumdur; bu aynı zamanda makineyi bağlama göre boyutlandırmanız gereken durumdur. Sunucu henüz yeniyse, çalışan bir Ollama kurulumu ile başlayın ve modeller sorunsuz yüklendikten sonra bağlam ayarlarını optimize edin.
FAQ
Ollama'da varsayılan bağlam uzunluğu (context length) nedir?
Bu durum derlemeye ve donanıma bağlıdır, bu nedenle varsayımda bulunmak yerine kontrol edilmelidir. Ollama'nın SSS sayfası 4096 token değerini belirtirken, Modelfile referansı num_ctx varsayılanı olarak 2048 değerini verir; bağlam uzunluğu sayfası ise mevcut VRAM miktarına göre belirlenen bir varsayılanı işaret eder: 24 GiB altı için 4k, 24 ile 48 GiB arası için 32k ve üzeri için 256k. Yalnızca CPU kullanan bir VPS, bu aralığın alt sınırında kalır. ollama ps, ilgili sütunu içeren derlemelerde uygulanan bağlamı yazdırır; prompt_eval_count ise her derlemede API yanıtı içerisinde bunu doğrular.
Ollama neden uzun istemimin (prompt) başını görmezden geliyor?
İstem, bağlam penceresinden daha uzun olduğu için sunucu, model görmeden önce onu kesmiştir ve herhangi bir hata dönmemiştir. Aynı istemi daha büyük bir num_ctx değeriyle tekrar gönderin ve yanıttaki prompt_eval_count değerinin arttığını gözlemleyin. Eğer bu sayı değişmiyorsa, sizinle sunucu arasındaki bir katman num_ctx değerini kendi kendine ayarlıyordur; bu durum sohbet arayüzlerinde ve aracı (agent) çerçevelerinde sıkça görülür.
Daha büyük bir num_ctx ne kadar ek RAM gerektirir?
Bağlam uzunluğunu token başına önbellek maliyeti olan 2 * layers * kv_heads * head_dim * bytes_per_value ile çarpın. Llama 3.1 8B f16 modeli için bu değer token başına 128 KiB'dir; dolayısıyla 32k token, ağırlıklara ek olarak 4 GiB, tam 128k ise 16 GiB maliyet getirir. Önbellek model yüklendiğinde ayrıldığı için, büyük bir num_ctx değeri, istemleriniz kısa kalsa bile bu bellek miktarını tüketir.
Daha büyük bir bağlam penceresi Ollama'yı yavaşlatır mı?
Evet, iki şekilde yavaşlatır. Prefill (ön doldurma) işlemi, istem uzunluğunun karesiyle orantılı olarak artar; bu nedenle uzun bir girdi, ilk token'ın gelmesini uzunluğunun ima ettiğinden daha fazla geciktirir. Daha büyük önbellek ayrıca bellek için rekabet eder: GPU'lu bir sistemde katmanları sistem RAM'ine iter, CPU'lu bir sistemde ise makineyi swap kullanımına zorlar. Hiç doldurmadığınız büyük bir num_ctx değeri, prefill süresini etkilemese bile bellek maliyetini oluşturmaya devam eder.
Bir model için num_ctx değerini kalıcı olarak ayarlayabilir miyim?
Evet. FROM llama3.1:8b ve PARAMETER num_ctx 16384 içeren bir Modelfile oluşturun ve ardından ollama create llama3.1-16k -f ./Modelfile komutunu çalıştırın. llama3.1-16k isteyen her istemci, herhangi bir seçenek göndermesine gerek kalmadan bu bağlam değerini alır. Kendi num_ctx değerini taşıyan bir istek yine de öncelikli olacağından, bu işlem bir tavan değil, varsayılan bir değer belirler.