VPS-এ llama.cpp সার্ভার সেটআপ করার নিয়ম
VPS-এ llama-server বিল্ড করা, GGUF মডেল হোস্ট করা এবং OpenAI API ব্যবহারের পূর্ণাঙ্গ নির্দেশিকা। systemd সার্ভিস কনফিগারেশন ও মেমরি লিমিট সেট করার সঠিক পদ্ধতি এখানে দেখুন।
আপনি যা তৈরি করছেন
একটি VPS-এ llama.cpp সার্ভার চালানোর অর্থ হলো একটি মাত্র বাইনারি, llama-server, যা একটি GGUF মডেল ফাইল লোড করে এবং OpenAI-এর সাথে সামঞ্জস্যপূর্ণ API-তে HTTP অনুরোধের উত্তর দেয়। যেকোনো OpenAI ক্লায়েন্টকে http://127.0.0.1:8080/v1-এর দিকে নির্দেশ করলেই এটি কাজ করে। ইনস্টলেশন প্রক্রিয়াটি এর সহজ অংশ।
বাকি কাজগুলো হলো অপারেশনাল: একটি নির্দিষ্ট ভার্সন পিন করা, পোর্টটিকে localhost-এ সীমাবদ্ধ রাখা, একটি systemd ইউনিট লেখা এবং সার্ভারের মেমরি শেষ হয়ে গেলে কী হবে তা নির্ধারণ করা। এই নির্দেশিকায় আমরা এই বিষয়গুলোই কভার করব। আপনি যদি এখনো দুটি স্পষ্ট অপশনের মধ্যে সিদ্ধান্ত নিতে না পেরে থাকেন, তবে প্রথমে Ollama এবং llama.cpp-এর মধ্যে পার্থক্য পড়ে নিন, কারণ সেই তুলনামূলক আলোচনায় যে ব্যবহারিক নির্দেশিকাটি বাদ দেওয়া হয়েছে, সেটিই এখানে তুলে ধরা হলো।
একটি রিলিজ ট্যাগ নির্বাচন করুন এবং তা লিখে রাখুন
llama.cpp প্রায় প্রতিটি মার্জের জন্য একটি রিলিজ ট্যাগ তৈরি করে, তাই এই ট্যাগগুলো মূলত বিল্ড নম্বর। 18 আগস্ট 2026 অনুযায়ী b10488 হলো সর্বশেষ রিলিজ। এখানে দীর্ঘমেয়াদী কোনো স্থিতিশীল (stable) ব্রাঞ্চ নেই, যার অর্থ হলো "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-এ গিয়ে শেষ হয়, যার ফলে কার্নেলের আউট-অফ-মেমরি কিলার কম্পাইলারকে বন্ধ করে দেয়। জবের সংখ্যা কমিয়ে দিন অথবা বিল্ডের জন্য সোয়াপ (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, যা অনেক এন্ট্রি-লেভেল প্ল্যানের ডিস্কে জায়গা হয় না, এবং এরপরও এটিকে মেমরিতে লোড করতে হয়। আপনি যদি নির্দিষ্ট কোনো মডেল ফ্যামিলি নিয়ে কাজ করতে চান, তবে GLM-এর জন্য একই সাইজিং অনুশীলন দেখুন; এটি দেখায় যে কীভাবে একটি বড় মডেল দ্রুত একটি VPS-এর বাজেটের বাইরে চলে যায়, যেখানে ছোট সংস্করণটি সহজেই জায়গা করে নেয়।
প্রতিটি ডাউনলোডের আগে df -h পরীক্ষা করুন। 12 জিবি ফাইল ট্রান্সফারের সময় রুট ফাইলসিস্টেম পূর্ণ হয়ে গেলে তা অন্যান্য রাইট অপারেশনকেও বাধাগ্রস্ত করে, যার মধ্যে জার্নালও অন্তর্ভুক্ত।
একবার হাতে কলমে চালান এবং পরীক্ষা করুন
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-সামঞ্জস্যপূর্ণ API এবং এই পোর্টে আর যা কিছু আছে
POST /v1/chat/completions, POST /v1/completions এবং POST /v1/embeddings হলো OpenAI-সামঞ্জস্যপূর্ণ রুট এবং GET /v1/models লোড করা মডেলের তথ্য প্রদান করে। GET /health হলো উপরের readiness check, GET /props সার্ভারের বর্তমান সেটিংস দেখায় এবং আপনি যদি --metrics ফ্ল্যাগ দিয়ে শুরু করেন তবে GET /metrics প্রমিথিউস (Prometheus) কাউন্টারগুলো প্রকাশ করে।
আপনি বেস URL-কে http://127.0.0.1:8080/v1-এ সেট করে এবং একটি নন-এম্পটি API কি (key) স্ট্রিং প্রদান করলে যেকোনো OpenAI SDK কাজ করবে। আপনি নিজে --api-key সেট না করা পর্যন্ত কোনো কিছুই সেই কি (key) যাচাই করে না।
অন্য কারো থ্রুপুট (throughput) দাবিকে আপনার নিজের পরিকল্পনার জন্য চূড়ান্ত সংখ্যা হিসেবে ধরবেন না। CPU ইনফারেন্সের গতি নির্ভর করে কোর সংখ্যা, মেমরি ব্যান্ডউইথ এবং আপনি যে হোস্ট শেয়ার করছেন তার প্রতিবেশীদের ওপর। তাই আপনার নিজের বক্সে প্রতি সেকেন্ডে টোকেন পরিমাপ করুন এবং সেই ফলাফলকেই সত্য হিসেবে গ্রহণ করুন। নয়েজি নেইবার থেকে স্টিল টাইম এখানে জেনারেশন স্পিড হিসেবে দেখা দেয়, যা প্রতি ঘণ্টায় পরিবর্তিত হতে পারে।
Keep it on 127.0.0.1 and put a proxy in front
--host already defaults to 127.0.0.1, so the server is unreachable from outside until you change it. Leave it alone. There is no user model, no rate limit and no useful audit log in llama-server, and the single built-in control is --api-key, which compares one string. An open inference port is free compute for whoever finds it, and the same mistake made with Ollama has the same shape: locking down a self-hosted model API applies here line for line.
Terminate TLS (transport layer security) in nginx and proxy to the loopback port.
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 is required for streaming. With buffering on, nginx holds the server-sent events (SSE) until the response finishes, so the client waits in silence and then receives the whole answer at once. proxy_read_timeout 600s covers long generations, because the default of 60 seconds turns a slow answer into 504 Gateway Time-out. Get the certificate with Certbot and Let's Encrypt on nginx.
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 এই ইউনিটের জন্য পুরো ফাইলসিস্টেমকে রিড-অনলি করে দেয়, যা ঠিক আছে কারণ সার্ভারটি শুধুমাত্র মডেলটি পড়ে। আপনি যদি চান সার্ভিসটি নিজে -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 ছাড়া, পরবর্তী রিবুটের পর সার্ভারটি আর চালু থাকবে না। আপনি যদি সার্ভারকে ঘিরে নিয়মিত কোনো কাজ করতে চান, যেমন নতুন রিলিজের জন্য প্রতি রাতে চেক করা, তবে একটি systemd সার্ভিস এবং টাইমার হলো এর সঠিক পদ্ধতি।
OOM ঘটার আগেই সিদ্ধান্ত নিন কী ঘটবে
মেমরি ব্যবহারের দুটি অংশ আছে এবং লিমিটের অধীনে তারা ভিন্নভাবে কাজ করে। মডেল ফাইলটি ডিফল্টভাবে মেমরি-ম্যাপ করা থাকে, তাই এর পেজগুলো ফাইল-ব্যাকড: কার্নেল এগুলোকে ড্রপ করতে পারে এবং প্রয়োজনে ডিস্ক থেকে পুনরায় পড়তে পারে। KV cache, যা প্রতিটি সক্রিয় কথোপকথনের জন্য সার্ভার কর্তৃক সংরক্ষিত প্রতি-টোকেন স্টেট, তা হলো অ্যানোনিমাস মেমরি। এটি ড্রপ করা যায় না, তাই এর কারণেই প্রসেসটি কিল বা বন্ধ হয়ে যায়।
এ কারণেই ইউনিটের দুটি লিমিট ভিন্ন কাজ করে। MemoryHigh=3G হলো একটি সফট লিমিট: এর উপরে গেলে কার্নেল cgroup-এর ওপর রিক্লেইম প্রেশার দেয়, ফলে ম্যাপ করা মডেল পেজগুলো ইভিক্ট হয় এবং পরবর্তী টোকেনের সময় ডিস্ক থেকে পুনরায় পড়া হয়। সার্ভিসটি কাজ চালিয়ে যায় কিন্তু ধীর হয়ে পড়ে। MemoryMax=3500M হলো একটি হার্ড লিমিট: এর উপরে গেলে প্রসেসটি কিল হয়ে যায় এবং জার্নালে তা স্পষ্টভাবে উল্লেখ থাকে।
llama-server.service: A process of this unit has been killed by the OOM killer.--ctx-size নিজে সেট করুন। ডিফল্ট হলো 0, যার অর্থ হলো যে কনটেক্সট দিয়ে মডেলটিকে ট্রেনিং দেওয়া হয়েছিল, এবং আধুনিক লং-কনটেক্সট মডেলের ক্ষেত্রে এটি শুরুতে অনেক বড় KV cache বরাদ্দ করে। ফলে একটি রিকোয়েস্ট সার্ভ করার আগেই সার্ভিসটি বন্ধ হয়ে যায়। --parallel একই খরচকে গুণিতক হারে বাড়ায়, কারণ প্রতিটি স্লট নিজস্ব কথোপকথনের স্টেট ধরে রাখে, তাই কনকারেন্সি প্রয়োজন না হওয়া পর্যন্ত এটি 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) এড়িয়ে চলুন। সোয়াপ-আউট হওয়া মডেল প্রতিটি টোকেনকে র্যান্ডম-অফসেট ডিস্ক রিডে পরিণত করে। মডেল ফাইলটিকে মেমরি-ম্যাপ করলে কম ক্ষতিতে একই ফলাফল পাওয়া যায়, কারণ কার্নেল তার প্রয়োজনীয় পেজগুলো সরাসরি ফাইল থেকে পড়ে নেয়।
যেখানে 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 বন্ধ করে দিন যাতে টোকেনগুলো তৈরি হওয়ার সাথে সাথেই ক্লায়েন্টের কাছে পৌঁছাতে পারে।
ইউনিটটি বারবার চালু হয়ে বন্ধ হয়ে যায় (flapping) এবং শেষে start request repeated too quickly দেখায়। প্রতিবার চালু হওয়ার সময় কোনো কিছু এটিকে বন্ধ করে দিচ্ছে। OOM killer লাইনটি দেখার জন্য journalctl -u llama-server চেক করুন, তারপর --ctx-size কমিয়ে দিন, --parallel কমিয়ে দিন, অথবা MemoryMax বাড়িয়ে দিন।
FAQ
আমার VPS-এ কি llama.cpp-এর server নাকি Ollama চালানো উচিত?
আপনি যখন একটি নির্দিষ্ট build ব্যবহার করতে চান, সুনির্দিষ্ট flag পাস করতে চান এবং এমন একটি মডেল ফাইল রাখতে চান যা আপনার অজান্তে পরিবর্তিত হবে না, তখন llama-server চালান। আপনি যখন মডেল ম্যানেজমেন্ট এবং এক-কমান্ডে আপগ্রেড সুবিধা চান, তখন Ollama চালান; কারণ নাম দিয়ে মডেল পুল করা, ডিস্কে একাধিক মডেল রাখা এবং অব্যবহৃত মডেল আনলোড করার মতো কাজগুলো আপনাকে অন্যথায় স্ক্রিপ্ট লিখে করতে হতো। উভয়ই OpenAI-compatible API প্রদান করে, তাই পরবর্তীতে পরিবর্তন করলেও আপনার client code-এ কোনো প্রভাব পড়বে না।
আমার কোন llama.cpp version-টি ব্যবহার করা উচিত?
যে কোনো tag যা আপনি সফলভাবে build এবং test করেছেন। llama.cpp প্রায় প্রতিটি merge-এর জন্য tag তৈরি করে এবং নামগুলো build number হিসেবে থাকে, যেমন b10488, যা 18 আগস্ট 2026 তারিখে সর্বশেষ ছিল। এখানে আলাদা কোনো stable branch নেই, তাই "current" সংস্করণ দিনে কয়েকবার পরিবর্তিত হতে পারে। --branch <tag> দিয়ে clone করুন, একটি filename-এ সেই tag যুক্ত করে binary-টি install করুন এবং একটি symlink ব্যবহার করুন, যাতে আপগ্রেড এবং রোলব্যাক করা একটি কমান্ডের কাজ হয়।
llama-server-এর জন্য কতটুকু RAM প্রয়োজন?
GGUF ফাইলের আকার থেকে শুরু করুন, তারপর এর সাথে KV cache যোগ করুন, যা --ctx-size এবং --parallel স্লটের সংখ্যার সাথে বৃদ্ধি পায়। প্রকাশিত পরিসংখ্যান আপনার নিজস্ব সেটআপের পরিমাপের বিকল্প নয়, কারণ মোট RAM-এর পরিমাণ মডেল, কোয়ান্টাইজেশন এবং আপনি যে context নির্ধারণ করেছেন তার ওপর নির্ভর করে। একটি request চলাকালীন systemctl show llama-server -p MemoryCurrent চালান এবং যে সংখ্যাটি দেখতে পান সেটি ব্যবহার করুন।
কেন /health এন্ডপয়েন্ট "Loading model" মেসেজসহ 503 error দেয়?
প্রসেসটি শুরু হয়েছে কিন্তু মডেল ফাইলটি এখনো মেমরিতে লোড হয়নি, তাই সার্ভার {"error":{"code":503,"message":"Loading model","type":"unavailable_error"}} উত্তর দেয়। প্রতিটি রিস্টার্টের পর এটি স্বাভাবিক এবং ফাইলটি পড়তে যতটুকু সময় লাগে ততক্ষণ এটি স্থায়ী হয়। এটি তখনই সমস্যা হয়ে দাঁড়ায় যখন কোনো client বা proxy সেই প্রথম 503-কে চূড়ান্ত ব্যর্থতা হিসেবে গণ্য করে। {"status": "ok" } না পাওয়া পর্যন্ত /health পোল করতে থাকুন।
আমি কি সরাসরি ইন্টারনেটে llama-server উন্মুক্ত করতে পারি?
এটিকে 0.0.0.0-এ bind করবেন না এবং পোর্ট ওপেন করবেন না। এতে কোনো অ্যাকাউন্ট সিস্টেম, রেট লিমিটিং বা অডিট করার মতো কোনো রিকোয়েস্ট লগ নেই এবং এর একমাত্র বিল্ট-ইন চেক হলো --api-key, যা একটি মাত্র স্ট্রিং তুলনা করে। ডিফল্ট 127.0.0.1 bind বজায় রাখুন, সামনে TLS সহ nginx বসান এবং --api-key সেট করুন, যাতে প্রক্সি কনফিগারেশনে একটি ভুলের কারণে মডেলটি সবার জন্য উন্মুক্ত না হয়ে যায়।