음.. 이미 Claude MAX, GPT, Gemini 를 모두 사용중이라.. 로컬LLM 으로 개발관련 돌릴 일은 없는데, 오프라인 환경은 언제든 올 수 있으니 다운은 받아두고 사용법도 익혀두고자 해서..
크로드에게 시켜 남기는 글. 즉, 클로드가 작성..ㅎㅎ
Qwen3.6 + Rapid-MLX + OpenCode로 Spring Boot 4
작성: 2026년 5월
환경: MacBook Pro M5 Max 48GB / macOS 15+ / Spring Boot 4.0 + Java 21
요즘 클라우드 코딩 에이전트(Claude Code, Codex 등)가 너무 잘 동작해서 굳이 로컬을 쓸 일이 없지만, 오프라인 환경 대비나 민감한 코드베이스를 다룰 때를 위해서 로컬 셋업 한 벌은 갖춰두는 게 좋다. 이 글은 그런 "보험용" 환경을 깔끔하게 구축하는 가이드다.
조합은 다음과 같다.
역할 도구 비고
| 모델 | Qwen3.6-35B-A3B-MLX-4bit | MoE, 활성 파라미터 3B, ~20GB |
| 모델 서버 | Rapid-MLX | OpenAI 호환 API, MLX 네이티브 |
| 에이전트 CLI | OpenCode | MIT 라이선스, 터미널 네이티브 |
| 테스트 프로젝트 | Spring Boot 4.0 + Java 21 | 2025년 11월 출시한 최신 메이저 |
전부 인터넷 끊어도 동작한다.
0. 왜 이 조합인가
Qwen3.6-35B-A3B는 알리바바가 2026년 4월에 공개한 MoE 모델이다. 총 35B 파라미터지만 토큰당 활성 파라미터가 3B밖에 안 돼서 작은 모델 수준의 속도가 나온다. 에이전틱 코딩과 도구 호출에 특히 강하다.
Rapid-MLX는 Apple Silicon 전용으로 만들어진 추론 엔진이다. Ollama 대비 2~4배 빠르고, OpenAI 호환 API를 그대로 노출한다. MLX 네이티브라 통합 메모리를 효율적으로 쓴다.
OpenCode는 Claude Code의 오픈소스 대안 중 가장 활발한 프로젝트다. 75개 이상의 프로바이더를 지원하고, MIT 라이선스이며, 터미널 TUI가 깔끔하다.
참고: 현재(2026년 5월) Qwen3.6 GGUF는 비전 모델 분리 이슈로 Ollama에서 동작하지 않는다. 그래서 어차피 MLX 경로가 정공법이다.
1. 사전 준비
하드웨어
- Apple Silicon Mac (M1 이상)
- 통합 메모리 32GB 이상 (35B 모델 기준 권장 48GB+)
- 디스크 여유 25GB 이상
이 글은 M5 Max 48GB 기준으로 작성됐다.
소프트웨어
# Homebrew (이미 있다면 스킵)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Python 3.10+
brew install python@3.12
# Java 21 (Spring Boot 4 최소 요구사항)
brew install openjdk@21
sudo ln -sfn /opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk \
/Library/Java/JavaVirtualMachines/openjdk-21.jdk
# Maven (Gradle 쓸 거면 스킵)
brew install maven
# Hugging Face CLI (모델 다운로드용)
pip install -U "huggingface_hub[cli]"
~/.zshrc에 추가:
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
export PATH=$JAVA_HOME/bin:$PATH
확인:
java -version
# openjdk version "21.x.x" ...
2. 모델 다운로드 — Qwen3.6-35B-A3B-MLX-4bit
# 가상환경 만들기 (권장)
python3 -m venv ~/venvs/mlx
source ~/venvs/mlx/bin/activate
# 모델 다운로드 (~20GB, 처음엔 시간 좀 걸림)
huggingface-cli download mlx-community/Qwen3.6-35B-A3B-MLX-4bit
다운로드된 위치는 보통 ~/.cache/huggingface/hub/다. 이미 받아둔 모델은 오프라인에서도 그대로 동작한다.
3. Rapid-MLX 설치 및 실행
# 같은 venv에서 설치
pip install rapid-mlx
# 자가 진단 (Metal GPU, 임포트 등 점검)
rapid-mlx doctor
다음과 같이 나오면 OK:
Rapid-MLX Doctor
============================================================
[metal] OK # Apple Silicon Metal GPU available
[imports] OK # Core modules import cleanly
[cli] OK # CLI commands respond
서버 띄우기
rapid-mlx serve qwen3.6-35b --port 8000
처음 실행하면 모델을 메모리에 로드하느라 30초~1분 정도 걸린다. 다음과 같은 로그가 나오면 준비 완료:
Server running on http://localhost:8000
OpenAI-compatible endpoint: /v1/chat/completions
동작 확인 (다른 터미널)
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.6-35b",
"messages": [{"role": "user", "content": "Hello!"}]
}'
응답이 돌아오면 모델 서버는 끝.
4. OpenCode 설치
# 한 줄 설치
curl -fsSL https://opencode.ai/install | bash
# 또는 Homebrew
brew install opencode
설치 확인:
opencode --version
Rapid-MLX를 프로바이더로 등록
~/.config/opencode/opencode.json 파일을 만들거나 편집한다:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"rapid-mlx": {
"npm": "@ai-sdk/openai-compatible",
"name": "Rapid-MLX (Local Qwen3.6)",
"options": {
"baseURL": "http://localhost:8000/v1",
"apiKey": "dummy"
},
"models": {
"qwen3.6-35b": {
"name": "Qwen3.6 35B (MLX 4-bit)",
"limit": {
"context": 65536,
"output": 8192
}
}
}
}
},
"model": "rapid-mlx/qwen3.6-35b"
}
메모리 팁: 35B-A3B는 256K 컨텍스트까지 지원하지만, KV 캐시가 메모리를 많이 먹는다. 48GB 환경이라면 64K로 시작하는 걸 권장한다.
5. Spring Boot 4 + Java 21 프로젝트 생성
먼저 빈 프로젝트만 만들어두고, 실제 코딩은 OpenCode에게 시킬 거다.
Spring Initializr로 골격 생성
mkdir ~/projects && cd ~/projects
curl https://start.spring.io/starter.tgz \
-d type=maven-project \
-d language=java \
-d bootVersion=4.0.0 \
-d baseDir=hello-local-ai \
-d groupId=com.grissom \
-d artifactId=hello-local-ai \
-d name=hello-local-ai \
-d description="Local AI coded Hello World" \
-d packageName=com.grissom.hellolocalai \
-d packaging=jar \
-d javaVersion=21 \
-d dependencies=web,actuator \
| tar -xzvf -
cd hello-local-ai
생성된 pom.xml 확인
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.0</version>
</parent>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
6. OpenCode로 Hello World 작성하기
OpenCode 시작
프로젝트 디렉토리 안에서:
cd ~/projects/hello-local-ai
opencode
처음 실행하면 OpenCode가 프로젝트 구조를 분석하라고 권한다. /init 명령으로 AGENTS.md 파일을 만든다.
> /init
OpenCode가 프로젝트를 스캔해서 다음과 같은 AGENTS.md를 생성한다(예시):
# Hello Local AI — Spring Boot 4 Project
## Tech Stack
- Spring Boot 4.0.0
- Java 21
- Maven
## Conventions
- Package: com.grissom.hellolocalai
- REST controllers go in com.grissom.hellolocalai.controller
- Use Java 21 features (records, pattern matching) where appropriate
이 파일은 이후 OpenCode가 모든 작업에서 참고한다. Git에 커밋해두면 좋다.
첫 번째 프롬프트 — Hello World 컨트롤러
> Spring Boot 4의 새로운 API Versioning 기능을 사용해서 /api/hello
엔드포인트를 만들어줘. v1은 단순 문자열 "Hello, World!"를 반환하고,
v2는 인사말과 현재 timestamp를 함께 JSON으로 반환해줘.
Java 21 record를 활용해서 응답 DTO를 만들고.
OpenCode가 생성하는 코드 (예시)
OpenCode는 다음 파일들을 단계적으로 생성하고, 각 파일마다 diff를 보여주며 승인을 요청한다.
src/main/java/com/grissom/hellolocalai/controller/HelloController.java
package com.grissom.hellolocalai.controller;
import com.grissom.hellolocalai.dto.GreetingResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/api/hello")
public class HelloController {
@GetMapping(version = "1")
public String helloV1() {
return "Hello, World!";
}
@GetMapping(version = "2")
public GreetingResponse helloV2() {
return new GreetingResponse("Hello, World!", LocalDateTime.now());
}
}
src/main/java/com/grissom/hellolocalai/dto/GreetingResponse.java
package com.grissom.hellolocalai.dto;
import java.time.LocalDateTime;
public record GreetingResponse(
String message,
LocalDateTime timestamp
) {}
src/main/resources/application.yml (API 버전 설정)
spring:
mvc:
apiversion:
use:
header: X-API-Version
default: "1"
supported:
- "1"
- "2"
server:
port: 8080
빌드 및 실행
OpenCode 안에서 그대로 실행할 수 있다.
> mvn spring-boot:run 명령으로 띄워줘
OpenCode가 bash 도구로 직접 실행하고 로그를 보여준다.
[INFO] Started HelloLocalAiApplication in 1.234 seconds
테스트
# v1 (기본)
curl http://localhost:8080/api/hello
# Hello, World!
# v2 — 헤더로 버전 지정
curl -H "X-API-Version: 2" http://localhost:8080/api/hello
# {"message":"Hello, World!","timestamp":"2026-05-10T14:23:45.123"}
7. 추가 프롬프트 예시 — 더 써먹어보기
테스트 추가
> HelloController에 대한 통합 테스트를 작성해줘.
Spring Boot 4의 새 RestTestClient를 사용해서 v1과 v2를 모두 검증해줘.
Actuator 엔드포인트 노출
> actuator의 health, info, metrics를 외부에 노출하도록 설정하고,
애플리케이션 정보(이름, 버전, 설명)를 info 엔드포인트에 추가해줘.
Virtual Thread 활성화
> Java 21 가상 스레드를 활용하도록 application.yml에 설정 추가해줘.
8. 종료 및 정리
작업 끝나면
- OpenCode 종료: /exit 또는 Ctrl+C
- Rapid-MLX 종료: 서버 터미널에서 Ctrl+C
이렇게 하면 메모리가 즉시 회수된다. Ollama처럼 백그라운드 데몬이 남아있지 않는다.
다시 시작할 때
작업할 때만 두 줄이면 된다.
# 터미널 1
rapid-mlx serve qwen3.6-35b --port 8000
# 터미널 2
cd ~/projects/hello-local-ai && opencode
9. 메모리 사용량 실측 (M5 Max 48GB 기준)
대략적인 수치다.
항목 메모리
| Qwen3.6-35B-A3B-MLX-4bit (모델) | ~20GB |
| KV 캐시 (64K 컨텍스트) | ~3~5GB |
| Rapid-MLX 프로세스 오버헤드 | ~1GB |
| OpenCode + 노드 런타임 | ~500MB |
| macOS + IDE + 브라우저 등 | ~10GB |
| 합계 | ~35GB |
48GB 중 13GB 정도 여유가 있다. 컨텍스트를 더 늘리거나 다른 도구를 띄울 여지가 있다.
10. 한계 및 솔직한 평가
이 셋업이 Claude Code를 대체할 수 있냐고 묻는다면, 솔직히 아직은 아니다.
잘 되는 것
- 단순~중간 난이도의 코드 생성 (CRUD, DTO, 컨트롤러 등)
- 기존 코드 리팩토링
- 테스트 작성
- 문서화
약한 부분
- 도구 호출 안정성: 4-bit 양자화 모델 특성상 여러 단계 도구 호출에서 가끔 파싱이 깨진다. Rapid-MLX가 자동 복구해주긴 하지만 100%는 아니다.
- 긴 추론 체인: 복잡한 아키텍처 결정이나 디버깅은 클라우드 프론티어 모델이 압도적으로 낫다.
- 속도: M5 Max에서 70~80 토큰/초 정도. Claude Code의 응답 체감보다는 느리다.
그래서 언제 쓰면 좋은가
- 오프라인 환경 (출장, 비행기, 보안 사이트)
- 민감 코드베이스 (사외 반출 금지)
- API 호출량이 많은 반복 작업 (대량 리팩토링, 마이그레이션)
- 학습 목적 (LLM 동작 이해)
평소엔 Claude Max나 GPT/Gemini 구독을 메인으로 쓰고, 위와 같은 상황에서만 꺼내 쓰는 "보험" 셋업으로 적당하다.
마치며
로컬 LLM 생태계는 분기마다 의미 있게 좋아지고 있다. 작년만 해도 35B 모델이 4-bit로 노트북에서 도구 호출까지 안정적으로 한다는 건 꿈같은 얘기였다. 지금은 가능하다.
이 환경 한 번 깔아두면, 모델만 새로 받으면(huggingface-cli download ...) 항상 최신 상태를 유지할 수 있다. 1년에 한두 번 정도 모델 바꿔주는 정도의 유지보수만 하면 된다.