M4 MacBook Pro에서 로컬 Qwen 3.8 27B 모델로 9가지 코딩 하네스 벤치마킹

TL;DR

단일 M4 MacBook Pro에서 로컬로 서빙되는 Qwen 3.8 27B 모델로 9가지 인기 코딩 에이전트 하네스를 실행한 결과, 세 가지 뚜렷한 성능 그룹이 드러났습니다: (1) 가벼우면서 안정적인 하네스 (pi, mini-swe-agent, chad)는 약 8토큰/초의 속도와 1초 미만의 턴 지연 시간을 제공합니다; (2) 무겁지만 규율 있는 하네스 (dsh, cline, codex, goose)는 6–8토큰/초를 달성하지만 첫 토큰 대기 시간이 더 깁니다; (3) 시작이 무거운 하네스 (crush, opencode)는 출력 전에 3–4분을 소비하며 약 5–6토큰/초로 떨어집니다. 차이는 주로 시스템 프롬프트 크기, 도구 스키마 수, 캐시 재사용 효율성에서 비롯됩니다.


실험 설정

  • 하드웨어: Apple M4 MacBook Pro, 24GB RAM, macOS 26.6.2.
  • 모델: Qwen 3.8 27B, unsloth/Qwen3.8-27B-GGUF를 통해 3비트 양자화, llama.cpp (빌드 10470)로 서빙.
  • 서버: 모든 하네스가 공유하는 단일 llama-server 인스턴스; 프록시가 균일한 샘플링 방식을 강제했습니다 (temperature = 1.0, top_k = 20, top_p = 0.95, min_p = 0.05).
  • 캐시: 32,768토큰 통합 프리픽스 캐시, 4개 슬롯으로 분할.
  • 벤치마크: 8개의 Exercism Python 연습문제, 각각 자동 승인 모드에서 동일한 한 문장 프롬프트로 실행. 메트릭은 서버 자체 회계에서 수집되었습니다 (두 개의 chad 행은 내부 추적을 사용한 경우 제외).

메트릭 정의

메트릭 의미
첫 토큰 전 대기 시스템 프롬프트, 도구 스키마, 첫 사용자 요청을 프리필하는 시간.
이후 턴 대기 첫 턴 이후의 중앙값 및 90번째 백분위수 일시 중지 (사이드 요청 제외).
캐시 재사용 후속 턴에서 프리픽스 캐시에서 제공된 토큰의 백분율.
체감 토큰/초 총 생성 토큰을 벽시계 시간으로 나눈 값 (프리필 및 도구 오버헤드 포함).
통과 (게이트) 1,200초 제한 시간 내에 완료된 Exercism 작업 수.

로컬 추론이 클라우드보다 어려운 이유

  1. 대용량 시스템 프롬프트 및 도구 스키마 – 약 90토큰/초를 읽고 약 10토큰/초를 쓰는 노트북에서 2,000토큰 프롬프트는 생성 전에 약 22초가 소요됩니다; 18,000토큰 프롬프트 (Opencode에서 사용)는 약 226초가 소요됩니다. 클라우드 GPU는 >10k토큰/초로 프리필하여 이러한 지연을 1초 미만으로 줄입니다.
  2. 축소된 컨텍스트 창 – 시스템 프롬프트를 소비한 후, 남은 컨텍스트는 종종 <32k토큰입니다. Opencode의 18k토큰 프롬프트는 실제 작업에 창의 약 44%만 남기지만, 가벼운 pi 하네스는 약 94%를 유지합니다.
  3. 사이드 요청 오버헤드 – 보조 요청 (예: 코드 요약)을 반복적으로 발행하는 하네스는 로컬 모델이 대기열에 추가되거나 다시 프리필되도록 하여 GPU가 벽시계 시간의 >100% 동안 "바쁘게" 만듭니다.

벤치마크 결과

하네스 버전 도구 프롬프트 (토큰) 첫 토큰 대기 이후 턴 대기 (중앙값·p90) 캐시 재사용 토큰/초 통과 (24개 중)
mini-swe-agent 2.4.6 1 1,171 12.2초 3.6초·21초 96% 8.0 11 (14시간 초과)
pi 0.80.3 4 2,008 21.6초 1.3초·22초 99% 8.1 19 (7시간 초과)
cline 3.0.60–61 26 5,876 64.1초 9.9초·52초 94% 7.3 17
codex 0.151.0 10 7,804 87.8초 9.6초·28초 94% 6.9 19 (5시간 초과)
dsh 0.1.1-rc.2 25 8,052 94.4초 2.2초·34초 99% 7.2 18
goose 1.50.0 18 9,617 110.3초 1.0초·22초 100% 8.0 22 (3시간 초과)
crush 0.92.0 26 16,263 199.8초 1.8초·40초 100% 5.8 18 (8시간 초과)
opencode 1.17.12 10 18,046 225.7초 4.6초·44초 99% 5.7 15 (13시간 초과)
chad (llama.cpp) 2.0.3 5 2,563 25.6초 0.8초·19초 99% 7.9 24
chad (MLX, 직렬) * 2.0.3 5 2,566 4.7초 1.0초·19초 99% 12.4 21 (3시간 초과)
chad (MLX, dflash2) * 2.0.3 5 2,562 4.6초 0.9초·36초 99% 17.4 22 (3시간 초과)

