3,000개가 넘는 Obsidian 메모를 누군가의 서버에 올리는 건, 솔직히 마음이 불편하다.
ChatGPT나 Claude에게 "내 노트 기반으로 요약해줘"를 시키려면 결국 업로드가 필요하고,
그 순간 내 사고의 원석이 외부 서버로 떠나기 때문이다. 그래서 직접 만들었다 😎.
Mac Mini M4 Pro 한 대 + vLLM-MLX + Qwen3.6-35B + Obsidian 플러그인.
이 조합이면 메모 검색, 요약, 작성, 웹 검색까지 — 모든 토큰이 책상 위 알루미늄 박스 안에서 끝난다!

📌 이 글의 핵심 요약
- Qwen3.6-35B는 MoE 구조 덕분에 19GB 가중치, 3B 수준 속도, 35B 수준 품질을 제공한다 💡
- vLLM-MLX는 Mac의 통합 메모리를 직접 활용해 PCIe 복사 병목이 없다.
- Obsidian 플러그인은 ReAct 루프로 7개 도구(검색·요약·작성·웹 등)를 자동으로 연결해서 처리한다.
- 모든 처리가 로컬에서 끝나 프라이버시와 오프라인 사용이 동시에 보장된다.
1. 왜 로컬 LLM인가? — 클라우드로 보낼 수 없는 이유
로컬 LLM 설치를 선택하는 세 가지 현실적인 이유가 뭘까?
클라우드 LLM이 뛰어난 성능을 제공한다는 사실은 부정할 수 없다.
그럼에도 로컬 LLM 설치를 선택하는 데는 명확한 이유가 있다.
Obsidian 볼트에는 미발표 아이디어, 개인 일정, 업무 전략이 섞여 있다. OpenAI나 Anthropic의 서버 정책이 아무리 좋아도, 토큰 자체가 외부로 나가는 구조는 기업 환경에서 허용되지 않는 경우가 많기 때문이다.
GPT-4o 기준 입력 1M 토큰당 $2.50다. 하루 10회 긴 문서를 처리하면 월 수십 달러가 나간다. 반면, 로컬 서버는 초기 하드웨어 비용 이후 전기세만 발생한다.
출장 중 인터넷이 불안정한 환경에서도 Obsidian 볼트와 AI가 동시에 작동할 수 있다(물론 로컬에 설치한 경우). 클라우드 의존성 없이 완결된 개인 AI 인프라가 된다는 것이다.
2. 전체 스택 구조 한눈에 보기
Obsidian + vLLM-MLX + Qwen3.6의 전체 아키텍처는 어떻게 구성될까?
전체 흐름은 단순하다.
Obsidian 사이드바가 에이전트 UI 역할을 하고, 요청이 Caddy 리버스 프록시를 거쳐 vLLM-MLX 서버로 전달되며, Qwen3.6-35B가 추론을 처리한다.
│ HTTPS :8443 + Bearer API Key
▼
Caddy (TLS internal, 리버스 프록시)
│ HTTP :8001
▼
vLLM-MLX (OpenAI 호환 /v1/* 엔드포인트)
│
▼
Qwen3.6-35B-A3B-4bit (mlx-community, ~19GB)
| 단계 | 도구 | 역할 |
|---|---|---|
| 🎙 입력 | Obsidian 플러그인 (vault-agent) |
사이드바 채팅 UI + ReAct 루프 |
| 🔒 보안 | Caddy | TLS + Bearer 토큰 인증 + 리버스 프록시 |
| ⚙️ 추론엔진 | vLLM-MLX | Continuous batching + Prefix cache + MCP 통합 |
| 🧠 언어모델 | Qwen3.6-35B-A3B-4bit | MoE 35B, 활성 파라미터 3B, 262K 컨텍스트 |
3. vLLM-MLX 설치 및 설정 — Mac에서 로컬 LLM 서버 구동하기
Mac에서 vLLM-MLX로 로컬 LLM을 설치하는 방법은? 🛠
설치 자체는 어렵지 않다. Python 3.11 가상환경을 만들고, vllm-mlx를 설치한 뒤 모델을 지정해 서버를 기동하면 된다. 핵심은 상시 가동을 위한 launchd 설정이다.
source .venv/bin/activate
--model mlx-community/Qwen3.6-35B-A3B-4bit \
--port 8001 \
--host 0.0.0.0
launchd로 Mac 부팅 시 자동 실행되도록 설정하는 방법은? 🛠
서버가 꺼져도 자동으로 재시작되게 하려면 macOS의 launchd를 활용한다.
아래 plist 파일을 ~/Library/LaunchAgents/에 저장해두면 된다.
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.moai.vllm-mlx</string>
<key>KeepAlive</key><true/>
<key>RunAtLoad</key><true/>
<key>ThrottleInterval</key><integer>30</integer>
</dict>
</plist>
launchd 적용 명령어:
4. Qwen3.6-35B를 선택한 이유 — 로컬 LLM 사용법의 핵심
Qwen3.6 35B 모델이 로컬 환경에 적합한 이유가 뭘까?
단순히 "좋은 모델"이 아니다.
로컬 하드웨어의 제약 조건을 정확히 겨냥한 설계 덕분에 선택했다.
세 가지 핵심 특성이 결정적이었다.
① MoE(Mixture-of-Experts) 구조 — "지식은 35B, 속도는 3B"
Qwen3.6-35B-A3B는 Mixture-of-Experts 아키텍처다.
총 파라미터는 35B이지만, 토큰 생성 시 실제 활성화되는 파라미터는 약 3B 수준이다.
즉, 추론 품질은 35B 모델과 유사하면서 생성 속도는 3B 모델에 가깝다.
Mac Mini M4 Pro에서 실측 기준 20~50 tokens/s 속도가 이 구조 덕분에 가능하다.
② 4-bit 양자화 — 19GB로 35B를 담는다
mlx-community/Qwen3.6-35B-A3B-4bit 모델은 4-bit 양자화를 통해 가중치 크기가 약 19GB이다. Apple Silicon의 통합 메모리 64GB 기준으로 전체 메모리의 25%만 차지하므로, 나머지 40GB를 IDE, 브라우저, Claude Code, Obsidian이 공유할 수 있다.
그렇기 때문에 스왑이 발생하지 않는 안정적인 운영이 가능하다.
③ 262K 컨텍스트 — 이전 세대 대비 8배
Qwen3.5-35B의 최대 컨텍스트는 32K였다.
Qwen3.6은 이를 262,144 토큰으로 확장했다고 한다. 이 차이는 실무에서 매우 크다고 본다.
| 활용 시나리오 | Qwen3.5 (32K) | Qwen3.6 (262K) |
|---|---|---|
| 긴 문서 전체 분석 | ❌ 분할 필요 | ✅ 통째로 가능 |
| Obsidian 볼트 컨텍스트 주입 | ❌ 일부만 | ✅ 수백 개 노트 |
| 멀티스텝 에이전틱 작업 | ⚠️ 제한적 | ✅ 안정적 |
vLLM-MLX가 Mac에서 다른 추론 엔진보다 유리한 이유가 뭘까?
Ollama, LM Studio와 비교해서 vLLM-MLX를 선택한 실질적인 근거다.
CPU와 GPU가 동일한 물리 RAM을 공유한다. 전통적인 GPU 추론처럼 PCIe를 통한 VRAM 복사 단계가 없어, 19GB 가중치가 Metal 연산에 즉시 접근할 수 있다.
Ollama는 이 필드를 무시하지만, vLLM-MLX는 읽고 동작한다. Qwen3.6의 <think>...</think> 내부 추론 출력을 서버 단에서 직접 차단할 수 있다.
재기동 직후 디스크에서 4.6GB KV 캐시가 메모리로 복구된다. 반복되는 시스템 프롬프트나 MCP 툴 스키마의 첫 토큰 생성 시간이 수 초 단위로 단축된다.
/v1/chat/completions, /v1/models가 바로 준비된다. 클라이언트 코드 변경 없이 클라우드 API와 로컬 서버를 URL 하나로 전환할 수 있다.
5. Obsidian 플러그인 연동 — ReAct 루프로 7개 도구를 자동 체인
Obsidian에서 로컬 LLM을 에이전트로 활용하는 구조는 어떻게 될까??
핵심은 ReAct(Reason + Act) 루프다. 모델이 단순히 질문에 답하는 것이 아니라, 필요한 도구를 스스로 선택하고 실행하며 결과를 종합한다. 플러그인 이름은 vault-agent (v0.2.4)이며, TypeScript로 작성되어 있다.
├── agent/
│ ├── AgentController.ts // ReAct 루프 (최대 3라운드)
│ ├── ToolRegistry.ts // 7개 도구 등록/실행
│ ├── PromptBuilder.ts // 시스템 프롬프트 조립
│ └── ConversationManager.ts
├── llm/
│ ├── LLMService.ts // OpenAI-compat 클라이언트
│ └── QwenAdapter.ts
├── tools/ // 7개 도구 구현
└── ui/ChatView.ts
7개 도구는 어떤 작업을 자동화하나요?
| 도구명 | 역할 | 실제 활용 예시 |
|---|---|---|
vault_search |
볼트 내 파일 검색 | "n8n 관련 메모 찾아줘" |
vault_read_contents |
특정 파일 내용 읽기 | 검색 결과 파일 상세 조회 |
vault_summarize |
파일 요약 생성 | "이 글의 핵심 3줄로 요약해줘" |
write_to_file |
새 파일 작성 | "오늘 회의 내용으로 새 노트 만들어줘" |
replace_in_file |
기존 파일 수정 | "이 섹션 내용 업데이트해줘" |
web_search |
실시간 웹 검색 | "최신 vLLM 릴리즈 정보 검색해줘" |
youtube_transcript |
유튜브 자막 추출 | "이 영상 내용 요약해서 노트에 저장해줘" |
ReAct 루프를 3라운드로 제한한 이유가 뭘까?
무한 루프 방지가 목적이다. 모델이 "한 번만 더 검색해볼게요"를 반복하다 발산하는 사례를 실제로 경험했다. MAX_TOOL_ROUNDS = 3으로 설정하면 대부분의 작업이 "검색 → 읽기 → 요약/작성" 3단계 사이클 안에서 자연스럽게 완료된다.
6. 실전 삽질 로그 — 모델 업그레이드 후 부서진 것들
Qwen3.5에서 3.6으로 업그레이드 시 발생하는 주요 호환성 문제는?
Qwen 3.5에서 3.6으로 올린 날, 플러그인이 네 곳에서 동시에 터졌다. 흥미로운 점은 모두 "모델이 더 똑똑해져서 생긴 회귀"라는 공통점이다.
🔴 문제 1: arguments가 객체로 옵니다 (JSON 문자열이 아닌)
3.5까지는 tool_calls[0].function.arguments가 항상 JSON 문자열이었다. 3.6은 일부 응답에서 이미 파싱된 객체를 반환하기 시작했고, 기존 JSON.parse(args)가 실패하면서 빈 인자로 도구가 호출되었다.
try {'{'} return JSON.parse(input); {'}'} catch {'{'} return {'{'} raw: input {'}'}; {'}'} {'}'}
💡 한 줄 수정에 회귀 테스트 3개(문자열/객체/비JSON 경로)를 붙여 두었다.
다음 업그레이드 때 같은 함정에 빠지지 않기 위해서다.
🔴 문제 2: <think>...</think> 태그가 응답에 그대로 노출돼
Qwen3.6의 Thinking Mode가 활성화되면 내부 추론 과정이 답변에 섞여 나온다.
단순한 프롬프트 지시 한 줄로는 막히지 않아, 4중 방어 레이어를 구성했다.
| 레이어 | 방법 |
|---|---|
| ① 시스템 프롬프트 | ## THINKING MODE RULE 블록 + /no_think 토큰 삽입 |
| ② API 요청 body | chat_template_kwargs.enable_thinking: false 추가 |
| ③ 클라이언트 후처리 | <think>, <thinking>, <reasoning> 태그 정규식 제거 |
| ④ 메타 문장 제거 | "Final answer.", "Done." 등 서두 문장 정리 |
💡 교훈: 로컬 모델에서 "설정 하나면 된다"는 문서는 절반만 맞는다.
서버 토글 + 프롬프트 + 클라이언트 후처리 세 레이어가 모두 필요하다 😤
🔴 문제 3: 한국어 응답에 한자·가나가 섞여나와
Qwen은 중국어 기반 모델이다. 샘플링 단계에서 저빈도 한자나 히라가나가 산발적으로 혼입된다. 단순 언어 설정으로는 해결이 안 되어, 시스템 프롬프트에 ## LANGUAGE RULE (STRICT) 블록으로 간체/번체 한자 + 히라가나/가타카나 사용 금지를 명시했다. 이후 혼입 사례가 사실상 사라졌다.
🟡 Caddy TLS 문제 — 외부 접근 설정에서 이틀을 소모했어 😤
iPhone에서도 볼트에 접근하기 위해 DDNS + Caddy 리버스 프록시를 구성하다 세 가지 함정을 만났다.
- :8443 포트만 지정하면 TLS 인증서가 발급 안 됨 → 호스트명을 명시적으로 등록해야 해.
- health_uri를 /로 설정하면 vLLM의 404 응답으로 모든 요청이 503 →
/v1/models로 변경한다. - 외부 DDNS에서 body가 빈 채로 200 응답 반환 → Caddyfile의 site block에 DDNS 호스트명이 누락된 것이 원인이었다. 응답 헤더의
Via: 1.1 Caddy유무로 reverse_proxy 실행 여부를 판별할 수 있다.
7. 성능 및 비용 비교 — Mac Mini M4 Pro vs RTX 4090 데스크탑
로컬 LLM 서버를 위한 Mac Mini M4 Pro와 RTX 4090 데스크탑의 실제 차이는?
| 항목 | Mac Mini M4 Pro (64GB) | 데스크탑 + RTX 4090급 |
|---|---|---|
| 아이들 전력 | 10~20W | 80~150W |
| 추론 피크 전력 | 60~90W | 400~550W |
| 팬 소음 | 대부분 무음 | 부하 시 분명히 들림 |
| 설치 공간 | 13 × 13 cm | ATX 타워 |
| 초기 비용 | 약 250~300만원 | 400~500만원+ |
| 35B 모델 가용 메모리 | 64GB 통합 메모리 | 24GB VRAM |
| 추론 속도 (35B 4bit) | 20~50 tokens/s | 더 빠름 (배치 처리) |
"늘 켜놓고 로컬 LLM을 API로 쓰고 싶다"는 용도라면, 전력·소음·공간·비용 네 축 모두 Mac Mini가 유리하다. 단, 수백만 토큰 배치 처리나 절대 속도가 중요한 경우는 GPU 데스크탑이 필요하다.
8. 자주 묻는 질문 (FAQ)
Q. Mac Mini M4 Pro 64GB 외에 다른 사양에서도 Qwen3.6-35B가 작동할까?
최소 사양은 32GB 통합 메모리다. 32GB에서는 4-bit 양자화 모델(19GB)을 올릴 수 있지만, 다른 애플리케이션과의 메모리 경합으로 스왑이 발생할 수 있다. 16GB에서는 small 모델(7B~14B)로 다운그레이드해야 할 것이다. 64GB가 여유로운 운영의 최적점.
Q. vLLM-MLX 대신 Ollama를 써도 될까?
Obsidian 플러그인의 기본 채팅 기능은 Ollama에서도 동작한다. 단, chat_template_kwargs.enable_thinking 필드를 Ollama는 무시하기 때문에 Qwen3.6의 think 태그 누수를 서버 단에서 차단할 수 없다. 또한 MCP 통합, Prefix Cache, Reasoning Parser 등 vLLM의 서비스 기능을 사용하려면 vLLM-MLX가 필요.
Q. iPhone에서 Obsidian 볼트에 AI로 접근하는 것이 실제로 가능할까?
가능하다. Caddy를 통해 DDNS + TLS 인증서를 설정하면 외부 네트워크에서도 접근된다. 단, SNI 매칭 문제로 LLMService.ts에서 IP 접속 시 servername을 강제 오버라이드하는 처리가 필요하다. 또한 NAT idle timeout으로 인한 ECONNRESET을 막기 위해 매 요청마다 새 소켓을 여는 설정이 권장된다.
Q. 262K 컨텍스트를 실제로 다 사용하면 메모리가 부족하지 않을까?
128K 이상을 본격적으로 사용하면 KV Cache가 메모리를 상당히 점유한다. 64GB 기준으로는 128K까지 안정적이고, 그 이상에서는 --cache-memory-percent 옵션 조정이 필요하다. 일반적인 에이전틱 작업(검색·요약·작성)은 32K 이내에서 충분히 처리된다.
Q. vault-agent 플러그인을 직접 설치하고 사용할 수 있을까?
GitHub 저장소(github.com/cyans/rocal_llm_obsidian_plugin)에서 소스를 받아 npm run build 한 번으로 빌드할 수 있다. esbuild 번들 후 자동으로 Obsidian 플러그인 폴더에 배포된다. TypeScript와 Node.js 환경만 갖춰져 있으면 충분하다.
마치며 — 로컬 LLM을 "믿을 만하게" 쓰는 것의 의미
로컬 LLM을 올리고 구동하는 것은 30분이면 된다. "믿을 만하게" 쓰는 것은 완전히 다른 이야기이다.
arguments가 어느 날부터 객체로 오고, 응답에 <think> 태그가 새어 나오고, Caddy가 Host 매칭을 조용히 실패하고, NAT이 keepalive 소켓을 RST로 끊겼다. 이 모든 것이 qwen3.5에서 qwen3.6으로 올리는 순간에 몰아쳐 왔다.
그 과정을 버티게 해준 것이 vLLM-MLX + Mac Mini M4 Pro 조합이었다. 통합 메모리, OpenAI 호환 API, 서버 단 Thinking 토글, MCP 통합 — 각각은 화려하지 않지만, 합쳐 놓으면 "내 노트에 말을 거는 35B 어시스턴트를 주말에 구축할 수 있는 수준"까지 내려온다.
직접 구축해 볼래?
지금까지 vLLM-MLX 설치부터 Obsidian 플러그인 연동까지의 전체 과정을 단계별로 설명했다.
직접 구축하다가 어려움이 있으면 물어보라!
- vLLM-MLX GitHub:
github.com/mzbac/vllm-mlx - Qwen3.6-35B-A3B-4bit:
mlx-community/Qwen3.6-35B-A3B-4bit - vault-agent 플러그인:
github.com/cyans/rocal_llm_obsidian_plugin - Qwen3.6 공식 문서: Alibaba Cloud Model Studio







댓글 쓰기