요즘 코딩용 로컬 LLM을 고를 때 제일 헷갈리는 지점은, 벤치마크에서 좋아 보이는 모델과 실제 내 장비에서 편하게 굴러가는 모델이 다르다는 점인 것 같습니다.
이번 테스트의 목적은 그냥 "로컬 챗봇으로 어떤 모델이 좋나"가 아니라, opencode에서 코딩을 시킬 때 붙일 로컬 LLM을 고르는 것이었습니다. 즉 OpenAI 호환 API 주소를 opencode에 연결해 두고, 실제 코드베이스를 읽고 수정하는 코딩 보조 백엔드로 쓸 만한 모델을 찾는 쪽에 가깝습니다.
이번 테스트의 논지는 단순합니다.
Mac 64GB와 DGX Spark에서 각각 메모리 한계 안에 올릴 수 있는 코딩용 로컬 LLM 후보를 고르고, 공개 코딩 벤치에서 좋아 보이는 Qwen3.6 27B / 35B A3B 계열을 기준으로 비교했습니다. 여기에 35B A3B 기반 텍스트 전용 distill + 코딩 LoRA 계열 Q4/Q8, 그리고 뒤늦게 추가한 Qwen3-Coder-Next까지 같이 넣었습니다.
중요한 전제부터 말하면, 이 글의 실측은 공식 벤치마크를 재현한 것이 아닙니다. opencode에 붙이기 전에 "이 로컬 엔드포인트가 긴 컨텍스트를 얼마나 빨리 받아먹고, 코드 출력을 얼마나 안정적으로 내는가"를 보려고 만든 실사용 전 단계 테스트입니다.
1. 모델 선택 기준: 공개 벤치와 양자화 추정치
처음 후보를 고를 때는 공개 SWE-bench 계열 점수를 기준으로 봤습니다. 다만 양자화 모델은 공식 벤치가 없는 경우가 많아서, 제작자가 주장한 값이 있으면 그쪽을 참고하고, 없으면 원본 대비 손실을 보수적으로 추정했습니다.
| 후보 | 기준 점수 | 구분 | 해석 |
|---|---|---|---|
| Qwen3.6 27B 원본 | 77.2 | 공식 | 공개 SWE-bench Verified 기준으로 가장 좋아 보이는 후보 |
| Qwen3.6 27B MLX 8bit | 76.4 | 추정 | 8bit라 원본에 매우 가깝다고 가정 |
| Qwen3.6 35B A3B 원본/FP8 | 73.4 | 공식 | MoE라 실사용 속도와 메모리 효율 기대 |
| Qwen3.6 35B A3B Q8_K_XL | 72.8 | 추정 | Q8이라 품질 손실은 작다고 가정 |
| Qwen3.6 35B A3B Q4 계열 | 71.0 | 추정 | Q4 손실을 감안한 보수적 추정 |
| Qwen3-Coder-Next 원본/FP8 | 70.6 | 공식 | 점수는 27B보다 낮지만 코딩 특화/논싱킹 모드가 강점 |
| Qwen3-Coder-Next Q4 | 67.8 | 추정 | Q4 양자화 손실 반영 |
| 35B A3B Distill Q4/Q8 | 72.0 | 추정 | distill/LoRA 계열은 벤치 직접 비교가 어려워 참고치로만 사용 |
여기서 벌써 함정이 하나 있습니다. Qwen3.6 27B의 공식 코딩 벤치 점수는 꽤 높지만, 그 점수는 대개 에이전트 스캐폴드, 파일 수정 도구, 긴 컨텍스트, 긴 출력 예산을 포함한 조건에서 나온 값입니다. opencode도 실제로는 에이전트 루프에 가깝지만, 그 전에 백엔드 모델 자체가 긴 입력을 견디고 코드 형식으로 안정적으로 답해야 합니다. 그래서 이 글의 스모크는 OpenAI 호환 API에 프롬프트 하나를 넣고, 나온 코드만 추출해서 바로 실행했습니다. 공식 벤치의 "에이전트로 문제 풀기"와는 다른 시험입니다.
참고한 모델 카드:
Qwen3.6-27B,
Qwen3.6-35B-A3B,
Qwen3-Coder-Next,
Qwen3-Coder-Next-FP8,
Brooooooklyn Q8_K_XL MLX,
hesamation GGUF
2. 테스트 방법
측정 항목은 네 가지입니다.
| 항목 | 내용 |
|---|---|
| 프리필 | 긴 프롬프트를 넣고 첫 응답까지 걸리는 시간. 512, 4K, 16K, 47.5K 입력을 사용 |
| 생성 속도 | 짧은 설명/코드 생성에서 decode tok/s 측정 |
| 코딩 스모크 | 파이썬 3문제의 결과 코드를 실제로 실행해 assert 통과 여부 확인 |
| 메모리/크기 | 다운로드 파일 크기와 실행 시 관찰된 메모리 점유 |
opencode 용도에서는 특히 프리필이 중요했습니다. 코드베이스 일부, 에러 로그, diff, 관련 파일을 한 번에 넣는 순간 첫 응답이 너무 늦으면, 모델의 토큰 생성 속도가 좋아도 실제 코딩 흐름이 끊깁니다.
코딩 스모크는 다음 3개입니다.
| 문제 | 요구사항 |
|---|---|
| merge_intervals | 겹치거나 맞닿은 구간 병합, 입력 원본 불변 |
| parse_duration | d/h/m/s 문자열을 초 단위로 파싱, 잘못된 입력은 ValueError |
| LRUCache | O(1) get/put, eviction, capacity=0 예외 처리 |
응답은 먼저 fenced code block을 찾고, 없으면 from, import, def, class가 시작되는 지점부터 코드를 추출했습니다. LM Studio에서 일부 모델은 content가 비고 reasoning_content에만 답이 들어와서, content가 비어 있으면 reasoning_content도 fallback으로 검사했습니다.
다만 이것은 여전히 원샷 테스트입니다. opencode가 실제로 수행하는 재시도, 자기수정, 파일 편집 도구, 테스트 로그를 보고 고치는 에이전트 루프는 넣지 않았습니다. 그래서 이 수치는 "opencode 최종 성능"이라기보다, opencode에 붙일 로컬 모델의 기본 반응성/출력 안정성을 보는 값에 가깝습니다.
3. Mac 64GB 결과
Mac 64GB에서는 결론이 꽤 현실적으로 갈립니다. 35B A3B Q4/Q8은 속도와 메모리 면에서 생각보다 괜찮았지만, 코딩 스모크 안정성은 Coder Next Q4가 더 좋았습니다.
| Mac 64GB 후보 | 47.5K 첫 프리필 | 생성 속도 | 코딩 스모크 | 판단 |
|---|---|---|---|---|
| Qwen3.6 27B MLX 8bit | 60K 별도 테스트 927s | 8.7 tok/s | 0/3 | 공식 벤치 점수와 달리 이번 원샷 API 조건에서는 부적합 |
| Qwen3.6 35B A3B Q4_K_M | 105.5s | 42.1 tok/s | 1/3 | 장문 입력은 빠른 편, 품질은 아쉬움 |
| Qwen3.6 35B A3B Q8_K_XL | 128.2s | 43.1 tok/s | 1/3 | Q4보다 품질 기대는 있지만 스모크는 1/3 |
| 35B A3B Distill Q4 | 647.0s | 29.4 tok/s | 1/3 | 긴 컨텍스트 프리필이 너무 느림 |
| Qwen3-Coder-Next Q4 | 136.0s | 41.3 tok/s | 2/3 | Mac 64GB 최종 품질 후보 |
Qwen3-Coder-Next Q4는 47.5K 첫 프리필이 약 136초라 아주 가볍지는 않습니다. 그래도 코딩 스모크에서 2/3을 통과했고, 출력 형식이 비교적 안정적이었습니다. Mac에서 실사용한다면 64K를 항상 꽉 채우기보다는 32K~48K 정도를 현실적인 상한으로 보는 편이 좋아 보입니다.
Qwen3.6 27B MLX 8bit는 공식 점수만 보면 가장 기대되는 후보였지만, 이번 조건에서는 느렸고 코드 스모크도 실패했습니다. 특히 LM Studio에서 /no_think를 붙여도 content가 비고 reasoning_content만 길게 나오는 케이스가 많았습니다. 출력 예산을 짧게 두면 최종 코드까지 못 가고, 길게 두면 한 문제당 몇 분씩 걸리는 형태였습니다. 이것은 "모델이 코딩을 못한다"라기보다, 이 서빙 조합과 원샷 테스트 방식이 27B의 장점을 잘 살리지 못했다는 쪽으로 보는 게 맞겠습니다.
4. Mac 깨알 팁: 통합메모리 GPU 할당
Mac에서 LM Studio 같은 로컬 LLM 앱을 쓸 때, 통합메모리를 GPU 쪽에 더 많이 잡도록 iogpu.wired_limit을 올리면 큰 모델 로딩에 도움이 되는 경우가 있었습니다.
제가 64GB Mac에서 테스트했을 때는 53248 정도가 괜찮았습니다. 조금 보수적으로는 49152부터 볼 만합니다.
sudo sysctl iogpu.wired_limit=53248
메모리별 기준값은 대략 아래처럼 잡았습니다.
| Mac 통합메모리 | iogpu.wired_limit |
|---|---|
| 32GB | 24576 |
| 48GB | 36864 |
| 64GB | 49152 또는 53248 |
| 96GB | 73728 |
| 128GB | 98304 |
| 192GB | 147456 |
이 설정은 재부팅하면 다시 초기화됩니다. 그리고 너무 높게 잡으면 시스템 메모리 여유가 줄어들 수 있으니, 본인 작업 환경에서 조금씩 올려보는 쪽이 낫습니다.
5. DGX Spark 결과
DGX Spark에서는 vLLM으로 올린 Qwen3.6 35B A3B FP8/NVFP4가 긴 입력 처리에서 매우 강했습니다. 47.5K 첫 프리필이 8초대였고, 반복 측정 평균은 4초대까지 내려갔습니다.
| DGX Spark 후보 | 47.5K 첫 프리필 | 생성 속도 | 코딩 스모크 | 판단 |
|---|---|---|---|---|
| Qwen3.6 27B FP8 | 46.3s | 7.7 tok/s | 1/3 | 이번 구성에서는 장점이 작음 |
| Qwen3.6 35B A3B FP8 | 8.3s | 52.0 tok/s | 2/3 | 작고 빠른 실사용 후보 |
| Qwen3.6 35B A3B NVFP4 | 8.3s | 49.0 tok/s | 2/3 | FP8과 비슷한 실사용 후보 |
| 35B A3B Distill Q8_0 GGUF | 22.2s | 57.4 tok/s | 2/3 | 생성 속도는 가장 빠름 |
| Qwen3-Coder-Next FP8 | 10.4s | 46.9 tok/s | 2/3 | DGX 최종 코딩 특화 후보 |
Qwen3-Coder-Next FP8은 모델 캐시만 약 75GB라 부담이 큽니다. 그래도 64K 컨텍스트로 기동했고, 코딩 특화 후보라는 점에서 DGX 쪽 최종 후보로 넣을 만했습니다.
반대로 Qwen3.6 35B A3B FP8/NVFP4는 더 작고 빠릅니다. 큰 코드베이스를 자주 넣고 반복 질의하는 용도라면 여전히 매우 매력적입니다.
6. 생성 속도와 코딩 스모크
이 표만 보면 27B가 낮게 보이는데, 이 부분은 꼭 조심해서 해석해야 합니다. 공식 벤치와 이 테스트는 목적이 다릅니다.
공식 SWE-bench 계열은 보통 저장소 전체를 보고, 파일을 수정하고, 테스트를 돌리고, 필요하면 다시 고치는 에이전트 환경에서 평가됩니다. Qwen3.6 27B 같은 reasoning 모델은 이런 구조에서 강점을 발휘할 수 있습니다. 이 점에서는 opencode의 실제 사용 방식과 더 비슷합니다.
반면 이 글의 코딩 스모크는 다음 조건입니다.
| 구분 | 공식 코딩 벤치 | 이 글의 스모크 |
|---|---|---|
| 실행 방식 | 에이전트/툴 사용 가능 | 원샷 응답 1회 |
| 코드 수정 | 파일 편집 가능 | 응답 코드만 추출 |
| 재시도 | 가능하거나 스캐폴드에 포함 | 없음 |
| 테스트 피드백 | 활용 가능 | 없음 |
| 출력 예산 | 길게 설정되는 경우 많음 | 기본 900 tokens, 27B는 별도 긴 reasoning 재시도 |
| 평가 의미 | 에이전트 문제 해결 능력 | opencode에 붙일 로컬 API의 기본 안정성 |
그래서 이 결과를 "27B가 Coder Next보다 코딩을 못한다"로 읽으면 안 됩니다. 더 정확히는 "내가 쓰는 로컬 API 원샷 워크플로우에서는 Coder Next가 더 안정적으로 코드를 뱉었다"입니다.
특히 Coder Next는 모델 자체가 non-thinking mode only에 가깝게 설계되어 있어, OpenAI 호환 API에서 바로 코드가 나오는 쪽에 유리했습니다. 반대로 27B는 reasoning을 충분히 기다리거나, opencode 같은 에이전트 루프와 파일 도구를 붙이면 공식 벤치에 가까운 강점이 나올 수 있습니다. 다만 그 경우는 속도와 사용 방식이 완전히 달라지므로 별도 카테고리로 봐야 합니다.
7. 모델 크기와 메모리
| 모델/양자화 | 파일/캐시 크기 | 실행 시 관찰 메모리 | 비고 |
|---|---|---|---|
| Qwen3.6 27B MLX 8bit | 약 28GB급 | Mac 64GB에서 여유 작음 | 60K 테스트는 매우 느림 |
| Qwen3.6 35B A3B Q4_K_M | 약 20GB급 | Mac 64GB에서 실사용 가능 | 속도/메모리 균형 좋음 |
| Qwen3.6 35B A3B Q8_K_XL MLX | 약 36GB급 | Mac 64GB에서 가능하나 무거움 | Q4보다 여유 적음 |
| 35B A3B Distill Q4 | 약 20GB급 | Mac 가능 | 긴 프리필이 느림 |
| Qwen3-Coder-Next Q4 | 약 40GB급 추정 | Mac 64GB 한계권 | 품질 후보지만 여유 적음 |
| Qwen3.6 35B A3B FP8 | DGX 캐시 약 35GB | vLLM에서 가벼운 편 | DGX 실사용 후보 |
| Qwen3.6 35B A3B NVFP4 | DGX 캐시 약 22GB | 가장 가벼운 편 | FP8과 성능 유사 |
| 35B Distill Q8_0 GGUF | 약 35GB | llama.cpp 구동 | 생성 속도 우수 |
| Qwen3-Coder-Next FP8 | DGX 캐시 약 75GB | vLLM 로딩 약 74.9GiB | 무겁지만 코딩 특화 |
Qwen3-Coder-Next FP8은 DGX에서 vLLM 로그상 모델 로딩에 약 74.9GiB를 사용했고, KV cache는 약 28.1GiB가 잡혔습니다. 64K로 기동은 가능했지만, 가볍게 여러 모델을 바꿔가며 쓰는 후보는 아닙니다.
8. Mac과 DGX의 한계
| 항목 | Mac 64GB | DGX Spark |
|---|---|---|
| 최종 품질 후보 | Qwen3-Coder-Next Q4 | Qwen3-Coder-Next FP8 |
| 실사용 대안 | Qwen3.6 35B A3B Q4/Q8 | Qwen3.6 35B A3B FP8/NVFP4 |
| 현실적 컨텍스트 | 32K~48K 권장, 64K는 가능하지만 무거움 | 64K 실사용권 |
| 47.5K 첫 프리필 | Coder Next Q4 약 136s | Coder Next FP8 약 10.4s |
| 생성 속도 | 약 41 tok/s | 약 47 tok/s |
| 코딩 스모크 | 2/3 | 2/3 |
Mac 64GB는 "돌아가느냐"와 "편하게 쓰느냐" 사이가 꽤 다릅니다. 64K까지 올리는 것은 가능해도, 큰 컨텍스트를 매번 새로 넣는 코딩 워크플로우에서는 32K~48K 정도를 현실적인 상한으로 보는 편이 맞겠습니다.
DGX Spark는 긴 입력 프리필에서 차이가 큽니다. 47.5K 입력을 넣고 첫 응답을 받는 시간이 Mac에서는 100초대, DGX에서는 10초 안팎으로 줄어듭니다. 코드베이스나 로그를 통째로 넣는 작업에서는 이 차이가 생성 tok/s보다 더 크게 체감됩니다.
9. 최종 결론
opencode에 붙일 로컬 LLM이라는 목적 기준으로 결론을 정리하면 이렇습니다.
| 용도 | 추천 |
|---|---|
| Mac 64GB에서 코딩 품질 우선 | Qwen3-Coder-Next Q4 |
| Mac 64GB에서 가벼운 실사용/긴 입력 반복 | Qwen3.6 35B A3B Q4_K_M 또는 Q8_K_XL |
| DGX Spark에서 코딩 특화 최대 후보 | Qwen3-Coder-Next FP8 |
| DGX Spark에서 속도/메모리 균형 | Qwen3.6 35B A3B FP8 또는 NVFP4 |
| DGX Spark에서 생성 속도 우선 | 35B A3B Distill Q8_0 GGUF |
양자화 기준으로 보면, 툴콜이나 간단한 구조화 출력은 Q4/FP4 계열에서도 생각보다 나쁘지 않았습니다. 하지만 opencode에서 실제 코딩을 맡기는 용도라면 기준을 조금 더 보수적으로 잡는 편이 맞아 보였습니다. 단순히 함수 하나를 만드는 것이 아니라, 파일을 읽고, 맥락을 유지하고, 수정 방향을 안정적으로 잡아야 하기 때문입니다.
제 체감상 일반 모델 기준으로는 Q8 또는 FP8급이 코딩용 마지노선에 가깝고, Q4/FP4는 "돌아간다"와 "믿고 코딩을 맡긴다" 사이에 간극이 있었습니다. 다만 Qwen3-Coder-Next Q4처럼 코딩 특화 모델은 예외적으로 꽤 버텼습니다. 그래서 Mac 64GB에서는 Coder Next Q4를 품질 후보로 남겼지만, 범용 35B A3B 계열이라면 Q8 쪽이 더 마음 편한 선택입니다.
장비 기준으로는, opencode용 백엔드는 역시 Mac보다 DGX Spark 쪽이 더 잘 맞았습니다. 생성 속도 차이보다 더 크게 느껴지는 것은 긴 컨텍스트 첫 프리필입니다. opencode는 코드베이스 일부, diff, 로그, 관련 파일을 한 번에 물고 들어가는 경우가 많아서, 47.5K 입력이 Mac에서 100초대, DGX에서 10초 안팎으로 갈리는 차이는 실제 작업 흐름에서 꽤 큽니다.
그리고 이 글에서 가장 중요한 해석 포인트는 Qwen3.6 27B입니다.
공개 벤치만 보면 27B가 매우 강력한 후보입니다. 하지만 이번 로컬 원샷 테스트에서는 27B가 낮게 나왔습니다. 이유는 크게 세 가지로 보입니다.
- 공식 SWE-bench 조건은 에이전트/도구/파일 수정/긴 출력 예산을 포함하는 경우가 많습니다.
- 이번 테스트는 OpenAI 호환 API에 한 번 묻고, 나온 코드만 바로 실행했습니다.
- Mac LM Studio의 27B MLX는 content 대신 reasoning_content로 긴 생각을 계속 내보내서, 짧은 출력 예산에서는 최종 코드까지 도달하지 못하는 경우가 있었습니다.
따라서 이 결과는 "27B가 코딩을 못한다"가 아닙니다. 더 정확한 결론은 "현재 제 로컬 서빙 환경에서 opencode 백엔드 후보로 쓰기에는, 기본 응답 안정성과 지연 시간 면에서 27B보다 Coder Next와 35B A3B 계열이 더 편했다"입니다.
실제 opencode처럼 파일을 열고, 테스트를 돌리고, 실패 로그를 보고 고치는 구조라면 27B의 공식 벤치 강점이 일부 다시 살아날 수 있습니다. 반대로 LM Studio나 vLLM의 OpenAI 호환 API에 붙여서 빠르게 코드를 받고 싶은 용도라면, 출력 형식이 안정적인 Coder Next가 더 편했습니다.
한 줄로 줄이면 이렇습니다.
Mac 64GB에서 opencode에 붙일 모델은 "Qwen3-Coder-Next Q4"가 품질 쪽 최종 후보, Qwen3.6 35B A3B Q8이 보수적인 실사용 대안입니다. DGX Spark는 "Qwen3-Coder-Next FP8"이 코딩 특화 최대 후보이고, Qwen3.6 35B A3B FP8/NVFP4가 작고 빠른 실사용 후보입니다. 툴콜만 보면 Q4/FP4도 쓸 만하지만, 코딩까지 안정적으로 맡기려면 Q8/FP8급을 기준선으로 보는 쪽이 맞아 보였습니다.
이 테스트는 제 장비와 설정 기준입니다. LM Studio, MLX, llama.cpp, vLLM, 채팅 템플릿, context length, KV cache 설정에 따라 체감은 꽤 달라질 수 있습니다. 특히 reasoning 모델은 "어떤 런타임에서 어떤 템플릿으로, 얼마나 기다려서 답을 받는가"가 성능표만큼 중요했습니다.


* 실제 64K컨텍스트로 구동하면 메모리는 Mac은 Coder q4가 48G차지, DGX는 Coder fp8이 117G 차지합니다. 간당간당하죠.
* 의외로 맥64G에서 코더q4가 성능이 좋더군요. q8과 비빌 수준이에요
그래서 다음 벤치는 맥64G코더 q4와 DGX Spark코더 fp8의 벤치를 좀 더 심도깊게 파보려고 합니다.
LM Studio, MLX, llama.cpp, vLLM중에 opencode에 붙인 프로바이더는 어떤것인가요?
저는 opencode에 연결하는것 부터가 어렵더라구요