Ollama-তে num_ctx সেট করে দীর্ঘ prompt ঠিক করুন
Ollama দীর্ঘ prompt নীরবে কেটে দিতে পারে। প্রতি request-এ বা server-wide num_ctx সেট করুন, তবে বাড়ানোর আগে KV cache-এর RAM চাহিদা মাপুন।
num_ctx কী করে এবং আপনার দীর্ঘ prompt কেন কেটে গেছে
Ollama context length হলো একসঙ্গে memory-তে loaded model যে সংখ্যক token ধরে রাখতে পারে। num_ctx হলো সেই মান নির্ধারণের option। Ollama এমন একটি default বেছে নেয়, যা model-এর ঘোষিত maximum-এর তুলনায় অনেক কম। তাই model input পড়ার আগেই দীর্ঘ prompt কেটে যায়। Response-এ এটি ঘটেছে কি না, তার কোনো তথ্য থাকে না।
Ollama model library-তে Llama 3.1 8B-এর context window 128k হিসেবে উল্লেখ আছে। একটি stock server আপনাকে এই সম্পূর্ণ সীমা দেবে না। Ollama-এর নিজস্ব documentation-এর বিভিন্ন page-এ ভিন্ন default দেওয়া আছে: FAQ-তে 4096 token, Modelfile reference-এ num_ctx-এর default 2048, এবং context length page-এ বলা হয়েছে যে available VRAM (video RAM) অনুযায়ী default নির্ধারিত হয়—24 GiB-এর নিচে 4k, 24 থেকে 48 GiB পর্যন্ত 32k, এবং এর বেশি হলে 256k। ভিন্ন build-এ এগুলোর প্রতিটিই সত্য ছিল। এখানকার গুরুত্বপূর্ণ শিক্ষা হলো: কোনো page-এর তথ্যের ওপর, এমনকি এই page-এর ওপরও, নির্ভর না করে নিজের running server থেকে মানটি পড়ুন।
Truncation নীরবে ঘটে, কারণ model তবুও উত্তর দেয় এবং উত্তরটি পড়তেও স্বাভাবিক লাগে। তবে উত্তরটি আপনার input-এর শেষ অংশ ব্যবহার করে তৈরি হয়। কোনো document-এর প্রথম অর্ধ বাদ পড়লে summary-টি দুর্বল model-এর output বলে মনে হতে পারে। সাধারণত এর কারণ ছোট context window।
আপনার server আসলে যে Ollama context length প্রয়োগ করেছে তা পরীক্ষা করুন
যে check যেকোনো build-এ কাজ করে সেটি হলো prompt_eval_count। এটি server যে prompt token process করেছে বলে জানায়, তার সংখ্যা। context যতটা ধারণ করতে পারে তার চেয়ে বেশি পাঠালে এই সংখ্যা limit-এ থেমে যায়।
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-এ প্রায় 18,000টি word আছে, তাই এটি 4096 token-এর চেয়ে অনেক বড়। server বাকি অংশ বাদ দেওয়ায় prompt_eval_count প্রকৃত token count-এর কাছাকাছি না হয়ে প্রায় 4096 দেখায়। "num_ctx":16384 ব্যবহার করে আবার চালালে count বেড়ে যায়। আপনার build truncate না করে error ফেরত দিলে সেটিও একই finding, তবে আরও স্পষ্টভাবে বোঝা যায়।
ollama psযেসব build এই column দেখায়, সেসব build-এ CONTEXT column-এ বর্তমানে loaded model যে context length নিয়ে চলছে তা থাকে। এর পাশের PROCESSOR column-এ model-এর অবস্থান দেখানো হয়। GPU না থাকা VPS-এ 100% CPU স্বাভাবিক। GPU server-এ 30%/70% CPU/GPU-এর মতো split দেখা গেলে weights এবং cache আর VRAM-এ একসঙ্গে fit করছে না। সাধারণত বাড়ানো num_ctx-এর কারণেই এটি ঘটে।
journalctl -u ollama --no-pager | grep -i n_ctx | tail -n 5Inference runner n_ctx থাকা একটি line-এ context size দেখায়। release ভেদে exact wording বদলে যায়। তাই line না পাওয়াকে কোনো কিছুর প্রমাণ হিসেবে না দেখে rename হিসেবে বিবেচনা করুন।
num_ctx সেট করার চারটি স্থান
অনুরোধে। "options": {"num_ctx": 16384}, /api/generate অথবা /api/chat-এ পাঠান। অন্য সব সেটিংয়ের তুলনায় এর অগ্রাধিকার বেশি এবং এটি শুধু ওই একটি call-এর ক্ষেত্রে প্রযোজ্য। লোড করা model বর্তমানে যে মান নিয়ে চলছে, তার থেকে এই মান ভিন্ন হলে server প্রথমে model reload করে। Response-এর load_duration-এ এটি দেখা যায়: সময় প্রায় শূন্য থেকে কয়েক সেকেন্ডে বেড়ে যায়। Model দীর্ঘ সময় idle থাকার কারণে unload হলেও একই অপেক্ষা দেখা যায়। তাই context size নির্ধারণ করার পর keep_alive দিয়ে model resident রাখা উপযোগী।
ইন্টার্যাক্টিভ session-এ। ollama run-এর ভিতরে /set parameter num_ctx 16384 লিখুন। এটি ওই session পর্যন্ত কার্যকর থাকে।
একটি Modelfile-এ। এতে মানটি একটি নামযুক্ত model-এর মধ্যে স্থায়ীভাবে সংরক্ষিত হয়। ফলে client-side কোনো পরিবর্তন ছাড়াই প্রতিটি client সেটি পায়।
FROM llama3.1:8b
PARAMETER num_ctx 16384ollama create llama3.1-16k -f ./Modelfile
ollama run llama3.1-16kServer-এ। OLLAMA_CONTEXT_LENGTH এমন প্রতিটি request-এর জন্য default নির্ধারণ করে, যেটিতে নিজস্ব num_ctx নেই। systemd ব্যবহার করলে unit file সম্পাদনা না করে একটি drop-in যোগ করুন।
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_CONTEXT_LENGTH=16384"sudo systemctl daemon-reload
sudo systemctl restart ollama
ollama psDebugging-এর সময় precedence বিশেষভাবে গুরুত্বপূর্ণ, বিশেষ করে অন্য কারও client পরীক্ষা করলে। num_ctx বহনকারী request server default-কে অগ্রাহ্য করে। তাই chat front end বা agent নিজে থেকে একটি ছোট মান পাঠালে আপনার systemd পরিবর্তনটি নীরবে অকার্যকর হয়ে যেতে পারে। কোনো coding agent-কে আপনার Ollama server-এ নির্দেশ করার আগে client কী পাঠাচ্ছে তা পরীক্ষা করুন; server-কে দোষ দেওয়ার আগে এটি যাচাই করা উচিত।
আপনি কেন শুধু num_ctx-কে মডেলের সর্বোচ্চ মানে সেট করতে পারবেন না
Attention প্রতিটি token-কে তার আগের প্রতিটি token দেখতে দেয়। আগের token-গুলোর জন্য গণনা করা key এবং value সংরক্ষণ করা হয়, যাতে প্রতিটি নতুন token-এর জন্য সেগুলো আবার গণনা করতে না হয়। এই সংরক্ষণস্থলকে KV cache (key/value cache) বলা হয়। মডেল লোড হওয়ার সময় পুরো num_ctx-এর জন্য এটি বরাদ্দ করা হয়, conversation বাড়ার সঙ্গে সঙ্গে নয়। তাই এক লাইনের prompt হলেও বড় context-এর জন্য নির্ধারিত memory ব্যবহৃত হয়।
DigitalOcean-এর inference cost tutorial এক লাইনে এই হিসাবটি দিয়েছে:
kv_bytes_per_token = 2 * layers * kv_heads * head_dim * bytes_per_value2 দিয়ে key এবং value আলাদাভাবে গণনা করা হয়। বাকি সংখ্যাগুলো আপনার নিজের মডেলের তথ্য থেকে নিন।
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-তে 32টি layer এবং 8টি key/value head আছে। Head dimension হলো embed-কে heads দিয়ে ভাগ করলে যা পাওয়া যায়। তাই এখানে 4096 / 32 = 128। কিছু মডেল এই মানটি সরাসরি llama.attention.key_length হিসেবে প্রকাশ করে। Default cache f16 value সংরক্ষণ করে, তাই bytes_per_value হলো 2। সুতরাং 2 32 8 128 2 = 131,072 bytes। অর্থাৎ context-এর প্রতিটি token-এর জন্য cache-এ 128 KiB memory লাগে। Context length দিয়ে গুণ করলে খরচটি স্পষ্ট হয়ে যায়।
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টি row উপরের formula থেকে করা গাণিতিক হিসাব, কোনো measurement নয়। Total column-এ Ollama library 2026 সালের August-এ llama3.1:8b-এর জন্য তালিকাভুক্ত 4.9 GB download যোগ করা হয়েছে, যা 4.6 GiB-এর সমান। এতে compute buffer এবং server process নিজে অন্তর্ভুক্ত নয়। তাই এটিকে সর্বনিম্ন হিসাব হিসেবে ধরুন।
মূল বিষয় হলো বৃদ্ধির ধরন। 8k context-এ cache-এর জন্য 1 GiB লাগে, যা weights-এর তুলনায় খুবই কম। মডেলের সম্পূর্ণ 128k context-এ cache-এর জন্য 16 GiB লাগে। এটি weights-এর তিন গুণেরও বেশি, ফলে মোট memory প্রায় 20.6 GiB হয়। তাই 4 GB VPS কোনো ব্যবহারযোগ্য context-এ এই মডেল লোড করতে পারবে না। 8 GB VPS-এ 8k context স্বচ্ছন্দে চালানো যায়। 16 GB VPS-এ বাকি সিস্টেমের জন্য memory রেখে 32k context পর্যন্ত যাওয়া যায়। Weights বাড়লে প্রতিটি সীমাও বাড়ে। তাই এই 8B মডেলের বদলে বড় মডেল নেওয়ার কথা ভাবলে, 8 থেকে 64 GB-এর মধ্যে context-এর জন্য weights কতটা memory রেখে যায় তা Qwen-এর 27B tag-কে CPU-only VPS-এ চালানোর হিসাব থেকে বোঝা যায়।
KV cache-এ স্থান না হলে কী ঘটে
CPU-only VPS-এ process-এর memory ব্যবহার বাড়তে থাকে। Model load হওয়ার সময় এবং দীর্ঘ request চলার সময় এটি monitor করুন।
free -m
ps -eo rss,comm --sort=-rss | head -n 5RSS (resident set size) kilobytes-এ দেখানো হয়। free -m-এ ব্যবহৃত swap বাড়তে শুরু করলে context কমিয়ে দিন। swap-এ থাকা KV cache generation-কে প্রতি token-এ কয়েক সেকেন্ডের জন্য থামিয়ে দিতে পারে, কারণ প্রতিটি নতুন token পুরো cache পড়ে।
সার্ভারের memory সম্পূর্ণ শেষ হয়ে গেলে kernel সবচেয়ে বড় process নির্বাচন করে সেটি বন্ধ করে দেয়।
sudo dmesg | grep -i "killed process"Out of memory: Killed process 1234 (ollama) লেখা একটি line-এর অর্থ হলো, আপনার নির্ধারিত context memory-তে স্থান পায়নি। Ollama প্রায়ই এই পর্যায়ে পৌঁছানোর আগেই request প্রত্যাখ্যান করে। তখন request ব্যর্থ হয় এবং message-এ প্রয়োজনীয় memory ও তখন available থাকা memory-এর পরিমাণ উল্লেখ থাকে।
GPU server-এ ব্যর্থতাটি কম স্পষ্ট হয়। কিছু layer system RAM-এ চলে যায়, ollama ps CPU ও GPU-এর বিভাজন দেখায়, এবং throughput দ্রুত কমে যায়। কমার মাত্রা আপনার hardware-এর ওপর নির্ভর করে। তাই অন্য কারও machine-এর figure বিশ্বাস না করে প্রতিটি context setting-এ নিজের server-এ প্রতি সেকেন্ডে কত token তৈরি হচ্ছে তা মাপুন।
প্রম্পটের তুলনায় Prefill সময় দ্রুত বাড়ে
প্রথম output token প্রদর্শিত হওয়ার আগে আপনার input-এর ওপর যে কাজ করা হয়, সেটিই Prefill। প্রতিটি prompt token তার আগের প্রতিটি token-এর দিকে attention দেয়। তাই মোট কাজ input-এর দৈর্ঘ্যের বর্গের সঙ্গে বাড়ে। Prompt দ্বিগুণ করলে প্রথম token পাওয়ার অপেক্ষা দ্বিগুণের চেয়েও বেশি হয়।
Response-এই পরিমাপ দেওয়া থাকে। তাই এটি যাচাই না করে বিশ্বাস করার প্রয়োজন নেই।
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)}'সংক্ষিপ্ত prompt দিয়ে এটি চালান। এরপর দীর্ঘ prompt দিয়ে আবার চালান। প্রতিটি ক্ষেত্রে tokens-কে seconds দিয়ে ভাগ করুন। CPU-only VPS-এ দীর্ঘ-context request-এর ক্ষেত্রে prefill সাধারণত সবচেয়ে ধীর ধাপ। সংক্ষিপ্ত prompt থেকে পাওয়া tokens per second মান দীর্ঘ prompt-এর prefill-এর গতি পূর্বাভাস দিতে পারে না। prefill-এর সময়সীমা সামনের কোনো timeout-এর চেয়ে বেশি হয়ে গেলে সাধারণত দীর্ঘ prompt-এর ফল হিসেবে উত্তরের পরিবর্তে context deadline exceeded দেখা যায়। তাই context কমানোর আগে কোন layer কাজ বন্ধ করেছে তা নির্ধারণ করুন।
Concurrency-এর সময় এই সমস্যা সবচেয়ে বেশি দেখা যায়। পরিবেশন করা প্রতিটি request-এর জন্য নিজস্ব cache প্রয়োজন। তাই উপরের chart-এর memory প্রতি request-এর জন্য প্রযোজ্য, পুরো server-এর জন্য নয়। একটি দীর্ঘ request server-এর সম্পদ ধরে রাখতে পারে, ফলে ছোট request-গুলো তার পেছনে queue-তে অপেক্ষা করে। OLLAMA_NUM_PARALLEL ইচ্ছাকৃতভাবে নির্ধারণ করুন। একই সঙ্গে উভয় সংখ্যা বাড়ানোর আগে একটি self-hosted LLM কতজন concurrent user পরিবেশন করতে পারে তা দেখুন।
ছোট cache ব্যবহার করে memory ব্যবহারের পরিমাণ কমান
bytes_per_value সূত্রের একটি setting, যা আপনি নিয়ন্ত্রণ করেন। Ollama-এর FAQ-তে OLLAMA_KV_CACHE_TYPE নথিভুক্ত আছে; এর default হলো 2 bytes, পাশাপাশি f16 1 byte এবং তার নিচে q8_0 ও q4_0 রয়েছে। q8_0 ব্যবহার করলে cache অর্ধেক হয়। ফলে 32k row-এর জন্য 4 GiB-এর বদলে 2 GiB লাগে। একই memory budget-এর অন্য দিক থেকে weights quantise করলে memory খালি হয়। VPS-এ বাস্তবে চলার উপযোগী GLM tag-এর ক্ষেত্রেও trade-off হিসেবে quantisation-এর প্রতিটি ধাপ আলাদাভাবে দেখানো হয়েছে। একই FAQ-তে OLLAMA_FLASH_ATTENTION=1-ও নথিভুক্ত আছে। Quantised cache কার্যকর করতে কিছু build-এ এটি আগে সেট করা প্রয়োজন।
[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"অনুমান না করে নিশ্চিত করুন। service restart করুন, আগের মতো একই num_ctx-এ model load করুন, এবং RSS তুলনা করুন। Support model ও backend-এর ওপর নির্ভর করে। কোনো setting-এ পরিবর্তন না হলে আপনার combination এই support-এর আওতায় নেই। Documentation-এ এই option-গুলো দেওয়া আছে, তবে ভালো ফলের নিশ্চয়তা দেওয়া হয়নি। তাই নির্ভর করার আগে নিজের prompt দিয়ে q4_0 পরীক্ষা করুন। এই knob-গুলো ব্যবহারের কারণেই যদি আপনি এখানে এসে থাকেন, Ollama এবং llama.cpp এগুলো ভিন্নভাবে প্রকাশ করে।
num_ctx বাছাই করার পদ্ধতি
/api/showথেকে মডেলের সর্বোচ্চ context, layer-এর সংখ্যা এবং key/value head-এর সংখ্যা পড়ুন।- সূত্র ব্যবহার করে প্রতি token-এর bytes হিসাব করুন। এরপর আপনার প্রয়োজনীয় context দিয়ে গুণ করুন।
- এর সঙ্গে weight-এর size যোগ করুন। মোট পরিমাণ free RAM-এর সঙ্গে তুলনা করুন। বাকি সিস্টেমের জন্য অন্তত 1 GiB RAM খালি রাখুন।
- মানটি সেট করুন এবং মডেল load করুন। এরপর
ollama psএবংprompt_eval_countদিয়ে প্রয়োগ হওয়া মান নিশ্চিত করুন। free -mmonitor করে আপনার প্রকৃত workload চালান। swap ব্যবহার শুরু হলে context অর্ধেক করে দিন।
অনেক কাজেই মানুষ যত বড় context দেয়, তার চেয়ে কম context যথেষ্ট। একটি দীর্ঘ report summarise করতে 16k যথেষ্ট। পাঁচটি document chunk যোগ করা একটি retrieval front end সাধারণত 8k-এর বেশি পাঠায় না। যে coding agent সম্পূর্ণ file পড়ে, তার ক্ষেত্রে সত্যিই 64k বা তার বেশি প্রয়োজন হতে পারে। এই ক্ষেত্রেই context-এর ভিত্তিতে machine-এর capacity নির্ধারণ করা উচিত, উল্টোভাবে নয়। server-টি যদি এখনও নতুন হয়, তাহলে VPS-এ সচল Ollama install থেকে শুরু করুন এবং model পরিষ্কারভাবে load হওয়ার পরে context tune করুন।
FAQ
Ollama-তে ডিফল্ট context length কত?
এটি build এবং hardware-এর ওপর নির্ভর করে। তাই অনুমান না করে যাচাই করুন। Ollama-এর FAQ-তে 4096 token নথিভুক্ত আছে, Modelfile reference-এ num_ctx-এর default হিসেবে 2048 দেওয়া আছে, এবং context length page-এ available VRAM অনুযায়ী একটি default নথিভুক্ত আছে: 24 GiB-এর কম হলে 4k, 24 থেকে 48 GiB হলে 32k, এবং এর বেশি হলে 256k। CPU-only VPS সাধারণত ছোট সীমাতেই থাকে। যে build-গুলোতে এই column আছে, সেগুলোতে ollama ps প্রয়োগ করা context দেখায়। API response-এ prompt_eval_count থাকলে প্রতিটি build-এ এটি নিশ্চিত করা যায়।
Ollama আমার দীর্ঘ prompt-এর শুরুটি উপেক্ষা করে কেন?
কারণ prompt-টি context window-এর চেয়ে দীর্ঘ ছিল। তাই model এটি দেখার আগেই server prompt-এর শুরু বাদ দিয়েছে এবং কোনো error ফেরত দেয়নি। একই prompt আবার বড় num_ctx দিয়ে পাঠান এবং response-এ prompt_eval_count-এর মান বাড়ছে কি না পর্যবেক্ষণ করুন। ওই সংখ্যা না বদলালে আপনার এবং server-এর মধ্যবর্তী কোনো উপাদান নিজেই num_ctx নির্ধারণ করছে। Chat front end এবং agent framework-এ এটি সাধারণ ঘটনা।
বড় num_ctx-এর জন্য অতিরিক্ত RAM কত লাগবে?
Context length-কে প্রতি token cache cost দিয়ে গুণ করুন। এই cost হলো 2 * layers * kv_heads * head_dim * bytes_per_value। Llama 3.1 8B-এর f16-এর ক্ষেত্রে প্রতি token-এ এটি 128 KiB। তাই 32k token-এর জন্য weights-এর অতিরিক্ত 4 GiB এবং সম্পূর্ণ 128k-এর জন্য 16 GiB লাগে। Model load হওয়ার সময় cache allocate করা হয়। তাই prompt ছোট থাকলেও বড় num_ctx ওই পরিমাণ memory ব্যবহার করবে।
বড় context window কি Ollama-কে ধীর করে?
হ্যাঁ, দুইভাবে। Prompt-এর দৈর্ঘ্যের বর্গের সঙ্গে prefill কাজ বাড়ে। তাই দীর্ঘ input-এর ক্ষেত্রে প্রথম token পেতে সময় তার দৈর্ঘ্য দেখে অনুমান করার চেয়ে বেশি লাগে। বড় cache-ও memory-এর জন্য প্রতিযোগিতা করে। GPU server-এ এটি কিছু layer system RAM-এ সরিয়ে দিতে পারে। CPU server-এ এটি machine-কে swap ব্যবহারের দিকে ঠেলে দিতে পারে। আপনি কখনও পুরোপুরি ব্যবহার না করলেও বড় num_ctx-এর জন্য memory বরাদ্দ থাকে। তবে এতে prefill time বাড়ে না।
একটি model-এর জন্য কি num_ctx স্থায়ীভাবে নির্ধারণ করা যায়?
হ্যাঁ। FROM llama3.1:8b এবং PARAMETER num_ctx 16384-সহ একটি Modelfile লিখুন। এরপর ollama create llama3.1-16k -f ./Modelfile চালান। llama3.1-16k চাইলে প্রতিটি client কোনো option না পাঠিয়েই ওই context পাবে। তবে নিজস্ব num_ctx-সহ কোনো request এলে সেটিই প্রাধান্য পাবে। তাই এটি default নির্ধারণ করে, সর্বোচ্চ সীমা নয়।