SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-08-26

Reasoning Effort LLM Lokal: Dampak pada Waktu dan Token

Pelajari cara reasoning effort mengubah token penalaran, waktu generasi CPU atau GPU, dan context window pada LLM lokal tanpa mengubah bobot model.

Perubahan reasoning effort pada LLM lokal

Reasoning effort adalah pengaturan yang menentukan berapa lama model berpikir sebelum memberikan jawaban. Pengaturan ini hanya mengubah panjang segmen penalaran. Bobot model di disk tetap identik pada setiap tingkat, kuantisasi juga identik, dan jawaban dihasilkan dari forward pass yang sama. Perbedaannya terletak pada jumlah token yang digunakan model untuk scratchpad internalnya terlebih dahulu.

Perbedaan ini penting karena berkaitan dengan penggunaan token tersebut. Pada API hosted, token penalaran tercantum dalam tagihan. Pada VPS milik Anda sendiri, token tersebut dibayar dengan waktu generasi pada CPU atau GPU Anda dan ruang di dalam context window. Model yang dibiarkan pada tingkat effort tertinggi dapat menggunakan sebagian besar outputnya untuk penalaran sebelum kata pertama jawaban muncul. Pada hardware self-hosted, hal ini dapat menentukan apakah respons selesai dalam dua detik atau dua menit.

Tempat level ditentukan: chat template, bukan weights

Model thinking dilatih untuk menghasilkan segmen penalaran, biasanya dibungkus dalam tag <think> dan </think>, sebelum jawaban akhirnya. Level usaha merupakan instruksi yang ditulis chat template model ke dalam prompt. Template tersebut adalah file Jinja yang disertakan bersama model. Template membaca variabel seperti reasoning_effort lalu merender baris tingkat sistem yang berbeda untuk setiap nilai. Model dilatih untuk memperpendek atau memperpanjang scratchpad sebagai respons terhadap baris tersebut.

Ada dua hal yang perlu diperhatikan. Nama level merupakan bagian dari model, bukan runtime Anda. Karena itu, nama dari card suatu model dapat tidak berarti apa-apa bagi model lain. Selain itu, jika komponen mana pun dalam rangkaian mengganti chat template model dengan template generik, variabel tersebut tidak pernah dirender dan pengaturan ini diam-diam tidak berfungsi.

Berdasarkan pemeriksaan pada 2026-08-20, model card Qwen3.8-27B mendokumentasikan tiga level usaha: low, medium, dan xhigh, dengan xhigh sebagai nilai default. Tidak ada high. Fitur thinking diaktifkan dengan enable_thinking dan secara default aktif. Card tersebut juga mendokumentasikan preserve_thinking, yang secara default aktif dan mempertahankan penalaran dari giliran sebelumnya dalam riwayat percakapan. gpt-oss menggunakan low, medium, dan high. Banyak keluarga model lain hanya menerima nilai boolean. Baca card untuk versi persis yang Anda unduh, karena nama-nama ini bukan standar. Menjalankan model 27B di VPS adalah langkah pertama. Halaman ini membahas pengaturan yang perlu diterapkan setelah model tersebut memberikan jawaban.

Mengapa upaya penalaran tinggi membutuhkan biaya lebih besar di VPS

Token output. Token penalaran dihasilkan melalui loop decode yang sama seperti token jawaban. Keduanya diproses pada jumlah token per detik yang dapat ditangani perangkat keras Anda. Misalnya, suatu tugas menghasilkan 200 token jawaban dan 4,000 token penalaran. Sistem menghasilkan 4,200 token, tetapi pembaca hanya melihat 200 token. Kecepatan decode ditentukan oleh bandwidth memori dan kuantisasi yang Anda pilih, sehingga satu-satunya faktor yang masih dapat diubah adalah jumlah token.

