로컬 LLM 설정에서 시스템 프롬프트 상단에 타임스탬프를 넣을 경우 발생하는 문제점
요약
로컬 LLM 환경에서 시스템 프롬프트 상단에 매 턴마다 변경되는 요소(예: 타임스탬프)를 배치하면, KV 캐시 재사용이 방해되어 전체 프롬프트를 반복 계산해야 하는 문제가 발생합니다. 이로 인해 프리필 시간이 크게 증가하며, 성능 최적화를 위해서는 변하는 내용은 항상 프롬프트의 맨 뒤에 위치시키는 것이 중요합니다.
핵심 포인트
- 매 턴 변경되는 요소는 프롬프트 끝에 배치하여 KV 캐시 재사용을 극대화해야 합니다.
- 타임스탬프 같은 작은 변화도 전체 프리필 시간을 크게 늘릴 수 있습니다.
- 캐시 적중률 계산 시 `prompt_eval_count - prompt_eval_cached_count` 공식을 사용하세요.
- 따뜻한 캐시 상태의 성능 지표는 신뢰하지 않는 것이 좋습니다.
이 내용은 Ollama에 관한 것이지만, llama.cpp 기반으로 구축된 모든 것(LM Studio, Jan, Open WebUI in front of Ollama, 자체 스크립트 등)에 동일하게 적용되는 메커니즘입니다. 로컬 모델은 이미 처리한 프롬프트의 KV cache를 유지하며 다음 요청에서 이를 재사용합니다. 이러한 재사용은 공유 접두사(shared prefix)가 있는 경우에만 생존합니다: 가장 처음 토큰부터 새로운 프롬프트가 이전 프롬프트와 일치하는 동안 정확하게 유효합니다. 그러나 달라지는 첫 번째 토큰이 발생하면, 나머지 부분이 아무리 동일하더라도 그 이후의 모든 것은 폐기됩니다. 이는 메시지마다 변경되는 아주 작은 요소 하나가 시스템 프롬프트 상단에 위치할 경우, 매 턴(turn)마다 전체 프롬프트를 다시 계산해야 함을 의미합니다. 타임스탬프가 일반적인 원인입니다. '현재 날짜 및 시간: 2026-10-12 09:41'은 매우 흔한 첫 줄입니다. 측정해 보았습니다. 동일 모델(qwen2.5:7b), 동일 324 토큰 시스템 프롬프트, 동일 단어들을 사용했습니다. 유일한 차이점은 21 토큰짜리 타임스탬프가 위치하는 곳뿐이었습니다:
| Timestamp position | Prompt tokens | Reused from cache | Prefill time |
|---|---|---|---|
| At the top | 324 | 4 | 64.6 ms |
| At the bottom | 324 | 290 | 18.6 ms |
상단에 있을 때보다 하단에 있을 때 프리필(prefill) 시간이 약 3.5배나 절약되었습니다. RAG 청크가 포함된 2,000 토큰 시스템 프롬프트의 경우 배율이 더 나빠지며, 프리필은 각 턴에서 GPU가 실제로 작업하는 부분입니다. 두 번의 호출로 자체 설정을 확인해 보세요. Ollama 0.33.3 버전부터는 네이티브 API가 캐시가 반환한 내용을 보고합니다. 동일한 채팅을 두 번 보내고 두 번째 답변을 살펴보세요:
`sh for i in 1 2; do curl -s localhost:11434/api/chat -d '{
턴마다 변경되는 내용은 맨 뒤에 배치하는 것이 좋습니다: 시간, 사용자 이름, 세션 ID, 검색된 청크(retrieved chunks) 등이 있습니다. 그리고 설정이 변경되지 않은 경우 RAG 청크는 안정적인 순서를 유지해야 합니다. 턴 사이에 이들을 재순위화(re-ranking)하면 움직인 첫 번째 청크에서 캐시가 깨집니다. 모델은 같은 내용을 받습니다. 다만 다시 읽지 않을 뿐입니다. 측정 시 주의할 두 가지 함정이 있습니다: prompt_eval_duration은 0.33.3 버전 이후로 캐시되지 않은 토큰에 대해서만 시간을 측정하는 반면, prompt_eval_count는 여전히 전체 토큰 수를 나타냅니다. 모든 대시보드에서 하듯이 이 둘을 나누면 캐시 적중률(cache hit ratio)로 인해 프리필 속도(prefill speed)가 부풀려집니다. 대신 prompt_eval_count - prompt_eval_cached_count로 나누세요. Ollama 0.35 이상 버전에서는 OpenAI 호환 엔드포인트에 준비된 타이밍인 prompt_per_second를 제공하지만, 여기에도 같은 실수가 내재되어 있습니다. 저는 따뜻한 캐시(warm cache) 상태에서 3875 tok/s가 보고되었지만 실제로는 125 tok/s였습니다 (ollama/ollama#18948에 기록됨). 따뜻한 캐시 상태의 해당 필드는 신뢰하지 마세요. 공개합니다: 저는 Ollama을 위한 로컬 관측 가능 UI인 LLMxRay를 유지 관리하고 있습니다 (Apache-2.0, localhost를 벗어나지 않음, npx llmxray ). 이 도구에는 턴 사이에 값이 변경되는 프롬프트의 부분을 찾아내고, 공유 접두사(shared prefix)가 깨지는 지점을 보여주며, 움직임으로 얻는 절약량을 자체 데몬과 비교 측정하는 페이지가 있습니다. 위 모든 것은 그것 없이도 작동합니다; 두 개의 curl 명령어가 전체 방법입니다. Open WebUI 등에서 사람들이 어떤 크기의 프롬프트를 사용하는지, 그리고 누군가 그들의 프론트엔드가 프롬프트 상단에 무엇을 넣는지 살펴봤는지 궁금합니다. 그들 중 몇몇은 날짜를 먼저 주입(inject)합니다. submitted by /u/GuruCsharp [link] [comments]
AI 자동 생성 콘텐츠
본 콘텐츠는 r/SelfHosted (AI filter)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기