Engineering note · AI

Llama.cpp와 Qwen 3.5로 Claude Code 로컬 구축하기

2026년 05월 16일이현수
태그aiqwenllamacppclaudecode

M 시리즈 맥북 환경에서 llama.cpp와 Unsloth Qwen 3.5 모델을 사용해 API 비용 부담 없이 Claude Code 에이전트 코딩 환경을 구축하는 단계별 튜토리얼입니다.

클로드코드로 로컬 모델을 연결해서 쓸 수 있다는 말에 맥북에서 한번 돌려보기로 했다. 48GB 메모리를 가진 맥북 Pro 환경에서 llama.cpp와 Qwen 3.5 35B 모델을 사용해 완전히 오프라인 상태에서도 동작하는 무료 에이전트 코딩 환경을 구축하는 방법을 공유한다.

왜 llama.cpp와 Qwen 3.5인가

처음에는 Ollama 로 설치해서 테스트했으나 제대로 안돌아가기도 하고, 설정도 한계가 있어서 llama.cpp 서버를 직접 올리기로 결정.

사용할 로컬 LLM으로는 Qwen 3.5 모델군을 선택했다.

  • 내 맥북의 메모리가 48GB인 점을 감안하여 35B(350억 파라미터) 크기의 모델(unsloth/Qwen3.5-35B-A3B-GGUF:Q4_K_M)을 선택했다.
  • 메모리 용량이 다소 부족한 경우 27B 모델 혹은 14B 이하 버전 사용

llama.cpp 설치 및 서버 구동

sh
brew install llama.cpp

우선 Homebrew를 통해 터미널 환경에 llama.cpp를 설치한다. 설치가 완료되면 로컬 서버(llama-server)를 구동해야 한다. 단순히 켜는 것이 아니라, 에이전트가 끊임없이 컨텍스트를 유지하고 도구(Tools)를 사용할 수 있도록 고도의 최적화 옵션을 지정해 주는 것이 핵심이다.

다음 명령어를 통해 서버를 시작한다.

sh
llama-server \
  -hf unsloth/Qwen3.5-35B-A3B-GGUF:Q4_K_M \
  --port 8131 \
  -c 131072 \
  -b 2048 \
  -ub 1024 \
  --parallel 1 \
  -fa on \
  --jinja \
  --keep 1024 \
  --cache-type-k q8_0 \
  --cache-type-v q8_0 \
  --swa-full \
  --no-context-shift \
  --chat-template-kwargs '{"enable_thinking": false}' \
  --mlock \
  --no-mmap
옵션설명
-c 131072컨텍스트 윈도우 크기를 128k(131,072)로 지정
--chat-template-kwargs '{"enable_thinking": false}'생각(Thinking/Reasoning) 모드 비활성화. 에이전트 코딩 환경에서는 불필요한 토큰 낭비를 막기 위해 추론 모드를 끄는 것을 권장
--swa-full슬라이딩 윈도우 어텐션(SWA) 캐시를 전체 컨텍스트로 확장하여 프롬프트 캐싱 효율을 끌어올린다. RAM 소모는 늘어나지만 성능 향상이 크다.
--no-context-shift에이전트 구동에 필수 옵션이다. 컨텍스트 시프트가 일어나면 SWA 캐시가 깨질 수 있어 비활성화한다.
--cache-type-k/v q8_0정밀도 손실이 거의 없는 q8_0 포맷으로 키/값 캐시를 구성해 처리 속도를 대폭 높인다.
--keep 1024최초 입력된 시스템 프롬프트를 캐시에서 삭제하지 않고 보존한다.
--mlock --no-mmapRAM에 메모리를 잠가서 가상 메모리 스왑으로 인한 성능 저하를 방지하는 macOS 최적화 옵션이다.

Claude Code 설정

json
{
  "env": {
    "ANTHROPIC_BASE_URL": "http://127.0.0.1:8131",
    "ANTHROPIC_AUTH_TOKEN": "local",
    "ANTHROPIC_MODEL": "unsloth/qwen3.5-35b-a3b",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "unsloth/qwen3.5-35b-a3b",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "unsloth/qwen3.5-35b-a3b",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "unsloth/qwen3.5-35b-a3b",
    "CLAUDE_CODE_SUBAGENT_MODEL": "unsloth/qwen3.5-35b-a3b",
    "CLAUDE_CODE_MAX_OUTPUT_TOKENS": "128000",
    "DISABLE_PROMPT_CACHING": "1",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
    "CLAUDE_CODE_ATTRIBUTION_HEADER": "0"
  },
  "permissions": {
    "allow": [
      "Bash(git *)", "Bash(npm *)", "Bash(npx *)", "Bash(node *)", "Bash(ls *)", 
      "Bash(cat *)", "Bash(mkdir *)", "Bash(cp *)", "Bash(mv *)", "Bash(rm *)", 
      "Read", "Edit", "Write", "Glob", "Grep"
    ]
  }
}

이제 설치된 Claude Code가 방금 띄운 로컬 Llama 서버를 바라보도록 설정 파일을 수정해 준다. 사용자의 Claude 설정 경로(~/.claude/settings.json) 파일을 열고 아래와 같이 수정한다.

!IMPORTANT 환경 변수 export 명령으로 헤더 등을 차단하려 할 경우 오동작할 수 있으므로, 반드시 위의 json 설정 방식을 사용하는 것을 권장한다.

실행 편리성을 위한 Alias 등록

sh
cat << 'EOF' >> ~/.zshrc
cclocal() {
  export ANTHROPIC_BASE_URL="http://127.0.0.1:8131"
  export ANTHROPIC_AUTH_TOKEN="local"
  claude "$@"
}
EOF
source ~/.zshrc

이제 터미널에 cclocal을 입력하기만 하면 로컬 LLM을 기반으로 오프라인 Claude 에이전트 코딩이 가능해진다.

실제 구동 성능 확인

서버 로그를 확인해 보면 아래와 같이 실시간 처리 타임이 기록되는 것을 볼 수 있다.

text
> prompt eval time = 31108.14 ms / 3912 tokens ( 7.95 ms per token, 125.75 tokens per second)
> eval time = 21045.89 ms / 338 tokens ( 62.27 ms per token, 16.06 tokens per second)
> total time = 52154.03 ms / 4250 tokens
  • 프롬프트 파싱 속도 (Prompt Eval): 초당 약 125 tokens 수준으로 로컬 구동임에도 매우 쾌적한 속도를 보여준다.
  • 텍스트 생성 속도 (Eval): 초당 약 16 tokens 수준으로 에이전트의 생각을 지연 없이 실시간으로 받아볼 수 있다.

그런데 과금해서 사용하는 것보다 확실히 많이 느리고, 결과물도 아직은 퀄리티가 좋은지 모르겠다.. 하지만 나중에는 모든 사람들의 로컬에서 llm 이 자체적으로 돌아가는 세상이 오지 않을까 싶다. 메모리만 충분하면!

참고한 페이지

좋아요와 댓글

댓글 남기기

댓글 0개

댓글을 불러오는 중입니다.