본문으로 건너뛰기

© 2026 Molayo

HN분석2026. 06. 15. 14:39

macOS에서 로컬 코딩 에이전트(Local Coding Agent)를 설정하는 방법

요약

macOS 환경에서 Gemma 4 모델을 활용하여 인터넷 연결 없이도 작동하는 로컬 코딩 에이전트를 구축하는 방법을 소개합니다. llama.cpp와 Metal 가속, MTP(Multi-Token Prediction) 기술을 결합하여 실용적인 속도를 확보하는 설정 과정을 다룹니다.

핵심 포인트

  • macOS Metal 가속을 활용한 llama.cpp 기반 로컬 환경 구축
  • Gemma 4의 MTP 기술을 통한 추론 속도 최적화
  • OpenAI 호환 API 및 멀티모달 기능을 갖춘 에이전트 설정
  • Apple Silicon(M1 Max) 환경에서의 실제 성능 벤치마크 제공

최근 인터넷 연결이 몇 번 끊기면서 코딩 에이전트(Coding Agent)를 사용할 수 없는 상황에 처하곤 했습니다. 그래서 Gemma 4의 "MTP(Multi-Token Prediction)를 통해 Gemma 4가 이제 2배 더 빠르게 실행됩니다"라는 업데이트 소식을 보았을 때, 직접 실행해 보기로 결심했습니다.

저는 다음과 같은 조건을 갖춘 로컬 코딩 에이전트(Local Coding Agent) 설정을 원했습니다:

  • 제 Mac에서 실제로 사용할 수 있을 만큼 충분히 빠를 것
  • OpenAI 호환 API를 통해 작동할 것 (다른 도구에서도 사용할 수 있도록)
  • 그리고 가급적 필요할 때 스크린샷/이미지를 처리할 수 있을 것 (에이전트가 만든 결과물의 스크린샷을 입력으로 줄 수 있도록)

그리고 성공했습니다! 이 영상은 실시간입니다. 에이전트가 완벽하게 사용 가능한 속도로 응답하는 모습을 보여줍니다.

최종 테스트를 거쳐 제가 완성한 설정은 다음과 같습니다:

  • macOS에서 Metal로 빌드된 llama.cpp
  • GGUF 형식의 Gemma 4 26B-A4B
  • 투기적 디코딩(Speculative Decoding)을 위한 Q8 MTP 초안 모델(Draft Model)
  • Gemma 4 멀티모달 프로젝터(Multimodal Projector)
  • 터미널 코딩 에이전트로서의 Pi

이 테스트는 macOS 15.7.7을 실행 중인 64GB 통합 메모리(Unified Memory)를 갖춘 Apple M1 Max에서 진행되었습니다.

모델 (The Model)

메인 모델은 다음과 같습니다: gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf

.

Huggingface 링크: models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf

해당 파일의 크기는 약 16GB입니다. MTP 초안 헤드(Draft Head)와 멀티모달 프로젝터(Multimodal Projector)를 포함한 모델 폴더의 크기는 약 17GB입니다.

벤치마크 프롬프트는 다음과 같았습니다:

Write a compact Python function that parses a unified diff and returns the changed file paths. Then explain two edge cases.

각 벤치마크는 약 128개의 토큰(Tokens)을 생성했습니다.

베이스라인: llama.cpp + Metal

먼저 Metal 가속을 사용하여 llama.cpp를 통해 메인 모델을 직접 실행했습니다:

repos/llama.cpp/build/bin/llama-cli \
-m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
-ngl 999 \
...

결과:

설정프롬프트 토큰/초 (Prompt tok/s)생성 토큰/초 (Generation tok/s)
Gemma 4 26B-A4B Q4, llama.cpp Metal298.058.2

초당 58개 토큰은 아주 빠른 편은 아니지만 사용 가능한 수준입니다. 하지만 코딩 에이전트(Coding-agent) 작업의 경우, 특히 에이전트가 많은 도구 호출(Tool Calls)을 수행할 때는 가능한 한 빨라야 합니다.

MTP 초안 모델(MTP Draft Model) 추가하기

Gemma 4에 이제 MTP 초안 모델(MTP draft model)을 사용할 수 있습니다:

MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf

이는 llama.cpp에서 투기적 초안 모델(speculative draft model)로 로드할 수 있습니다:

repos/llama.cpp/build/bin/llama-cli \
-m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
--model-draft models/unsloth-gemma-4-26B-A4B-it-GGUF/MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf \
...

MTP를 사용한 첫 실행 결과는 4개의 초안 토큰(draft tokens)을 사용하여 초당 69.2 토큰(tokens/second)이었습니다. 하지만, MTP 모델 실행 방법에 관한 Unsloth의 가이드에는 다음과 같은 참고 사항이 포함되어 있습니다:

