Maskot beruang kutub NordBastion duduk di bangku batu berukir di dalam ruang bawah tanah Nordic yang gelap dengan laptop di pangkuannya, kisi neural cyan yang bercahaya tersegel di dalam wadah kaca heksagonal di atas rak server di sampingnya, dan aliran pendek token cyan yang mengalir dari wadah itu turun ke layarnya, di balik pintu berukir rune yang tertutup
How-to · Agen AI·17 menit baca · 30 menit hands-on

Self-host LLM di VPS.
Tanpa GPU. Tanpa API key. Tidak ada prompt yang pernah keluar dari server Anda.

Enam langkah menuju LLM yang berjalan di perangkat keras Anda sendiri — perhitungan yang memprediksi token per detik sebelum Anda membeli mesinnya, model mana yang muat di 4, 8, 16, atau 32 GB, autentikasi yang tidak disediakan Ollama, dan daftar jujur soal pekerjaan yang tidak cocok. Diuji di Debian 12.

Enam langkah
  1. 01

    Ukuran

    Bandwidth, bukan core

  2. 02

    Pasang

    Ollama

  3. 03

    Ukur

    Token/detik Anda sendiri

  4. 04

    Lindungi

    TLS + token

  5. 05

    Hubungkan

    Satu base URL

  6. 06

    Batasi

    Konteks, RAM, disk

Sebelum mulai · Perhitungan

Satu pembagian sederhana memberi tahu Anda apa yang bisa dilakukan mesin ini. Lakukan sebelum Anda membeli mesinnya.

Hampir semua tulisan tentang menjalankan model bahasa secara lokal membahas kartu grafis, yang tidak banyak membantu kalau yang Anda punya adalah mesin virtual. Model mental yang berguna di sini jauh lebih sederhana daripada kesan yang diberikan wacana seputar GPU, dan bisa diringkas dalam satu kalimat: untuk menghasilkan satu token saja, model dense harus membaca seluruh bobotnya dari memori. Bukan sebagian — semuanya, setiap kali menghasilkan satu token.

Satu fakta itu saja menuntaskan seluruh persoalan performa. Kecepatan generasi tidak ditentukan oleh berapa banyak core yang Anda sewa; ia ditentukan oleh seberapa cepat mesin bisa mengalirkan model keluar dari RAM. Itu memberi Anda batas atas yang bisa dihitung di belakang amplop sebelum Anda mengeluarkan sepeser pun:

tokens per second  ≈  memory bandwidth (GB/s)  ÷  model size (GB)

Model 8B yang terkuantisasi memakan sekitar 5 GB. Pada host virtual di mana Anda secara realistis bisa mengalirkan data sekitar 20 GB/s, batas atasnya kira-kira empat token per detik, dan angka yang benar-benar Anda amati mungkin hanya separuh sampai dua pertiga dari itu. Kira-kira tiga kata per detik. Anggap itu sebagai fakta tentang beban kerjanya, bukan kekecewaan: itu lambat untuk jendela chat, tapi sepenuhnya memadai untuk pekerjaan yang mengklasifikasikan sebuah dokumen dan mengembalikan satu baris JSON.

Core tetap penting, hanya saja bukan karena alasan yang orang kira. Menambah thread membantu sampai jalur memorinya jenuh, dan pada mesin seperti ini itu terjadi lebih awal dari dugaan — sering di sekitar empat sampai delapan thread. Melewati titik itu, core ekstra hanya menganggur sementara semuanya menunggu RAM. Itulah sebabnya mesin enam belas core tidak empat kali lebih cepat daripada mesin empat core saat menghasilkan teks, dan mengapa membayar lebih untuk jumlah core dengan harapan kecepatan adalah cara paling umum untuk salah membeli tingkat layanan.

Membaca itu cepat, menulis itu lambat. Ada dua fase dalam setiap permintaan, dan keduanya berperilaku sama sekali berbeda. Memproses prompt — prefill — adalah operasi matriks yang compute-bound atas seluruh input sekaligus, dan berjalan berkali-kali lebih cepat daripada generasi. Menghasilkan jawaban adalah bagian yang memory-bound seperti dijelaskan di atas, satu token setiap kali. Jadi menyerahkan dokumen dua ribu kata ke model dan meminta tiga kalimat sebagai balasan adalah beban kerja yang nyaman, sementara memintanya menulis esai dua ribu kata bukan. Rancang prompt Anda mengikuti asimetri itu, dan mesin CPU akan terasa jauh lebih baik daripada yang disarankan oleh angka token rate-nya.

Tingkatan Memori Model terbesar yang masih nyaman dipakai Orde besar Untuk apa
Sentinel · $3.904 GB3B pada Q4 (~2 GB)satu kalimat per detikKlasifikasi, tagging, routing, embedding
Garrison · $7.908 GB8B pada Q4 (~5 GB)beberapa kata per detikDefault-nya. Ringkasan, ekstraksi JSON, jawaban RAG
Ravelin · $16.9016 GB14B pada Q4 (~9 GB)kira-kira separuh dari di atasPenalaran lebih berat, konteks panjang, pipeline batch
Bulwark · $32.9032 GB32B pada Q4 (~20 GB)kurang dari satu kata per detikKualitas di atas kecepatan. Hanya untuk pekerjaan asinkron
Citadel · $62.9064 GB70B pada Q4 (~40 GB)beberapa menit per jawabanMuat. Tidak interaktif. Pekerjaan semalaman

Ukuran model di sini adalah kuantisasi Q4_K_M yang biasa, yang menukar sedikit kualitas — yang umumnya tidak terasa — dengan memori kurang dari separuhnya. Kolom kecepatan adalah orde besar yang diturunkan dari perhitungan di atas, bukan hasil benchmark — inti dari langkah 03 adalah Anda mengukur mesin Anda sendiri, bukan memercayai tabel begitu saja, termasuk tabel ini.

