llama.cpp 컨텍스트 길이와 KV 캐시, GPU 오프로딩만으로 해결되지 않는 메모리 문제
AI를 활용하여 생성한 이미지입니다.
로컬 LLM을 실행할 때 GGUF 파일이 GPU 메모리에 들어가는지만 계산하면 실제 사용량을 자주 놓칩니다. 짧은 질문은 잘 되는데 긴 대화에서 급격히 느려지거나, 모델 하나는 로드되지만 두 번째 요청에서 메모리가 부족해지는 이유는 가중치 외에 컨텍스트, KV 캐시, 배치 버퍼와 동시 슬롯이 함께 자리를 차지하기 때문입니다. Ollama·LM Studio·llama.cpp의 큰 차이를 먼저 보고 싶다면 로컬 LLM 기초 비교 글을 참고하고, 여기서는 llama.cpp 계열 서버의 조정 순서를 다룹니다.
모델 파일 크기는 전체 예산의 시작점입니다
llama.cpp는 여러 양자화 형식을 지원하고, 모델이 GPU 메모리보다 클 때 CPU와 GPU에 나누어 실행하는 하이브리드 구성을 지원합니다.[1] 따라서 Q4나 Q8 파일 크기는 가중치 저장에 필요한 대략적인 출발점일 뿐입니다. 실행 중에는 이미 처리한 토큰의 상태를 보관하는 KV 캐시, 프롬프트를 묶어 처리하는 배치 버퍼, 런타임과 운영체제가 쓰는 여유 공간이 추가됩니다.
| 항목 | 늘어나는 조건 | 나타나는 증상 |
|---|---|---|
| 가중치 | 더 큰 모델·높은 정밀도 | 처음부터 로드 실패 또는 오프로딩 감소 |
| KV 캐시 | 긴 입력·긴 대화·여러 슬롯 | 대화가 길어질수록 메모리와 지연 증가 |
| 배치·실행 버퍼 | 큰 배치·동시 처리 | 동시 요청에서 급격한 메모리 압박 |
| 운영체제 여유 | 다른 앱·화면·백그라운드 작업 | 스왑, 멈춤, 예측하기 어려운 지연 |
ctx-size는 품질 옵션이 아니라 자원 계약입니다
llama-server의 -c 또는 --ctx-size는 한 요청이 사용할 컨텍스트 크기를 정합니다. 0이면 모델에서 읽은 기본값을 사용합니다.[2] 큰 값을 지정하면 긴 문서를 한 번에 넣을 여지가 생기지만, 실제 입력이 짧은데도 큰 컨텍스트를 잡으면 다른 작업에 남는 메모리가 줄어들 수 있습니다.
./llama-server -m ./models/model.gguf --host 127.0.0.1 --port 8080 -c 8192 -ngl 99
처음부터 128K처럼 큰 값을 고르기보다 작업을 나누는 것이 낫습니다. 짧은 질의응답은 작은 컨텍스트로 시작하고, 요약은 문서를 검색해 필요한 부분만 넣으며, 코딩은 현재 파일과 관련 함수만 보내는 식입니다. 긴 컨텍스트가 필요하더라도 “최대 길이”와 “항상 실제로 넣는 길이”를 구분해야 합니다.
KV 캐시가 긴 대화에서 커지는 방식
KV 캐시는 이미 처리한 토큰의 어텐션 상태를 저장해 다음 토큰을 만들 때 앞부분을 매번 다시 계산하지 않도록 합니다. 그래서 대화가 이어질 때 계산을 줄이는 장점이 있지만, 저장해야 할 토큰이 늘어나면 메모리도 함께 사용합니다. 모델의 모든 레이어를 GPU에 올렸다는 사실은 긴 대화와 다중 사용자 요청이 안전하다는 뜻이 아닙니다.
다음 증상이 함께 나타나는지 기록해 보세요.
- 짧은 질문은 빠르지만 같은 대화가 길어질수록 생성 속도가 떨어집니다.
- 첫 요청은 성공하는데 두 번째 동시 요청에서 운영체제가 메모리를 압박합니다.
- 컨텍스트를 높인 뒤 모델 로드는 되지만 화면이 멈추거나 스왑이 늘어납니다.
- 단일 슬롯에서는 괜찮지만 서버를 여러 사용자가 공유할 때만 오류가 납니다.
이 경우 양자화를 바로 더 낮추기 전에 -c와 슬롯 수를 실제 사용량에 맞추세요. 품질이 중요한 작업에서 무조건 더 작은 양자화를 택하면 메모리는 줄어도 출력 품질과 지시 준수 정도가 달라질 수 있습니다.
GPU 오프로딩은 단계적으로 조정하세요
-ngl은 GPU에 올릴 레이어 수를 조절하는 대표 옵션입니다.[1] GPU에 더 많이 올리면 CPU와의 왕복을 줄일 수 있지만, GPU에는 가중치뿐 아니라 KV 캐시와 실행 버퍼를 위한 여유도 필요합니다. GPU 메모리가 빠듯하면 모든 레이어를 올리는 것보다 일부를 CPU에 두어 안정성을 확보하는 편이 낫습니다.
- 다른 GPU 작업과 브라우저·편집 앱을 닫고 기본 메모리 여유를 확인합니다.
- 한 슬롯과 작은 컨텍스트로 모델을 먼저 실행합니다.
- 짧은 입력, 긴 입력, 동시 요청을 각각 같은 조건에서 비교합니다.
- 메모리가 남을 때만
-ngl을 단계적으로 올립니다. - 오류가 나면 마지막으로 바꾼 값 하나만 되돌려 원인을 보존합니다.
속도가 느리다는 이유만으로 컨텍스트와 GPU 레이어와 동시 슬롯을 동시에 올리면 무엇이 병목인지 알 수 없습니다. 하드웨어 세대, 메모리 공유 방식, 드라이버, 백엔드에 따라 같은 옵션의 결과도 다르므로, 특정 토큰/초 수치를 보편적인 기준처럼 사용하지 마세요.
배치·동시 요청을 별도로 보세요
개인용 대화와 서버 운영은 메모리 조건이 다릅니다. 한 사람이 한 대화를 쓰는 환경에서는 컨텍스트가 핵심이지만, 여러 사용자가 같은 서버에 요청을 보내면 슬롯 수와 각 슬롯의 컨텍스트가 함께 문제를 만듭니다. 입력을 한꺼번에 처리하는 배치 크기를 높이면 처리량에 도움이 될 수 있지만, 피크 메모리를 먼저 확인해야 합니다.
| 사용 장면 | 먼저 고정할 값 | 관찰할 것 |
|---|---|---|
| 짧은 개인 질문 | 작은 ctx·1슬롯 | 기본 로드와 생성 지연 |
| 긴 문서 요약 | 문서 분할·필요 구간만 입력 | KV 캐시와 반복 입력 비용 |
| 내부 API 서버 | 슬롯 수·최대 입력 길이 | 동시 요청의 메모리 피크와 대기열 |
서버 주소와 API 옵션도 실제 실행값과 맞춰야 합니다. llama-server 문서는 기본적으로 로컬 주소와 OpenAI 호환 엔드포인트를 설명하지만, 클라이언트가 보내는 컨텍스트·출력 길이 옵션이 서버에서 그대로 적용된다는 뜻은 아닙니다.[2] Ollama를 함께 쓴다면 모델을 메모리에서 내리는 방법과 로컬 API 요청 형식을 각각 확인하세요.[3][4]
재현표를 만들어야 선택이 쉬워집니다
모델 파일명, 양자화 형식, -c, -ngl, 슬롯 수, 배치 관련 값, 운영체제와 GPU 메모리를 한 줄에 기록하세요. 같은 프롬프트를 짧은 입력·긴 입력·동시 입력으로 나누고, 성공 여부·메모리 피크·지연·출력 품질을 적습니다. 숫자를 비교할 때는 백그라운드 앱과 입력 토큰 수를 고정해야 합니다. 공식 문서는 특정 컴퓨터에서의 보편적인 속도를 보장하지 않으므로 자신의 모델과 입력으로 측정해야 합니다.
메모리 부족 때 되돌리는 순서
- 동시 슬롯과 배치 크기를 먼저 낮춥니다.
ctx-size를 실제 작업 길이에 맞게 줄입니다.- 그래도 부족하면
-ngl을 낮춰 CPU 혼합 실행으로 돌아갑니다. - 그 뒤에도 모델이 맞지 않을 때만 양자화나 모델 크기를 재검토합니다.
반대로 속도가 느리다면 컨텍스트를 줄인 상태에서 GPU 레이어를 조금씩 올리고, 단일 요청과 동시 요청을 분리해 측정하세요. “VRAM에 모델이 들어간다”는 것은 실행 가능성의 한 조건일 뿐입니다. 안정적인 설정은 작업의 실제 문맥 길이와 사용자 수를 정하고 KV 캐시와 실행 버퍼에 여유를 남기는 설정입니다.
자주 묻는 질문
ctx-size를 크게 잡으면 답변 품질이 항상 좋아지나요?
아닙니다. 긴 문맥을 실제로 활용해야 하는 작업에서만 이점이 있습니다. 불필요한 문서와 반복 대화를 넣으면 메모리와 지연만 커지고 중요한 지시가 묻힐 수 있습니다.
GPU 오프로딩을 100%로 하면 가장 빠른가요?
GPU에 남는 메모리가 충분할 때는 유리할 수 있지만, KV 캐시와 버퍼까지 계산해야 합니다. 빠른 로드보다 안정적인 반복 실행이 우선이면 일부 CPU 실행이 더 적합할 수 있습니다.
동시 요청에서만 OOM이 나는 이유는 무엇인가요?
각 요청이 별도의 컨텍스트와 캐시를 사용할 수 있기 때문입니다. 슬롯 수와 최대 입력 길이를 낮춘 뒤 단일 요청과 같은 입력으로 다시 비교하세요.
Ollama 설정과 llama-server 설정을 그대로 바꿔도 되나요?
이름이 비슷해도 런타임이 옵션을 처리하는 방식은 다를 수 있습니다. 실제 서버 문서와 API 응답을 확인하고, 클라이언트가 보낸 값이 적용됐는지 로그로 확인하세요.
[…] 메모리와 실행 조건이 궁금하다면 Llama.cpp 컨텍스트 크기와 KV 캐시 정리도 참고할 수 […]
[…] llama.cpp 컨텍스트 길이와 KV 캐시, GPU 오프로딩만으로 해결되지 않는 메모리 … […]