SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-13

Ollama num_ctx 설정과 긴 프롬프트 잘림 확인

Ollama는 기본 컨텍스트 창이 작아 긴 프롬프트를 잘릴 수 있습니다. 요청별 또는 서버 전체에 num_ctx를 설정하고, 4096토큰 기본값과 KV cache RAM 사용량을 확인하는 방법을 설명합니다.

num_ctx의 기능과 긴 프롬프트가 잘린 이유

Ollama의 컨텍스트 길이는 로드된 모델이 한 번에 메모리에 보관할 수 있는 토큰 수이며, num_ctx가 이 값을 설정하는 옵션이다. Ollama는 모델이 지원한다고 명시한 최대값보다 훨씬 낮은 기본값을 선택한다. 따라서 모델이 프롬프트를 읽기 전에 긴 프롬프트가 잘릴 수 있다. 응답만 보고는 이 일이 발생했는지 알 수 없다.

Ollama 모델 라이브러리에는 Llama 3.1 8B의 컨텍스트 윈도우가 128k로 표시되어 있다. 기본 서버가 이 값을 제공하지는 않는다. Ollama의 공식 문서도 페이지마다 서로 다른 기본값을 제시한다. FAQ에는 4096토큰이라고 되어 있고, Modelfile reference에는 num_ctx의 기본값이 2048이라고 되어 있다. 컨텍스트 길이 페이지에는 사용 가능한 VRAM(video RAM)에 따라 기본값을 선택한다고 설명되어 있다. 24 GiB 미만에서는 4k, 24~48 GiB에서는 32k, 그 이상에서는 256k를 사용한다는 내용이다. 각각의 값은 특정 빌드에서는 사실이었다. 여기서 얻을 수 있는 중요한 교훈은 이것이다. 이 페이지를 포함한 어떤 문서도 그대로 믿지 말고, 실행 중인 서버에서 직접 값을 확인해야 한다.

잘린 사실이 드러나지 않는 이유는 모델이 계속 응답하고, 그 응답도 여전히 자연스럽게 읽히기 때문이다. 그러나 모델은 입력의 뒷부분만 사용해 응답을 작성했다. 문서의 앞부분을 놓친 요약은 모델의 성능이 낮아서 생긴 것처럼 보인다. 실제 원인은 대개 작은 컨텍스트 윈도우다.

Ollama에서 서버에 실제로 적용된 컨텍스트 길이 확인

어떤 빌드에서도 사용할 수 있는 확인 방법은 prompt_eval_count입니다. 이는 서버가 처리했다고 보고하는 프롬프트 토큰 수입니다. 컨텍스트가 수용할 수 있는 양보다 더 많이 전송하면 이 수가 한도에서 멈춥니다.

sudo apt update && sudo apt install -y jq
LONG=$(python3 -c "print('the quick brown fox jumps over the lazy dog. ' * 2000)")
jq -n --arg p "$LONG" '{model:"llama3.1:8b", prompt:$p, stream:false, options:{num_ctx:4096}}' |
  curl -s http://localhost:11434/api/generate -d @- |
  jq '{prompt_eval_count, prompt_eval_duration}'

이 프롬프트는 약 18,000단어이므로 4096토큰보다 훨씬 큽니다. 서버가 나머지를 삭제하므로 prompt_eval_count은 실제 토큰 수에 가까운 값이 아니라 4096에 가까운 값으로 반환됩니다. "num_ctx":16384를 사용해 다시 실행하면 이 수가 증가합니다. 빌드에 따라 잘라내는 대신 오류를 반환할 수도 있습니다. 이 경우에도 더 명확하게 나타날 뿐 같은 결과입니다.

ollama ps

빌드에서 표시하는 경우 CONTEXT 열에는 현재 로드된 모델이 사용하는 컨텍스트 길이가 표시됩니다. 그 옆의 PROCESSOR 열에는 모델이 배치된 위치가 표시됩니다. GPU가 없는 VPS에서는 100% CPU가 정상입니다. GPU 서버에서 30%/70% CPU/GPU과 같이 분할되어 있다면 가중치와 캐시가 더 이상 VRAM에 모두 들어가지 않는다는 뜻이며, 일반적인 원인은 증가한 num_ctx입니다.

