Ollama num_ctx: Atur Batas Konteks Prompt
Prompt panjang terpotong karena default Ollama bisa hanya 2048 token. Pelajari cara mengatur num_ctx per permintaan atau server, serta menghitung kebutuhan RAM KV cache.
Fungsi num_ctx dan alasan prompt panjang Anda terpotong
Panjang konteks Ollama adalah jumlah token yang dapat disimpan model yang dimuat di memori pada satu waktu, dan num_ctx adalah opsi yang mengaturnya. Ollama memilih nilai default yang jauh lebih kecil daripada maksimum yang dinyatakan model. Akibatnya, prompt yang lebih panjang terpotong sebelum pernah dibaca oleh model. Tidak ada informasi dalam respons yang memberi tahu Anda bahwa hal itu terjadi.
Llama 3.1 8B tercantum dengan jendela konteks 128k pada pustaka model Ollama. Server dengan konfigurasi bawaan tidak akan memberi Anda kapasitas tersebut. Dokumentasi Ollama sendiri mencantumkan nilai default yang berbeda pada halaman yang berbeda: FAQ menyebut 4096 token, referensi Modelfile menyebut num_ctx secara default bernilai 2048, dan 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 nilai tersebut. Masing-masing nilai pernah benar 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 tanda karena model tetap memberikan jawaban dan jawabannya tetap terlihat baik. Jawaban tersebut ditulis berdasarkan bagian akhir input Anda. Ringkasan yang tidak mencakup bagian pertama dokumen terlihat seperti hasil model yang lemah. Biasanya, penyebabnya adalah jendela konteks yang 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 tersebut berisi sekitar 18,000 kata, jauh lebih banyak daripada 4096 token. prompt_eval_count menghasilkan nilai mendekati 4096, bukan jumlah token sebenarnya, karena server membuang bagian sisanya. Jalankan kembali dengan "num_ctx":16384 dan jumlahnya meningkat. Jika build Anda menghasilkan error, bukan memotong prompt, hasil tersebut menunjukkan temuan yang sama dengan sinyal yang lebih jelas.
ollama psKolom CONTEXT, pada build yang menampilkannya, berisi panjang konteks yang sedang digunakan model yang dimuat. Kolom PROCESSOR di sebelahnya menunjukkan posisi model. 100% CPU merupakan nilai 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 berisi n_ctx. Teks persisnya dapat berubah antar-rilis, jadi anggap baris yang tidak ditemukan sebagai perubahan nama, bukan sebagai bukti apa pun.
Empat tempat untuk mengatur num_ctx
Dalam request. Kirim "options": {"num_ctx": 16384} ke /api/generate atau /api/chat. Pengaturan ini mengesampingkan semua pengaturan lain dan hanya berlaku untuk satu pemanggilan tersebut. Jika nilainya berbeda dari nilai yang digunakan model yang sedang dimuat, server akan memuat ulang model terlebih dahulu. Hal ini dapat dilihat pada load_duration dalam respons: waktunya meningkat dari hampir nol menjadi beberapa detik. Waktu tunggu yang sama juga muncul ketika model terlalu lama tidak digunakan hingga dibongkar dari memori. Jadi, setelah menentukan ukuran konteks, sebaiknya pertahankan model tetap berada di memori dengan keep_alive.
Dalam sesi interaktif. Di dalam ollama run, ketik /set parameter num_ctx 16384. Pengaturan ini berlaku selama sesi tersebut.
Dalam Modelfile. Cara ini menyimpan nilai tersebut ke dalam model bernama, sehingga setiap client mendapatkannya tanpa perubahan di sisi client.
FROM llama3.1:8b
PARAMETER num_ctx 16384ollama create llama3.1-16k -f ./Modelfile
ollama run llama3.1-16kDi server. OLLAMA_CONTEXT_LENGTH menetapkan nilai default untuk setiap request yang tidak membawa 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 ini paling penting saat Anda men-debug client milik orang lain. Request yang membawa num_ctx mengesampingkan default server. Jadi, front end chat atau agent yang mengirim nilai kecilnya sendiri dapat secara diam-diam membatalkan perubahan systemd Anda. Saat Anda menghubungkan coding agent ke server Ollama Anda, 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 tersebut disebut KV cache (key/value cache). KV cache dialokasikan untuk seluruh num_ctx saat model dimuat, bukan saat percakapan bertambah panjang. Karena itu, context yang besar tetap menggunakan memori sebanyak itu meskipun prompt hanya satu baris.
Blog tutorial biaya inference 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, jadi 4096 / 32 = 128 dalam kasus ini. Beberapa model mencantumkannya langsung sebagai llama.attention.key_length. Cache default menyimpan value f16, sehingga bytes_per_value adalah 2. Dengan demikian, 2 32 8 128 2 menghasilkan 131,072 byte. Artinya, cache menggunakan 128 KiB untuk setiap token context. Kalikan dengan panjang context, dan biayanya menjadi jelas.
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 baris tersebut merupakan hasil perhitungan dari formula di atas, bukan hasil pengukuran. Kolom total menambahkan download 4.9 GB yang dicantumkan oleh library Ollama untuk llama3.1:8b pada August 2026, yaitu 4.6 GiB. Kolom ini tidak mencakup buffer komputasi dan proses server itu sendiri. Anggap angka tersebut sebagai batas minimum.
Yang penting adalah polanya. Pada 8k, cache menggunakan 1 GiB, jumlah yang kecil dibandingkan dengan bobot model. Pada 128k penuh milik model, cache menggunakan 16 GiB, lebih dari tiga kali ukuran bobot, dengan total sekitar 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. Jadi, jika Anda mempertimbangkan model yang lebih besar dibandingkan model 8B ini, perhitungan yang sama pada tag Qwen 27B pada VPS khusus CPU menunjukkan betapa sedikit memori yang tersisa untuk context pada VPS berukuran 8 hingga 64 GB.
Apa yang terjadi jika cache KV tidak muat
Pada VPS yang hanya menggunakan CPU, proses akan terus menggunakan memori. Pantau proses tersebut saat model dimuat dan saat permintaan panjang dijalankan.
free -m
ps -eo rss,comm --sort=-rss | head -n 5RSS (resident set size) ditampilkan dalam kilobyte. Jika swap yang digunakan pada free -m mulai meningkat, kurangi ukuran context. Cache KV yang berada di swap membuat proses generasi berhenti selama beberapa detik untuk setiap token karena setiap token baru membaca seluruh cache.
Jika memori 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 tahap tersebut. Permintaan kemudian gagal dengan pesan yang menyebutkan jumlah memori yang dibutuhkan dibandingkan dengan memori yang tersedia.
Pada server dengan GPU, kegagalan ini lebih sulit terlihat. Sebagian layer dialihkan ke RAM sistem, ollama ps menampilkan pembagian beban antara CPU dan GPU, dan throughput turun tajam. Seberapa besar penurunannya bergantung pada hardware Anda. Karena itu, ukur token per detik pada server Anda sendiri untuk setiap pengaturan context, alih-alih mempercayai angka dari mesin orang lain.
Waktu prefill bertambah lebih cepat daripada prompt
Prefill adalah pekerjaan yang dilakukan pada input sebelum token output pertama muncul. Setiap token prompt memperhatikan semua token sebelumnya, sehingga total pekerjaan bertambah secara kuadrat terhadap panjang input. Menggandakan panjang prompt akan membuat waktu tunggu token pertama bertambah lebih dari dua kali lipat.
Respons tersebut menyertakan hasil pengukuran, sehingga Anda tidak perlu menerimanya 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 pengujian tersebut dengan prompt pendek, lalu ulangi dengan prompt panjang. Setelah itu, bagi jumlah token dengan waktu dalam detik untuk setiap pengujian. Pada VPS yang hanya menggunakan CPU, prefill biasanya merupakan bagian paling lambat dari permintaan dengan konteks panjang. Angka token per detik yang diukur menggunakan prompt pendek tidak dapat memprediksi kinerja tersebut. Jika prefill berlangsung lebih lama daripada timeout pada lapisan di depannya, permintaan dengan prompt panjang biasanya berakhir dengan batas waktu konteks terlampaui, bukan menghasilkan jawaban. Karena itu, cari tahu lapisan mana yang menghentikan permintaan sebelum mengurangi ukuran konteks.
Masalah ini paling terasa saat concurrency digunakan. Setiap request yang dilayani memerlukan cache sendiri. Karena itu, penggunaan memori pada bagan di atas berlaku per request, bukan per server. Satu request panjang dapat menahan resource server sehingga request pendek harus mengantre di belakangnya. Atur OLLAMA_NUM_PARALLEL secara sadar, lalu baca berapa banyak pengguna serentak yang dapat dilayani oleh LLM yang di-host sendiri sebelum menaikkan kedua angka tersebut secara bersamaan.
Dapatkan kembali konteks dengan cache yang lebih kecil
bytes_per_value dalam formula 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 mengurangi ukuran cache menjadi setengahnya, sehingga baris 32k memerlukan 2 GiB, bukan 4 GiB. Kuantisasi bobot membebaskan memori dari sisi lain dalam anggaran yang sama, dan tag GLM yang benar-benar muat di VPS dibahas melalui setiap tingkat kuantisasi jika itu adalah kompromi yang lebih Anda pilih. FAQ yang sama juga mendokumentasikan OLLAMA_FLASH_ATTENTION=1, yang diperlukan oleh beberapa build agar cache terkuantisasi diterapkan.
[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"Pastikan hasilnya, jangan 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, jadi uji q4_0 dengan prompt Anda sendiri sebelum mengandalkannya. Jika pengaturan inilah alasan Anda membaca bagian ini, Ollama dan llama.cpp mengeksposnya dengan cara yang berbeda.
Cara memilih num_ctx
- Baca konteks maksimum model, jumlah layer, dan jumlah key/value head dari
/api/show. - Hitung byte per token menggunakan rumus, lalu kalikan dengan konteks yang Anda inginkan.
- Tambahkan ukuran bobot, bandingkan dengan RAM yang tersedia, dan sisakan setidaknya 1 GiB untuk kebutuhan lain di 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. Meringkas laporan panjang dapat dilakukan dengan 16k. Front end retrieval yang menyertakan lima potongan dokumen biasanya jarang melebihi 8k. Coding agent yang membaca seluruh file adalah kasus yang benar-benar memerlukan 64k atau lebih. Untuk 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 dan jangan berasumsi. FAQ Ollama mendokumentasikan 4096 token, referensi Modelfile mendokumentasikan default num_ctx sebesar 2048, sedangkan halaman panjang konteks mendokumentasikan 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 rendah. ollama ps menampilkan konteks yang diterapkan pada build yang memiliki kolom tersebut, sedangkan prompt_eval_count dalam respons API membuktikannya pada semua build.
Mengapa Ollama mengabaikan awal prompt panjang saya?
Karena prompt lebih panjang daripada jendela konteks, sehingga server memotongnya sebelum model menerimanya, dan tidak ada error yang dikembalikan. Kirim prompt yang sama lagi dengan num_ctx yang lebih besar, lalu pantau peningkatan prompt_eval_count dalam respons. Jika angka tersebut tidak berubah, sesuatu di antara Anda dan server sedang menetapkan num_ctx sendiri. Hal ini umum terjadi pada antarmuka 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 128 KiB per token. Jadi, 32k token memerlukan 4 GiB dan 128k penuh memerlukan 16 GiB di luar bobot model. Cache dialokasikan saat model dimuat, sehingga num_ctx yang besar tetap 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 berdasarkan kuadrat panjang prompt, sehingga input yang panjang menunda token pertama lebih lama daripada yang diperkirakan dari panjangnya. Cache yang lebih besar juga bersaing untuk mendapatkan memori: pada mesin GPU, cache mendorong sebagian layer ke RAM sistem, sedangkan pada mesin CPU, cache mendorong mesin mendekati penggunaan swap. num_ctx yang besar dan tidak pernah terisi tetap menggunakan memori, meskipun 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 akan mendapatkan konteks tersebut tanpa mengirim opsi apa pun. Request yang membawa num_ctx sendiri tetap memiliki prioritas, sehingga pengaturan ini menetapkan default, bukan batas maksimum.