본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 16. 07:04

개인 개발을 위해 Ollama로 로컬 LLM 실행하기

요약

Ollama를 사용하여 로컬 환경에서 LLM을 실행할 때 발생하는 컨텍스트 윈도우 제한 문제와 작동 원리를 설명합니다. Ollama가 llama.cpp를 기반으로 GGUF 형식을 어떻게 활용하는지, 그리고 효율적인 실행을 위한 양자화와 메모리 계산법을 다룹니다.

핵심 포인트

  • Ollama는 기본적으로 2048 토큰의 컨텍스트 윈도우를 제공하여 초과 시 데이터를 잘라냄
  • Ollama는 llama.cpp를 래퍼로 사용하여 일반 하드웨어에서 추론을 가능하게 함
  • GGUF 형식은 가중치, 토크나이저, 하이퍼파라미터를 포함한 독립적 패키지임
  • 로컬 실행 시 중요한 것은 파라미터 수가 아닌 양자화된 가중치의 메모리 용량임

모델을 로컬에서 처음 실행하는 거의 모든 사람이 첫 주에 겪게 되는 일이 있습니다. 반짝거리는 새로운 로컬 어시스턴트에 600줄짜리 파일을 붙여넣고 버그를 찾아달라고 요청하면, 모델은 자신이 읽은 부분에도 없는 함수를 아주 자신 있게 다시 작성해 버립니다. 에러도 없고, 경고도 없습니다. 모델이 파일을 보기 전부터 그냥... 조용히 파일의 대부분을 바닥에 떨어뜨려 버린 것입니다.

이것은 모델이 멍청해서 발생하는 일이 아닙니다. Ollama가 지시받은 대로 정확히 수행하고 있기 때문입니다. 기본적으로 Ollama는 모든 모델에 **2048 토큰 (tokens)**의 컨텍스트 윈도우 (context window)를 제공하며, 그 범위를 넘어서는 것은 조용히 잘라냅니다 (truncate). 이는 "Ollama를 설치했다"와 "내 머신에서 무엇이 실행되고 있는지 실제로 이해하고 있다"를 가르는 몇 가지 작은 차이점 중 하나입니다. 중요한 내용들을 살펴보겠습니다. 내부적으로 어떻게 작동하는지, 실제로 어떤 하드웨어가 필요한지, 주의해야 할 점(gotchas), 그리고 "그냥 API를 호출하는 대신 굳이 이 고생을 할 가치가 있는가?"에 대한 솔직한 답변까지 말이죠.

Ollama의 실체

Ollama는 "LLM을 위한 Docker"라고 설명되곤 하는데, 이는 꽤 괜찮은 일차적인 근사치입니다. 모델을 pull 하고, run 하며, 레지스트리(registry)가 존재하죠. 하지만 Ollama는 실제 무거운 작업을 수행하는 주체를 숨깁니다. 그 이면에서 Ollama는 llama.cpp를 친숙하게 감싸고 있는 래퍼 (wrapper)입니다. llama.cpp는 일반 소비자용 하드웨어에서 이러한 모델들을 실행하는 것을 처음으로 실용적으로 만든 C/C++ 추론 엔진 (inference engine)입니다. ollama run을 입력하면, 여러분은 실제로 합리적인 기본 설정과 깔끔한 HTTP 서버가 결합된 llama.cpp 런타임 (runtime)을 부팅하는 것입니다.

Ollama가 실행하는 모델들은 GGUF (GPT-Generated Unified Format)라고 불리는 형식으로 되어 있습니다. GGUF 파일은 단순한 가중치 (weights)가 아닙니다. 텐서 (tensors), 토크나이저 설정 (tokenizer config), 아키텍처 세부 정보, 그리고 학습된 컨텍스트 길이와 같은 하이퍼파라미터 (hyperparameters)를 모두 하나의 파일에 묶은 독립적인 패키지입니다. 그렇기 때문에 ollama pull llama3.1을 실행하면 바로 작동하는 결과물을 얻게 됩니다. 런타임이 모델을 재구성하는 데 필요한 모든 것이 상자 안에 들어있기 때문입니다.

Ollama 자체는 아직 신생 프로젝트입니다. 이 프로젝트는 2023년 7월 초에 첫 번째 릴리스를 출시했으며, 일반 개발자들도 "노트북에서 실제 LLM을 실행하는 것"을 가능하게 만든 오픈 웨이트 (open-weight) 모델의 물결(같은 달 Llama 2 출시)을 타고 성장했습니다. 그 전까지 로컬 추론 (local inference)이란 무언가를 컴파일하고 수많은 GitHub 이슈를 읽어야 함을 의미했습니다. Ollama의 핵심 가치는 바로 그러한 마찰을 제거하는 것입니다.

아무도 미리 설명해주지 않는 하드웨어 계산법