journalctl -u ollama --no-pager | grep -i n_ctx | tail -n 5

추론 실행기는 n_ctx을 포함하는 줄에 컨텍스트 크기를 출력합니다. 릴리스마다 정확한 문구가 달라지므로 해당 줄이 없다고 해서 특정 사실이 입증된 것으로 보지 말고, 이름이 변경된 것으로 판단해야 합니다.

num_ctx를 설정하는 네 가지 위치

요청에서 설정합니다. "options": {"num_ctx": 16384}/api/generate 또는 /api/chat로 전송합니다. 이 설정은 다른 모든 설정에 우선하며 해당 호출 하나에만 적용됩니다. 값이 현재 로드된 모델의 실행 설정과 다르면 서버가 먼저 모델을 다시 로드합니다. 이 과정은 응답의 load_duration에서 확인할 수 있습니다. 값이 거의 0에서 몇 초 단위로 증가합니다.

대화형 세션에서 설정합니다. ollama run 안에서 /set parameter num_ctx 16384을 입력합니다. 이 설정은 해당 세션 동안 유지됩니다.

Modelfile에서 설정합니다. 값을 이름이 지정된 모델에 포함하므로 클라이언트 측을 변경하지 않아도 모든 클라이언트가 해당 값을 사용합니다.

FROM llama3.1:8b
PARAMETER num_ctx 16384
ollama create llama3.1-16k -f ./Modelfile
ollama run llama3.1-16k

서버에서 설정합니다. OLLAMA_CONTEXT_LENGTH는 자체 num_ctx을 포함하지 않는 모든 요청의 기본값을 설정합니다. systemd를 사용하는 경우 unit 파일을 직접 편집하지 말고 drop-in을 추가합니다.

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_CONTEXT_LENGTH=16384"
sudo systemctl daemon-reload
sudo systemctl restart ollama
ollama ps

다른 사람이 작성한 클라이언트를 디버깅할 때는 우선순위가 가장 중요합니다. num_ctx을 포함한 요청은 서버 기본값보다 우선합니다. 따라서 chat front end나 agent가 자체적으로 작은 값을 전송하면 systemd 변경 사항이 조용히 무시됩니다. 코딩 agent를 Ollama 서버에 연결할 때는 서버를 의심하기 전에 클라이언트가 무엇을 전송하는지 확인합니다.

model의 최대값으로 num_ctx를 단순히 설정할 수 없는 이유

Attention은 모든 토큰이 앞에 있는 모든 토큰을 참조하도록 처리합니다. 이전 토큰에 대해 계산한 key와 value는 새 토큰마다 다시 계산하지 않도록 보관하며, 이 저장 공간이 KV cache(key/value cache)입니다. 모델을 로드할 때 전체 num_ctx에 대해 할당되며 대화가 길어질 때마다 늘어나는 방식이 아닙니다. 따라서 한 줄짜리 프롬프트만 사용해도 큰 context는 해당 메모리를 차지합니다.

DigitalOcean의 inference cost tutorial에서는 계산식을 다음 한 줄로 제시합니다.

kv_bytes_per_token = 2 * layers * kv_heads * head_dim * bytes_per_value

2는 key와 value를 별도로 계산한다는 뜻입니다. 나머지 수치는 사용 중인 모델에서 직접 확인합니다.

curl -s http://localhost:11434/api/show -d '{"model":"llama3.1:8b"}' |
  jq '.model_info | {ctx: ."llama.context_length", layers: ."llama.block_count", heads: ."llama.attention.head_count", kv_heads: ."llama.attention.head_count_kv", embed: ."llama.embedding_length"}'

Llama 3.1 8B는 32개 layer와 8개 key/value head를 사용합니다. head dimension은 embedheads로 나눈 값입니다. 따라서 여기서는 4096 / 32 = 128이며, 일부 모델은 이 값을 llama.attention.key_length로 직접 공개합니다. 기본 cache는 f16 값을 저장하므로 bytes_per_value는 2입니다. 따라서 2 32 8 128 2는 131,072바이트가 됩니다. context의 토큰 하나마다 128 KiB의 cache가 필요한 셈입니다. 여기에 context 길이를 곱하면 비용의 규모가 분명해집니다.