Waktu nyata. Pengguna menunggu token pertama dari jawaban, karena semua proses sebelumnya hanya menampilkan layar kosong atau indikator pemuatan yang diciutkan. Token penalaran dihasilkan terlebih dahulu, sehingga waktu tunggu kira-kira sama dengan jumlah token penalaran dibagi kecepatan decode, ditambah waktu pemrosesan prompt. Jika panjang penalaran digandakan, waktu tunggu tersebut juga menjadi dua kali lipat.

Konteks. Token penalaran mengisi jendela konteks seperti token lainnya. Saat preserve_thinking aktif, scratchpad dari giliran pertama masih berada dalam prompt pada giliran kelima. Akibatnya, pemrosesan prompt menjadi lebih lambat pada setiap giliran, sementara jendela konteks terisi dari kedua arah. Menaikkan num_ctx untuk menampungnya membutuhkan memori cache KV, yang pada VPS tanpa GPU berupa RAM sistem yang mungkin tidak tersedia.

Kapan level perlu dinaikkan dan kapan perlu dibiarkan rendah

Naikkan level untuk pekerjaan yang hasilnya dapat rusak oleh satu langkah antara yang salah: aritmetika dan konversi satuan bertahap, perencanaan pengeditan di beberapa file, kode yang harus dikompilasi, serta masalah dengan batasan ketika satu jawaban harus memenuhi beberapa kondisi sekaligus. Dalam kasus ini, scratchpad benar-benar digunakan untuk bekerja. Scratchpad yang lebih panjang merupakan cara murah untuk menemukan kesalahan yang mungkin tidak akan disadari model.

Biarkan level tetap rendah ketika jawabannya sudah terdapat dalam input dan tugasnya adalah memindahkan informasi tersebut. Ekstraksi, klasifikasi, pemberian tag, penerjemahan, penulisan ulang, peringkasan, dan pemformatan termasuk dalam kategori ini. Segmen penalaran sebagian besar hanya mengulang tugas. Segmen tersebut juga memberi model ruang untuk mengubah respons awal yang sebenarnya sudah benar.

Biarkan level tetap rendah untuk segala sesuatu yang bersifat interaktif. Dalam chat box atau editor, Anda tetap terlibat dalam proses. Karena itu, jawaban cepat yang dapat Anda koreksi lebih baik daripada jawaban lambat yang harus Anda tunggu. Inilah pertimbangan utama di balik mengarahkan coding agent ke model lokal: agent melakukan banyak panggilan kecil, dan biaya penalaran dikenakan pada setiap panggilan tersebut.

Cara mengatur level di llama.cpp

llama.cpp menulis variabel tersebut langsung ke dalam template. Dengan demikian, runtime ini adalah tempat Anda dapat memastikan bahwa level telah diteruskan. Arahkan -m ke file GGUF yang sudah Anda miliki.

llama-server -m ./qwen3.8-27b-Q4_K_M.gguf \
  --jinja \
  --reasoning-effort medium \
  --reasoning-format deepseek \
  -c 32768 \
  --host 127.0.0.1 --port 8080

--jinja menggunakan chat template milik model dan diaktifkan secara default pada build saat ini. --reasoning-effort menerima default, minimal, low, medium, high, xhigh, atau max. default berarti membiarkan default bawaan template. Daftar tersebut adalah kosakata llama.cpp, bukan kosakata model. Karena itu, hanya teruskan nama yang tercantum pada kartu model. Level yang tidak didefinisikan oleh template dapat menyebabkan error template saat request diproses. --reasoning-format deepseek memindahkan proses penalaran dari message.content ke message.reasoning_content. Inilah yang membuat pemisahan tersebut dapat diukur pada bagian berikutnya.

Untuk menonaktifkan proses berpikir, bukan sekadar mempersingkatnya, tetapkan variabel template sendiri:

llama-server -m ./qwen3.8-27b-Q4_K_M.gguf --jinja \
  --chat-template-kwargs '{"enable_thinking": false}'