모델이 사용자의 기기에서 잘 작동할지를 결정하는 숫자는 파라미터 (parameter) 수가 아닙니다. 그것은 양자화 (quantization) 이후 가중치 (weights)가 차지하는 메모리 용량입니다. 이것은 모델을 로컬에서 실행하기 위한 가장 중요한 개념이므로, 잠시 시간을 들여 살펴볼 가치가 있습니다.

모델의 가중치는 원래 16비트 부동 소수점 (16-bit floating point)으로 저장됩니다. 양자화는 이를 더 낮은 정밀도, 일반적으로 4비트 정수 (4-bit integers)로 압축하여 파일 크기를 줄이고, 똑같이 중요한 점으로서 추론 (inference)의 병목 현상을 일으키는 메모리 대역폭 (memory-bandwidth) 압박을 완화합니다. Ollama에서 기본적으로 보게 될 형식은 llama.cpp의 "K-quant" 제품군의 일부인 Q4_K_M입니다. 이 트레이드오프 (trade-off)는 진정으로 훌륭합니다. Q4_K_M은 16비트 원본 대비 메모리 사용량을 약 75% 절감하면서도, 대부분의 벤치마크에서 품질 손실은 1% 미만으로 유지합니다. 이것이 완전히 공짜 점심은 아니지만, 대부분의 사람들이 다른 것을 사용하지 않을 정도로 충분히 근접한 수치입니다.

하드웨어 규모를 정할 때 실제로 도움이 되는 경험 법칙은 다음과 같습니다. Q4_K_M 기준으로 10억 파라미터당 약 0.6 GB를 예산으로 잡고, 여기에 컨텍스트 (context)를 위한 여유 공간을 추가하세요. 즉:

모델 크기Q4_K_M 점유 공간여유롭게 구동 가능한 환경
7B~4-6 GB8 GB GPU, 또는 모든 M-시리즈 Mac
...

이 모델이 상주하기를 원하는 메모리는 VRAM (비디오 램), 즉 GPU의 메모리입니다. 왜냐하면 그곳에서 추론 (inference) 속도가 빠르기 때문입니다. 만약 모델이 VRAM에 들어가지 않는다면, Ollama는 시스템 RAM을 사용하여 CPU에서 기꺼이 실행할 것이며, 작동은 하겠지만 속도는 느려질 것입니다. Apple Silicon에서는 이 경계가 아주 기분 좋게 모호해집니다. 통합 메모리 (unified memory) 방식은 GPU와 CPU가 하나의 풀을 공유함을 의미하므로, 64 GB Mac은 PC에서 여러 개의 외장 GPU가 필요한 모델들을 실행할 수 있습니다.

A comparison of one 7B model at FP16, Q8_0, Q5_K_M and Q4_K_M, with memory footprint shrinking from about 14 GB to about 4 GB and Q4_K_M noted as under 1 percent quality loss.

이것이 속도 측면에서 어떤 이득을 줄까요? 현실적으로 생각해야 합니다. CPU 전용 추론 (CPU-only inference)의 경우 대략 초당 10-25 토큰 (tokens per second) 정도를 기대할 수 있는데, 이는 짧은 답변에는 사용 가능하지만 긴 답변에는 고통스러운 수준입니다. 동일한 모델을 괜찮은 GPU에 완전히 올리면 초당 40-80+ 토큰으로 뛰어오릅니다. RTX 4090은 초당 130-160 토큰에 도달할 수 있으며, 이는 클라우드 API와 같은 수준입니다. 여기서 하드웨어가 게임의 전부입니다. 잘못된 하드웨어에서 돌아가는 로컬 모델은 더 저렴한 API가 아니라, 더 나쁜 API일 뿐입니다.

조용한 컨텍스트 윈도우 (context-window)의 함정

가장 많은 시간을 낭비하게 만드는 서두의 주의 사항으로 돌아가 보겠습니다. Ollama는 해당 모델이 실제로 처리하도록 훈련된 내용과 관계없이, 모든 모델의 컨텍스트 윈도우 (context window)인 num_ctx를 기본값으로 2048 토큰으로 설정합니다. Llama 3.1은 128k 토큰의 컨텍스트를 지원하지만, 별도의 설정 없이는 Ollama가 2048 토큰만 제공합니다.

이러한 기본값은 버그가 아니라 의도된 것입니다. 이를 통해 사용자가 메모리 예산을 먼저 계산해야 하는 부담 없이, 8GB 노트북을 포함한 어떤 하드웨어에서도 Ollama가 어떤 모델이든 즉시 부팅할 수 있게 해줍니다. 문제는 설정된 용량을 초과했을 때 발생합니다. Ollama는 입력을 조용히 잘라냅니다 (silently clips). 오류도, 경고도 없습니다. 한도를 초과한 토큰은 모델에 아예 전달되지 않습니다. 만약 로컬 모델에 큰 파일을 입력했을 때 모델이 앞부분을 "잊어버리는" 현상을 목격했다면, 이는 거의 항상 이 문제 때문입니다.