Sebelum mulai · Muat

Apa yang benar-benar muat di CPU. Dan apa yang tidak, dikatakan terus terang.

Versi jujur dari bagian ini lebih berharga daripada versi yang penuh semangat, karena cara tercepat untuk meninggalkan model self-hosted adalah mengarahkannya ke satu pekerjaan yang paling buruk dikerjakannya, lalu menyimpulkan bahwa seluruh idenya konyol.

Muat dengan nyaman. Apa pun yang output-nya singkat dan nilainya terletak pada penilaian, bukan pada prosa. Mengklasifikasikan sebuah pesan ke salah satu dari beberapa kategori. Memutuskan apakah sebuah tiket dukungan bersifat mendesak. Mengekstraksi lima field dari sebuah faktur menjadi JSON. Meringkas satu thread menjadi tiga kalimat. Memberi tag pada sebuah dokumen. Menulis ulang deskripsi produk. Menerjemahkan string pendek. Mendeteksi apakah dua catatan menggambarkan orang yang sama. Menyamarkan nama dari sebuah paragraf sebelum dikirim ke tempat lain. Semua itu mengonsumsi input yang panjang dan menghasilkan output yang pendek — persis asimetri yang ditangani CPU dengan baik.

Muat, dengan sedikit kesabaran. Pekerjaan yang tidak ditunggu oleh manusia. Batch semalaman, queue worker, proses malam hari atas dokumen sepanjang hari, laporan terjadwal. Jika tidak ada yang menunggu jawabannya, token rate yang tidak tertahankan di jendela chat jadi sama sekali tidak penting — pekerjaan yang berjalan enam menit pukul tiga pagi cuma sekadar pekerjaan yang selesai dijalankan.

Tidak muat. Asisten interaktif yang benar-benar nyaman dipakai orang: pada kecepatan seperti ini kursornya merayap dan pengalamannya lebih buruk daripada tidak punya asisten sama sekali. Generasi teks panjang — tuliskan dua ribu kata untuk saya — di mana seluruh output-nya adalah bagian yang lambat. Agen coding yang berulang kali menelusuri repositori besar, di mana konteks maupun standar kualitasnya melampaui kemampuan model kecil. Apa pun yang butuh konteks seratus ribu token, di mana cache-nya saja sudah melebihi kapasitas mesin. Dan model gambar atau video, yang merupakan disiplin yang sama sekali berbeda dan memang betul-betul butuh GPU.

Jika beban kerja Anda masuk ke kelompok terakhir itu, jawaban yang masuk akal bukan membeli mesin CPU yang lebih besar — melainkan pendekatan hybrid. Pertahankan model lokal untuk sebagian besar panggilan, dan arahkan sebagian kecil yang butuh penalaran frontier ke API hosted — persis bentuk yang dijelaskan panduan menjalankan agen AI 24/7 untuk sisi runtime-nya. Panduan itu sengaja tidak membahas modelnya sendiri. Panduan ini adalah separuh yang hilang itu.

Langkah 01 · Ukuran

Beli sesuai model, bukan sesuai jumlah core. Dan sisakan ruang lebih.

Bekerja mundur dari pekerjaannya. Tentukan apa yang harus dilakukan model itu, pilih ukuran terkecil yang bisa melakukannya, cari tahu berapa besar ukuran itu pada Q4_K_M, lalu tambahkan overhead-nya:

RAM needed  =  model file  +  KV cache  +  ~2 GB for the system

  3B  Q4_K_M  ≈  2.0 GB        KV cache at 8k context   ≈  0.5–1 GB
  8B  Q4_K_M  ≈  4.9 GB        KV cache at 32k context  ≈  2–4 GB
 14B  Q4_K_M  ≈  9.0 GB
 32B  Q4_K_M  ≈ 20.0 GB
 70B  Q4_K_M  ≈ 40.0 GB

Cache key-value adalah overhead yang sering dilupakan orang. Setiap token yang sudah ada dalam percakapan disimpan di memori supaya model tidak perlu menghitungnya ulang, dan penyimpanan itu membesar seiring konteks yang Anda izinkan. Menggandakan konteks kira-kira menggandakan ukurannya juga. Model yang muat dengan konteks 4k bisa gagal muat pada 32k, dan kegagalannya muncul pada permintaan kesepuluh, bukan yang pertama — sehingga terlihat seperti misteri, padahal sebenarnya cuma kesalahan perhitungan.

Tidak ada degradasi yang halus di sini. Ketika totalnya melebihi RAM, kernel tidak melambat dengan sopan: ia mulai melakukan paging bobot model bolak-balik ke disk, pada setiap token. Generasi yang seharusnya empat detik jadi empat menit, load average naik ke puluhan, dan semua hal lain di mesin itu — database, web server, sesi SSH Anda — ikut menderita. Muat di memori bukan sebuah optimisasi. Itu adalah syarat mutlak.

Di panel: Order → VPS → tingkat yang ditunjukkan hasil perhitungan Anda, image Debian 12. Tidak perlu alamat email untuk membuka akun, tidak ada dokumen identitas yang diminta di tahap mana pun, dan tagihannya diselesaikan dalam Monero, Bitcoin, Lightning, atau aset lain yang didukung — yang justru lebih penting di sini dibanding di web server biasa, untuk alasan-alasan yang dijelaskan panduan utama hosting VPS anonim, dan bab privasi di bawah ini menerapkannya secara khusus pada prompt.

Langkah 02 · Pasang

Satu perintah, satu layanan. Terikat ke loopback, dan dibiarkan di sana.

Perkeras mesinnya dulu — SSH khusus kunci, firewall yang tidak mengizinkan apa pun yang tidak Anda minta, pembaruan keamanan otomatis tanpa pengawasan. Checklist jam pertama memakan waktu sekitar satu jam, dan ini adalah mesin yang sebentar lagi akan menyimpan setiap pertanyaan yang Anda ajukan padanya.

