1편: 24GB의 벽 — 무엇이 왜 깨졌나 (현재 글)
2편: 하드웨어 견적 전수 조사 — 그 메모리, 대체 어디서 사나
3편: API 손익분기점 — 사는 게 정말 나은가
MacBook Air M5 24GB 한 대로 로컬 AI 에이전트를 굴려보겠다고 시작했다가, 넉 달 동안 네 종류의 벽에 순서대로 부딪혔다. 이 글은 그 벽들의 기록이다. 결론부터 말하면 문제는 모델 품질이 아니라 메모리와 컨텍스트였고, 그 사실을 깨닫는 순간부터 "장비를 늘릴 것인가, API로 갈 것인가"라는 다음 질문이 시작됐다.
출발점: 왜 Hermes Agent였나
구성 자체는 단순했다. MacBook Air M5(24GB 유니파이드 메모리) 위에 Ollama를 올리고, 그 위에 Hermes Agent를 얹었다. 클라이언트는 텔레그램 봇. 어디서든 메시지를 보내면 집에 있는 맥북이 처리해서 답을 주는 그림이었다.
수많은 에이전트 프레임워크 중에 Hermes를 고른 이유는 세 가지였다. 첫째, 4계층 메모리 구조를 갖추고 있어서 대화가 길어져도 맥락이 흐트러지지 않는다. 둘째, 자기학습 스킬 파일 개념이 있어서 반복 작업을 한 번 가르치면 파일로 남는다. 셋째, MCP 기반 툴 연동이라 외부 도구를 붙이기가 표준화되어 있다. 개인 비서형 자동화를 만들기에 이보다 잘 맞는 구조를 못 찾았다.
모델 배치는 이랬다. 메인 오케스트레이터는 qwen3:4b-instruct. 작지만 툴 호출이 안정적이었다. 한국어 처리가 필요한 구간에는 EXAONE 3.5 7.8B를 서브 에이전트로 붙였다. 작은 모델로 흐름을 잡고, 한국어는 잘하는 모델에 넘긴다는 발상이었다.
이론상으로는 완벽했다. 실제로는 첫 주부터 삐걱거렸다.
첫 번째 벽: macOS Metal의 75% GPU 메모리 캡
더 큰 모델을 올리려니 로드 자체가 실패했다. 24GB면 되겠지 싶었는데 안 됐다. 로그를 파고 들어가 보니 원인은 모델도 Ollama도 아니었다. macOS가 Metal에 할당하는 GPU 메모리에 대략 75% 수준의 상한이 걸려 있다는 것이었다.
즉 24GB 유니파이드 메모리라고 해서 24GB를 모델에 쓸 수 있는 게 아니다. 실질 가용치는 18GB 안팎으로 봐야 한다. 여기서 OS와 다른 앱이 쓰는 몫까지 빼면 실제로 모델에 줄 수 있는 건 15~16GB 정도다.
이 숫자가 나오자 계산이 완전히 달라졌다. 양자화 수준별로 대략 이렇게 잡힌다. Q4 기준으로 7~9B 모델은 5~6GB, 30B급은 18~20GB, 46B급은 26~28GB가 필요하다. 즉 내 맥북에서는 30B급조차 아슬아슬하다는 결론이 나왔다. 46B는 애초에 논외였다.
이 경험이 나중에 하드웨어를 검토할 때 "표기 용량 × 0.75"를 기본 계산식으로 깔고 들어가게 만들었다. 유니파이드 메모리는 숫자가 커 보이지만 전부 모델 몫은 아니다. 스펙표의 숫자를 그대로 믿으면 안 된다는 걸 여기서 처음 배웠다.
두 번째 벽: Hermes 프로바이더 설정의 컨텍스트 불일치
모델은 어찌어찌 떴는데 이번엔 긴 대화에서 엉뚱하게 잘려나갔다. 앞에서 분명히 말한 내용을 에이전트가 기억 못 하는 증상이었다. 처음엔 Hermes의 4계층 메모리가 오작동하는 줄 알고 메모리 쪽 코드를 한참 들여다봤다.
엉뚱한 데를 판 것이었다. 원인은 Hermes 프로바이더 설정의 컨텍스트 길이 자동 감지였다. Hermes가 Ollama에 모델의 컨텍스트 길이를 물어보고 그 값을 쓰도록 되어 있었는데, 이 자동 감지값과 Ollama가 실제로 잡고 있는 값이 어긋나 있었다. Hermes는 넉넉하다고 믿고 프롬프트를 밀어넣는데 Ollama 쪽에서는 이미 초과라 뒤를 잘라내고 있었던 것이다.
해결은 허무할 만큼 단순했다. 자동 감지에 의존하지 말고 설정 파일에 context_length를 직접 하드코딩하는 것. 한 줄 고치고 나니 며칠 동안 붙잡고 있던 증상이 사라졌다. 자동화 계층이 하나 늘어날 때마다 "그 계층이 잘못 알고 있을 가능성"도 같이 늘어난다는 걸 체감한 사건이었다.
세 번째 벽: keep_alive와 프리필 병목
동작은 하는데 느렸다. 텔레그램으로 메시지를 보내면 첫 응답까지 한참이 걸렸다. 짧은 질문 하나에도 수십 초씩 걸리니 실사용이 불가능했다.
원인은 두 겹이었다. 하나는 모델 언로드/재로드. Ollama는 일정 시간 호출이 없으면 모델을 메모리에서 내린다. 텔레그램 봇처럼 띄엄띄엄 호출되는 워크로드에서는 매번 모델을 다시 올리는 시간이 그대로 응답 지연이 된다. 다른 하나는 프롬프트 프리필. 시스템 프롬프트와 메모리 컨텍스트가 길다 보니 첫 토큰이 나오기까지 처리해야 할 입력이 많았다.
환경변수 세 개로 상당 부분 잡혔다.
| 환경변수 | 설정값 | 효과 |
|---|---|---|
| OLLAMA_KEEP_ALIVE | -1 | 모델을 메모리에 무기한 상주시켜 재로드 시간 제거 |
| OLLAMA_FLASH_ATTENTION | 1 | 어텐션 연산 최적화로 프리필 속도 개선 |
| OLLAMA_KV_CACHE_TYPE | q8_0 | KV 캐시를 양자화해 메모리 점유 축소 |
세 번째가 특히 중요했다. KV 캐시는 컨텍스트가 길어질수록 커지는데, 이걸 q8_0으로 양자화하면 메모리를 꽤 아낀다. 앞서 말한 18GB 제약 안에서 컨텍스트를 조금이라도 더 확보하려면 이 옵션이 필수였다.
네 번째 벽: EXAONE 3.5의 32K 천장
마지막이 제일 아팠다. 한국어 품질이 확실히 좋아서 EXAONE 3.5 7.8B를 서브가 아니라 메인 오케스트레이터로 승격시켜 보려 했다. 작은 모델 두 개를 굴리느니 한국어 잘하는 모델 하나로 통합하는 게 나아 보였다.
그런데 이 모델의 컨텍스트 상한이 32K에서 하드하게 막혀 있었다. Hermes를 메인 모델로 굴리려면 최소 64K가 필요하다. 4계층 메모리 구조가 매 턴마다 상당한 컨텍스트를 잡아먹기 때문에, 시스템 프롬프트와 툴 정의까지 더하면 32K로는 실사용 대화가 몇 턴 못 간다.
이건 설정으로 넘을 수 있는 벽이 아니었다. 모델 아키텍처 자체의 제약이라 튜닝 여지가 없다. 결국 EXAONE은 메인에서 내리고 한국어 처리용 호출 가능 스킬 도구로 역할을 되돌렸다. 필요할 때만 불러 쓰는 전문 도구로 쓰는 게 이 모델의 자리였다.
모델 후보군 재점검
네 번째 벽에 부딪히고 나서 모델 선정 자체를 다시 했다. 한국어 품질, 코딩, 툴 호출 세 축으로 테스트 계획을 짜서 후보군을 돌렸다. EXAONE 3.5 7.8B, Qwen3.5 9B, Gemma4-12B 커뮤니티 파인튜닝이 대상이었다.
결과적으로 현재는 Qwen3.5 9B로 운용 중이다. 한국어는 EXAONE만 못 하지만 컨텍스트와 툴 호출 안정성에서 앞섰다. 에이전트 프레임워크에서는 "한국어를 예쁘게 쓰는 능력"보다 "함수를 정확히 호출하는 능력"이 훨씬 중요하다는 게 이 테스트의 교훈이었다.
참고로 별도로 가지고 있는 RTX 5070 8GB 윈도우 노트북에서도 Ollama를 돌려봤는데, VRAM 8GB로는 7B급이 한계였다. 전용 VRAM이라 속도는 빨랐지만 용량이 발목을 잡았다. 이 경험은 나중에 "유니파이드 메모리냐 전용 VRAM이냐" 판단에 그대로 반영됐다.
Trouble Shooting
| 증상 | 원인 | 해결 방법 |
|---|---|---|
| 24GB인데 큰 모델 로드 실패 | macOS Metal의 GPU 메모리 약 75% 상한 | 실사용 가용치를 18GB 선으로 재계산, 모델 크기·양자화 하향 |
| 긴 대화에서 앞부분을 기억 못 함 | Hermes 프로바이더의 컨텍스트 자동 감지값과 Ollama 실제값 불일치 | context_length를 설정 파일에 하드코딩 |
| 메모리 코드를 잘못 의심하며 시간 낭비 | 증상(기억 못 함)과 원인 계층(컨텍스트 설정)이 달랐음 | 상위 계층부터 의심하지 말고 실제 전달 토큰 수를 먼저 로깅 |
| 텔레그램 첫 응답 지연 | 모델 언로드 후 재로드 + 프롬프트 프리필 병목 | OLLAMA_KEEP_ALIVE=-1, OLLAMA_FLASH_ATTENTION=1, OLLAMA_KV_CACHE_TYPE=q8_0 |
| 컨텍스트를 늘리면 메모리 초과 | KV 캐시가 컨텍스트 길이에 비례해 증가 | KV 캐시를 q8_0으로 양자화해 점유량 축소 |
| EXAONE 3.5를 메인 모델로 못 씀 | 32K 하드 컨텍스트 상한 (Hermes는 64K 이상 요구) | 메인에서 제외, 한국어 전용 서브 스킬 도구로 전환 |
| RTX 5070 노트북에서 7B급이 한계 | 전용 VRAM 8GB 용량 제약 | 대형 모델은 유니파이드 메모리 쪽으로 방향 전환 |
1편 결산: 확정된 것, 남은 질문
| 내용 | |
|---|---|
| 확정 #1 | macOS 실가용 메모리 = 표기 용량 × 0.75 |
| 확정 #2 | 46B급 모델은 Q4 기준 실가용 26~28GB 필요 |
| 확정 #3 | 에이전트 모델 선택 기준: 한국어 유창함 < 툴 호출 정확도 |
| 확정 #4 | Hermes를 메인 모델로 쓰려면 64K 이상 컨텍스트 필요 |
| 확정 #5 | 전용 VRAM 8GB = 빠르지만 7B가 상한 |
| 남은 질문 | 그 26~28GB, 대체 어디서 얼마에 구할 수 있는가? |
느낀 점 / 다음에 할 일
일곱 개 항목 중 여섯 개는 설정과 선택으로 풀렸다. 문제는 나머지 하나, 즉 물리적 메모리 총량이었다. 설정으로 못 넘는 벽이 하나라도 있으면 나머지를 아무리 잘 튜닝해도 천장은 그대로다.
이 넉 달의 진짜 소득은 요구사항이 숫자로 확정됐다는 것이다. 46B급 모델을 Q4로 안정적으로 돌리려면 26~28GB의 실가용 메모리가 필요하고, macOS라면 표기 용량 기준 36GB 이상이어야 한다. 막연히 "메모리가 더 필요하다"가 아니라 정확한 숫자가 나오니 비로소 견적을 낼 수 있게 됐다.
여기서 갈림길이 생겼다. 장비를 늘려서 로컬을 키울 것인가, 아니면 그냥 API를 쓸 것인가. 다음 편에서는 맥미니·맥스튜디오·미니PC·eGPU·데스크탑 자작까지 다섯 갈래를 전부 견적 뽑아본 과정을 정리한다. 2026년의 메모리 가격 폭등이 이 계산을 얼마나 이상하게 만들어놨는지도 함께.
댓글
댓글 쓰기