두 가지 방법 중 하나로 이를 해결할 수 있습니다. 일회성으로 해결하려면 요청 옵션(request options)에 num_ctx를 전달하세요.

요청별 오버라이드 (Per-request override)

curl http://localhost:11434/api/generate -d '{
  "model": "llama3.1",
  "prompt": "Summarize this file...",
...

모델별로 영구적인 기본값을 설정하려면, Modelfile에 이를 포함시켜 자신만의 변형 모델을 만드세요.

Modelfile

FROM llama3.1
PARAMETER num_ctx 16384

한 번 빌드하기 (Build it once)

ollama create llama3.1-16k -f Modelfile
ollama run llama3.1-16k

하지만 대가가 따르며, 이는 선택 사항이 아닙니다. 컨텍스트 윈도우 (context window)는 **KV 캐시 (KV cache)**에 상주하며, 이는 num_ctx에 따라 선형적으로 증가합니다. 7B 모델의 윈도우를 32k로 높이면 가중치(weights) 외에 약 6 GB의 VRAM이 추가로 필요할 수 있습니다. 따라서 컨텍스트 길이는 무작정 최대로 돌릴 수 있는 무료 다이얼이 아닙니다. 이는 모델과 동일한 메모리를 두고 직접적으로 경쟁합니다. 실제 작업 부하에 맞는 가장 작은 윈도우를 선택하세요.

경고
2048 기본값과 조용한 잘라내기(silent truncation)는 사람들이 "로컬 모델은 멍청하다"라고 결론 내리는 가장 흔한 이유입니다. 모델은 대개 그렇지 않습니다. 단지 입력값의 일부만 보여지고 있을 뿐입니다. 모델을 탓하기 전에 num_ctx를 먼저 확인하세요.

에디터에 연결하기

대부분의 개발자들이 처음에 이 방식을 찾는 이유는 프라이빗 코딩 어시스턴트(private coding assistant) 때문입니다. 즉, 코드 한 줄도 외부로 전송하지 않는 자동 완성(autocomplete)과 채팅(chat) 기능입니다. Ollama는 11434 포트에서 로컬 HTTP API를 노출하며, Continue와 같은 에디터 확장 프로그램(editor extensions)이 이 API와 직접 통신합니다. 여러분의 코드는 에디터에서 본인의 머신에 있는 프로세스로 전달되었다가 다시 돌아옵니다. 네트워크를 통과하는 것은 아무것도 없습니다.

연결 방법은 간단합니다. Continue 설정을 로컬 모델을 가리키도록 지정하면 됩니다:

Continue 설정 (버전에 따라 형태가 다를 수 있음)