Lalu instal runner-nya. Ollama adalah llama.cpp yang dibungkus model registry, REST API, dan unit systemd, dan installer satu baris ini menyiapkan ketiganya sekaligus:

apt update && apt install -y curl
curl -fsSL https://ollama.com/install.sh | sh

systemctl status ollama --no-pager
ss -ltnp | grep 11434
# → 127.0.0.1:11434 — loopback only. Leave it that way.

Baris terakhir itu layak dibaca dua kali. Secara default layanannya mendengarkan di interface loopback, dan itu memang sudah benar — kesalahan paling umum yang terjadi sepuluh menit berikutnya adalah mengatur OLLAMA_HOST ke 0.0.0.0 karena ada sesuatu di mesin lain yang tidak bisa menjangkaunya. Langkah 04 adalah cara menjangkaunya dengan benar; tidak ada versi di mana port 11434 menghadap langsung ke internet.

Ada dua pengaturan yang layak Anda tetapkan sekarang, bukan ditemukan belakangan. Secara default model disimpan di /usr/share/ollama dan ukurannya besar, jadi arahkan itu ke mana pun Anda punya ruang. Dan secara default model tetap resident di RAM selama lima menit setelah permintaan terakhir, yang cukup longgar untuk mesin yang juga mengerjakan hal lain:

systemctl edit ollama
[Service]
Environment="OLLAMA_MODELS=/var/lib/ollama/models"
Environment="OLLAMA_KEEP_ALIVE=30m"
Environment="OLLAMA_NUM_PARALLEL=1"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
systemctl daemon-reload && systemctl restart ollama

Permintaan paralel dan banyak model yang termuat sekaligus sama-sama melipatgandakan pemakaian memori, dan pada mesin yang ukurannya pas untuk satu model saja, tidak ada gigabyte tersisa untuk salinan kedua. Menyerialkan antreannya bukan keterbatasan pada perangkat keras ini; itu adalah satu-satunya konfigurasi yang tidak akan ambruk.

Langkah 03 · Ukur

Dapatkan angka Anda sendiri. Benchmark orang lain tidak bicara soal mesin Anda.

Tarik satu model. Model instruct kelas 8B mana pun yang tersedia saat ini sudah cukup untuk pengukuran pertama — ukurannya cukup mirip sehingga waktunya lebih bicara soal perangkat keras Anda daripada soal modelnya:

ollama pull llama3.1:8b        # ~4.9 GB at Q4_K_M
ollama list
ollama ps                      # nothing resident yet

Sekarang jalankan satu generasi dengan timings diaktifkan. Angka yang penting adalah eval rate — token yang dihasilkan per detik, setelah prompt-nya selesai dibaca:

ollama run llama3.1:8b --verbose "Reply with exactly one sentence about the Baltic Sea."
total duration:        14.2s
load duration:          3.1s
prompt eval count:        24 token(s)
prompt eval rate:      92.11 tokens/s      ← reading: fast
eval count:               38 token(s)
eval rate:              3.42 tokens/s      ← writing: the real ceiling

Dua baris, dua dunia yang berbeda. Membaca berjalan di sekitar sembilan puluhan token per detik; menulis di tiga setengah. Rasio itu adalah asimetri dari bab perhitungan tadi, terukur di perangkat keras Anda sendiri, dan itu adalah fakta paling berguna yang akan Anda kumpulkan hari ini. Artinya: beri mesin ini input yang panjang, dan minta output yang pendek.

Pengukuran yang sama lewat API, yang sebenarnya lebih Anda butuhkan kalau Anda berniat men-scripting perbandingan antara dua atau tiga ukuran model:

apt install -y jq

curl -s http://127.0.0.1:11434/api/generate -d '{
  "model":  "llama3.1:8b",
  "prompt": "List three Nordic capitals.",
  "stream": false
}' | jq '{
  tokens: .eval_count,
  seconds: (.eval_duration / 1000000000),
  rate: (.eval_count / (.eval_duration / 1000000000))
}'

Ukur ukuran di bawahnya dan di atasnya, lalu berhenti. Tarik model 3B dan 14B, jalankan prompt yang sama pada keduanya, dan catat ketiga kecepatannya. Sekarang Anda tahu persis berapa harga pertukaran itu di mesin ini — biasanya mendekati dua kali lipat di masing-masing arah — dan Anda bisa memilih berdasarkan jenis pekerjaan, bukan berdasarkan opini. Lalu hapus model yang tidak Anda pakai lagi, karena masing-masing memakan beberapa gigabyte.

Satu catatan penting untuk run pertama model apa pun: load duration pada output itu adalah waktu yang dihabiskan untuk membaca bobotnya dari disk ke RAM. Waktu itu hanya «dibayar» ketika modelnya belum resident, dan itulah yang dikendalikan oleh OLLAMA_KEEP_ALIVE. Jangan masukkan angka itu saat membandingkan kecepatan, dan jangan khawatir karenanya — di NVMe hanya hitungan detik, dan hanya terjadi sekali.

Langkah 04 · Lindungi

Ollama tidak punya autentikasi. Sama sekali tidak ada. Bukan lemah — memang tidak ada.

Ini adalah bagian dari panduan yang mencegah sesuatu yang buruk terjadi, jadi ini disampaikan tanpa basa-basi: API Ollama tidak punya kata sandi, tidak punya token, tidak punya model pengguna, dan tidak punya sistem izin. Apa pun yang bisa membuka koneksi TCP ke port 11434 bisa menghasilkan teks di CPU Anda, mendaftar model yang sudah Anda tarik, menarik model baru, dan menghapus yang sedang Anda pakai. Tidak ada pengaturan yang bisa diaktifkan, karena memang tidak ada mekanismenya untuk diaktifkan.