ChartLlama 3.1 8B at f16: KV cache and total RAM by context length, in GiB
The data behind this chart
[
  {
    "label": "4k",
    "kv_cache_gib": 0.5,
    "total_ram_gib": 5.1
  },
  {
    "label": "8k",
    "kv_cache_gib": 1,
    "total_ram_gib": 5.6
  },
  {
    "label": "16k",
    "kv_cache_gib": 2,
    "total_ram_gib": 6.6
  },
  {
    "label": "32k",
    "kv_cache_gib": 4,
    "total_ram_gib": 8.6
  },
  {
    "label": "64k",
    "kv_cache_gib": 8,
    "total_ram_gib": 12.6
  },
  {
    "label": "128k",
    "kv_cache_gib": 16,
    "total_ram_gib": 20.6
  }
]

6개의 행은 위 공식으로 계산한 값이며, 측정값이 아닙니다. total 열에는 2026년 8월 Ollama library가 llama3.1:8b에 대해 표시한 4.9 GB 다운로드 크기, 즉 4.6 GiB를 더했습니다. compute buffer와 server process 자체는 포함하지 않았습니다. 따라서 이 값은 최저 비용으로 보아야 합니다.

중요한 것은 증가 양상입니다. 8k에서는 cache가 1 GiB이므로 weights에 비하면 무시할 수 있는 수준입니다. 모델의 최대 128k에서는 16 GiB가 필요합니다. weights의 3배를 넘으며 총 메모리는 약 20.6 GiB입니다. 따라서 4 GB VPS에서는 이 모델을 유용한 context 길이로 로드할 수 없습니다. 8 GB VPS에서는 8k가 여유롭습니다. 16 GB VPS에서는 다른 시스템 구성에 필요한 공간을 남겨 두고 32k까지 사용할 수 있습니다. 이러한 기준은 weights가 커질수록 모두 높아집니다. 이 8B 모델과 더 큰 모델 중에서 선택하려는 경우, CPU만 사용하는 VPS에서 Qwen의 27B tag에 대해 같은 계산을 수행하면 8~64 GB 메모리 범위에서 weights를 제외하고 context에 남는 공간이 얼마나 적은지 확인할 수 있습니다.

KV 캐시가 들어가지 않을 때 발생하는 현상

CPU만 사용하는 VPS에서는 프로세스의 메모리 사용량이 계속 증가합니다. 모델을 로드할 때와 긴 요청을 실행할 때 이를 모니터링합니다.

free -m
ps -eo rss,comm --sort=-rss | head -n 5

RSS(resident set size)는 킬로바이트 단위로 출력됩니다. free -m의 사용 중인 swap이 증가하기 시작하면 context 크기를 줄입니다. swap에 저장된 KV 캐시는 토큰마다 수 초가 걸릴 정도로 생성을 지연시킵니다. 새 토큰을 생성할 때마다 전체 캐시를 읽어야 하기 때문입니다.

서버의 메모리가 완전히 고갈되면 커널은 가장 큰 프로세스를 선택해 종료합니다.

sudo dmesg | grep -i "killed process"

Out of memory: Killed process 1234 (ollama)로 표시된 행은 요청한 context가 메모리에 들어가지 않았다는 뜻입니다. Ollama는 대개 이 단계에 도달하기 전에 요청을 거부합니다. 그러면 요청이 실패하고, 필요한 메모리와 당시 사용 가능했던 메모리를 나타내는 메시지가 출력됩니다.

GPU 서버에서는 오류가 덜 명확하게 나타납니다. 일부 레이어가 시스템 RAM으로 넘어가고, ollama ps에는 CPU와 GPU의 분할 상태가 표시되며, 처리량이 급격히 감소합니다. 감소 폭은 하드웨어에 따라 다릅니다. 따라서 다른 사람의 시스템에서 얻은 수치를 그대로 사용하지 말고, 각 context 설정에서 자신의 서버에서 초당 토큰 수를 측정합니다.

