VPS-এ llama.cpp সার্ভার সেটআপ করার নিয়ম
VPS-এ llama-server বিল্ড করে GGUF মডেল হোস্ট করার সম্পূর্ণ নির্দেশিকা। OpenAI API ব্যবহার, localhost বাইন্ডিং এবং systemd-এর মাধ্যমে মেমোরি লিমিট সেট করার পদ্ধতি এখানে দেখুন।
আপনি যা তৈরি করছেন
একটি VPS-এ llama.cpp সার্ভার চালানোর অর্থ হলো একটি মাত্র বাইনারি, llama-server, যা একটি GGUF মডেল ফাইল লোড করে এবং OpenAI-সামঞ্জস্যপূর্ণ API-তে HTTP অনুরোধের উত্তর দেয়। যেকোনো OpenAI ক্লায়েন্টকে http://127.0.0.1:8080/v1-এর দিকে নির্দেশ করলেই এটি কাজ করে। ইনস্টলেশন প্রক্রিয়াটি তুলনামূলক সহজ।
বাকি কাজগুলো হলো অপারেশনাল: একটি নির্দিষ্ট ভার্সন পিন করা, পোর্টটিকে localhost-এ সীমাবদ্ধ রাখা, একটি systemd unit লেখা এবং সার্ভারের মেমোরি শেষ হয়ে গেলে কী ঘটবে তা নির্ধারণ করা। এই নির্দেশিকাটি সেই বিষয়গুলোই কভার করে। আপনি যদি এখনো দুটি সুস্পষ্ট বিকল্পের মধ্যে সিদ্ধান্ত না নিয়ে থাকেন, তবে প্রথমে Ollama এবং llama.cpp-এর মধ্যে পার্থক্য পড়ে নিন, কারণ সেই তুলনামূলক আলোচনায় এই কাজের পদ্ধতিগুলো ইচ্ছাকৃতভাবে বাদ দেওয়া হয়েছে।
একটি রিলিজ ট্যাগ নির্বাচন করুন এবং তা লিখে রাখুন
llama.cpp প্রায় প্রতিটি মার্জের জন্য একটি রিলিজ ট্যাগ তৈরি করে, তাই এই ট্যাগগুলো মূলত বিল্ড নম্বর। 18 আগস্ট 2026 অনুযায়ী b10488 হলো নতুনতম রিলিজ। এখানে দীর্ঘমেয়াদী কোনো স্টেবল ব্রাঞ্চ নেই, যার অর্থ হলো "latest" ট্যাগটি প্রতিনিয়ত পরিবর্তিত হয় এবং আপনি যে সংস্করণটি পরীক্ষা করেছেন, শুধুমাত্র সেটিই সাপোর্ট করা সম্ভব। একটি ট্যাগ নির্বাচন করুন, সেটি লিখে রাখুন এবং আপনার ক্লোন, বাইনারি নাম ও নোটের ক্ষেত্রে একই স্ট্রিং ব্যবহার করুন।
প্রতিটি ট্যাগের সাথে প্রি-বিল্ট আর্কাইভও থাকে। শুধুমাত্র CPU-ভিত্তিক x86 VPS-এর জন্য এটি হলো llama-b10488-bin-ubuntu-x64.tar.gz, আর আপনি যদি x86-এর পরিবর্তে ARM VPS ব্যবহার করেন, তবে তার পাশেই arm64 আর্কাইভটি পাবেন।
curl -LO https://github.com/ggml-org/llama.cpp/releases/download/b10488/llama-b10488-bin-ubuntu-x64.tar.gz
tar tf llama-b10488-bin-ubuntu-x64.tar.gz | headআর্কাইভটি এক্সট্র্যাক্ট করার আগে তার ফাইলগুলো দেখে নিন, যাতে আপনি বুঝতে পারেন ফাইলগুলো কোথায় জমা হবে। এই বাইনারিগুলো যে ইমেজ থেকে তৈরি হয়েছে, তার C লাইব্রেরির সাথে লিঙ্ক করা থাকে। তাই পুরনো ডিস্ট্রিবিউশনে এগুলো চালানোর সময় এমন একটি GLIBC_ সংস্করণের ত্রুটি দেখাতে পারে যা সিস্টেমে ইনস্টল করা নেই। একটি ছোট VPS-এ সোর্স থেকে বিল্ড করতে কয়েক মিনিট সময় লাগে এবং এতে এই ধরনের সমস্যা পুরোপুরি দূর হয়, তাই নিচে সেই পদ্ধতিটিই দেওয়া হলো।
একটি নির্দিষ্ট ট্যাগ থেকে llama-server বিল্ড করা
sudo apt update
sudo apt install -y build-essential cmake git libssl-dev
git clone --depth 1 --branch b10488 https://github.com/ggml-org/llama.cpp
cd llama.cpp
cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_EXAMPLES=OFF
cmake --build build --config Release -t llama-server -j 2একটি --depth 1 ক্লোনে --branch b10488 কমান্ডটি শুধুমাত্র সেই নির্দিষ্ট ট্যাগটিকেই চেকআউট করে, ফলে কাজ করার সময় বিল্ডের কোনো পরিবর্তন বা ড্রিফট হওয়ার সুযোগ থাকে না।
libssl-dev গুরুত্বপূর্ণ কারণ LLAMA_OPENSSL অপশনটি ডিফল্টভাবে চালু থাকে, যা পরবর্তীতে বাইনারিটিকে HTTPS-এর মাধ্যমে মডেল ডাউনলোড করতে দেয়। হেডার ফাইলগুলো না থাকলে কনফিগারেশন ধাপটি ব্যর্থ হয়।
-DBUILD_SHARED_LIBS=OFF আপনাকে একটি স্বয়ংসম্পূর্ণ বাইনারি প্রদান করে। ডিফল্ট বিল্ডে শেয়ার্ড লাইব্রেরিগুলো এক্সিকিউটেবলের পাশেই থাকে, তাই শুধুমাত্র এক্সিকিউটেবল ফাইলটি /usr/local/bin-এ কপি করলে তা error while loading shared libraries: libllama.so এর কারণে ব্যর্থ হয়।
-t llama-server শুধুমাত্র সার্ভার টার্গেটটি বিল্ড করে। ডিফল্ট বিল্ডে অন্যান্য টুল এবং টেস্টগুলোও কম্পাইল হয়, যা একটি দুই কোরের VPS-এ অপ্রয়োজনীয় ফাইলগুলোর জন্য কয়েক মিনিট বাড়তি সময় নষ্ট করে।
-j 2 ইচ্ছাকৃতভাবে ব্যবহার করা হয়েছে। প্রতিটি প্যারালাল কম্পাইল জব নিজস্ব মেমোরি ব্যবহার করে, তাই ছোট প্ল্যানে -j $(nproc) ব্যবহার করলে তা c++: fatal error: Killed signal terminated program cc1plus-এ গিয়ে শেষ হয়, যা মূলত কার্নেলের আউট-অফ-মেমোরি কিলার (OOM killer) দ্বারা কম্পাইলারকে বন্ধ করে দেওয়া। জবের সংখ্যা কমিয়ে দিন অথবা বিল্ডের জন্য সোয়াপ (swap) যোগ করুন।
একটি ফ্ল্যাগ যা আপনি পরিবর্তন করতে চাইতে পারেন: GGML_NATIVE ডিফল্টভাবে চালু থাকে, তাই কম্পাইলার বিল্ড করা CPU-এর আর্কিটেকচার অনুযায়ী কোড তৈরি করে। আপনি যদি সেই একই মেশিনে এটি চালাতে চান তবে এটিই কাম্য। যদি আপনি একবার বিল্ড করে বাইনারিটি অন্য কোনো হোস্টে কপি করতে চান, তবে -DGGML_NATIVE=OFF যোগ করুন। কারণ অন্য CPU-তে নেই এমন ইনস্ট্রাকশন ব্যবহার করলে বাইনারিটি প্রথম ইনফারেন্সের সময় Illegal instruction (core dumped) এর কারণে বন্ধ হয়ে যাবে।
ট্যাগ অনুযায়ী নাম দিয়ে এটি ইনস্টল করুন।
./build/bin/llama-server --version
sudo install -m 755 build/bin/llama-server /usr/local/bin/llama-server-b10488
sudo ln -sfn /usr/local/bin/llama-server-b10488 /usr/local/bin/llama-server--version কমান্ডটি বিল্ড নম্বর এবং কমিট আইডি প্রদর্শন করে। এটি আপনার চেকআউট করা ট্যাগের সাথে মিলতে হবে। যদি না মেলে, তবে আপনি অন্য কিছু বিল্ড করেছেন। ফাইলের নামে নম্বরটি রাখা এবং একটি সিমলিংক (symlink) ব্যবহার করার অর্থ হলো, আপগ্রেড করার জন্য শুধুমাত্র একটি ln -sfn এবং একটি রিস্টার্ট প্রয়োজন, আর রোলব্যাক করার জন্য পুরনো নম্বর দিয়ে একই কমান্ড চালানোই যথেষ্ট।
একটি GGUF মডেল সংগ্রহ করুন এবং প্রথমে ডিস্কের জায়গা পরীক্ষা করুন
GGUF হলো একক ফাইলের ফরম্যাট যা llama.cpp লোড করে। একটি ফাইলেই ওয়েট (weights), টোকেনাইজার এবং মেটাডেটা থাকে, তাই আলাদা করে আর কিছু ইনস্টল করার প্রয়োজন নেই। ফাইলের নামের শেষের অংশটি হলো কোয়ান্টাইজেশন, যা নির্দেশ করে ওয়েটগুলো কী পরিমাণ প্রিসিশনে সংরক্ষিত আছে: Q4_K_M হলো 4-বিটের একটি মিশ্রণ, Q8_0 হলো 8-বিট, এবং f16 হলো আনকোয়ান্টাইজড হাফ-প্রিসিশন ফাইল।
কিছু ডাউনলোড করার আগেই একটি সার্ভিস অ্যাকাউন্ট এবং একটি মডেল ডিরেক্টরি তৈরি করে নিন।
sudo useradd --system --home /srv/llama --create-home --shell /usr/sbin/nologin llama
sudo install -d -o llama -g llama /srv/models
df -h /srvসার্ভার নিজেই -hf ব্যবহার করে মডেলটি সংগ্রহ করতে পারে, যা আপনার বিল্ডটি কাজ করছে কি না তা যাচাই করার দ্রুততম উপায়।
sudo -u llama env LLAMA_CACHE=/srv/models /usr/local/bin/llama-server \
-hf ggml-org/gemma-3-1b-it-GGUF:Q4_K_M --host 127.0.0.1 --port 8080LLAMA_CACHE ডাউনলোড ডিরেক্টরি নির্ধারণ করে। এটি ছাড়া ফাইলটি ~/.cache/llama.cpp-এ চলে যায়, যা যে অ্যাকাউন্ট থেকে কমান্ডটি চালানো হয়েছে তার অধীনে থাকে। এটি এমন একটি সার্ভিসের জন্য ভুল জায়গা, যার হোম ডিরেক্টরি আপনি শীঘ্রই অপাঠ্য (unreadable) করে ফেলতে যাচ্ছেন। এর পরে ls -lh /srv/models চালান, কারণ ক্যাশ করা ফাইলের নাম সাধারণ ফাইলের নামের পরিবর্তে রিপোজিটরির নাম থেকে তৈরি হয়।
সার্ভিসের জন্য, আপনার পছন্দমতো একটি পাথে ডাউনলোড করুন, যাতে ইউনিট ফাইলের নির্দেশ করার জন্য একটি স্থিতিশীল জায়গা থাকে।
sudo -u llama curl -L --output-dir /srv/models -O \
https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.ggufডিস্কের জায়গার সীমাবদ্ধতা হলো প্রথম সমস্যা যা ব্যবহারকারীরা সম্মুখীন হন। 18 আগস্ট 2026 তারিখে যাচাই করা দুটি মডেলের প্রকাশিত ফাইলের আকার নিচে দেওয়া হলো।
The data behind this chart
[
{
"label": "gemma-3-1b-it Q4_K_M",
"size_gb": 0.81
},
{
"label": "gemma-3-1b-it Q8_0",
"size_gb": 1.07
},
{
"label": "gemma-3-1b-it f16",
"size_gb": 2.01
},
{
"label": "gpt-oss-20b MXFP4",
"size_gb": 12.11
}
]1বি (1B) মডেলের 4-বিট ফাইলের আকার হলো 0.81 GB। একই মডেল কোনো কোয়ান্টাইজেশন ছাড়া 2.01 GB, তাই ফরম্যাট নির্বাচনের ওপর ভিত্তি করে ফাইলের আকার দ্বিগুণেরও বেশি পরিবর্তিত হয়। MXFP4 ফরম্যাটে একটি 20বি (20B) মডেলের আকার 12.11 GB, যা অনেক এন্ট্রি-লেভেল প্ল্যানের ডিস্কে জায়গা হয় না, এবং এরপরও সেটিকে মেমরিতে লোড করতে হয়।
প্রতিটি ডাউনলোডের আগে df -h পরীক্ষা করুন। 12 GB ফাইল ট্রান্সফারের সময় রুট ফাইলসিস্টেম পূর্ণ হয়ে গেলে তা অন্য সব রাইট অপারেশনকে অকেজো করে দেয়, যার মধ্যে জার্নালও অন্তর্ভুক্ত।
একবার ম্যানুয়ালি চালান এবং যাচাই করুন
sudo -u llama /usr/local/bin/llama-server \
--model /srv/models/gemma-3-1b-it-Q4_K_M.gguf \
--host 127.0.0.1 --port 8080 \
--ctx-size 4096 --parallel 1 --threads 2 --no-webuiদ্বিতীয় একটি সেশনে সার্ভারটি প্রস্তুত কি না তা জিজ্ঞাসা করুন।
curl -s http://127.0.0.1:8080/healthফাইলটি লোড হওয়ার সময় আপনি HTTP 503 এবং এই বডিটি পাবেন:
{"error":{"code":503,"message":"Loading model","type":"unavailable_error"}}যখন এটি প্রস্তুত হয়, তখন বডিটি হয় {"status": "ok" }। এরপর একটি প্রকৃত রিকোয়েস্ট পাঠান।
curl -s http://127.0.0.1:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"local","messages":[{"role":"user","content":"Say hello in five words."}]}'একটি JSON অবজেক্ট যার মধ্যে choices অ্যারে আছে, তা নির্দেশ করে যে সার্ভারটি কাজ করছে। model ফিল্ডটি সেখানে থাকে কারণ OpenAI ক্লায়েন্টরা সবসময় এটি পাঠায়। এই সার্ভারে একটি মাত্র মডেল লোড করা আছে, তাই মানটি কোনো কিছু নির্বাচন করার জন্য ব্যবহৃত হয় না।
OpenAI-compatible API এবং পোর্টে আর যা যা আছে
POST /v1/chat/completions, POST /v1/completions এবং POST /v1/embeddings হলো OpenAI-compatible রুট এবং GET /v1/models লোড করা মডেলের তথ্য প্রদান করে। GET /health হলো উপরের readiness check, GET /props সার্ভারের বর্তমান সেটিংস দেখায় এবং আপনি যদি --metrics দিয়ে শুরু করেন তবে GET /metrics Prometheus কাউন্টারগুলো উন্মুক্ত করে।
আপনি যখন base URL-কে http://127.0.0.1:8080/v1 হিসেবে সেট করবেন এবং একটি নন-এম্পটি API key প্রদান করবেন, তখন যেকোনো OpenAI SDK কাজ করবে। আপনি নিজে --api-key সেট না করা পর্যন্ত কোনো কিছুই সেই কি (key) যাচাই করে না।
অন্য কারো throughput-এর দাবিকে আপনার নিজের পরিকল্পনার জন্য চূড়ান্ত সংখ্যা হিসেবে ধরবেন না। CPU inference-এর গতি নির্ভর করে কোর সংখ্যা, মেমরি ব্যান্ডউইথ এবং আপনি যে হোস্ট শেয়ার করছেন তার অন্যান্য ব্যবহারকারীদের ওপর। তাই আপনার নিজের মেশিনে tokens per second পরিমাপ করুন এবং সেই ফলাফলকেই সত্য হিসেবে গ্রহণ করুন। Noisy neighbour থেকে আসা steal time এখানে জেনারেশন স্পিড হিসেবে দেখা দেয়, যা প্রতি ঘণ্টায় পরিবর্তিত হতে পারে।
এটিকে 127.0.0.1-এ রাখুন এবং সামনে একটি প্রক্সি ব্যবহার করুন
--host ডিফল্টভাবেই 127.0.0.1-এ সেট করা থাকে, তাই আপনি পরিবর্তন না করা পর্যন্ত সার্ভারটি বাইরে থেকে অ্যাক্সেস করা সম্ভব নয়। এটি এভাবেই রাখুন। llama-server-এ কোনো ইউজার মডেল, রেট লিমিট বা কার্যকর অডিট লগ নেই এবং এর একমাত্র বিল্ট-ইন কন্ট্রোল হলো --api-key, যা কেবল একটি স্ট্রিং তুলনা করে। একটি ওপেন ইনফারেন্স পোর্ট যে কেউ খুঁজে পেলে তা তাদের জন্য বিনামূল্যে কম্পিউট রিসোর্স ব্যবহারের সুযোগ করে দেয়, এবং Ollama-এর ক্ষেত্রেও একই ভুল একই পরিণতির দিকে নিয়ে যায়: সেলফ-হোস্টেড মডেল API সুরক্ষিত রাখা-এর নির্দেশনাগুলো এখানে হুবহু প্রযোজ্য।
nginx-এ TLS (transport layer security) টার্মিনেট করুন এবং লুপব্যাক পোর্টে প্রক্সি করুন।
server {
listen 443 ssl;
server_name llm.example.com;
location /v1/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 600s;
}
}স্ট্রিমিংয়ের জন্য proxy_buffering off প্রয়োজন। বাফারিং চালু থাকলে, nginx সার্ভার-সেন্ট ইভেন্টগুলো (SSE) রেসপন্স শেষ না হওয়া পর্যন্ত আটকে রাখে, ফলে ক্লায়েন্ট কোনো আউটপুট না পেয়ে অপেক্ষা করে এবং শেষে পুরো উত্তরটি একসাথে পায়। দীর্ঘ জেনারেশনের জন্য proxy_read_timeout 600s প্রয়োজন, কারণ ডিফল্ট 60 সেকেন্ডের সময়সীমা একটি ধীরগতির উত্তরকে 504 Gateway Time-out-এ পরিণত করে। nginx-এ Certbot এবং Let's Encrypt ব্যবহার করে সার্টিফিকেট সংগ্রহ করুন।
systemd unit
/etc/systemd/system/llama-server.service লিখুন।
[Unit]
Description=llama.cpp server
After=network-online.target
Wants=network-online.target
[Service]
User=llama
Group=llama
Environment=LLAMA_ARG_MODEL=/srv/models/gemma-3-1b-it-Q4_K_M.gguf
Environment=LLAMA_ARG_HOST=127.0.0.1
Environment=LLAMA_ARG_PORT=8080
Environment=LLAMA_ARG_CTX_SIZE=4096
Environment=LLAMA_ARG_N_PARALLEL=1
Environment=LLAMA_ARG_THREADS=2
ExecStart=/usr/local/bin/llama-server --no-webui
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
MemoryHigh=3G
MemoryMax=3500M
OOMPolicy=stop
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
[Install]
WantedBy=multi-user.targetসেটিংগুলো Environment= লাইনে থাকে কারণ llama-server অধিকাংশ ফ্ল্যাগের জন্য LLAMA_ARG_* ভেরিয়েবলগুলো পড়ে এবং কমান্ড লাইনের আর্গুমেন্টগুলো সংশ্লিষ্ট ভেরিয়েবলকে ওভাররাইড করে। এটি আপনাকে কনটেক্সট সাইজ পরিবর্তনের জন্য একটি নির্দিষ্ট জায়গা দেয় এবং ExecStart-কে এক নজরে পড়ার মতো সংক্ষিপ্ত রাখে।
ProtectSystem=strict এই ইউনিটের জন্য পুরো ফাইলসিস্টেমকে রিড-অনলি (read-only) করে দেয়, যা ঠিক আছে কারণ সার্ভারটি শুধুমাত্র মডেলটি পড়ে। আপনি যদি চান সার্ভিসটি নিজে -hf ব্যবহার করে মডেল ডাউনলোড করুক, তবে ReadWritePaths=/srv/models যোগ করুন। ProtectHome=yes, /home এবং /root-কে লুকিয়ে ফেলে, আর মডেলগুলোকে /srv-এ রাখার এটি দ্বিতীয় কারণ: ProtectHome চালু থাকলে, ডিফল্ট ~/.cache/llama.cpp পাথটি প্রসেসের কাছে মোটেও দৃশ্যমান থাকে না।
sudo systemctl daemon-reload
sudo systemctl enable --now llama-server
systemctl status llama-server
curl -s http://127.0.0.1:8080/health
journalctl -u llama-server -n 50 --no-pagerenable --now হলো সেই অংশ যা মানুষ এড়িয়ে যায়। enable ছাড়া, পরবর্তী রিবুটের পর সার্ভারটি আর চালু থাকবে না। আপনি যদি সার্ভিসের আশেপাশে কোনো নির্ধারিত কাজ (scheduled work) করতে চান, যেমন নতুন রিলিজের জন্য প্রতি রাতে চেক করা, তবে একটি systemd service এবং timer হলো এর সঠিক উপায়।
OOM ঘটার আগেই সিদ্ধান্ত নিন কী ঘটবে
মেমরি ব্যবহারের দুটি অংশ আছে এবং একটি সীমার অধীনে তারা ভিন্নভাবে কাজ করে। মডেল ফাইলটি ডিফল্টভাবে memory-mapped থাকে, তাই এর পেজগুলো file-backed: কার্নেল চাইলে এগুলো মুছে ফেলে পরে আবার ডিস্ক থেকে পড়ে নিতে পারে। KV cache, যা প্রতিটি সক্রিয় কথোপকথনের জন্য সার্ভার কর্তৃক সংরক্ষিত per-token স্টেট, তা anonymous memory। এটি মুছে ফেলা যায় না, তাই এই মেমরি ব্যবহারের কারণেই প্রসেসটি বন্ধ (kill) হয়ে যায়।
এ কারণেই ইউনিটের দুটি সীমা ভিন্ন কাজ করে। MemoryHigh=3G হলো একটি soft limit: এর উপরে গেলে কার্নেল cgroup-এর ওপর reclaim pressure তৈরি করে, ফলে mapped মডেল পেজগুলো evicted হয় এবং পরবর্তী টোকেনের সময় সেগুলো আবার ডিস্ক থেকে পড়া হয়। সার্ভিসটি সচল থাকে কিন্তু ধীরগতির হয়ে যায়। MemoryMax=3500M হলো একটি hard limit: এর উপরে গেলে প্রসেসটি বন্ধ হয়ে যায় এবং জার্নালে তা স্পষ্টভাবে উল্লেখ থাকে।
llama-server.service: A process of this unit has been killed by the OOM killer.--ctx-size আপনি নিজেই সেট করুন। ডিফল্ট মান হলো 0, যার অর্থ হলো মডেলটি যে কনটেক্সট নিয়ে প্রশিক্ষিত হয়েছে তা ব্যবহার করা, এবং আধুনিক long-context মডেলগুলো শুরুতে খুব বড় আকারের KV cache বরাদ্দ করে। ফলে একটি অনুরোধ পাওয়ার আগেই সার্ভিসটি বন্ধ হয়ে যায়। --parallel একই খরচকে গুণিতক হারে বাড়ায়, কারণ প্রতিটি স্লট নিজস্ব কথোপকথনের স্টেট ধরে রাখে, তাই কনকারেন্সি (concurrency) প্রয়োজন না হওয়া পর্যন্ত এটি 1-এ রাখুন।
Restart=on-failure থাকলে একটি বন্ধ হয়ে যাওয়া সার্ভিস আবার চালু হয়। যদি প্রতিবার শুরুর সময় এটি বন্ধ হয়ে যায়, তবে systemd হাল ছেড়ে দেয় এবং systemctl status তখন start request repeated too quickly প্রদর্শন করে। এটিই সঠিক আচরণ: একটি রিস্টার্ট লুপ যা প্রতি পাঁচ সেকেন্ডে 12 GB ফাইল পুনরায় পড়ে, তা সার্ভিসের ডাউনটাইমের চেয়েও খারাপ। সীমা বা কনটেক্সট সাইজ ঠিক করুন, তারপর sudo systemctl reset-failed llama-server দিয়ে স্টেট ক্লিয়ার করুন।
অনুরোধ চলাকালীন systemctl show llama-server -p MemoryCurrent দিয়ে প্রকৃত সংখ্যাটি পর্যবেক্ষণ করুন। systemd দিয়ে প্রসেস মেমরি ও CPU সীমাবদ্ধ করা-তে এই নির্দেশিকাগুলো নিয়ে বিস্তারিত আলোচনা করা হয়েছে।
এই কাজের জন্য swap ব্যবহার এড়িয়ে চলুন। একটি swapped-out মডেল প্রতিটি টোকেনকে random-offset ডিস্ক রিডে পরিণত করে। মডেল ফাইলটিকে memory-mapping করলে কম ক্ষতিতে একই ফলাফল পাওয়া যায়, কারণ কার্নেল তখন সরাসরি ফাইল থেকে প্রয়োজনীয় পেজগুলো পড়ে নেয়।
যেখানে Ollama একটি ভালো সমাধান
এটি একটি সিদ্ধান্ত নেওয়ার মুহূর্ত। যখন আপনি এমন একটি প্রসেস চান যেখানে আপনার সেট করা ফ্ল্যাগ, আপনার পিন করা বিল্ড এবং আপনার বেছে নেওয়া ফাইল থাকবে, এবং যেখানে অন্য কিছু না চলায় আপনার অজান্তে কোনো পরিবর্তন হবে না, তখন llama-server বেছে নিন।
যখন আপনি মডেল ম্যানেজমেন্ট চান, তখন Ollama বেছে নিন: নাম ধরে মডেল পুল করা, ডিস্কে একাধিক মডেল রাখা, অব্যবহৃত মডেল আনলোড করা এবং রি-বিল্ড না করে একটি মাত্র কমান্ডের মাধ্যমে আপগ্রেড করা। এগুলো এমন কাজ যা অন্যথায় আপনাকে নিজে স্ক্রিপ্ট করতে হতো। VPS-এ Ollama চালানো হলো একই কাজ, যেখানে আপনি অন্য বিকল্পটি বেছে নিচ্ছেন। উভয়ই OpenAI-compatible API প্রদান করে, তাই ক্লায়েন্ট কোড যেকোনো দিকে পরিবর্তন করলেও তা কার্যকর থাকে।
একটি পিন করা বিল্ড আপগ্রেড করা
bNNNNN-কে সেই ট্যাগ দিয়ে প্রতিস্থাপন করুন যেটিতে আপনি পরিবর্তন করছেন।
cd llama.cpp
git fetch --tags
git checkout bNNNNN
cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_EXAMPLES=OFF
cmake --build build --config Release -t llama-server -j 2
sudo install -m 755 build/bin/llama-server /usr/local/bin/llama-server-bNNNNN
sudo ln -sfn /usr/local/bin/llama-server-bNNNNN /usr/local/bin/llama-server
sudo systemctl restart llama-serverপুরানো বাইনারিটি ডিস্কে থেকে যায়, তাই রোলব্যাক করার জন্য শুধুমাত্র ln -sfn থেকে llama-server-b10488-এ ফিরে গিয়ে একবার রিস্টার্ট করলেই হয়। কোনো পরিবর্তনের আগে রিলিজ নোটগুলো পড়ে নিন। GGUF ফাইলগুলো ভার্সনযুক্ত এবং পুরানো ফাইলগুলো লোড হতে থাকে, কিন্তু ফ্ল্যাগগুলোর নাম পরিবর্তন হতে পারে: --mlock এবং --no-mmap ইতিমধ্যেই বাতিল করা হয়েছে এবং এর পরিবর্তে --load-mode ব্যবহার করা হচ্ছে। যদি কোনো ইউনিট ফাইলে এমন কোনো ফ্ল্যাগ থাকে যা সরিয়ে ফেলা হয়েছে, তবে সেটি স্টার্ট হওয়ার সময় একটি unrecognised argument মেসেজ দিয়ে ব্যর্থ হবে।
ব্যর্থতার ধরন এবং যে বার্তাগুলো আপনি দেখতে পাবেন
error while loading shared libraries: libllama.so বাইনারিটি অন্য কোথাও কপি করার পর। ডিফল্ট বিল্ড প্রক্রিয়ায় এর পাশাপাশি শেয়ার্ড লাইব্রেরি তৈরি হয়। -DBUILD_SHARED_LIBS=OFF ব্যবহার করে পুনরায় বিল্ড করুন, অথবা পুরো build/bin ডিরেক্টরি কপি করুন।
Illegal instruction (core dumped) স্টার্টআপের সময় বা প্রথম রিকোয়েস্টের ক্ষেত্রে। বাইনারিটি GGML_NATIVE চালু রেখে এমন একটি CPU-এর জন্য কম্পাইল করা হয়েছে, যা বর্তমানটির চেয়ে ভিন্ন। এই মেশিনে পুনরায় বিল্ড করুন, অথবা -DGGML_NATIVE=OFF দিয়ে কনফিগার করুন।
c++: fatal error: Killed signal terminated program cc1plus বিল্ড চলাকালীন। অতিরিক্ত মেমরি ব্যবহারের কারণে কম্পাইলারটিকে বন্ধ করে দেওয়া হয়েছে। -j কমিয়ে দিন, অথবা বিল্ডের জন্য সাময়িকভাবে সোয়াপ (swap) যোগ করুন এবং পরে তা সরিয়ে ফেলুন।
curl: (7) Failed to connect ... Connection refused আপনার ল্যাপটপ থেকে। এটি সঠিক: সার্ভারটি VPS-এর লুপব্যাক অ্যাড্রেসে লিসেন করছে। VPS-এর ভেতরেই পরীক্ষা করুন, অথবা ssh -L 8080:127.0.0.1:8080 user@your-vps দিয়ে একটি টানেল তৈরি করুন এবং লোকালি http://127.0.0.1:8080 ব্যবহার করুন।
HTTP 503 এবং "message":"Loading model" রিস্টার্টের পর প্রথম কয়েক সেকেন্ড বা মিনিটের জন্য। কয়েক গিগাবাইটের ফাইল পড়তে সময় লাগে, এবং প্রসেস শুরু হওয়ার সাথে সাথেই systemd ইউনিটটিকে সক্রিয় হিসেবে রিপোর্ট করে, যদিও মডেলটি তখনো মেমরিতে লোড হয়নি।
রিকোয়েস্ট হ্যাং হয়ে যায় এবং তারপর 504 Gateway Time-out রিটার্ন করে। মডেলটি কাজ শেষ করার আগেই প্রক্সি সংযোগ বিচ্ছিন্ন করে দিয়েছে। proxy_read_timeout বাড়িয়ে দিন এবং proxy_buffering বন্ধ করে দিন যাতে টোকেনগুলো তৈরি হওয়ার সাথে সাথেই ক্লায়েন্টের কাছে পৌঁছাতে পারে।
ইউনিটটি ফ্ল্যাপ করে এবং তারপর start request repeated too quickly দিয়ে বন্ধ হয়ে যায়। প্রতিবার শুরুর সময় কোনো কিছু এটিকে বন্ধ করে দিচ্ছে। OOM কিলার লাইনটি দেখার জন্য journalctl -u llama-server চেক করুন, তারপর --ctx-size কমান, --parallel কমান, অথবা MemoryMax বাড়িয়ে দিন।
FAQ
আমার VPS-এ কি llama.cpp-এর server নাকি Ollama চালানো উচিত?
যখন আপনি একটি নির্দিষ্ট বিল্ড ব্যবহার করতে চান, সুনির্দিষ্ট ফ্ল্যাগ পাস করতে চান এবং এমন একটি মডেল ফাইল রাখতে চান যা আপনার অজান্তে পরিবর্তিত হবে না, তখন llama-server চালান। যখন আপনি মডেল ম্যানেজমেন্ট এবং এক-কমান্ডে আপগ্রেড সুবিধা চান, তখন Ollama ব্যবহার করুন। কারণ নাম দিয়ে মডেল পুল করা, ডিস্কে একাধিক মডেল রাখা এবং অলস মডেলগুলোকে আনলোড করার কাজগুলো আপনাকে অন্যথায় স্ক্রিপ্ট লিখে করতে হতো। উভয়ই OpenAI-সামঞ্জস্যপূর্ণ API প্রদান করে, তাই পরবর্তীতে পরিবর্তন করলেও আপনার ক্লায়েন্ট কোড পরিবর্তনের প্রয়োজন হবে না।
আমার কোন llama.cpp ভার্সনটি পিন করা উচিত?
যেকোনো ট্যাগ যা আপনি নিজে বিল্ড এবং টেস্ট করেছেন। llama.cpp প্রায় প্রতিটি মার্জের জন্য ট্যাগ তৈরি করে এবং নামগুলো বিল্ড নম্বর অনুযায়ী হয়, যেমন b10488, যা 18 আগস্ট 2026 তারিখে নতুন ছিল। এখানে আলাদা কোনো স্টেবল ব্রাঞ্চ নেই, তাই "current" ভার্সনটি দিনে কয়েকবার পরিবর্তিত হতে পারে। --branch <tag> দিয়ে ক্লোন করুন, সেই ট্যাগযুক্ত ফাইলনামে বাইনারিটি ইনস্টল করুন এবং একটি সিমলিংক (symlink) ব্যবহার করুন, যাতে আপগ্রেড এবং রোলব্যাক করা একটি কমান্ডের কাজ হয়ে দাঁড়ায়।
llama-server-এর জন্য কতটুকু RAM প্রয়োজন?
GGUF ফাইলের আকার থেকে শুরু করুন, তারপর এর সাথে KV ক্যাশ যোগ করুন, যা --ctx-size এবং --parallel স্লটের সংখ্যার সাথে বৃদ্ধি পায়। প্রকাশিত পরিসংখ্যান আপনার নিজস্ব সেটআপ পরিমাপের বিকল্প নয়, কারণ মোট RAM-এর পরিমাণ মডেল, কোয়ান্টাইজেশন এবং আপনি যে কনটেক্সট অনুমতি দিচ্ছেন তার ওপর নির্ভর করে। রিকোয়েস্ট চলাকালীন systemctl show llama-server -p MemoryCurrent চালান এবং যে সংখ্যাটি দেখতে পান সেটি ব্যবহার করুন।
কেন /health এন্ডপয়েন্ট "Loading model" মেসেজসহ 503 এরর দেয়?
প্রসেসটি শুরু হয়েছে কিন্তু মডেল ফাইলটি এখনো মেমরিতে লোড হয়নি, তাই সার্ভার {"error":{"code":503,"message":"Loading model","type":"unavailable_error"}} রেসপন্স দেয়। প্রতিটি রিস্টার্টের পর এটি স্বাভাবিক এবং ফাইলটি পড়তে যতটুকু সময় লাগে ততক্ষণ এটি স্থায়ী হয়। এটি তখনই সমস্যা হয়ে দাঁড়ায় যখন কোনো ক্লায়েন্ট বা প্রক্সি সেই প্রথম 503 এররটিকে চূড়ান্ত ব্যর্থতা হিসেবে গণ্য করে। {"status": "ok" } না আসা পর্যন্ত /health পোল করতে থাকুন।
আমি কি সরাসরি ইন্টারনেটে llama-server উন্মুক্ত করতে পারি?
এটিকে 0.0.0.0-এ বাইন্ড করবেন না এবং পোর্ট ওপেন করবেন না। এতে কোনো অ্যাকাউন্ট সিস্টেম, রেট লিমিটিং বা অডিট করার মতো রিকোয়েস্ট লগ নেই এবং এর একমাত্র বিল্ট-ইন চেক হলো --api-key, যা একটি মাত্র স্ট্রিং তুলনা করে। ডিফল্ট 127.0.0.1 বাইন্ড বজায় রাখুন, সামনে TLS সহ nginx বসান এবং --api-key সেট করুন, যাতে প্রক্সি কনফিগারেশনে একটি ভুলের কারণে মডেলটি সবার জন্য উন্মুক্ত না হয়ে যায়।