Port 11434 dipindai terus-menerus, dengan alasan yang jelas: model runner yang terbuka adalah komputasi gratis milik orang lain. Gejalanya bukan sebuah alert. Gejalanya adalah mesin yang terasa lambat selama dua minggu dan grafik bandwidth yang tidak cocok dengan apa pun yang Anda lakukan. Jaga layanan itu tetap di loopback, dan pasang sesuatu di depannya yang menanyakan siapa yang memanggil.

Jika tidak ada yang di luar mesin ini butuh model tersebut, berhenti di sini — Anda sudah selesai. Loopback ditambah firewall adalah jawaban yang lengkap, dan agen, stack otomasi, atau aplikasi web yang berjalan di VPS yang sama bisa menjangkau model itu lewat 127.0.0.1 tanpa perlu apa pun di bawah ini. Lanjutkan hanya jika ada sesuatu di mesin lain yang harus memanggilnya.

Proxy-nya, dan token-nya. Buat token acak yang panjang, arahkan A record ke mesinnya, dan biarkan Caddy yang mengurus sertifikat sekaligus pintu masuknya:

openssl rand -hex 32      # → the bearer token, store it in a password manager
apt install -y caddy

/etc/caddy/Caddyfile

llm.example.com {
    @unauthorised not header Authorization "Bearer PASTE_THE_HEX_TOKEN_HERE"
    respond @unauthorised "unauthorised" 401

    reverse_proxy 127.0.0.1:11434 {
        # Generation is slow by nature — do not let the proxy give up first.
        transport http {
            read_timeout 10m
        }
    }
}
systemctl reload caddy
ufw allow 80,443/tcp
ufw status                # 11434 must appear nowhere

Ada keanggunan tersendiri dalam memilih token bearer alih-alih basic authentication. Ollama mengekspos API yang kompatibel dengan OpenAI, setiap klien OpenAI mengirim key-nya persis lewat header itu, sehingga token yang baru saja Anda buat langsung menjadi API key yang sudah dikenal aplikasi Anda cara membawanya. Tidak perlu header khusus, dan merotasi akses cukup satu baris di Caddyfile dan satu variabel lingkungan di sisi pemanggil.

Verifikasi dari mesin yang bukan server itu sendiri. Panggilan pertama seharusnya ditolak, dan yang kedua seharusnya menjawab:

curl -s -o /dev/null -w '%{http_code}\n' https://llm.example.com/api/tags
# → 401

curl -s https://llm.example.com/api/tags -H "Authorization: Bearer THE_TOKEN" | jq '.models[].name'
# → the list of models you pulled

Jika model itu akan dipanggil oleh agen, bukan oleh Anda sendiri, urusan eksposurnya butuh pembahasan yang lebih lengkap di panduan hosting server MCP jarak jauh — penalaran yang sama soal TLS, token, dan apa yang seharusnya bisa dijangkau dari mana, diterapkan pada layanan yang menyerahkan tools alih-alih token.

Langkah 05 · Sambungkan

Satu base URL, dan semuanya sudah bisa memakainya. Anda hanya perlu mengganti satu string.

Ollama menyediakan permukaan yang kompatibel dengan OpenAI di /v1, berdampingan dengan API-nya sendiri. Itulah keseluruhan cerita integrasinya: apa pun yang dibuat untuk OpenAI — SDK resmi, wrapper framework, node otomasi — cukup bekerja dengan mengganti base URL dan key-nya, tidak ada yang lain yang perlu diubah.

curl -s https://llm.example.com/v1/chat/completions \
  -H "Authorization: Bearer THE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.1:8b",
    "messages": [{"role":"user","content":"Reply with the word OK."}]
  }' | jq -r '.choices[0].message.content'

Dari Python, satu-satunya baris yang berbeda dari setup hosted hanyalah dua baris di bagian atas:

from openai import OpenAI

client = OpenAI(
    base_url="https://llm.example.com/v1",
    api_key="THE_TOKEN",
)

r = client.chat.completions.create(
    model="llama3.1:8b",
    messages=[{"role": "user", "content": "Classify: 'the invoice is overdue'"}],
)
print(r.choices[0].message.content)

Minta JSON, dapat JSON. Fitur paling berguna untuk otomasi adalah constrained output. Ollama bisa memaksa jawabannya menjadi JSON yang valid, alih-alih berharap modelnya berperilaku baik — ini mengubah model kecil dari narator yang tidak bisa diandalkan menjadi parser yang bisa dipercaya, dan itulah bedanya antara workflow yang berjalan tanpa pengawasan dan yang rusak setiap item keempat puluh:

curl -s http://127.0.0.1:11434/api/generate -d '{
  "model":  "llama3.1:8b",
  "prompt": "Extract the total and the currency: Invoice 4021, 1 249,90 EUR due 30 days.",
  "format": "json",
  "stream": false
}' | jq -r .response
# → {"total": 1249.90, "currency": "EUR"}

Hal serupa berlaku pada stack otomasi: n8n menyediakan node Ollama khusus, dan node OpenAI-nya menerima base URL kustom, jadi workflow yang sudah ada bisa berpindah ke inferensi lokal hanya dengan mengubah satu kredensial. Panduan self-hosting n8n membahas engine otomasinya sendiri; jalankan keduanya di mesin terpisah kalau bisa, sebab engine yang idle di 700 MB dan model yang butuh lima gigabyte adalah tetangga yang tidak akur di mesin delapan gigabyte.

Dan endpoint embedding, tempat mesin ini benar-benar membuktikan kegunaannya. Model embedding berukuran dua orde besar lebih kecil daripada model generasi, dan mereka hanya melakukan satu pass per chunk tanpa perlu menghasilkan apa pun, sehingga CPU menanganinya dengan kecepatan yang terasa instan:

ollama pull nomic-embed-text      # ~275 MB