프리필 시간은 프롬프트보다 더 빠르게 증가한다

프리필은 첫 번째 출력 토큰이 나타나기 전에 입력에 대해 수행하는 작업이다. 각 프롬프트 토큰은 앞에 있는 모든 토큰에 어텐션을 적용하므로 전체 작업량은 입력 길이의 제곱에 비례해 증가한다. 프롬프트를 2배로 늘리면 첫 번째 토큰이 나올 때까지의 대기 시간은 2배보다 더 길어진다.

응답에 측정값이 포함되므로 이를 그대로 믿을 필요가 없다.

jq -n --arg p "$LONG" '{model:"llama3.1:8b", prompt:$p, stream:false, options:{num_ctx:16384}}' |
  curl -s http://localhost:11434/api/generate -d @- |
  jq '{tokens: .prompt_eval_count, prefill_seconds: (.prompt_eval_duration/1000000000)}'

짧은 프롬프트로 실행한 다음 긴 프롬프트로 다시 실행하고, 각 경우에 토큰 수를 초 단위 시간으로 나눈다. CPU만 사용하는 VPS에서는 긴 컨텍스트 요청의 프리필이 보통 가장 느린 단계다. 짧은 프롬프트에서 측정한 초당 토큰 수로는 긴 요청의 성능을 예측할 수 없다.

동시성에서 이 문제가 가장 크게 나타난다. 처리 중인 각 요청에는 자체 캐시가 필요하다. 따라서 위 차트의 메모리는 서버 전체가 아니라 요청당 메모리다. 긴 요청 하나가 서버를 점유하면 짧은 요청은 그 뒤에서 대기할 수 있다. OLLAMA_NUM_PARALLEL을(를) 의도적으로 설정하고, 두 수치를 함께 늘리기 전에 셀프 호스팅 LLM이 동시에 처리할 수 있는 사용자 수를 확인한다.

더 작은 캐시로 메모리 여유 확보

수식의 bytes_per_value는 사용자가 제어하는 설정이다. Ollama FAQ에는 OLLAMA_KV_CACHE_TYPE이 설명되어 있으며, 기본값은 2바이트인 f16이다. 그보다 작은 값으로는 1바이트인 q8_0q4_0이 있다. q8_0으로 변경하면 캐시 크기가 절반으로 줄어들므로, 32k 행에 필요한 비용은 4 GiB가 아니라 2 GiB가 된다. 같은 FAQ에는 OLLAMA_FLASH_ATTENTION=1도 설명되어 있다. 일부 빌드에서는 양자화된 캐시를 적용하려면 이 설정이 먼저 필요하다.

