삼태연구소
SAMTAELABS삼태연구소
가이드2026년 4월 15일·8분 읽기

Gemma 4를 로컬에서 Codex CLI에 연결하기: 실전 온프레미스 LLM 구축 가이드 (blog.danielvaughan.com)

Gemma4Codex CLI로컬LLM온프레미스AIllama.cppOllamaAI코딩에이전트Apple SiliconNVIDIA Blackwell프라이버시
Gemma 4를 로컬에서 Codex CLI에 연결하기: 실전 온프레미스 LLM 구축 가이드
목차(4)

한줄 요약

Gemma 4, 도구 호출 86.4% 달성으로 로컬 AI 코딩 에이전트 시대 열다

어떤 상황에서 필요한가?

로컬 LLM 기반 코딩 에이전트는 세 가지 조건이 겹칠 때 진지하게 고려할 만하다. 첫째, 클라우드 API 비용이 일정 수준을 넘어섰을 때. 여러 세션을 병렬로 돌리는 헤비 유저라면 청구서가 쌓이는 속도를 체감하게 된다. 둘째, 코드베이스를 외부 서버로 보내기 어려운 경우. 사내 시스템이나 미공개 프로젝트를 다룬다면 프라이버시는 선택이 아니라 필수다. 셋째, 클라우드 API의 가용성 자체를 신뢰하기 어려운 환경. 레이트 리밋, 가격 정책 변경, 순간적인 다운타임은 외부 서비스를 쓰는 한 피할 수 없다.

문제는 지금까지 로컬 모델이 도구 호출을 제대로 못 했다는 점이었다. Codex CLI의 핵심 가치는 모델이 파일을 읽고, 코드를 작성하고, 테스트를 실행하는 에이전트 루프에 있다. 이전 세대 Gemma는 tau2-bench 함수 호출 벤치마크에서 6.6%를 기록했다. 100번 중 93번 실패하는 모델로는 에이전트를 만들 수 없다.

Gemma 4 31B는 동일 벤치마크에서 86.4%를 기록한다. 이 숫자 하나가 판을 바꿨다.

핵심 구현 방법

Daniel Vaughan은 두 머신에서 동일한 태스크를 돌렸다. 24GB M4 Pro MacBook Pro에서는 26B MoE 변형 모델을 Q4_K_M 양자화로, 128GB NVIDIA Blackwell 칩을 탑재한 Dell Pro Max GB10에서는 31B Dense 모델을 Ollama v0.20.5로 구동했다. 두 머신 모두 Codex CLI의 config.toml에 커스텀 모델 프로바이더로 등록하고 wire_api = "responses"로 설정했다.

Apple Silicon(Mac) 셋업

Ollama는 쓸 수 없었다. v0.20.3에 스트리밍 버그가 있어 Gemma 4의 도구 호출 응답이 tool_calls 배열 대신 reasoning 출력으로 라우팅되고, Flash Attention 이슈로 500토큰 이상의 프롬프트에서 응답이 멈춘다. Codex CLI의 시스템 프롬프트만 약 27,000 토큰이니 사실상 사용 불가다.

해결책은 Homebrew로 설치한 llama.cpp였다. 핵심 서버 실행 명령은 다음과 같다:

llama-server \
  -m /path/to/gemma-4-26B-A4B-it-Q4_K_M.gguf \
  --port 1234 -ngl 99 -c 32768 -np 1 --jinja \
  -ctk q8_0 -ctv q8_0

24GB 환경에서 각 플래그가 모두 의미를 갖는다. -np 1은 슬롯을 하나로 제한해 KV 캐시 메모리 복제를 막는다. -ctk q8_0 -ctv q8_0은 KV 캐시를 양자화해 940MB에서 499MB로 줄인다. --jinja는 Gemma 4 도구 호출 템플릿 적용에 필수다. -m으로 직접 경로를 지정해야 하는데, -hf 플래그를 쓰면 1.1GB 비전 프로젝터를 자동으로 내려받아 메모리 부족으로 크래시된다.

Codex CLI 설정에서는 web_search = "disabled"를 반드시 추가해야 한다. web_search_preview 도구 타입을 llama.cpp가 거부하기 때문이다.

NVIDIA GB10 셋업

vLLM은 실패했다. v0.19.0의 컴파일된 익스텐션이 PyTorch 2.10.0 기반인데, aarch64 Blackwell(sm_121)용 CUDA 가능 PyTorch는 2.11.0+cu128뿐이라 ABI 불일치로 임포트 에러가 난다.