"--spec-draft-n-max 2가 가장 좋은 시작점임을 확인했습니다. 하지만 성능은 하드웨어에 따라 달라지므로 2가 최적이라고 가정하지 마십시오. 1부터 6 사이의 모든 값을 시도해 보고 귀하의 시스템에서 가장 빠른 값을 사용하십시오."

--spec-draft-n-max를 전수 조사한 결과, 3개의 초안 토큰을 사용했을 때 초당 72.2 토큰으로 가장 좋은 결과를 얻었습니다.

설정프롬프트 tok/s생성(Generation) tok/s속도 향상(Speedup)
메인 모델만 사용298.058.21.00x
메인 모델 + Q8 MTP 초안295.672.21.24x

유용한 점은 프롬프트 처리(prompt processing) 속도는 기본적으로 동일하게 유지되면서, 생성(generation) 속도는 약 24% 향상되었다는 것입니다.

MTP 튜닝

--spec-draft-n-max 값을 1부터 6까지 테스트했습니다.

--spec-draft-n-max |

프롬프트 tok/s생성(Generation) tok/s
1295.5
...

제 M1 Max 기기에서는 3이 가장 빨랐으며, 2도 충분히 근접하여 어느 쪽이든 괜찮았습니다. 그 이상의 값은 더 느려졌습니다.

MLX 비교

Mac에서 모델을 실행하는 더 빠른 방법이 llama.cpp인지 mlx인지 알아보기 위해 mlx-lm을 통해 MLX 모델도 테스트했습니다.

런타임(Runtime)모델생성(Generation) tok/s
llama.cpp Metal + MTPUnsloth GGUF Q4 + Q8 MTP72.2
...

저는 MLX가 (Mac에 최적화되어 있으므로) 가장 빠를 것이라고 생각했습니다.

하지만 이 특정 설정에서는 llama.cpp가 MLX보다 빨랐으며, MTP를 사용한 llama.cpp가 확실히 가장 좋은 옵션이었습니다.

llama.cpp에 그동안 투입된 모든 노력과 미세 조정(tweaking) 덕분에, 크로스 플랫폼임에도 불구하고 macOS에 상당히 잘 최적화되어 있다는 생각이 듭니다.

또한 gemma-4-swift-mlx를 통해 Gemma 4 MTP를 시도해 보았으나, 테스트한 26B 4-bit MLX 체크포인트(checkpoints)가 로더(loader)가 기대하는 가중치 키(weight keys)와 일치하지 않았습니다. 이미 이전 MLX 테스트 결과들이 있었기에, 모델을 새로 다운로드하고 일치시키기 위해 설정을 조정(tweak)하는 대신 다음 단계로 넘어갔습니다.

이미지 지원 추가 (Adding Image Support)

Pi의 경우, 스크린샷을 첨부할 수 있기를 원했습니다. 처음에 설정한 로컬 모델 엔트리(entry)는 모델을 텍스트 전용(text-only)으로 선언했습니다:

"input": ["text"]

이는 Pi가 이미지 도구 출력(image tool output)을 모델로 제대로 전달하지 못함을 의미했습니다.

멀티모달(multi-modal) 기능이 작동하려면 llama.cpp 서버에도 Gemma 4 멀티모달 프로젝터(multimodal projector)가 필요합니다 (12B 모델만 네이티브 멀티모달을 지원합니다):

mmproj-BF16.gguf

--mmproj와 함께 로드하면, llama.cpp가 멀티모달 지원을 알리며 Pi가 이미지를 보낼 수 있게 됩니다.

속도에 변화가 없는지 확인하기 위해 프로젝터를 로드한 상태에서 텍스트 벤치마크(benchmark)를 다시 실행했습니다:

설정 (Setup)프로젝터 (Projector)프롬프트 토큰/초 (Prompt tok/s)생성 토큰/초 (Generation tok/s)
llama.cpp Metal + MTP없음 (none)120.371.4
llama.cpp Metal + MTPmmproj-BF16.gguf297.472.2

프로젝터를 사용한 최종 실행 결과, 텍스트 생성 속도 저하는 나타나지 않았습니다.

이제 설정 지침입니다:

llama.cpp 설치 (Install llama.cpp)

의존성(dependencies) 설치:

brew install cmake git tmux python@3.11

lama.cpp 클론(clone) 및 빌드(build):

mkdir -p ~/Developer/ML-Models/Gemma4/repos
cd ~/Developer/ML-Models/Gemma4
git clone https://github.com/ggml-org/llama.cpp repos/llama.cpp
...

제가 테스트한 빌드 설정은 다음과 같습니다:

GGML_METAL=ON
GGML_ACCELERATE=ON
GGML_BLAS=ON
...

모델 파일 다운로드 (Download the Model Files)

Python 환경 생성:

cd ~/Developer/ML-Models/Gemma4
python3.11 -m venv .venv
source .venv/bin/activate
...