--reasoning-budget adalah mekanisme yang berbeda. Opsi ini membatasi segmen penalaran berdasarkan jumlah token. 0 langsung mengakhirinya, sedangkan -1 membiarkannya tanpa batas. Opsi ini tidak meminta model membuat rencana yang lebih singkat. Kedua flag berlaku pada seluruh server. llama-server tidak menerima reasoning_effort sebagai field per request. Karena itu, untuk melayani dua level upaya secara bersamaan, jalankan dua proses pada dua port.

vLLM mengekspos variabel yang sama untuk setiap request, di dalam body yang kompatibel dengan OpenAI:

{"model": "Qwen/Qwen3.8-27B",
 "messages": [{"role": "user", "content": "Summarise this changelog in two lines."}],
 "chat_template_kwargs": {"reasoning_effort": "medium"}}

Cara menetapkan level di Ollama

Ollama memiliki field sendiri, think, pada /api/chat dan /api/generate. Field ini menerima true, false, atau salah satu dari low, medium, high, dan max, dengan max yang meminta level tertinggi yang ditawarkan model. Thinking aktif secara default pada model yang mendukungnya.

ollama run qwen3.8:27b --think=low "Draft a one line commit message for a README typo fix"
{"model": "qwen3.8:27b",
 "messages": [{"role": "user", "content": "Which HTTP status code means the request body was too large?"}],
 "think": "low",
 "stream": false}

Penalaran dikembalikan dalam message.thinking dan jawaban dalam message.content, sehingga keduanya sudah dipisahkan. Dalam sesi interaktif ollama run, /set think dan /set nothink dapat digunakan untuk mengaktifkan atau menonaktifkannya tanpa restart.

Perhatikan ketidaksesuaian ini. Kosakata Ollama adalah low, medium, high, dan max. Template Qwen3.8 mendefinisikan low, medium, dan xhigh. Salah satunya harus dipetakan ke yang lain. Selain itu, model Ollama membawa template yang dikemas di dalam tag-nya, bukan file Jinja dari repositori asli. Karena itu, apakah level Anda diteruskan ke model bergantung pada template yang dikemas tersebut. Jangan berasumsi bahwa pengaturan itu berhasil. Pengukurannya memerlukan waktu sekitar satu menit.

Cara mengukur apakah tingkat penalaran benar-benar diterapkan

Kirim prompt yang sama pada lebih dari satu tingkat dengan temperature bernilai 0, lalu bandingkan jumlah tokennya. Di sini jq menyusun body sehingga Anda tidak perlu melakukan escape tanda kutip secara manual.

for level in low medium max; do
  body=$(jq -n --arg lvl "$level" '{
    model: "qwen3.8:27b",
    messages: [{role: "user", content: "A pump fills a 4500 litre tank in 25 minutes. A second pump is 40 percent slower. How long do both together take? Answer in minutes."}],
    think: $lvl,
    stream: false,
    options: {temperature: 0, num_ctx: 8192}
  }')
  echo "== $level"
  curl -s http://localhost:11434/api/chat -d "$body" | jq '{
    thinking_chars: (.message.thinking // "" | length),
    answer_chars: (.message.content | length),
    eval_count: .eval_count,
    seconds: (.total_duration / 1e9),
    tok_per_sec: (.eval_count / (.eval_duration / 1e9))
  }'
done

eval_count mencakup setiap token yang dihasilkan, termasuk token penalaran, sehingga selisih antara dua tingkat hampir seluruhnya merupakan penalaran. thinking_chars memberikan pemisahannya secara langsung. Dua hal harus terpenuhi: angkanya berubah antartingkat, dan jawaban tetap benar pada tingkat yang lebih rendah. Jika eval_count tetap berada dalam rentang noise pada ketiga pengujian, tingkat tersebut diabaikan. Solusinya adalah menggunakan runtime yang meneruskannya, bukan mengganti nama tingkat.

Waktu total hanya mencakup separuh informasi. Karena itu, ukur jeda hingga token jawaban pertama dengan melakukan streaming dan berhenti pada chunk content pertama yang tidak kosong. Pengukuran ini memerlukan jq dan bc.