Ollama v0.20.5가 첫 시도에서 작동했다. ollama pull gemma4:31b 후 Codex CLI가 localhost만 확인하는 --oss 모드를 쓰기 때문에, 원격 머신이라면 SSH로 포트 11434를 터널링해야 한다. codex --oss -m gemma4:31b으로 실행하면 된다.

놓치면 세션이 죽는 설정 하나

프로바이더 설정에서 stream_idle_timeout_ms를 최소 1,800,000으로 올려야 한다. Mac 환경에서 단일 도구 호출 사이클이 1분 39초까지 걸렸다. 기본 타임아웃 값이면 모델이 생각하는 도중에 세션이 끊긴다.

실전에서 주의할 점

속도가 품질을 대체하지 않는다는 사실이 이번 실험의 핵심 교훈이다. Mac은 MoE 아키텍처 덕분에 토큰 생성 속도가 GB10보다 5.1배 빠르다. 두 머신의 메모리 대역폭은 273GB/s로 동일하지만, 31B Dense는 토큰 하나에 모든 파라미터를 읽고, 26B MoE는 토큰당 3.8B만 활성화한다. 같은 파이프에 넣는 데이터 양이 근본적으로 다르다.

그러나 실제 태스크 완료 시간에서 Mac이 GB10보다 30% 빠른 데 그쳤다. 도구 호출 3회로 끝낼 것을 10회 시도했고, 테스트 파일 작성에 다섯 번 실패했으며, 구현 코드에 삭제하지 않은 잔여 코드가 남았다. 이는 24GB + Q4_K_M 조합의 양자화 한계로 봐야 한다. 같은 Apple Silicon이라도 메모리가 더 넓고 높은 양자화를 쓸 수 있다면 결과는 달라질 가능성이 높다.

실용적 접근으로는 프로필 분리가 유효하다. 반복 작업이나 프라이버시가 중요한 작업은 codex --profile local, 복잡한 태스크는 클라우드 모델로 전환하는 하이브리드 방식이다. Codex CLI의 프로필 시스템은 플래그 하나로 전환을 지원한다.

llama.cpp 버전 고정도 빠뜨리면 안 된다. 빌드 간 3.3배 속도 회귀가 보고된 만큼, 버전을 고정하지 않으면 벤치마크 결과가 하룻밤 사이에 달라질 수 있다.

자주 묻는 질문

Q.Apple Silicon MacBook에서 Gemma 4를 Codex CLI와 연결할 때 Ollama를 쓰면 안 되나?

현재 시점 기준으로 Apple Silicon 환경에서는 Ollama 사용이 권장되지 않는다. v0.20.3에 존재하는 스트리밍 버그가 도구 호출 응답을 잘못된 필드로 라우팅하고, Flash Attention 이슈로 긴 프롬프트에서 응답이 멈춘다. Codex CLI의 시스템 프롬프트 자체가 약 27,000 토큰이므로 실질적으로 동작하지 않는다. Homebrew로 설치한 llama.cpp에 `--jinja` 플래그를 사용하는 것이 현재 검증된 경로다.

Q.24GB MacBook Pro에서 로컬 모델이 실용적인 수준인가?

작동은 하지만 클라우드 모델 대비 품질 차이가 있다. 동일 태스크에서 GB10의 31B Dense 모델은 3번의 도구 호출로 테스트를 통과시킨 반면, Mac의 26B MoE Q4_K_M은 10번의 도구 호출과 5번의 테스트 실패를 거쳤다. 이는 모델 자체의 한계가 아니라 24GB 환경에서 선택 가능한 최고 양자화 설정의 한계로 봐야 한다. 메모리가 넉넉한 머신에서 더 높은 양자화로 실행하면 결과가 개선될 것으로 보인다.

Q.로컬 셋업에서 가장 자주 발생하는 실패 원인은 무엇인가?

타임아웃과 도구 타입 불일치가 가장 흔한 원인이다. `stream_idle_timeout_ms`를 올리지 않으면 모델이 응답을 생성하는 중에 세션이 끊기고, `web_search = "disabled"` 설정을 빠뜨리면 llama.cpp가 `web_search_preview` 도구 타입을 거부해 요청이 실패한다. `-hf` 플래그 사용으로 불필요한 비전 프로젝터가 다운로드되어 OOM 크래시가 발생하는 경우도 많다. 세 가지를 먼저 확인하면 대부분의 초기 실패를 잡을 수 있다.

직접 구축이 어렵다면, 전문가에게 맡겨보세요

대표 개발자가 직접 소통하고, 설계하고, 구축합니다. 중간 과정 없이 의도 그대로.

관련 아티클