curl -s http://127.0.0.1:11434/api/embed -d '{
  "model": "nomic-embed-text",
  "input": ["the first chunk of a document", "the second chunk"]
}' | jq '.embeddings | length'
Langkah 06 · Batasi

Model runner yang tak dibatasi akan memakai semua yang Anda punya. Beri ia batas.

Batasi konteksnya. Panjang konteks adalah kenop utama pemakaian memori, dan nilai default-nya lebih longgar daripada yang diinginkan mesin kecil. Atur secara global sesuai kebutuhan prompt terpanjang yang realistis — sebagian besar pekerjaan klasifikasi dan ekstraksi nyaman dilakukan dalam empat ribu token — dan naikkan per permintaan hanya pada panggilan langka yang benar-benar butuh lebih:

Environment="OLLAMA_CONTEXT_LENGTH=4096"
curl -s http://127.0.0.1:11434/api/generate -d '{
  "model": "llama3.1:8b",
  "prompt": "…a long document…",
  "options": { "num_ctx": 16384 },
  "stream": false
}'

Tentukan berapa lama model tetap berada di memori. Model yang resident bisa langsung dipanggil, tapi menyandera beberapa gigabyte memori. Di mesin yang didedikasikan untuk inferensi, biarkan tetap termuat selamanya; di mesin bersama, biarkan ia lepas setelah beberapa saat. Nilai ini juga bisa diatur per permintaan, jadi batch malam hari bisa mengunci model itu selama proses berjalan dan melepaskannya di akhir:

OLLAMA_KEEP_ALIVE=-1     # resident until the service restarts
OLLAMA_KEEP_ALIVE=30m    # a sensible default on a shared box
OLLAMA_KEEP_ALIVE=0      # unload immediately after each request

ollama ps                # what is resident right now, and how much it holds

Serialkan antreannya. Dua permintaan yang berjalan bersamaan ke satu model tidak jadi dua kali lebih cepat; keduanya berebut jalur memori yang sama-sama sudah jenuh dan masing-masing malah jadi lebih lambat, dan jika Ollama memutuskan memuat salinan kedua untuk melayani keduanya, mesinnya kehabisan RAM. Pada kelas perangkat keras ini, satu permintaan pada satu waktu dengan antrean di depannya adalah konfigurasi yang paling cepat sekaligus satu-satunya yang aman — itulah sebabnya OLLAMA_NUM_PARALLEL dan OLLAMA_MAX_LOADED_MODELS dikunci ke angka satu sejak langkah 02.

Awasi disk-nya. Membandingkan empat model berarti menyisakan empat model, dan pada lima gigabyte masing-masing, itu adalah disk yang perlahan penuh tanpa ada yang mengeluh. Jadikan pembersihan sebagai bagian dari proses perbandingan, bukan tugas untuk nanti:

ollama list
du -sh /var/lib/ollama/models
ollama rm mistral:7b qwen2.5:14b

Terakhir, cadangkan apa yang tidak bisa direproduksi. Bobot model bukan termasuk itu — cukup pull ulang untuk mendapatkannya kembali. Yang layak masuk repositori adalah konfigurasi, Caddyfile, token, prompt yang Anda sempurnakan selama tiga minggu, dan jika Anda membuatnya, indeks vektor di balik retrieval Anda. Panduan backup terenkripsi membahas mekanismenya; daftar yang perlu disertakan untuk mesin ini pendek dan layak dituliskan.

Bagian baiknya · Retrieval

Di mana CPU justru mematahkan argumen itu. Embedding tidak lambat.

Semua yang di atas membahas generasi, bagian yang memang lambat dikerjakan CPU. Retrieval adalah separuh lainnya dari sebagian besar sistem yang berguna, dan ia membalikkan gambarannya sepenuhnya — itulah sebabnya tingkat termurah di halaman ini bisa melakukan sesuatu yang sungguh berharga, bahkan jika Anda tidak pernah menghasilkan satu token pun di sana.

Model embedding mengubah sepotong teks menjadi vektor. Ukurannya diukur dalam ratusan megabyte, bukan gigabyte, ia hanya melakukan satu forward pass per chunk, dan tidak ada loop token-demi-token yang terikat oleh bandwidth memori. Di mesin yang sama tempat model 8B menulis tiga kata per detik, model embedding akan melahap satu perpustakaan dokumen dengan kecepatan yang terasa seperti menyalin file.

Bentuknya seperti ini. Pecah dokumen Anda menjadi chunk berisi beberapa ratus kata. Embed setiap chunk sekali, lalu simpan vektornya. Saat ada pertanyaan, embed pertanyaannya, cari beberapa chunk terdekat, lalu serahkan itu ke model bersama pertanyaannya. Penyimpanannya tidak perlu yang eksotis: database SQLite dengan ekstensi vektor sudah cukup untuk puluhan ribu chunk di satu VPS, dan PostgreSQL dengan pgvector menutupi jauh lebih dari itu. Database vektor khusus adalah hal yang wajar diinginkan nanti, tapi dependensi yang tidak perlu di hari pertama.

Kenapa ini lebih penting daripada kecepatan. Lihat apa yang disentuh masing-masing tahap. Tahap generasi hanya melihat satu pertanyaan dan beberapa paragraf. Tahap embedding melihat <em>setiap dokumen yang Anda miliki</em> — seluruh arsip, setiap kontrak, setiap catatan, setiap pesan, dilewatkan ke model satu chunk demi satu chunk. Jika tahap itu dijalankan lewat endpoint hosted, seluruh korpus Anda telah dikirim ke pihak ketiga hanya untuk diindeks. Jika dijalankan di mesin Anda sendiri, tak satu pun dari itu berpindah.