파일 다운로드:

mkdir -p models/unsloth-gemma-4-26B-A4B-it-GGUF
huggingface-cli download unsloth/gemma-4-26B-A4B-it-GGUF \
gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
...

결과적으로 다음과 같은 파일들이 있어야 합니다:

models/unsloth-gemma-4-26B-A4B-it-GGUF/
gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf
mmproj-BF16.gguf
...

로컬 서버 시작 (Start the Local Server)

최종 서버 명령어는 다음과 같습니다:

repos/llama.cpp/build/bin/llama-server \
-m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
--model-draft models/unsloth-gemma-4-26B-A4B-it-GGUF/MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf \
...

OpenAI 호환 엔드포인트(OpenAI-compatible endpoint)는 다음과 같습니다:

저는 tmux 내에서 실행될 수 있도록 작은 start_server.sh 래퍼(wrapper)를 사용했습니다:

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
...

실행 방법:

chmod +x start_server.sh
./start_server.sh

서버가 실행 중인지 확인합니다:

curl http://127.0.0.1:8080/v1/models

Pi 설정 (Configure Pi)

Pi는 다음 경로에서 모델 제공자(model providers)를 읽어옵니다:

~/.pi/agent/models.json

로컬 제공자를 추가합니다:

{
"providers": {
"gemma4-local": {
...

중요한 부분은 다음과 같습니다:

baseUrl은 llama.cpp의 OpenAI 호환 서버를 가리킵니다. apiopenai-completions입니다. authHeader는 로컬 서버이므로 false입니다. input에는 textimage가 모두 포함되어야 하며, 그렇지 않으면 Pi는 이를 텍스트 전용으로 취급합니다.

선택적으로 다음 파일에서 기본값으로 설정할 수 있습니다:

~/.pi/agent/settings.json
{
"defaultProvider": "gemma4-local",
"defaultModel": "gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf",
...

그 다음 Pi가 이를 인식하는지 확인합니다:

pi --offline --list-models gemma

예상 결과:

provider model context max-out thinking images
gemma4-local gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf 65.5K 8.2K no yes

로컬 모델을 사용하여 Pi를 실행합니다:

pi --provider gemma4-local --model gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf

또는 비대화형 모드(non-interactive mode)를 사용합니다:

pi -p --provider gemma4-local --model gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
"Explain what this repository does"

스크린샷의 경우:

pi -p @"/path/to/screenshot.png" "Describe this image and point out anything relevant to the UI"

최종 설정 (Final Setup)

최종적인 로컬 코딩 에이전트 스택은 다음과 같습니다:

계층 (Layer)선택 (Choice)
추론 런타임 (Inference runtime)llama.cpp
...

주요 결론은 MTP 초안 모델(MTP draft model)을 사용할 가치가 있다는 것이었습니다. 이 기기에서 Gemma 4의 속도는 초당 58.2 토큰(tokens/second)에서 초당 72.2 토큰으로 향상되었으며, 동시에 로컬 OpenAI 호환 서버(OpenAI-compatible server)로 실행할 수 있을 만큼 설정을 단순하게 유지했습니다.

추신 (P.S): 일부에서는 Gemma 4 26B-A4B 대신 Qwen3.6 35B-A3B를 사용할 것을 제안했습니다.

제가 찾을 수 있는 벤치마크에 따르면, Qwen은 Gemma 4보다 훨씬 더 나은 코딩 에이전트(coding agent)입니다.

하지만 속도는 더 느립니다. Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf + unsloth-Qwen3.6-35B-A3B-MTP-GGUF + mmproj-BF16.gguf 조합은 72 tk/s 대신 55 tk/s의 결과를 보여줍니다. 이는 사용자가 기다리고 있을 때 상당히 유의미한 차이입니다.

모델 다운로드:

mkdir -p models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF
huggingface-cli download unsloth/Qwen3.6-35B-A3B-MTP-GGUF \
Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf \
...

서버 시작:

LLAMA_SERVER=/Users/kylehowells/Developer/ML-Models/Gemma4/repos/llama.cpp/build/bin/llama-server
$LLAMA_SERVER \
-m models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF/Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf \
...

Pi 설정 (Pi Config):

{
"providers": {
"qwen36-local": {
...

참고 문헌 (References):

  • unsloth.ai/docs/models/qwen3.6
  • unsloth.ai/docs/models/gemma-4
  • unsloth.ai/docs/models/mtp
  • github.com/ggml-org/llama.cpp
  • github.com/earendil-works/pi
  • Introducing Gemma 4 12B: a unified, encoder-free multimodal model
  • "MTP enables Google Gemma 4 run ~1.4–2.2× faster with no accuracy loss"
  • unsloth/gemma-4-26B-A4B-it-GGUF
  • unsloth/Qwen3.6-35B-A3B-MTP-GGUF

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0