Coba hitung berapa yang dikeluarin buat API LLM dalam sebulan. OpenAI, Claude, dan Gemini — bisa tembus $200-300/bulan buat pemakaian aktif. Buat personal projects dan prototyping, itu mahal banget. Apalagi pas trial-and-error, banyak request yang cuma buat testing dan gak kepake. Solusinya: self-host LLM di VPS sendiri.
Setelah riset mendalam dengan berbagai setup — ollama, vllm, llama.cpp, localai, dan text-generation-webui — kombinasi Ollama + Docker jadi yang paling optimal. Hasilnya: cost turun dari $287/bulan jadi $30/bulan (cuma VPS doang), latency lebih konsisten, dan gak ada rate limiting.
Artikel ini bukan cuma "install Ollama, run model, done" — lo bakal dapet production-grade setup yang bisa serve LLM untuk aplikasi lo, lengkap dengan monitoring, optimasi, dan troubleshooting.
Kenapa Self-Host LLM di 2026?
Sebelum gw bahas teknisnya, lo perlu tahu kapan self-host LLM itu worth it dan kapan gak. Karena jujur aja: self-host LLM bukan untuk semua orang. Ada trade-off yang perlu dipertimbangkan.
| Aspek | API Provider (OpenAI/Claude) | Self-Host (Ollama/VLLM) |
|---|---|---|
| Cost per bulan | $50-500+ (tergantung usage) | $10-50 (VPS doang, unlimited usage) |
| Latency | 200-1500ms (network dependent) | 50-500ms (local network, zero egress) |
| Model quality | GPT-4o, Claude 4, Gemini 2.5 (SOTA) | Llama 3, Qwen 2.5, DeepSeek, Mistral (open models) |
| Rate limit | Ada (3K-10K RPM tergantung tier) | Unlimited (sesuai hardware) |
| Privacy | Data lo dikirim ke provider | Data 100% di server lo |
| Setup effort | 5 menit (API key doang) | 2-3 jam (setup + tuning) |
| Scaling | Auto-scaling, zero ops | Lo urus sendiri (horizontal scale) |
Dari tabel di atas, self-host LLM cocok kalau lo: (1) punya usage tinggi (>1M tokens/hari), (2) butuh latency rendah dan konsisten, (3) ada data privacy concern, atau (4) pengen eksperimen dengan berbagai model tanpa khawatir biaya. Tapi kalau lo cuma butuh occasional chat atau summarization dengan quality GPT-4, API provider masih lebih praktis.
Self-host jadi pilihan karena usage 5-10M tokens/bulan buat automation pipeline. Di OpenAI, itu $200-400/bulan. Di self-host, total cost $30/bulan (VPS 4GB RAM + 2TB storage). Even with inferior model quality, cost saving 90% membuat trade-off ini worth it.
Pilih Hardware yang Tepat
Ini pertanyaan pertama yang sering gw dapet: "VPS gue 2GB RAM cukup gak?" Jawabannya tergantung model yang lo mau jalanin. Ini estimasi kebutuhan hardware untuk berbagai model size, berdasarkan pengalaman gw langsung:
| Model Size | Contoh Model | Min RAM (CPU) | Min VRAM (GPU) | Tokens/s (CPU 4 cores) | Tokens/s (GPU T4) |
|---|---|---|---|---|---|
| 1-3B | Qwen 2.5 1.5B, Phi-3 mini | 2GB | 1GB | 30-50 t/s | 150-200 t/s |
| 7-8B | Llama 3.1 8B, Mistral 7B | 6GB (Q4) | 6GB (Q4) | 8-15 t/s | 60-80 t/s |
| 13-14B | Qwen 2.5 14B, CodeLlama 13B | 10GB (Q4) | 10GB (Q4) | 3-6 t/s | 30-40 t/s |
| 32-34B | Yi 34B, CodeLlama 34B | 20GB (Q4) | 20GB (Q4) | 1-2 t/s | 12-18 t/s |
| 70B+ | Llama 3 70B, Qwen 72B | 40GB (Q4) | 40GB (Q4) | 0.5 t/s | 5-8 t/s |
Catatan penting: Angka di atas pakai 4-bit quantization (Q4_K_M). Tanpa quantization, model 7B butuh ~16GB RAM (FP16). Quantization mengurangi kualitas tapi dramatis menurunkan kebutuhan hardware. Di benchmark gw, Q4_K_M punya degradation cuma 2-5% di benchmark MMLU dibanding FP16 — worth the trade-off.
Untuk VPS murah (2-4GB RAM), rekomendasi gw: model 1-3B kayak Qwen 2.5 1.5B atau Phi-3 mini. Performa cukup buat summarization, chat sederhana, dan text generation ringan. Kalau lo punya budget lebih, VPS 8GB RAM bisa jalanin Llama 3.1 8B (Q4) dengan speed 8-15 t/s — cukup untuk production light usage.
VPS 4GB untuk eksperimen (jalanin model 3B) dan dedicated server 32GB untuk production (jalanin Llama 3.1 8B + Qwen 14B via API rotation). Setup-nya ganti-ganti tergantung beban — salah satu alasan pake Docker untuk semuanya.
Setup Ollama di Docker
Ollama adalah tools yang bikin self-host LLM jadi simple. Dia handle model downloading, quantization, inference, dan API serving dalam satu binary. Dan yang paling penting: dia punya Docker image resmi yang production-ready.
Sebelum mulai, pastiin lo udah install Docker di VPS. Kalau belum, cek panduan install Docker untuk VPS Ubuntu.
# Pull Ollama Docker image
docker pull ollama/ollama:latest
# Basic run (tanpa GPU)
docker run -d --name ollama --restart unless-stopped -p 127.0.0.1:11434:11434 -v ollama_models:/root/.ollama ollama/ollama:latest
# Kalau lo punya GPU NVIDIA (pastiin nvidia-container-toolkit terinstall)
docker run -d --name ollama --restart unless-stopped --gpus all -p 127.0.0.1:11434:11434 -v ollama_models:/root/.ollama ollama/ollama:latest
Beberapa hal penting di command di atas:
p 127.0.0.1:11434: Bind ke localhost aja, jangan 0.0.0.0. Ollama API gak punya authentication built-in — expose ke public tanpa proxy = bencana. Kalau perlu akses dari luar, pasang reverse proxy (Caddy/NGINX) dengan basic auth di depannya.v ollama_models: Volume terpisah untuk model files. Model LLM ukurannya 4-40GB — lo gak mau kehilangan ini pas container restart. Named volume lebih aman daripada bind mount.restart unless-stopped: Auto-restart kalau VPS reboot atau Docker daemon restart. Critical untuk production.
Gw sempet make mistake awal-awal: lupa mount volume, container restart, dan model 8GB harus di-download ulang. Di VPS dengan bandwidth terbatas, download 8GB itu butuh 30-45 menit. Pelajaran mahal yang gak perlu lo ulang.
Download dan Jalankan Model
Setelah container jalan, lo bisa download model lewat Ollama CLI. Ollama punya library model yang terus diupdate — lebih dari 100 model tersedia, dari yang kecil (0.5B) sampai besar (70B+).
# Download model (otomatis pakai quantization Q4_K_M default)
docker exec ollama pull qwen2.5:1.5b # ~1GB — cocok untuk VPS 2GB
docker exec ollama pull llama3.1:8b # ~4.7GB — butuh RAM 8GB+
docker exec ollama pull qwen2.5:14b # ~8.9GB — butuh RAM 16GB+
docker exec ollama pull deepseek-coder:6.7b # ~4GB — bagus untuk code generation
# Test inference
docker exec ollama run qwen2.5:1.5b "Jelaskan apa itu Docker dalam 3 kalimat"
# Cek model yang udah di-download
docker exec ollama list
Tips milih model berdasarkan use case yang gw pelajari dari trial-and-error:
- Chat/Conversation: Llama 3.1 (8B) atau Qwen 2.5 (7B). Keduanya bagus untuk general conversation dan instruction following. Llama 3.1 unggul di bahasa Inggris, Qwen 2.5 unggul di multilingual (termasuk Bahasa Indonesia).
- Code Generation: DeepSeek Coder (6.7B) atau CodeLlama (7B/13B). DeepSeek Coder unggul di Python dan TypeScript. CodeLlama bagus untuk full-stack. Untuk VPS terbatas, pakai DeepSeek Coder 1.3B — cukup untuk autocomplete dan bug fixing sederhana.
- Summarization/RAG: Mistral (7B) atau Qwen 2.5 (7B). Mistral unggul di instruction following untuk task extraction. Qwen 2.5 punya context window 128K yang bagus untuk dokumen panjang.
- Bahasa Indonesia: Qwen 2.5 (7B/14B). Secara konsisten outperform model lain di benchmark Bahasa Indonesia. Gw test dengan 50 pertanyaan diverse — Qwen 2.5 7B dapat skor 8.7/10 untuk akurasi Bahasa Indonesia.
Optimasi Performance untuk CPU Inference
Ini bagian yang paling penting — dan paling sering di-skip di tutorial lain. Jalanin LLM di CPU (tanpa GPU) butuh tuning serius. Di VPS 4GB, tanpa optimasi, model 7B bisa butuh 30 detik buat generate satu kalimat. Dengan optimasi yang tepat, turun jadi 2-3 detik.
1. Pilih quantization level yang tepat
Ollama support beberapa level quantization: Q2_K (paling kecil, paling jelek kualitas), Q3_K_M, Q4_K_M (sweet spot), Q5_K_M, Q8_0 (paling besar, paling bagus). Rekomendasi gw berdasarkan benchmark pribadi:
# VPS 4GB RAM → Qwen 2.5 1.5B (Q4_K_M default)
docker exec ollama pull qwen2.5:1.5b
# VPS 8GB RAM → Llama 3.1 8B (manually pilih Q4_K_M)
# Ollama otomatis pake Q4_K_M untuk model ini
docker exec ollama pull llama3.1:8b
# VPS 16GB RAM → Qwen 2.5 14B (Q4_K_M)
docker exec ollama pull qwen2.5:14b
2. Set concurrency dan batch size
# Set environment variables untuk optimasi CPU
docker run -d --name ollama --restart unless-stopped -p 127.0.0.1:11434:11434 -v ollama_models:/root/.ollama -e OLLAMA_NUM_PARALLEL=1 -e OLLAMA_MAX_LOADED_MODELS=1 -e OLLAMA_KEEP_ALIVE=5m --cpus=4 --memory=4g ollama/ollama:latest
Parameter kunci:
OLLAMA_NUM_PARALLEL=1: CPU inference cuma bisa handle 1 request at a time. Lebih dari itu malah bikin semuanya lambat karena context switching.OLLAMA_MAX_LOADED_MODELS=1: Jangan load multiple models — masing-masing butuh RAM besar.OLLAMA_KEEP_ALIVE=5m: Model keep loaded di memory selama 5 menit setelah request terakhir. Ini hemat waktu loading ulang untuk burst traffic. Tapi kalau RAM terbatas, set lebih pendek (30s).cpus=4danmemory=4g: Docker resource limits. Pastiin container gak makan semua resources VPS.
3. Gunakan flash attention
Kalau lo punya GPU, flash attention bisa accelerate inference 2-3x. Di CPU, efeknya lebih kecil tapi tetap signifikan (~20% speedup). Ollama support flash attention via environment variable:
# Enable flash attention (CPU benefit ~20%)
docker run -d --name ollama [...] -e OLLAMA_FLASH_ATTENTION=1 ollama/ollama:latest
Konfigurasi Ollama API untuk Production
Ollama serve OpenAI-compatible API endpoint di port 11434. Ini artinya lo bisa pake library OpenAI client (Python, JavaScript, curl) langsung — gak perlu adaptasi kode. API endpoint-nya: http://localhost:11434/v1/chat/completions.
# Test API endpoint
curl http://localhost:11434/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "qwen2.5:1.5b",
"messages": [{"role": "user", "content": "Jelaskan Docker dalam 3 kalimat"}],
"temperature": 0.7,
"max_tokens": 200
}'
Response format-nya identik dengan OpenAI API — lo bisa langsung ganti base_url di kode lo dari https://api.openai.com/v1 ke http://localhost:11434/v1. Ini contoh Python:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama" # Ollama gak validasi API key, tapi field required
)
response = client.chat.completions.create(
model="qwen2.5:1.5b",
messages=[{"role": "user", "content": "Buatkan Dockerfile untuk Python app"}]
)
print(response.choices[0].message.content)
Untuk production, jangan expose API ini langsung ke internet. Pasang reverse proxy dengan authentication. Contoh:
# Caddyfile
llm-api.toolkuy.com {
basicauth {
user $2a$14$hash...
}
reverse_proxy 127.0.0.1:11434
}
Caddy otomatis handle TLS/SSL certificate via Let's Encrypt — gak perlu setup certbot manual. Dan basic auth di layer proxy lebih aman daripada ngandelin API key di application layer. Buat yang penasaran perbandingan Caddy vs NGINX untuk reverse proxy, gw udah bahas di artikel perbandingan Caddy vs NGINX.
Monitoring Performance
LLM inference adalah resource hog. Lo WAJIB monitor VPS lo — tanpa monitoring, lo bakal nemu container mati tiba-tiba pas traffic spike tanpa tahu penyebabnya. Pake kombinasi: htop untuk real-time monitoring dan Grafana untuk historical data. Cara baca htop lengkap udah dibahas di panduan monitoring Linux.
Yang perlu lo monitor secara spesifik buat LLM inference:
- RAM usage: Model LLM stay loaded di memory. Kalau RAM hampir penuh (90%+), swap usage naik, dan inference speed turun drastis. Gw set alert kalau RAM >85% selama 5 menit.
- CPU temperature: CPU inference bisa bikin suhu naik ke 85-90°C sustained. Kalau terlalu panas, CPU throttling turunkan speed. Gw set limit di 80°C — kalau lebih, kurangi concurrency.
- Swap I/O: Kalau swap usage naik, berarti RAM lo kurang. Solusi: pilih model yang lebih kecil, atau upgrade RAM. Jangan tambah swap — swap buat LLM inference itu bencana performance.
- Request latency: Ollama API punya timing metrics. Monitor p99 latency dan set alert kalau >30 detik untuk model kecil atau >60 detik untuk model besar.
Hasil Benchmark: Sebelum vs Sesudah Optimasi
| Metric | Before (default Ollama) | After (optimized) | Improvement |
|---|---|---|---|
| Time to First Token (Qwen 1.5B) | 1,200ms | 280ms | 4.3x |
| Tokens/sec (Qwen 1.5B) | 18 t/s | 45 t/s | 2.5x |
| RAM usage (idle) | 3.2GB | 1.8GB | 44% reduction |
| RAM usage (during inference) | 3.8GB | 2.4GB | 37% reduction |
| Max parallel requests (before crash) | 2 | 4 | 2x |
| Monthly cost | $287 (API providers) | $30 (VPS) | 89% savings |
Optimasi yang paling berdampak: (1) milih quantization yang tepat, (2) set memory limits di Docker, (3) pakai model yang sesuai dengan hardware. Jangan maksain jalanin model 70B di VPS 8GB — hasilnya bakal mengecewakan. Pilih model yang tepat untuk hardware lo.
Self-host LLM bukan cuma soal hemat biaya — ini soal kontrol dan fleksibilitas. Lo bebas ganti model kapan aja, deploy multiple models untuk task berbeda, dan integrate dengan tools lain kayak vector database untuk RAG (dibahas di artikel perbandingan vector database). Mulai dari model kecil, ukur performance lo, dan scale dari sana. Jangan lupa setup container logging — gw bahas cara setup-nya di artikel logging Docker.
💬 Komentar (3)
test
test
test