Ollama num_ctx 설정 및 컨텍스트 길이 확인 방법
Ollama는 기본 컨텍스트 윈도우가 작아 긴 프롬프트가 잘릴 수 있습니다. num_ctx 옵션을 사용하여 컨텍스트 길이를 늘리는 방법과 서버의 실제 토큰 처리량을 확인하는 방법을 설명합니다. VRAM 용량에 따른 기본값 차이와 설정 시 주의사항을 확인하십시오.
num_ctx의 역할과 긴 프롬프트가 잘리는 이유
Ollama의 컨텍스트 길이는 로드된 모델이 한 번에 메모리에 담을 수 있는 토큰의 개수이며, num_ctx 옵션으로 이를 설정합니다. Ollama는 모델이 지원하는 최대치보다 훨씬 낮은 값을 기본값으로 선택하므로, 긴 프롬프트는 모델이 읽기도 전에 잘려 나갑니다. 응답 과정에서 이러한 잘림 현상이 발생했음을 알려주는 메시지는 없습니다.
Llama 3.1 8B는 Ollama 모델 라이브러리에서 128k 컨텍스트 윈도우를 지원한다고 명시되어 있습니다. 하지만 기본 설정된 서버에서는 해당 값을 온전히 사용할 수 없습니다. Ollama 공식 문서조차 페이지마다 서로 다른 기본값을 제시합니다. FAQ에는 4096 토큰이라고 되어 있고, Modelfile 참조 문서에는 num_ctx의 기본값이 2048이라고 되어 있으며, 컨텍스트 길이 페이지에서는 가용 VRAM(비디오 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 psCONTEXT 열은 해당 열을 출력하는 빌드에서 현재 로드된 모델이 실행 중인 컨텍스트 길이를 담고 있습니다. 그 옆의 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추론 실행기(inference runner)는 n_ctx를 포함하는 줄에 컨텍스트 크기를 출력합니다. 정확한 문구는 릴리스마다 변경될 수 있으므로, 해당 줄이 보이지 않는다고 해서 문제가 있다고 단정하기보다는 명칭이 변경되었을 가능성을 고려하십시오.
num_ctx를 설정하는 네 가지 방법
요청 시 설정. "options": {"num_ctx": 16384}을 /api/generate 또는 /api/chat로 전송합니다. 이 설정은 다른 모든 설정을 우선하며 해당 요청에만 적용됩니다. 설정값이 현재 로드된 모델의 실행값과 다르면 서버는 모델을 먼저 다시 로드합니다. 이는 응답의 load_duration에서 확인할 수 있는데, 값이 0에 가깝다가 수 초 단위로 급격히 증가합니다. 모델이 오랫동안 유휴 상태여서 언로드된 경우에도 동일한 대기 시간이 발생하므로, 컨텍스트 크기가 결정되었다면 keep_alive를 사용하여 모델을 상주시키는 것이 좋습니다.
대화형 세션에서 설정. ollama run 내부에서 /set parameter num_ctx 16384을 입력합니다. 해당 세션 동안 유지됩니다.
Modelfile에서 설정. 이 방법은 값을 명명된 모델에 고정하므로, 클라이언트 측 변경 없이 모든 클라이언트가 해당 값을 사용하게 됩니다.
FROM llama3.1:8b
PARAMETER num_ctx 16384ollama 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를 포함하는 요청은 서버 기본값을 우선하므로, 자체적으로 작은 값을 보내는 채팅 프론트엔드나 에이전트는 사용자가 적용한 systemd 설정을 조용히 무효화합니다. 코딩 에이전트를 Ollama 서버에 연결할 때 서버를 탓하기 전에 클라이언트가 무엇을 전송하는지 먼저 확인하십시오.
num_ctx를 모델 최댓값으로 설정하면 안 되는 이유
어텐션(Attention) 메커니즘은 모든 토큰이 이전의 모든 토큰을 참조하게 합니다. 이전 토큰들에 대해 계산된 키(key)와 값(value)은 매번 다시 계산하지 않도록 저장되는데, 이 저장소가 바로 KV 캐시(key/value cache)입니다. KV 캐시는 대화가 길어짐에 따라 커지는 것이 아니라 모델이 로드될 때 num_ctx 전체에 대해 할당되므로, 한 줄짜리 프롬프트를 입력하더라도 큰 컨텍스트를 설정하면 그만큼의 메모리를 점유하게 됩니다.
DigitalOcean의 추론 비용 튜토리얼은 이 계산식을 한 줄로 요약합니다.
kv_bytes_per_token = 2 * layers * kv_heads * head_dim * bytes_per_value2는 키와 값을 각각 계산함을 의미합니다. 나머지 수치는 사용 중인 모델의 사양을 확인하십시오.
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개의 레이어와 8개의 키/값 헤드를 가집니다. 헤드 차원은 embed을 heads로 나눈 값이며, 여기서는 4096 / 32 = 128입니다. 일부 모델은 이를 llama.attention.key_length로 직접 명시하기도 합니다. 기본 캐시는 f16 값을 저장하므로 bytes_per_value는 2가 되며, 2 32 8 128 2를 계산하면 131,072 바이트가 됩니다. 즉, 컨텍스트 토큰 하나당 128 KiB의 캐시가 필요합니다. 여기에 컨텍스트 길이를 곱하면 비용은 더 이상 추상적인 수치가 아니게 됩니다.
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 행은 위 공식에 따른 산술적 결과이며 실측값이 아닙니다. 총합 열에는 2026년 8월 기준 Ollama 라이브러리에 명시된 llama3.1:8b의 다운로드 용량인 4.9 GB(실제 4.6 GiB)를 더했으며, 연산 버퍼와 서버 프로세스 자체의 메모리는 제외되었습니다. 따라서 이 수치는 최소치로 간주해야 합니다.
핵심은 데이터의 형태입니다. 8k 컨텍스트에서 캐시 비용은 1 GiB로, 모델 가중치에 비하면 미미한 수준입니다. 하지만 모델의 최대치인 128k에 도달하면 캐시 비용은 16 GiB가 되어 가중치의 3배를 넘어서며, 총합은 20.6 GiB에 육박합니다. 따라서 4 GB VPS에서는 이 모델을 유용한 컨텍스트로 로드할 수 없습니다. 8 GB VPS는 8k 컨텍스트까지 무난하게 처리하며, 16 GB VPS는 32k 컨텍스트를 사용하면서도 시스템 운영을 위한 여유 메모리를 확보할 수 있습니다. 이러한 임계값은 모델 가중치가 커질수록 함께 상승합니다. 따라서 8B 모델보다 더 큰 모델을 고려 중이라면, CPU 전용 VPS에서의 Qwen 27B 태그 사례에서 계산한 것처럼 8 GB에서 64 GB 사이의 메모리에서 컨텍스트를 위해 남겨둘 수 있는 공간이 얼마나 적은지 확인해 보시기 바랍니다.
KV 캐시가 메모리에 맞지 않을 때 발생하는 현상
CPU 전용 VPS에서는 프로세스 크기가 단순히 증가합니다. 모델이 로드되는 동안과 긴 요청이 처리되는 동안 프로세스를 모니터링하십시오.
free -m
ps -eo rss,comm --sort=-rss | head -n 5RSS(resident set size)는 킬로바이트 단위로 출력됩니다. free -m에서 스왑 사용량이 증가하기 시작하면 컨텍스트 크기를 줄이십시오. 스왑에 위치한 KV 캐시는 토큰당 수 초의 생성 지연을 유발하는데, 이는 새로운 토큰을 생성할 때마다 전체 캐시를 읽어야 하기 때문입니다.
시스템 메모리가 완전히 고갈되면 커널은 가장 큰 프로세스를 선택하여 강제 종료합니다.
sudo dmesg | grep -i "killed process"Out of memory: Killed process 1234 (ollama)라는 메시지가 출력되면 요청한 컨텍스트가 메모리에 맞지 않는다는 의미입니다. Ollama는 대개 그 단계에 도달하기 전에 요청을 거부하며, 이때 요청은 필요한 메모리 용량과 가용 메모리 용량을 명시한 메시지와 함께 실패합니다.
GPU 서버에서는 실패 현상이 더 조용하게 나타납니다. 레이어가 시스템 RAM으로 넘어가고 ollama ps에서 CPU와 GPU의 분할 상태가 표시되며, 처리량(throughput)이 급격히 떨어집니다. 성능 저하 폭은 하드웨어에 따라 다르므로, 다른 사람의 측정치를 신뢰하기보다 본인의 서버에서 토큰당 처리 속도를 직접 측정하여 각 컨텍스트 설정에 따른 성능을 확인하십시오.
프리필(Prefill) 시간은 프롬프트 길이에 따라 기하급수적으로 증가합니다
프리필은 첫 번째 출력 토큰이 생성되기 전 입력 데이터에 대해 수행되는 작업입니다. 각 프롬프트 토큰은 이전의 모든 토큰을 참조하므로, 전체 작업량은 입력 길이의 제곱에 비례하여 증가합니다. 따라서 프롬프트 길이를 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에서는 일반적으로 긴 컨텍스트 요청의 prefill이 가장 느린 부분이다. 짧은 프롬프트로 측정한 초당 토큰 수로는 긴 요청의 성능을 예측할 수 없다. prefill이 앞단에 설정된 타임아웃보다 오래 걸리면 긴 프롬프트가 응답 대신 context deadline exceeded로 반환되는 경우가 많다. 따라서 컨텍스트를 줄이기 전에 어느 계층에서 먼저 처리를 중단했는지 확인해야 한다.
이 문제는 동시성(concurrency) 환경에서 가장 두드러집니다. 처리 중인 모든 요청은 각자의 캐시를 필요로 하므로, 위 차트의 메모리 사용량은 서버 전체가 아닌 요청 단위입니다. 따라서 하나의 긴 요청이 서버를 점유하면 짧은 요청들은 그 뒤에서 대기하게 됩니다. OLLAMA_NUM_PARALLEL 값을 신중하게 설정하십시오. 또한 두 값을 동시에 높이기 전에 자체 호스팅 LLM이 수용 가능한 동시 사용자 수에 관한 문서를 먼저 읽어보시기 바랍니다.
더 작은 캐시로 컨텍스트 메모리 확보하기
공식의 bytes_per_value는 사용자가 제어할 수 있는 설정입니다. Ollama의 FAQ는 OLLAMA_KV_CACHE_TYPE을 문서화하고 있으며, 기본값인 f16은 2바이트, q8_0은 1바이트, 그보다 낮은 설정은 q4_0를 사용합니다. q8_0으로 변경하면 캐시 크기가 절반으로 줄어들어, 32k 행의 경우 2 GiB를 차지하게 되어 기존의 4 GiB보다 메모리 사용량이 감소합니다. 가중치를 양자화하면 동일한 예산 내에서 다른 쪽의 메모리를 확보할 수 있으며, VPS에 적합한 GLM 태그는 이러한 절충안을 선택할 경우 양자화 단계별로 작업이 진행됩니다. 동일한 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 설정을 위한 레시피
/api/show에서 모델의 최대 컨텍스트, 레이어 수, 키/값 헤드 수를 확인합니다.- 공식으로 토큰당 바이트 수를 계산한 뒤, 원하는 컨텍스트 길이를 곱합니다.
- 모델 가중치 크기를 더한 후 가용 RAM과 비교합니다. 이때 시스템 운영을 위해 최소 1 GiB의 여유 공간을 확보해야 합니다.
- 값을 설정하고 모델을 로드한 뒤,
ollama ps및prompt_eval_count으로 실제 적용된 값을 확인합니다. - 실제 워크로드를 실행하면서
free -m을 모니터링하고, 스왑이 발생하기 시작하면 컨텍스트 크기를 절반으로 줄입니다.
대부분의 작업은 생각보다 적은 컨텍스트를 필요로 합니다. 긴 보고서를 요약하는 작업은 16k 내에서 충분히 가능합니다. 5개의 문서 조각을 붙여넣는 검색 프론트엔드도 8k를 넘는 경우가 드뭅니다. 전체 파일을 읽어야 하는 코딩 에이전트의 경우에만 64k 이상의 컨텍스트가 실제로 필요하며, 이럴 때는 컨텍스트에 맞춰 서버 사양을 결정해야 합니다. 서버를 새로 구축하는 중이라면 VPS에 Ollama 설치하기를 따라 시작하고, 모델이 정상적으로 로드된 후에 컨텍스트를 튜닝하십시오.
FAQ
Ollama의 기본 컨텍스트 길이는 얼마입니까?
빌드와 하드웨어에 따라 다르므로 가정하지 말고 직접 확인해야 합니다. Ollama FAQ는 4096 토큰을 명시하고, Modelfile 참조 문서는 num_ctx 기본값으로 2048을 명시하며, 컨텍스트 길이 페이지는 가용 VRAM에 따라 기본값이 결정된다고 설명합니다. 24 GiB 미만은 4k, 24~48 GiB는 32k, 그 이상은 256k가 적용됩니다. CPU 전용 VPS는 낮은 값을 사용하게 됩니다. ollama ps는 해당 열을 포함하는 빌드에서 적용된 컨텍스트를 출력하며, prompt_eval_count은 모든 빌드의 API 응답에서 이를 증명합니다.
Ollama가 긴 프롬프트의 앞부분을 무시하는 이유는 무엇입니까?
프롬프트가 컨텍스트 윈도우보다 길었기 때문에 서버가 모델에 전달하기 전에 이를 잘라냈으며, 별도의 오류 메시지도 반환되지 않았기 때문입니다. 더 큰 num_ctx 값을 설정하여 동일한 프롬프트를 다시 보내고 응답의 prompt_eval_count 값이 증가하는지 확인하십시오. 해당 숫자가 변하지 않는다면, 사용자 환경과 서버 사이의 무언가가 num_ctx 값을 자체적으로 설정하고 있는 것입니다. 이는 채팅 프론트엔드나 에이전트 프레임워크에서 흔히 발생합니다.
더 큰 num_ctx를 사용하려면 RAM이 얼마나 더 필요합니까?
컨텍스트 길이에 토큰당 캐시 비용인 2 * layers * kv_heads * head_dim * bytes_per_value를 곱하십시오. Llama 3.1 8B f16 모델의 경우 토큰당 128 KiB이므로, 32k 토큰은 4 GiB, 전체 128k는 모델 가중치 외에 16 GiB가 추가로 필요합니다. 캐시는 모델이 로드될 때 할당되므로, 프롬프트가 짧더라도 큰 num_ctx 값을 설정하면 해당 메모리만큼 비용이 발생합니다.
컨텍스트 윈도우를 크게 설정하면 Ollama가 느려집니까?
네, 두 가지 측면에서 느려집니다. 프리필(prefill) 작업은 프롬프트 길이의 제곱에 비례하여 증가하므로, 긴 입력은 길이 자체보다 더 큰 지연을 발생시켜 첫 번째 토큰 출력을 늦춥니다. 또한 더 커진 캐시는 메모리 자원을 점유합니다. GPU 서버에서는 레이어를 시스템 RAM으로 밀어내고, CPU 서버에서는 시스템이 스왑(swap)을 사용하게 만듭니다. 사용하지 않는 큰 num_ctx 값이라도 메모리는 점유하지만, 프리필 시간은 늘어나지 않습니다.
특정 모델에 대해 num_ctx를 영구적으로 설정할 수 있습니까?
네. FROM llama3.1:8b과 PARAMETER num_ctx 16384을 포함하는 Modelfile을 작성한 뒤 ollama create llama3.1-16k -f ./Modelfile를 실행하십시오. 이후 llama3.1-16k을 요청하는 모든 클라이언트는 별도의 옵션 전송 없이 해당 컨텍스트를 사용합니다. 요청 시 자체적인 num_ctx을 포함하면 해당 값이 우선 적용되므로, 이는 상한선이 아닌 기본값을 설정하는 것입니다.