Itu menghasilkan pendekatan hybrid yang sungguh baik bagi siapa pun yang tidak mau melepas kualitas frontier: mengindeks secara lokal, retrieve secara lokal, dan kirim hanya pertanyaan beserta tiga chunk hasil retrieval ke model hosted saat jawabannya harus benar-benar bagus. Korpusnya tetap di rumah; hanya sepotong tipis yang berpindah, dan hanya saat dibutuhkan.

Dua tetangga di situs ini membuat pola ini nyata. SearXNG self-hosted memberi lapisan retrieval front-end pribadi untuk web terbuka, bukan korpus; document store self-hosted memberinya korpus. Keduanya, ditambah modelnya, muat di tingkat yang biayanya per bulan lebih murah daripada satu seat hosted saja.

Lapisan di bawah model

Prompt-nya adalah bagian yang sensitif. Bukan jawabannya — pertanyaannya.

Orang biasanya berpikir soal privasi model seolah-olah risikonya ada pada output. Padahal tidak. Output-nya adalah teks generik; seribu orang lain bisa mendapatkan sesuatu yang mirip. Artefak yang sebenarnya membongkar rahasia adalah input-nya — dan setahun input adalah potret yang luar biasa lengkap tentang sebuah organisasi.

Pikirkan apa yang sebenarnya tersimpan dalam log permintaan. Kontrak yang Anda tempelkan untuk diringkas. Email pelanggan yang Anda minta diklasifikasikan, lengkap dengan identitas pelanggannya. Surat medis, angka gaji, surat pengunduran diri yang sedang Anda susun, kode dari repositori yang tidak publik. Lalu metadata di sekelilingnya: pertanyaan apa saja, dalam urutan apa, jam berapa, dari alamat mana, sepanjang berapa bulan. Tidak ada orang yang menandatangani dokumen bertuliskan «ini strategi kami» — tapi urutan pertanyaan itulah dokumennya, tersusun dengan jujur, oleh Anda sendiri, satu panggilan pada satu waktu.

Lapisan satu — apa yang disimpan endpoint-nya. Penyedia layanan yang serius menerbitkan kebijakan yang serius, dan yang bagus benar-benar tidak melatih model dari trafik API bisnis. Tapi itu bukan janji yang sama dengan tidak menyimpannya. Permintaan biasanya disimpan untuk jangka waktu tertentu demi pemantauan penyalahgunaan, bisa diakses staf dalam kondisi tertentu, dan bisa diminta lewat proses hukum — yang justru cara yang tepat untuk menjalankan platform besar, dan justru tempat yang salah untuk teks yang tidak akan Anda kirim lewat email ke orang asing. Model di mesin Anda sendiri tidak punya log semacam itu, kecuali Anda yang membuatnya.

Lapisan dua — identitas yang dikaitkan dengan log itu. Retensi saja hanya separuh dari eksposurnya. Separuh lainnya adalah kunci yang menghubungkannya: sebuah akun, nama perusahaan, alamat penagihan, sebuah kartu. Koneksi itulah yang mengubah «seseorang bertanya soal mengakuisisi kompetitor» menjadi «perusahaan ini yang bertanya, pada hari Selasa itu». Menghilangkan model dari persamaan menghilangkan retensinya; menghilangkan identitas dari mesinnya menghilangkan koneksinya. VPS yang dibuka tanpa alamat email atau dokumen identitas, di yurisdiksi Nordic, dibayar dengan Monero, adalah separuh kedua dari langkah yang sama.

Lapisan tiga — log yang Anda tulis sendiri. Self-hosting memindahkan risikonya, bukan menghapusnya, dan ada baiknya jelas soal ke mana risiko itu berpindah. Aplikasi Anda mungkin mencatat prompt-nya sendiri. Reverse proxy Anda mencatat setiap baris permintaan. Sesi debugging dua bulan lalu meninggalkan output verbose di journal. Modelnya sendiri tidak menyimpan apa pun di antara panggilan, tapi perangkat di sekelilingnya bisa menyimpan segalanya — jadi putuskan dengan sengaja apa yang dicatat, tetapkan masa retensinya, dan pegang log itu pada standar yang tidak mau Anda terima dari pihak lain.

Semua itu tidak membuat model lokal otomatis menjadi jaminan privasi dengan sendirinya. Yang terjadi adalah, inilah satu-satunya arsitektur di mana jaminan itu ada di tangan Anda untuk diberikan: teksnya tetap berada di perangkat keras yang Anda sewa, di bawah yurisdiksi yang Anda pilih, di balik token yang Anda terbitkan sendiri, dan tidak bertanggung jawab kepada siapa pun selain itu.

Catatan lapangan · Enam jebakan

Enam cara hal ini mengecewakan orang. Lima di antaranya bisa dihindari.

Jebakan 01 · Memori

Mesinnya macet total, bukannya sekadar melambat

Model beserta cache konteksnya melebihi RAM, dan kernel mulai melakukan paging bobot pada setiap token. Muat di memori atau turunkan satu ukuran — tidak ada pengaturan di tengah-tengah.

Jebakan 02 · Eksposur

Orang lain sudah memakai CPU Anda

OLLAMA_HOST diatur ke 0.0.0.0 supaya sebuah klien bisa berfungsi. API-nya sama sekali tidak punya autentikasi, dan 11434 rutin dipindai. Loopback ditambah proxy yang memeriksa token.

Jebakan 03 · Ekspektasi

Berfungsi, tapi mengetiknya seperti mesin faks

Model 32B dipilih untuk asisten interaktif. Sesuaikan ukuran dengan jenis interaksinya: interaktif menginginkan yang kecil, kualitas menginginkan yang asinkron.

Jebakan 04 · Konteks

Permintaan pertama lancar, yang kesepuluh merayap

Percakapan yang makin panjang membuat cache-nya makin besar, dan seluruh riwayatnya dibaca ulang setiap giliran. Batasi konteksnya, dan mulai percakapan baru alih-alih terus menambahkannya tanpa henti.

