Ollama num_ctx: Atasi Prompt Panjang Terpotong
Prompt panjang Ollama dapat terpotong karena default context window kecil. Atur num_ctx per request atau server, lalu hitung kebutuhan RAM KV cache sebelum menaikkannya.
Fungsi num_ctx dan alasan prompt panjang Anda terpotong
Panjang konteks Ollama adalah jumlah token yang dapat ditampung model yang dimuat di memori pada satu waktu, dan num_ctx adalah opsi yang mengaturnya. Ollama menetapkan nilai default yang jauh di bawah maksimum yang dinyatakan model. Akibatnya, prompt yang lebih panjang terpotong sebelum model membacanya. Tidak ada informasi dalam respons yang memberi tahu bahwa hal tersebut terjadi.
Llama 3.1 8B tercantum memiliki jendela konteks 128k pada pustaka model Ollama. Server dengan konfigurasi bawaan tidak akan memberikan kapasitas tersebut. Dokumentasi Ollama sendiri mencantumkan nilai default yang berbeda pada halaman yang berbeda: FAQ menyebut 4096 token, referensi Modelfile menyebut num_ctx dengan nilai default 2048, sedangkan halaman panjang konteks menyebut bahwa nilai default dipilih berdasarkan VRAM (video RAM) yang tersedia: 4k di bawah 24 GiB, 32k dari 24 hingga 48 GiB, dan 256k di atas kapasitas tersebut. Masing-masing nilai pernah berlaku pada build tertentu. Perbedaan ini memberikan pelajaran penting: baca nilai dari server Anda sendiri yang sedang berjalan, bukan dari halaman mana pun, termasuk halaman ini.
Pemotongan berlangsung tanpa indikasi karena model tetap memberikan jawaban dan jawabannya tetap terlihat baik. Jawaban tersebut ditulis berdasarkan bagian akhir input Anda. Ringkasan yang tidak memuat separuh awal dokumen tampak seperti hasil model yang lemah. Biasanya penyebabnya adalah jendela konteks yang terlalu kecil.
Periksa panjang konteks Ollama yang benar-benar diterapkan server
Pemeriksaan yang berfungsi pada build apa pun adalah prompt_eval_count, yaitu jumlah token prompt yang dilaporkan server telah diproses. Kirim prompt yang lebih panjang daripada kapasitas konteks. Jumlah tersebut akan berhenti pada batasnya.
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}'Prompt itu berisi sekitar 18,000 kata, sehingga jauh melebihi 4096 token. prompt_eval_count menghasilkan nilai mendekati 4096, bukan jumlah token sebenarnya, karena server membuang sisanya. Jalankan kembali dengan "num_ctx":16384 dan jumlahnya akan meningkat. Jika build Anda menghasilkan error alih-alih memotong prompt, hasilnya tetap sama, tetapi sinyalnya lebih jelas.
ollama psKolom CONTEXT, pada build yang menampilkannya, berisi panjang konteks yang sedang digunakan oleh model yang dimuat. Kolom PROCESSOR di sebelahnya menunjukkan lokasi model dijalankan. 100% CPU normal pada VPS tanpa GPU. Pembagian seperti 30%/70% CPU/GPU pada server dengan GPU berarti bobot model dan cache tidak lagi muat di VRAM. Nilai num_ctx yang lebih tinggi biasanya menjadi penyebabnya.
journalctl -u ollama --no-pager | grep -i n_ctx | tail -n 5Inference runner mencetak ukuran konteks pada baris yang memuat n_ctx. Teks persisnya dapat berubah antar-release. Karena itu, anggap baris yang tidak ditemukan sebagai perubahan nama, bukan sebagai bukti apa pun.
Empat tempat untuk menetapkan num_ctx
Dalam request. Kirim "options": {"num_ctx": 16384} ke /api/generate atau /api/chat. Pengaturan ini mengalahkan semua pengaturan lain dan hanya berlaku untuk pemanggilan tersebut. Jika nilainya berbeda dari nilai yang digunakan model yang dimuat, server memuat ulang model terlebih dahulu. Anda dapat melihatnya pada load_duration di respons: nilainya melonjak dari hampir nol menjadi beberapa detik penuh.
Dalam sesi interaktif. Di dalam ollama run, ketik /set parameter num_ctx 16384. Pengaturan ini berlaku selama sesi tersebut.
Dalam Modelfile. Cara ini menetapkan nilai ke dalam model bernama, sehingga setiap client mendapatkannya tanpa perubahan pada sisi client.
FROM llama3.1:8b
PARAMETER num_ctx 16384ollama create llama3.1-16k -f ./Modelfile
ollama run llama3.1-16kPada server. OLLAMA_CONTEXT_LENGTH menetapkan nilai default untuk setiap request yang tidak menyertakan num_ctx sendiri. Pada systemd, tambahkan drop-in, bukan mengedit unit file.
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_CONTEXT_LENGTH=16384"sudo systemctl daemon-reload
sudo systemctl restart ollama
ollama psUrutan prioritas paling penting saat Anda men-debug client milik orang lain. Request yang menyertakan num_ctx mengalahkan nilai default server. Karena itu, front end chat atau agent yang mengirim nilai kecilnya sendiri dapat diam-diam membatalkan perubahan systemd Anda. Saat Anda menghubungkan agent coding ke server Ollama, periksa nilai yang dikirim client sebelum menyalahkan server.
Mengapa Anda tidak dapat langsung menetapkan num_ctx ke maksimum model
Attention membuat setiap token melihat semua token sebelumnya. Key dan value yang dihitung untuk token sebelumnya disimpan agar tidak dihitung ulang untuk setiap token baru. Penyimpanan ini disebut KV cache (key/value cache). KV cache dialokasikan untuk seluruh num_ctx saat model dimuat, bukan saat percakapan bertambah. Karena itu, context besar tetap menggunakan memori meskipun prompt hanya terdiri dari satu baris.
Tutorial biaya inferensi DigitalOcean menyatakan perhitungannya dalam satu baris:
kv_bytes_per_token = 2 * layers * kv_heads * head_dim * bytes_per_valueAngka 2 menghitung key dan value secara terpisah. Ambil angka lainnya dari model Anda sendiri.
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 melaporkan 32 layer dan 8 key/value head. Dimensi head adalah embed dibagi heads, sehingga hasilnya 4096 / 32 = 128 dalam contoh ini. Beberapa model mencantumkannya langsung sebagai llama.attention.key_length. Cache default menyimpan nilai f16, sehingga bytes_per_value bernilai 2. Perhitungan 2 32 8 128 2 menghasilkan 131,072 byte. Itu berarti cache sebesar 128 KiB untuk setiap token context. Kalikan dengan panjang context, dan biayanya menjadi nyata.
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
}
]Baris 6 tersebut merupakan hasil perhitungan dari formula di atas, bukan hasil pengukuran. Kolom total menambahkan unduhan 4.9 GB yang dicantumkan oleh library Ollama untuk llama3.1:8b pada August 2026. Ukurannya adalah 4.6 GiB. Kolom tersebut tidak mencakup buffer komputasi dan proses server itu sendiri. Anggap angka ini sebagai batas minimum.
Bentuk perhitungannya adalah hal yang penting. Pada 8k, cache memerlukan 1 GiB, yang kecil dibandingkan bobot model. Pada 128k penuh, cache memerlukan 16 GiB, lebih dari tiga kali ukuran bobot, sehingga totalnya mendekati 20.6 GiB. Jadi, VPS 4 GB tidak dapat memuat model ini pada context yang berguna. VPS 8 GB cukup untuk 8k. VPS 16 GB dapat mencapai 32k dan masih menyisakan ruang untuk komponen lain pada server. Setiap batas tersebut meningkat seiring ukuran bobot. Jika Anda membandingkan model yang lebih besar dengan model 8B ini, perhitungan yang sama untuk tag Qwen 27B pada VPS yang hanya menggunakan CPU menunjukkan betapa sedikit ruang yang tersisa untuk context pada rentang 8 hingga 64 GB.
Apa yang terjadi ketika cache KV tidak muat
Pada VPS yang hanya menggunakan CPU, penggunaan memori proses akan terus bertambah. Pantau proses tersebut saat model dimuat dan saat permintaan panjang berjalan.
free -m
ps -eo rss,comm --sort=-rss | head -n 5RSS (resident set size) ditampilkan dalam kilobyte. Jika penggunaan swap pada free -m mulai meningkat, kurangi ukuran context. Cache KV yang berada di swap membuat proses generation berhenti selama beberapa detik per token karena setiap token baru membaca seluruh cache.
Jika memori pada server habis sepenuhnya, kernel memilih proses terbesar lalu menghentikannya.
sudo dmesg | grep -i "killed process"Baris yang berisi Out of memory: Killed process 1234 (ollama) berarti context yang diminta tidak muat. Ollama sering menolak permintaan sebelum mencapai kondisi tersebut. Permintaan kemudian gagal dengan pesan yang menyebutkan jumlah memori yang dibutuhkan dan jumlah memori yang tersedia.
Pada server dengan GPU, kegagalannya lebih sulit terlihat. Sebagian layer dipindahkan ke RAM sistem, ollama ps menampilkan pembagian beban antara CPU dan GPU, dan throughput turun tajam. Besarnya penurunan bergantung pada hardware yang digunakan. Karena itu, ukur token per detik pada server Anda sendiri untuk setiap pengaturan context, bukan mengandalkan angka dari mesin orang lain.
Waktu prefill meningkat lebih cepat daripada panjang prompt
Prefill adalah pekerjaan yang dilakukan pada input Anda sebelum token output pertama muncul. Setiap token dalam prompt memperhatikan semua token sebelumnya, sehingga total pekerjaan meningkat secara kuadrat terhadap panjang input. Jika panjang prompt digandakan, waktu tunggu hingga token pertama muncul meningkat lebih dari dua kali lipat.
Respons tersebut menyertakan hasil pengukurannya, sehingga Anda tidak perlu menerima pernyataan itu begitu saja.
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)}'Jalankan perintah tersebut dengan prompt pendek, lalu jalankan lagi dengan prompt panjang. Setelah itu, bagi jumlah token dengan jumlah detik untuk setiap kasus. Pada VPS yang hanya menggunakan CPU, prefill biasanya merupakan bagian paling lambat dari permintaan dengan konteks panjang. Angka token per detik yang diukur dari prompt pendek tidak dapat digunakan untuk memprediksinya.
Dampaknya paling besar saat terjadi konkurensi. Setiap permintaan yang sedang dilayani memerlukan cache sendiri. Karena itu, memori pada bagan di atas berlaku per permintaan, bukan per server. Satu permintaan panjang dapat menahan server sehingga permintaan pendek harus menunggu di belakangnya. Tetapkan OLLAMA_NUM_PARALLEL secara sengaja, lalu baca berapa banyak pengguna konkuren yang dapat dilayani satu LLM yang di-host sendiri sebelum menaikkan kedua angka tersebut secara bersamaan.
Dapatkan kembali kapasitas untuk konteks dengan cache yang lebih kecil
bytes_per_value dalam formula tersebut adalah pengaturan yang dapat Anda kendalikan. FAQ Ollama mendokumentasikan OLLAMA_KV_CACHE_TYPE, dengan f16 sebagai nilai default sebesar 2 byte, serta q8_0 sebesar 1 byte dan q4_0 di bawahnya. Beralih ke q8_0 akan membagi dua ukuran cache, sehingga baris 32k memerlukan 2 GiB, bukan 4 GiB. FAQ yang sama juga mendokumentasikan OLLAMA_FLASH_ATTENTION=1, yang diperlukan oleh beberapa build agar cache terkuantisasi dapat diterapkan.
[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"Pastikan hasilnya, bukan hanya berasumsi: restart service, muat model pada num_ctx yang sama seperti sebelumnya, lalu bandingkan RSS. Dukungan bergantung pada model dan backend, sehingga pengaturan yang tidak mengubah apa pun berarti kombinasi Anda tidak didukung. Dokumentasi mencantumkan opsi ini tanpa menjamin hasil kualitas tertentu. Karena itu, uji q4_0 dengan prompt Anda sendiri sebelum mengandalkannya. Jika pengaturan ini adalah alasan Anda membaca bagian ini, Ollama dan llama.cpp menyediakan pengaturan tersebut dengan cara yang berbeda.
Resep untuk menentukan num_ctx
- Baca konteks maksimum model, jumlah layer, serta jumlah head key/value dari
/api/show. - Hitung byte per token menggunakan rumus, lalu kalikan dengan konteks yang Anda inginkan.
- Tambahkan ukuran weight, bandingkan dengan RAM yang tersedia, dan sisakan setidaknya 1 GiB untuk komponen lain pada server.
- Tetapkan nilainya, muat model, lalu konfirmasikan nilai yang diterapkan dengan
ollama psdanprompt_eval_count. - Jalankan workload sebenarnya sambil memantau
free -m, lalu kurangi konteks menjadi setengah jika swap mulai digunakan.
Sebagian besar pekerjaan memerlukan konteks yang lebih kecil daripada yang biasanya diberikan. Perangkuman laporan panjang dapat dilakukan dengan 16k. Front end retrieval yang menempelkan lima potongan dokumen biasanya jarang melampaui 8k. Coding agent yang membaca seluruh file adalah kasus yang benar-benar memerlukan 64k atau lebih. Pada kasus ini, ukuran mesin sebaiknya ditentukan berdasarkan konteks, bukan sebaliknya. Jika server masih baru, mulai dari instalasi Ollama yang berfungsi pada VPS, lalu sesuaikan konteks setelah model dapat dimuat tanpa masalah.
FAQ
Berapa panjang konteks default di Ollama?
Nilainya bergantung pada build dan perangkat keras, jadi periksa nilainya, jangan berasumsi. FAQ Ollama mendokumentasikan 4096 token, referensi Modelfile mendokumentasikan nilai default num_ctx sebesar 2048, dan halaman panjang konteks mendokumentasikan nilai default yang dipilih berdasarkan VRAM yang tersedia: 4k di bawah 24 GiB, 32k dari 24 hingga 48 GiB, dan 256k di atasnya. VPS yang hanya menggunakan CPU berada pada kisaran terendah. ollama ps menampilkan konteks yang diterapkan pada build yang memiliki kolom tersebut, sedangkan prompt_eval_count dalam respons API membuktikannya pada setiap build.
Mengapa Ollama mengabaikan awal prompt panjang saya?
Karena prompt tersebut lebih panjang daripada jendela konteks, sehingga server memotongnya sebelum model membacanya dan tidak mengembalikan error. Kirim prompt yang sama lagi dengan num_ctx yang lebih besar, lalu pantau pertumbuhan prompt_eval_count dalam respons. Jika angka tersebut tidak berubah, ada komponen di antara Anda dan server yang menetapkan num_ctx sendiri. Hal ini umum terjadi pada front end chat dan framework agen.
Berapa tambahan RAM yang diperlukan oleh num_ctx yang lebih besar?
Kalikan panjang konteks dengan biaya cache per token, yaitu 2 * layers * kv_heads * head_dim * bytes_per_value. Untuk Llama 3.1 8B pada f16, nilainya adalah 128 KiB per token. Jadi, 32k token memerlukan 4 GiB dan 128k penuh memerlukan 16 GiB di luar memori bobot. Cache dialokasikan saat model dimuat, sehingga num_ctx yang besar menggunakan memori tersebut meskipun prompt Anda tetap pendek.
Apakah jendela konteks yang lebih besar membuat Ollama lebih lambat?
Ya, dalam dua hal. Pekerjaan prefill bertambah mengikuti kuadrat panjang prompt, sehingga input panjang menunda token pertama lebih lama daripada yang diperkirakan berdasarkan panjangnya. Cache yang lebih besar juga bersaing untuk mendapatkan memori: pada mesin dengan GPU, cache tersebut mendorong sebagian layer ke RAM sistem, sedangkan pada mesin dengan CPU, cache tersebut mendorong mesin menggunakan swap. num_ctx yang besar tetap menggunakan memori meskipun tidak pernah terisi penuh, tetapi tidak menambah waktu prefill.
Dapatkah saya menetapkan num_ctx secara permanen untuk satu model?
Ya. Tulis Modelfile yang berisi FROM llama3.1:8b dan PARAMETER num_ctx 16384, lalu jalankan ollama create llama3.1-16k -f ./Modelfile. Setiap client yang meminta llama3.1-16k mendapatkan konteks tersebut tanpa mengirim opsi apa pun. Request yang membawa num_ctx sendiri tetap diprioritaskan, jadi pengaturan ini menetapkan nilai default, bukan batas maksimum.