{
  "models": [
    {
...

이것이 프라이버시의 핵심이며, 이는 실제적인 이점입니다. 모델을 이미 내려받았다면(pulled), 이더넷 케이블을 뽑아도 계속 작동합니다. Ollama는 일반적인 추론(inference) 과정 중에 외부로 연락(phone home)하지 않습니다. 텔레메트리(telemetry) 업로드도, 클라우드 동기화도, 제3자에게 프롬프트(prompts)를 전송하는 일도 없습니다. 모델 파일은 삭제하기 전까지 여러분의 디스크에 머물며, 오직 초기 ollama pull 단계에서만 인터넷이 필요합니다. HIPAA, PCI-DSS 또는 GDPR 데이터 거주성(data-residency) 규칙을 준수하며 작업하는 사람들에게 이것은 단순한 '있으면 좋은 기능'이 아닙니다. 데이터가 물리적으로 여러분의 머신을 떠나지 않는 것보다 확실한 벤더(vendor)의 서류 작업은 없기 때문에, 이는 종종 허용되는 유일한 방식이기도 합니다.

An architecture diagram showing the editor, Ollama on port 11434, and the local GGUF model all inside a 'your machine' boundary, with the connection to a cloud API crossed out in red.

메모리 관리 시 주의사항

당황하기 전에 알아두어야 할 동작이 하나 더 있습니다. 요청을 마친 후, Ollama는 기본적으로 5분 동안 모델을 VRAM에 로드된 상태로 유지합니다. 그래야 다음 프롬프트에 대해 다시 로드 비용을 지불하는 대신 즉각적으로 응답할 수 있기 때문입니다. 유용한 기능이지만, 두 번째 대형 모델을 실행하려 할 때 첫 번째 모델이 여전히 GPU 메모리를 점유하고 있다는 사실을 발견하게 되면 곤란해질 수 있습니다.

이 기능은 keep_alive로 제어할 수 있습니다. 응답이 끝나자마자 언로드(unload)하려면 0으로 설정하고, 하루 종일 모델을 메모리에 고정하려면 `

curl http://localhost:11434/api/generate -d '{
  "model": "llama3.1",
  "prompt": "quick question",
...

ollama ps를 통해 현재 메모리에 상주 중인 모델을 확인할 수 있으며, ollama stop을 사용하여 수동으로 모델을 제거(evict)할 수 있습니다. 메모리가 부족한 환경에서 여러 모델을 번갈아 가며 사용해야 한다면, keep_alive를 관리하는 것이 원활한 전환과 지속적인 메모리 부족(Out-of-Memory, OOM) 오류 사이의 차이를 결정짓는 핵심입니다.

로컬 실행이 실제로 API보다 유리한 경우

이제 솔직한 이야기를 해보겠습니다. 정답은 "항상 그렇지는 않다"이기 때문입니다. 로컬에서 실행하는 것은 실제적인 엔지니어링 트레이드오프(trade-off)이며, 많은 경우 클라우드를 사용하는 것이 더 나은 선택입니다.

**비용(Cost)**은 사람들이 양방향 모두에서 잘못 판단하기 쉬운 함정입니다. 대략적인 교차점은 다음과 같습니다. 구매하고 운영해야 하는 하드웨어 비용을 고려하면, 하루에 약 100만(1M) 토큰 미만을 사용하는 경우에는 클라우드 API가 보통 더 저렴합니다. 하루에 약 500만(5M) 토큰을 넘어가는 시점부터는 하드웨어를 직접 소유하는 것이 이득이 되기 시작합니다. 이 기준선 아래에서는 대부분 유휴 상태로 방치되는 1,600달러짜리 GPU를 보유하는 것이 토큰당 과금 방식보다 더 나쁜 거래입니다. 가끔씩 자동 완성(autocomplete)을 하기 위해 4090을 구매하는 것은 절약이 아니라 취미 활동입니다.

**지연 시간(Latency)**은 특히 네트워크 왕복 시간(round-trip)이 지배적인 짧고 빈번한 호출의 경우 로컬에 유리할 수 있습니다. 하지만 이는 하드웨어가 뒷받침될 때만 해당됩니다. 수치를 기억하세요. 최상급 GPU는 클라우드의 처리량(throughput)과 맞먹지만, CPU 전용 추론(inference)은 4~10배 더 느립니다. 로컬이 자동으로 더 빠른 것은 아닙니다. 로컬이 더 빠른 경우는 "GPU가 있을 때"뿐입니다.

역량(Capability) 측면에서는 여전히 최상위 모델의 경우 클라우드가 유리합니다. API를 통해 접할 수 있는 가장 거대한 프런티어 모델(frontier models)들은 단일 머신에 담을 수 있는 그 어떤 모델보다 강력합니다. 일상적인 작업(자동 완성, 요약, 보일러플레이트 생성, 간단한 리팩토링)에는 성능이 좋은 로컬 8B 또는 32B 모델로도 충분합니다. 하지만 진정으로 어려운 추론(reasoning)의 경우, 그 격차는 여전히 실재합니다.

**개인정보 보호 및 컴플라이언스 (Privacy and compliance)**는 로컬 실행이 단순한 선호도를 넘어 필수 요건이 되는 지점입니다. 만약 데이터가 법적으로 경계를 벗어날 수 없다면 (환자 기록, 결제 데이터, 규제 대상인 EU 데이터 등), 추론 (inference)을 직접 제어하는 하드웨어에서 유지하는 것은 타협안이 아니라 그 자체로 목적이 됩니다. 어떤 기업용 계약도 데이터가 아예 전송되지 않는다는 사실을 대체할 수는 없습니다.

많은 팀이 도달하는 패턴은 '전부 아니면 전무 (all-or-nothing)' 방식이 아닙니다. 그것은 혼합형입니다. 즉, 프라이빗하고, 볼륨이 크며, 지연 시간 (latency)에 민감하고, 오프라인 작업이 필요한 경우에는 로컬 모델을 사용하고, 사용 가능한 가장 강력한 모델이 필요한 가끔 발생하는 무거운 요청에는 클라우드 API를 사용하는 방식입니다. 어느 한쪽을 선택할 필요는 없습니다. 각 도구가 실제로 어떤 작업에 적합한지를 알면 됩니다.

그러니 작게 시작하세요. 8B 모델을 가져와서(pull) 에디터를 그 모델에 연결하고, 일주일 동안 이를 통해 실제 코드를 작성해 보면서 토큰 미터가 움직이지 않는 것을 확인해 보세요. 그 후, 무엇이 실제로 당신의 기기에서 실행되고 있는지, 그리고 그 이유가 무엇인지 알게 되었을 때 무엇을 로컬로 유지할 가치가 있는지 결정하면 됩니다.

원문은 nazarboyko.com에 게시되었습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0