Jebakan 05 · Residensi

Lima gigabyte lenyap dan tidak ada yang berjalan

Modelnya memang sengaja dirancang tetap resident setelah panggilan terakhir. Atur OLLAMA_KEEP_ALIVE sesuai kebutuhan mesin Anda, dan periksa ollama ps sebelum menyalahkan hal lain.

Jebakan 06 · Disk

Disk penuh dengan model yang cuma pernah Anda bandingkan sekali

Empat kandidat model, masing-masing lima gigabyte, tak satu pun dihapus. Jadikan ollama rm bagian dari proses perbandingan, dan periksa direktori model saat peringatan disk muncul.

FAQ · Model lokal

Pertanyaan, dijawab.

Sepuluh pertanyaan yang menentukan apakah model CPU-only adalah alat yang tepat untuk pekerjaan yang Anda pikirkan.

Apakah benar-benar bisa menjalankan LLM tanpa GPU?

Ya, dengan satu catatan jujur soal kecepatan. Model yang terkuantisasi berjalan dengan sangat baik di CPU server biasa — bobotnya berada di RAM, perhitungannya sepenuhnya terjangkau, dan tidak ada bagian dari prosesnya yang butuh kartu grafis. Yang dibeli lewat GPU adalah bandwidth memori, dan bandwidth itulah yang menentukan kecepatan generasi. Jadi mesin CPU-only akan menjawab, dengan benar dan lengkap, pada kecepatan antara beberapa kata sampai beberapa lusin kata per detik, tergantung modelnya. Itu lambat untuk jendela chat, dan sepenuhnya memadai untuk pekerjaan yang sebenarnya diotomasi kebanyakan orang: mengklasifikasikan pesan, menarik JSON terstruktur dari sebuah dokumen, meringkas satu halaman, meng-embed teks untuk pencarian, menulis ulang satu paragraf. Pertanyaannya bukan pernah «bisa atau tidak» — melainkan «pada kecepatan berapa, dan apakah kecepatan itu penting untuk pekerjaan ini».

Berapa token per detik yang bisa saya harapkan?

Lakukan sendiri perhitungannya, jangan percaya begitu saja pada benchmark siapa pun, termasuk punya kami. Model dense membaca seluruh bobotnya dari memori untuk menghasilkan satu token, jadi batas atasnya kira-kira bandwidth memori dibagi ukuran model. Model 3B yang terkuantisasi sampai sekitar 2 GB, pada mesin dengan bandwidth efektif 20 GB/s, punya batas atas mendekati 10 token per detik; model 7B pada 4,4 GB mendekati 4,5; model 32B pada 20 GB di bawah 1. Angka sesungguhnya jatuh di bawah batas atas itu — sebut saja 50 sampai 70 persen — dan bervariasi tergantung host, tetangga di mesin yang sama, dan jumlah thread. Pemrosesan prompt adalah soal yang sama sekali berbeda: sifatnya compute-bound, berjalan berkali-kali lebih cepat, dan itulah sebabnya meringkas dokumen panjang terasa nyaman sementara mengobrol dengan model besar tidak.

Model apa yang sebaiknya jadi titik awal di RAM 8 GB?

Model instruct kelas 8B pada Q4_K_M, yang besarnya sekitar 4,5 sampai 5 GB dan menyisakan ruang untuk sistem operasi serta cache konteks. Ukuran itu adalah titik seimbang saat ini: cukup andal mengikuti instruksi, menghasilkan JSON yang valid saat diminta, meringkas, mengklasifikasikan, dan menulis ulang; cukup kecil untuk tetap responsif. Di bawahnya, model 3B sungguh berguna untuk klasifikasi, tagging, dan routing, dan kira-kira dua kali lebih cepat. Di atasnya, model 14B jelas lebih baik dalam penalaran multi-langkah dan kira-kira separuh kecepatannya — pertukaran yang wajar untuk pekerjaan batch, tapi buruk untuk apa pun yang interaktif. Mulai dari 8B, ukur, lalu bergerak ke arah mana pun yang ditunjukkan hasil pengukuran.

Berapa banyak RAM yang sebenarnya dibutuhkan sebuah model?

Ukuran file hasil kuantisasi, ditambah cache konteks, ditambah ruang untuk sistemnya — dan totalnya harus muat, sebab mode kegagalannya bukan sekadar melambat, melainkan ambruk total. Ketika modelnya tidak muat, kernel mulai men-swap bobot model ke disk, dan generasi yang seharusnya memakan waktu empat detik jadi empat menit, sementara load average naik ke puluhan. Sebagai aturan praktis pada Q4_K_M: model 3B sekitar 2 GB, model 8B sekitar 5 GB, model 14B sekitar 9 GB, model 32B sekitar 20 GB, model 70B sekitar 40 GB. Tambahkan dua gigabyte untuk Debian dan layanannya, dan satu sampai empat gigabyte lagi untuk cache key-value tergantung seberapa panjang konteks yang Anda izinkan. Lalu beli tingkat yang satu tangga di atas jawaban itu, bukan tingkat yang persis pas dengannya.

Ollama atau llama.cpp?

Ollama adalah llama.cpp, dibungkus dengan model registry, REST API, dan layanan systemd. Pakai Ollama kecuali Anda punya alasan khusus untuk tidak memakainya: satu perintah instalasi, ollama pull alih-alih memburu file GGUF sendiri, endpoint yang kompatibel dengan OpenAI, dan default yang masuk akal untuk jumlah thread serta memori. Gunakan llama.cpp langsung kalau Anda butuh flag yang tidak diekspos Ollama, ingin mengunci build tertentu supaya hasilnya bisa direproduksi persis sama, atau kalau Anda menjalankan satu model dengan satu konfigurasi selamanya dan lebih suka tidak ada daemon yang mengurus apa pun. Keduanya menjalankan bobot yang sama dengan kecepatan yang sama; bedanya sepenuhnya ada di sisi operasional.