숫자 해석

  • 가벼운 하네스 (pi, mini-swe-agent, chad)는 시스템 프롬프트를 약 2k토큰 미만으로 유지하고, >99% 캐시 재사용을 달성하며, 약 8토큰/초를 유지합니다. chad의 MLX 변형은 캐시를 프로세스 내에서 소유하여 처리량을 두 배로 늘립니다 (최대 17.4토큰/초).
  • 무겁지만 규율 있는 하네스는 첫 토큰 대기 시간이 더 길지만 (최대 약 110초) 높은 캐시 재사용을 유지하므로 정상 상태 처리량은 여전히 괜찮습니다 (약 7토큰/초).
  • 시작이 무거운 하네스 (crush, opencode)는 출력 전에 3분 이상을 소비하고 ≤6토큰/초로 떨어져 노트북에서 실용적이지 않습니다.
  • 통과율은 지연 시간과 상관관계가 있습니다: chad (두 변형 모두)만 24개 작업을 모두 해결했습니다; 다음으로 좋은 것은 goose (22/24)였습니다. mini-swe-agent의 낮은 통과 횟수는 괜찮은 토큰 속도에도 불구하고 빈번한 시간 초과에서 비롯됩니다.

로컬 모델 하네스를 위한 설계 교훈

  1. 시스템 프롬프트를 다듬으세요 – 추가 토큰마다 노트북에서 약 0.01초의 프리필 지연이 추가됩니다. 2k토큰 미만을 목표로 하세요.
  2. 도구 스키마를 제한하세요 – 추가 도구마다 프롬프트 크기가 커지고 사용 가능한 컨텍스트 창이 줄어듭니다.
  3. 프리픽스 캐시를 유지하세요 – 턴 간에 캐시된 프리필을 재사용하면 (≥95% 재사용) 반복 작업이 제거되고 체감 처리량이 크게 향상됩니다.
  4. 에이전트 루프와 모델을 함께 배치하세요 – chad의 프로세스 내 MLX 구현은 캐시를 소유하면 네트워크 왕복이 제거되어 2배-3배 속도 향상을 제공함을 보여줍니다.
  5. 드래프터를 제공하세요 – DFlash2 드래프터는 chad의 토큰 속도를 12.4 → 17.4토큰/초로 높여 초기 토큰 생성을 위한 경량 드래프트 모델의 가치를 입증합니다.

커뮤니티 피드백 하이라이트

"리소스가 제한된 환경을 위한 코딩 에이전트가 필요하다면 hax를 확인해 보세요 – 0.7MB 네이티브 바이너리로 미니멀한 프롬프트와 도구 세트를 갖추고 있습니다." – OleksandrC

"이런 벤치마크는 빠르게 변합니다; 재현 가능한 저장소가 있으면 누구나 자신의 하드웨어에서 턴당 토큰 수, 첫 토큰 지연 시간, 통과율을 비교할 수 있을 것입니다." – humbleferret

"jcode는 작은 Rust 바이너리로 RAM 사용량에서 모든 것을 능가하지만 연구에 포함되지 않았습니다." – lrvick

"Reasonix는 프리픽스 캐시 재사용에 크게 초점을 맞추기 때문에 흥미로운 비교가 될 수 있습니다." – swiftcoder

이러한 의견은 가벼운 프롬프트, 오픈 소스 재현성, 원래 매트릭스에 포함되지 않은 대체 초경량 에이전트의 존재의 중요성을 강조합니다.


벤치마크 재현

전체 실험은 chad 저장소에 스크립트로 작성되어 있습니다:

# 저장소 클론
git clone https://github.com/nathansutton/chad.git
cd chad

# 종속성 설치 (uv 권장)
uv run python benchmarks/matrix/run.py setup   # 모델 설치, llama.cpp 빌드
uv run python benchmarks/matrix/run.py smoke   # 정상 작동 확인
uv run python benchmarks/matrix/run.py llama   # llama.cpp 서버를 통해 모든 하네스 실행
uv run python benchmarks/matrix/run.py mlx     # MLX 백엔드로 chad 실행
uv run python benchmarks/matrix/run.py table   # 위의 마크다운 테이블 생성

모든 원시 데이터 (grid.json, turns.jsonl)는 벤치마크 코드와 함께 커밋되어 단일 행에서 집계된 숫자까지 완전한 추적성을 보장합니다.


결론

노트북에서 클라우드 LLM을 로컬 모델로 교체할 때 지배적인 요소는 프롬프트 크기로 인한 프리필 지연 시간입니다. 사실상 무료인 클라우드 프리필을 위해 설계된 하네스 (대용량 시스템 프롬프트, 많은 도구 스키마)는 로컬에서 사용할 수 없게 됩니다. 규율 있는 최소 프롬프트와 지속적인 프리픽스 캐싱, 가능하다면 프로세스 내 모델 루프를 결합하면 소비자 하드웨어에서 클라우드에 가까운 처리량을 제공할 수 있습니다.

Sources

관련