[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"

추측하지 말고 확인해야 한다. 서비스를 다시 시작하고, 이전과 동일한 num_ctx로 모델을 로드한 다음 RSS를 비교한다. 지원 여부는 모델과 백엔드에 따라 달라진다. 설정을 변경해도 아무런 차이가 없다면 해당 조합은 지원 범위에 포함되지 않는 것이다. 문서에는 이러한 옵션이 결과 품질을 보장하지 않은 채 나열되어 있으므로, 실제로 사용하기 전에 자체 프롬프트로 q4_0을 테스트해야 한다. 이 설정이 필요한 이유라면 Ollama와 llama.cpp는 이러한 설정을 서로 다르게 노출한다.

num_ctx를 선택하는 방법

  1. /api/show에서 모델의 최대 컨텍스트, 레이어 수, key/value 헤드 수를 확인합니다.
  2. 수식을 사용해 토큰당 바이트 수를 계산한 다음, 원하는 컨텍스트 크기를 곱합니다.
  3. 가중치 크기를 더하고 여유 RAM과 비교합니다. 나머지 시스템을 위해 최소 1 GiB는 남겨 둡니다.
  4. 값을 설정하고 모델을 로드한 다음, ollama psprompt_eval_count으로 적용된 값을 확인합니다.
  5. free -m을 모니터링하면서 실제 작업을 실행합니다. swap 사용량이 증가하기 시작하면 컨텍스트 크기를 절반으로 줄입니다.

대부분의 작업에는 사용자가 지정하는 것보다 작은 컨텍스트가 필요합니다. 긴 보고서 요약은 16k면 충분합니다. 문서 청크 5개를 붙여 넣는 검색 프런트엔드는 8k를 넘는 경우가 드뭅니다. 전체 파일을 읽는 코딩 에이전트는 실제로 64k 이상이 필요한 경우입니다. 이 경우에는 컨텍스트 크기에 맞춰 장비를 정해야 하며, 장비에 맞춰 컨텍스트를 정해서는 안 됩니다. 서버를 새로 구성하는 중이라면 먼저 VPS에서 작동하는 Ollama 설치부터 진행하고, 모델이 문제없이 로드된 후 컨텍스트를 조정합니다.

FAQ

Ollama의 기본 컨텍스트 길이는 얼마입니까?

빌드와 하드웨어에 따라 다르므로 추측하지 말고 확인해야 합니다. Ollama FAQ에는 4096 토큰이 기록되어 있고, Modelfile 참조 문서에는 num_ctx 기본값이 2048로 기록되어 있습니다. 컨텍스트 길이 페이지에는 사용 가능한 VRAM에 따라 선택되는 기본값이 기록되어 있습니다. 24 GiB 미만에서는 4k, 24~48 GiB에서는 32k, 48 GiB 초과에서는 256k입니다. CPU만 사용하는 VPS는 작은 값에 해당합니다. ollama ps 열을 지원하는 빌드에서는 적용된 컨텍스트를 출력하고, API 응답의 prompt_eval_count은 모든 빌드에서 이를 확인할 수 있습니다.

Ollama가 긴 프롬프트의 시작 부분을 무시하는 이유는 무엇입니까?

프롬프트가 컨텍스트 윈도우보다 길어서 서버가 모델에 전달하기 전에 잘라냈기 때문입니다. 이 경우 오류가 반환되지 않습니다. 더 큰 num_ctx을 사용해 같은 프롬프트를 다시 보내고, 응답에서 prompt_eval_count가 증가하는지 확인합니다. 해당 값이 변하지 않는다면 클라이언트와 서버 사이의 무언가가 num_ctx 자체를 설정하고 있는 것입니다. 이는 채팅 프런트엔드와 에이전트 프레임워크에서 흔히 발생합니다.

더 큰 num_ctx에는 RAM이 얼마나 더 필요합니까?

컨텍스트 길이에 토큰당 캐시 비용인 2 * layers * kv_heads * head_dim * bytes_per_value를 곱하면 됩니다. f16의 Llama 3.1 8B에서는 토큰당 128 KiB입니다. 따라서 32k 토큰에는 가중치 외에 4 GiB가 필요하고, 전체 128k 토큰에는 16 GiB가 필요합니다. 모델을 로드할 때 캐시를 할당하므로 프롬프트가 짧더라도 큰 num_ctx은 해당 메모리를 사용합니다.

컨텍스트 윈도우가 커지면 Ollama가 느려집니까?

그렇습니다. 두 가지 이유가 있습니다. 프리필 작업량은 프롬프트 길이의 제곱에 비례해 증가하므로 긴 입력은 길이만으로 예상하는 것보다 첫 토큰 반환을 더 지연시킵니다. 또한 큰 캐시가 메모리를 두고 경쟁합니다. GPU 서버에서는 일부 레이어가 system RAM으로 이동하고, CPU 서버에서는 시스템이 swap을 사용하게 될 가능성이 커집니다. 사용하지 않는 큰 num_ctx도 메모리는 차지하지만 프리필 시간은 증가시키지 않습니다.

한 모델에 num_ctx를 영구적으로 설정할 수 있습니까?

가능합니다. FROM llama3.1:8bPARAMETER num_ctx 16384을 포함하는 Modelfile을 작성한 다음 ollama create llama3.1-16k -f ./Modelfile을 실행합니다. llama3.1-16k을 요청하는 모든 클라이언트는 옵션을 보내지 않아도 이 컨텍스트를 사용합니다. 자체 num_ctx을 포함한 요청이 있으면 해당 요청이 우선하므로, 이는 상한이 아니라 기본값을 설정합니다.