start=$(date +%s.%N)
curl -sN http://localhost:11434/api/chat -d '{
  "model": "qwen3.8:27b",
  "messages": [{"role": "user", "content": "Explain what a reverse proxy does, in three sentences."}],
  "think": "low",
  "stream": true
}' |
while IFS= read -r line; do
  if [ -n "$(printf '%s' "$line" | jq -r '.message.content // ""')" ]; then
    echo "first answer token after $(echo "$(date +%s.%N) - $start" | bc)s"
    break
  fi
done

Jalankan pada low, lalu jalankan lagi pada max. Selisihnya adalah waktu tunggu yang Anda tambahkan. Pada llama.cpp, angka yang sama dikembalikan di dalam respons sehingga Anda tidak memerlukan perhitungan aritmetika shell:

curl -s http://localhost:8080/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model": "local", "temperature": 0,
       "messages": [{"role": "user", "content": "A pump fills a 4500 litre tank in 25 minutes. A second pump is 40 percent slower. How long do both together take?"}]}' | jq '{
  reasoning_chars: (.choices[0].message.reasoning_content // "" | length),
  answer_chars: (.choices[0].message.content | length),
  predicted_n: .timings.predicted_n,
  tok_per_sec: .timings.predicted_per_second
}'

Lakukan pengukuran ini pada server Anda sendiri. Perbandingan performa yang dipublikasikan diukur pada hardware yang bukan milik Anda, sedangkan kecepatan decode Anda adalah faktor yang mengubah jumlah token menjadi detik. Mengukur token per detik pada server Anda sendiri memberikan faktor tersebut: token penalaran dibagi kecepatan decode Anda adalah waktu tunggu yang baru saja Anda tambahkan.

Masalah yang Terjadi

Jawaban terpotong, atau content kosong sementara thinking berisi. Batas generasi habis untuk proses penalaran. num_predict milik Ollama membatasi seluruh generasi, termasuk penalaran. Karena penalaran diproses terlebih dahulu, batas 512 token pada tingkat upaya tinggi dapat mengakhiri respons sebelum jawaban dimulai. Ollama melaporkan "done_reason": "length" pada respons tersebut. Naikkan batas atau turunkan tingkat upaya. Cara num_predict menghitung token menjelaskan interaksi ini secara terperinci.

Perubahan tingkat tidak berpengaruh. Jumlah token sama pada setiap tingkat. Runtime mungkin tidak meneruskan variabel tersebut, atau template tidak membacanya. Periksa template yang benar-benar digunakan oleh runtime, bukan template dalam repositori asli. llama.cpp dengan --jinja dan --chat-template-kwargs menulis variabel tersebut secara manual, sehingga dapat digunakan sebagai pembanding. Jika tingkat tersebut berfungsi di sana tetapi tidak di tempat lain, modelnya berfungsi dengan baik dan runtime lain mengabaikan variabel tersebut.

Nama tingkat ditolak. Error template saat request, atau kegagalan pada pesan pertama meskipun server berfungsi normal, biasanya berarti Anda meneruskan tingkat yang tidak didefinisikan oleh template. Contohnya, high diteruskan ke model yang pada kartu modelnya hanya mencantumkan low, medium, dan xhigh.

Chat multi-turn melambat pada setiap turn. Penalaran lama disimpan dalam history. Atur preserve_thinking ke false jika model mendukungnya, atau hapus field thinking dari messages yang Anda kirim kembali. Jika tidak, pemrosesan prompt bertambah pada setiap turn, sementara panjang jawaban tetap sama.

Kualitas menurun pada tingkat upaya rendah untuk tugas yang Anda anggap sederhana. Sebagian tugas ekstraksi sebenarnya bukan ekstraksi. Jika input memerlukan konversi unit atau penerapan aturan secara berurutan, tugas tersebut merupakan tugas penalaran dengan output singkat. Naikkan tingkat untuk satu call tersebut, bukan untuk seluruh server.

Menjalankan dua tingkat secara bersamaan

llama.cpp menetapkan tingkat saat startup, sehingga server yang melayani editor dan tugas batch malam memerlukan dua proses pada dua port. Masing-masing proses memiliki --reasoning-effort sendiri. Dua proses juga berarti dua salinan bobot di memori, kecuali Anda menjalankan kedua tugas pada waktu yang berbeda. Pada satu VPS, pengaturan yang lebih hemat biasanya berupa server dengan upaya rendah untuk tugas yang sedang ditunggu pengguna, ditambah proses terjadwal dengan upaya lebih tinggi untuk pekerjaan yang tidak sedang dipantau. Apa yang terjadi saat beberapa pengguna berbagi satu model lokal juga berlaku di sini: token penalaran merupakan pekerjaan decode, sehingga peningkatan tingkat akan mengurangi konkurensi efektif Anda kira-kira dengan faktor yang sama dengan peningkatan jumlah token.

FAQ

Tingkat upaya penalaran apa yang sebaiknya digunakan secara default?

Mulailah dari tingkat terendah yang tersedia pada model, lalu naikkan hanya untuk tugas yang terbukti gagal. Beberapa model penalaran dirilis dengan tingkat default yang tinggi, dan Qwen3.8-27B menggunakan xhigh, yaitu tingkat tertingginya, per Agustus 2026. Default tersebut dipilih agar hasilnya terlihat baik pada tabel benchmark, sementara tabel benchmark tidak mengenakan biaya berdasarkan waktu. Pada perangkat keras Anda sendiri, waktu dibayar dalam detik. Karena itu, jadikan tingkat yang lebih tinggi sebagai pilihan per tugas, bukan pengaturan yang diwarisi oleh setiap permintaan.

Apakah token penalaran dihitung dalam context window saya?

Ya. Token tersebut merupakan token biasa dalam output dan menempati context window bersama semua konten lainnya. Apakah token tersebut tetap ada pada giliran berikutnya bergantung pada runtime dan model. Kartu Qwen3.8 mendokumentasikan preserve_thinking, yang aktif secara default dan mempertahankan penalaran sebelumnya dalam riwayat. Akibatnya, percakapan panjang membawa setiap scratchpad yang telah dihasilkan. Tetapkan nilainya ke false, atau hapus field thinking dari messages yang Anda kirim ulang. Dengan begitu, pemrosesan prompt tidak terus bertambah.

Mengapa mengubah tingkat berpikir tidak memengaruhi jumlah token saya?

Pengaturan tersebut tidak sampai ke chat template. Tingkat ini merupakan variabel template. Karena itu, tingkat tersebut hanya berfungsi jika runtime meneruskannya dan template yang dipaketkan membacanya. Beberapa runtime menyertakan template sendiri bersama model, bukan file Jinja dari repository asli. Dalam kondisi tersebut, variabel dapat terhapus tanpa pesan error apa pun. Buktikan dengan mengirim prompt yang sama pada tingkat terendah dan tertinggi, dengan temperature bernilai 0, lalu bandingkan eval_count. Jika jumlahnya sama dalam batas variasi kecil, tingkat tersebut diabaikan.

Apakah upaya penalaran yang lebih rendah membuat model kurang akurat?

Hal ini bergantung pada tugas. Sebaiknya ukur, bukan berasumsi. Jika jawaban sudah terdapat dalam input, seperti pada ekstraksi atau penulisan ulang, scratchpad yang lebih singkat biasanya tidak mengubah hasil. Jika langkah perantara harus benar sebelum langkah akhir dapat dilakukan, seperti pada aritmetika multilangkah atau kode yang harus dikompilasi, akurasi memang menurun ketika scratchpad lebih singkat. Buat set berisi dua puluh prompt dari workload nyata Anda, jalankan pada dua tingkat dengan temperature bernilai 0, lalu hitung jawaban yang salah. Jumlah tersebut spesifik untuk workload Anda. Tidak ada tabel yang dipublikasikan yang dapat memberikannya kepada Anda.