Apakah model self-hosted sebagus model hosted besar?

Tidak, dan berpura-pura sebaliknya cuma buang-buang waktu Anda. Model frontier di balik sebuah API lebih besar daripada apa pun yang muat di mesin virtual, dan ia akan lebih unggul dalam penalaran berat, konteks panjang, dan kode. Yang justru benar-benar kompetitif dari model lokal kecil adalah wilayah tengah yang sangat luas dari pekerjaan sehari-hari: memutuskan sebuah email masuk ke salah satu dari enam kategori, mengekstraksi lima field dari sebuah faktur, meringkas thread dukungan, menulis ulang deskripsi, memberi tag pada dokumen, menilai apakah dua catatan menggambarkan orang yang sama. Untuk kelas pekerjaan seperti itu, jarak antara model 8B dan model frontier kecil, selisih biayanya total, dan selisih privasinya mutlak. Sikap yang produktif bukan «menggantikan API», melainkan «berhenti mengirim sembilan puluh persen data yang sebenarnya tidak pernah perlu keluar».

Apakah Ollama punya autentikasi?

Tidak — sama sekali tidak ada, dan ini adalah fakta operasional paling penting dalam panduan ini. Tidak ada kata sandi, tidak ada token, tidak ada model pengguna. Apa pun yang bisa membuka koneksi TCP ke port 11434 bisa menghasilkan teks, mendaftar model Anda, menarik model baru, dan menghapus yang sudah ada. Port itu rutin dipindai, dan instance yang tidak terlindungi ditemukan lalu dipakai sebagai komputasi gratis oleh orang asing — yang pertama kali muncul sebagai load average yang misterius, dan kemudian sebagai tagihan bandwidth. Ikat Ollama ke 127.0.0.1, pasang reverse proxy di depannya, hentikan TLS di sana, dan wajibkan token bearer atau sertifikat klien di proxy tersebut. Jika tidak ada yang di luar mesin ini butuh model tersebut, jangan ekspos sama sekali.

Bisakah n8n atau runtime agen saya memakai model lokal?

Ya, dan biasanya cukup satu field saja. Ollama menyediakan API yang kompatibel dengan OpenAI di /v1, jadi klien apa pun yang mengizinkan Anda mengatur base URL — SDK OpenAI, LangChain, node OpenAI di n8n, sebagian besar framework agen — akan bisa berkomunikasi dengannya cukup dengan mengarah ke https://your-host/v1 dan mengirim string apa saja yang tidak kosong sebagai key-nya. n8n juga menyediakan node Ollama khusus. Pola yang terbukti berjalan baik di praktiknya adalah pendekatan hybrid: arahkan panggilan yang banyak, membosankan, dan bervolume tinggi ke model lokal, dan simpan API hosted untuk beberapa langkah yang memang butuh penalaran frontier, dengan fallback jika model lokalnya gagal menghasilkan JSON yang valid.

Apakah menjalankan embedding di CPU itu sepadan?

Ini adalah hal paling bernilai di seluruh halaman ini. Model embedding sangat kecil — puluhan sampai ratusan megabyte, bukan gigabyte — dan hanya melakukan satu forward pass per chunk tanpa generasi token demi token, sehingga CPU melahapnya dengan mudah. Artinya seluruh separuh retrieval dari sistem RAG — mengindeks dokumen Anda, meng-embed query, mencari chunk terdekat — berjalan nyaman di tingkat termurah sekalipun, dan itu juga separuh yang menyentuh setiap dokumen yang Anda miliki. Bahkan jika Anda memutuskan tahap generasinya sebaiknya ada di API hosted, memindahkan tahap embedding ke mesin Anda sendiri tetap menjaga korpus Anda jauh dari mesin orang lain.

Kenapa repot-repot self-host model, kalau API lebih cepat dan lebih murah?

Tiga alasan, diurutkan dari yang paling tidak penting ke yang paling menentukan. Biaya punya bentuknya sendiri: API lebih murah sampai suatu titik ia tidak lagi murah, dan workflow yang mengklasifikasikan lima puluh ribu pesan sebulan punya tagihan yang terus membesar, sementara VPS $7.90 tidak. Ketersediaan: tanpa rate limit, tanpa model yang tiba-tiba deprecated padahal sudah jadi tumpuan Anda, tanpa outage di status page milik orang lain. Dan yang benar-benar menentukan — prompt Anda adalah teks paling membongkar rahasia yang pernah Anda hasilkan. Bukan jawabannya, pertanyaannya. Apa yang Anda tanyakan, tentang siapa, pada hari apa, dalam urutan seperti apa. Endpoint hosted melihat semuanya, terhubung dengan identitas penagihan Anda. Model yang berjalan di mesin yang Anda sewa tanpa dokumen identitas, di yurisdiksi Nordic, dibayar dengan Monero, melihat teks yang sama dan tidak melaporkannya kepada siapa pun.

Dapatkan metalnya

VPS Nordic untuk model yang menjawab hanya kepada Anda. Bebas KYC, berbayar kripto.

Garrison (4 vCPU, 8 GB, 240 GB NVMe, $7.90/bulan) menjalankan model 8B dengan ruang tersisa untuk cache konteks dan sistemnya — tingkat yang paling cocok jadi titik awal kebanyakan orang. Ravelin menggandakan memorinya untuk model 14B dan konteks panjang. Tanpa email saat mendaftar, tanpa dokumen identitas, dan tanpa tagihan per token.

Terakhir ditinjau · 2026-08-24 · Sumber · Dokumentasi dan referensi API Ollama, dokumentasi llama.cpp, dokumentasi reverse proxy Caddy, model card resmi untuk build hasil kuantisasi yang dirujuk · Kadence · tahunan