2주 동안 로컬 LLM 20종을 같은 조건으로 돌려 봤습니다. 목적은 두 가지였습니다. 하나는 터미널 코딩 에이전트에 올릴 모델을 고르는 것, 다른 하나는 블로그 자동 발행 파이프라인의 각 단계(초안·코드검토·사실성 판정)에 앉힐 모델을 고르는 것이었습니다.
결과만 말하면 20종 중에 기존 세팅을 갈아치운 모델은 거의 없었습니다. 대신 남은 게 따로 있는데, "이걸 어떻게 재야 하는가"에 대한 실패 목록입니다. 개인적으로는 그게 순위표보다 훨씬 값졌습니다.
측정 환경
| 항목 |
값 |
| CPU |
Ryzen 9 5950X |
| GPU |
RTX 3080 12GB |
| RAM |
DDR4 64GB |
| 런타임 |
Ollama native /api/chat |
| 컨텍스트 |
num_ctx=32768 |
| 온도 |
temperature=0.2 |
| tok/s |
콜드런 버리고 웜런 |
- 측정 중 GPU 경쟁 여부는 5초 간격으로 VRAM·사용률·그 시점 로드된 모델 목록까지 샘플링해서 확인했습니다.
- 태스크는 6종 고정입니다. 도구 호출 / 코드 생성+실행 / 버그 진단(소·대) / 설계 문서(10점 체크리스트) / 언어 준수 / 롱컨텍스트 니들 검색.
첫 번째 벽: 12GB에 들어가는지 여부
가장 크고 단순한 분기점이었습니다. 모델 가중치가 12GB에 들어가면 100% GPU에 올라가고, 넘치면 CPU로 오프로드되면서 속도가 한 자리 수로 떨어집니다.
| 모델 |
VRAM |
gen tok/s |
GPU 비율 |
| llama3.2:3b |
6.0GB |
221.8 |
100% |
| ornith:9b |
7.1GB |
95.3 |
100% |
| qwen2.5-coder:7b |
7.5GB |
133.1 |
100% |
| llama3.1:8b |
9.1GB |
124.5 |
100% |
| gemma4:12b |
9.98GB |
63.8 |
100% |
| gemma4:26b |
11.7GB |
39.0 |
51% |
| qwen3.6:35b |
11.5GB |
38.8 |
59% |
| deepseek-coder-v2:16b |
11.1GB |
32.3 |
52% |
| mistral-nemo:12b |
11.0GB |
27.8 |
81% |
| deepseek-r1:14b |
11.2GB |
13.0 |
66% |
| gemma2:27b |
11.3GB |
5.4 |
54% |
| mistral-small3.2:24b |
11.3GB |
4.97 |
— |
| devstral-small-2:24b |
11.2GB |
4.88 |
— |
| qwen3.6:27b |
11.7GB |
3.92 |
51% |
| qwen2.5-coder:32b |
11.2GB |
3.1 |
36% |
| gemma4:31b |
11.4GB |
3.0 |
38% |
| deepseek-r1:32b |
11.2GB |
2.9 |
36% |
| llama3.3:70b |
10.7GB |
1.16 |
19% |
여기서 읽어야 할 것들입니다.
- 오프로드는 "조금 느려짐"이 아닙니다. 완전 적재 구간은 63~221 tok/s인데, 오프로드는 39 tok/s에서 시작해 1 tok/s대까지 떨어집니다. 체감상 다른 등급의 도구입니다.
- 70b의 VRAM 10.7GB는 "많이 올라갔다"가 아닙니다. 12GB를 꽉 채우고도 81%가 CPU에 남았다는 뜻입니다. 42GB를 디스크에 두고 1.16 tok/s를 쓸 이유는 없었습니다.
- 파라미터 수와 속도가 단조롭게 대응하지도 않습니다. 27b(3.92)가 35b(38.8)보다 10배 느렸습니다. 35b는 MoE라 활성 파라미터가 적고, 27b는 dense라 오프로드 비용을 그대로 물었습니다.
- 32B급 dense는 이 하드웨어에서 사실상 전멸입니다(3 tok/s대).
라운드 1 — 주력 후보 4종
기존 메인이던 qwen3.6:35b를 포함해 네 종을 붙였습니다. 이 표가 이후 모든 라운드의 기준선이 됐습니다.
| 항목 |
gemma4:12b |
ornith:9b |
qwen3.6:35b |
gemma4:26b |
| 적재 |
완전 |
완전 |
오프로드 |
오프로드 |
| 콜드로드 |
8.2s |
3.3s |
29.6s |
23.5s |
| gen tok/s |
63.8 |
95.3 |
38.8 |
39.0 |
| prompt tok/s |
814.7 |
1091.8 |
188.6 |
250.5 |
| VRAM |
9.98GB |
7.1GB |
11.5GB |
11.7GB |
| 툴콜 |
O |
O |
O |
think시 X |
| 설계문서 |
10/10 |
8/10 |
8/10 |
10/10 |
| 한국어 |
O |
O |
한자 누수 |
O |
| 코딩 |
4.5 |
3.5 |
3.5 |
3.5 |
| 종합 |
1위 |
2위 |
3위 |
4위 |
- 롱컨텍스트 니들 검색(≈12~14k 토큰)은 4종 전부 적중했습니다. 정확도가 아니라 속도만 갈렸습니다.
- 버그 진단에서는 gemma4:12b만 깔끔했습니다. qwen3.6:35b는 결론은 맞지만 초반에 데드락이라고 오도한 뒤 번복했고, gemma4:26b는 "다행히 5를 넘지 않는다"며 자기모순을 냈고(실제 값은 7), ornith:9b는 아예 "버그 없음"으로 오답을 냈습니다.
- ornith:9b의 think on은 위험했습니다. 사고 66.5k자·생성 32.5k 토큰을 쏟아붓고 답변은 공란으로 6분을 태웠습니다. 이 모델은 반드시 think off로 써야 합니다.
그런데 순위가 뒤집혔습니다
코딩 위주 벤치를 보완하려고 글쓰기·웹검색·상식을 추가로 재자 결과가 흔들렸습니다.
| 항목 |
gemma4:12b |
ornith:9b |
qwen3.6:35b |
gemma4:26b |
| 글쓰기 |
4.5 |
4.5 |
5 |
4.5 |
| 분량통제 |
초과 |
약간짧음 |
정확 |
초과 |
| 웹검색(툴6개) |
X |
O |
O |
△ |
| 상식·추론 |
O |
O |
O |
O |
- 툴을 6개 물리자 코딩 1위였던 gemma4:12b가 무너졌습니다. web_search를 호출조차 하지 않고 "검색 권한이 없다"며 거부했습니다. gemma4:26b는 엉뚱하게 get_datetime만 불렀습니다.
- 툴 1개짜리 벤치에서는 네 종 다 통과했는데, 툴 6개에서는 gemma 계열이 취약했습니다. 이 관찰이 이후 모든 툴콜 판정의 기준을 바꿨습니다.
- 결론은 이원화였습니다. 순수 코딩은 gemma4:12b, 웹검색 포함 범용은 ornith:9b.
라운드 2 — llama 3.x 계열 3종
llama3.2:3b / llama3.1:8b / llama3.3:70b를 붙였습니다. 여기서는 반복 횟수를 늘렸습니다(3b·8b는 n=3, 70b는 회당 35분이라 n=2).
| 모델 |
gen tok/s |
툴콜 |
설계 |
한국어 |
| llama3.2:3b |
221.8 |
3/3 |
2/10 |
X |
| llama3.1:8b |
124.5 |
1/3 |
4/10 |
O |
| llama3.3:70b |
1.16 |
0/2 |
2.5/10 |
△ |
- 세 종 모두 think를 지원하지 않습니다. {"think":true}에 400 does not support thinking이 떨어집니다. reasoning 축은 측정 자체가 불가였습니다.
- 실제 코드 버그 진단은 8런 전부 실패했습니다(8/8). 프록시 코드에서 본문을 재직렬화한 뒤 Content-Length를 갱신하지 않는 버그를 심었는데, 셋 다 "그럴듯하지만 틀린" 답을 확신조로 냈습니다. 8b가 제시한 수정 코드는 할당 전 변수를 참조해 그 자체로 NameError였습니다.
- llama3.1:8b는 한국어 문자열의 닫는 따옴표를 빠뜨려 SyntaxError를 냈고(2/3 재현), 에러를 툴 결과로 돌려받고도 2턴째 응답이 완전히 비었습니다. 에이전트 루프에서 이건 느린 것보다 나쁩니다. 복구도, 재시도도 없이 멈춥니다.
- llama3.2:3b는 툴콜 인자가 3/3 무결한 유일한 모델이었지만, 한국어 지시를 어기고 베트남어(2/3)·일본어(1/3)를 흘렸습니다.
- 설계문서 점수는 8b와 70b가 런 사이에 4.0↔2.5로 자리를 바꿨습니다. 평균이 완전 동률이라 단독 근거로 쓸 수 없는 지표였습니다.
라운드 3 — 코딩 특화 7종
deepseek-r1 2종, qwen2.5-coder 2종, mistral-nemo:12b, deepseek-coder-v2:16b, gemma2:27b입니다.
먼저 /api/show로 capabilities를 확인했더니 시나리오의 전제가 두 개 틀렸습니다.
| 모델 |
tools |
thinking |
| deepseek-coder-v2:16b |
X |
X |
| gemma2:27b |
X |
X |
| qwen2.5-coder:7b |
O |
X |
| qwen2.5-coder:32b |
O |
X |
| mistral-nemo:12b |
O |
X |
| deepseek-r1:14b |
O |
O |
| deepseek-r1:32b |
O |
O |
- 툴 미지원 2종은 에이전트 용도로 그 자리에서 실격입니다.
- deepseek-r1의 think:false는 동작하지 않습니다. 400도 없이 조용히 무시되고 사고 토큰이 계속 생성됩니다(14b는 think_off에서도 사고 12,512자). 끌 수 없는 사고는 32k 컨텍스트에서 무시할 비용이 아닙니다.
결과는 이렇게 갈렸습니다.
| 모델 |
gen tok/s |
툴콜 |
버그진단 |
설계 |
| mistral-nemo:12b |
27.8 |
O |
X |
6/10 |
| qwen2.5-coder:7b |
133.1 |
텍스트 누출 |
X |
8/10 |
| qwen2.5-coder:32b |
3.1 |
텍스트 누출 |
O |
3/10 |
| deepseek-r1:14b |
13.0 |
X |
O |
6/10 |
| deepseek-r1:32b |
2.9 |
X |
O |
4/10 |
| deepseek-coder-v2:16b |
32.3 |
미지원 |
X |
3/10 |
| gemma2:27b |
5.4 |
미지원 |
X |
5/10 |
- 속도·툴콜·코드이해가 한 모델에서 만나지 않았습니다. 구조적 툴콜에 성공한 건 mistral-nemo:12b 하나인데 그 하나가 버그 진단에 실패했고, 버그를 잡은 r1 계열은 툴을 아예 시도하지 않았습니다.
- qwen2.5-coder 2종은 올바른 툴콜 JSON을 본문 텍스트로 출력했습니다. tool_calls 배열은 비어 있습니다. 모델은 맞게 생성했는데 구조화되지 않아 클라이언트가 쓸 수 없습니다.
- r1 계열은 더 나빴습니다. 툴이 주어졌는데도 무시하고, 실행하지도 않은 명령의 출력을 지어냈습니다. 14b는 존재하지 않는 Take-First cmdlet까지 발명했습니다.
- r1 계열은 한국어 강제가 통하지 않습니다. 영어·포르투갈어·중국어에 일본어 가나까지 섞였습니다. 한자 몇 자 누수가 아니라 답변 언어 자체가 바뀌는 수준입니다.
- gemma2:27b는 num_ctx=32768을 요청해도 8192로 클램프됩니다. deepseek-coder-v2:16b는 ollama ps상 컨텍스트가 32768인데도 23k 토큰 프롬프트에서 400을 냈습니다.
여기서 결론이 한 번 뒤집혔습니다
같은 날 후속 검증에서 mistral-nemo:12b의 "툴콜 O"를 무효 처리했습니다. 위 T1은 툴 1개 + 가짜 툴 결과 1왕복이었기 때문입니다. 실제 배치 조건으로 다시 쟀습니다.
조건 초기 벤치 풀 툴셋 재검증
| 조건 |
초기 벤치 |
풀 툴셋 재검증 |
| 툴 개수 |
1개 |
4개 |
| 과제 |
1왕복 |
다중 파일 편집 |
| 채점 |
사람 확인 |
pytest 직접 실행 |
| 반복 |
1회 |
15회 |
| 모델 |
overall |
테스트 |
수정한 파일 |
| ornith:9b (대조군) |
15/15 |
15/15 |
— |
| ornith:35b |
15/15 |
15/15 |
— |
| mistral-nemo:12b |
0/15 |
0/15 |
0건 |
실패 양상이 핵심입니다. 타임아웃도 크래시도 아니고, 툴을 한 번도 호출하지 않았습니다. 대신 "먼저 실패하는 테스트를 확인해 봅시다" 하고 bash 명령을 코드펜스 텍스트로 적어놓고는 정상 종료했습니다.
이건 qwen2.5-coder가 툴콜 JSON을 본문으로 뱉은 것과 같은 실패 축입니다. 툴 개수와 과제 복잡도가 올라가자 mistral-nemo도 같은 자리로 무너졌습니다.
툴 1개 벤치의 툴콜 결과를 에이전트 적격으로 읽으면 안 됩니다. 이 라운드가 스스로 그걸 증명했습니다.
라운드 4 — 24B급 3종
devstral-small-2:24b / mistral-small3.2:24b / qwen3.6:27b입니다.
| 항목 |
devstral |
mistral3.2 |
qwen3.6:27b |
| 웜 tok/s |
4.88 |
4.97 |
3.92 |
| 툴콜 |
O |
O |
O |
| 피보나치 |
O |
날조 |
O |
| 버그(소) |
X |
X |
O |
| 버그(대) |
스킵 |
스킵 |
O |
| 설계문서 |
7/10 |
7/10 |
10/10 |
| 언어 |
clean |
clean |
가타카나 1건 |
- qwen3.6:27b가 이번 2주에서 가장 좋았습니다. 심은 버그를 소·대 둘 다 think_off에서 잡은 유일한 모델이고, 설계문서는 만점입니다. 로컬에서 프론티어에 인접한 코드 추론을 보여줬습니다.
- 다만 think on이 손해였습니다. 5,153토큰을 더 쓰고도 대용량 버그를 오히려 놓쳤습니다. think off로 써야 합니다.
- mistral-small3.2:24b는 배제했습니다. 코드 실행 툴의 출력이 빈 값이었는데도 "55"라고 단정했습니다. 우연히 정답이었지만, 관측 없이 확신하는 모델은 에이전트로 쓸 수 없습니다.
- qwen3.6:27b도 속도 이득은 없었습니다(3.92 tok/s). 주력 교체는 실태스크 A/B 후에 결정하는 게 맞다고 봤습니다.
판정자 자리는 성격이 다릅니다
블로그 자동 발행 파이프라인에는 "초안의 사실성을 검사하는" 단계가 있습니다. 여기 모델을 고르는 기준은 코딩 에이전트와 완전히 달랐습니다.
| 모델 |
붕괴 |
환각 |
속도 |
판정 |
| gemma4:31b |
0/5 |
없음 |
177~483s |
채택 |
| qwen3.6:35b |
0/4 |
1회 |
64~115s |
차선 |
| gemma4:26b |
3/5 |
— |
74s |
기각 |
| gemma4:12b |
— |
— |
— |
기각 |
| mistral-nemo:12b |
0/1 |
— |
16s |
기각 |
- gemma4:12b는 놓쳐서 기각, mistral-nemo:12b는 전부 막아서 기각입니다. 12b는 전제 붕괴가 4건인 글을 통과시켰습니다. mistral-nemo는 50배 빨랐지만, standalone이라 썼고 stand-alone이라 안 썼다는 이유로, very little이라 썼고 minimal이라 안 했다는 이유로 근거 미지지 판정을 냈습니다. 근거 부합을 문자열 일치로 착각한 겁니다. 이 기준이면 어떤 초안도 영원히 통과하지 못합니다.
- 판정자 자리에서는 후자가 더 나쁩니다. 파이프라인이 통째로 멈춥니다.
- 판정자의 환각은 로그에 그치지 않습니다. qwen3.6:35b가 asyncio.gather에 없는 인자가 존재한다고 서술했는데, 이 지적문은 다음 단계에서 "이 사실을 반영해 고쳐라"는 수리 지시가 됩니다. 없는 API를 글에 심을 수 있습니다.
- 초안을 qwen3.6으로 쓰고 판정을 gemma 계열로 둔 설계에 근거가 섰습니다. 같은 글에서 31b는 A 오류를, 35b는 B 오류를 잡고 서로 놓쳤습니다. 계열이 다르면 보는 오류가 다릅니다.
gemma4:26b는 왜 기각됐나 — 디제너레이션
판정은 정확히 하는데, 그 판정을 한국어로 쓰지 못했습니다.
done_reason=length eval=4096 content=8480자 → JSON 깨짐
앞부분은 멀쩡하게 진짜 오류를 짚습니다. 그러다 장이록(Persistence)의 특ing의 특징을의 특징의 특징의...가 수백 번 반복되고 중간에 l'en de l'en de, outputting outputting이 섞여 상한까지 갑니다.
- factual=true면 안 깨집니다. {"factual": true, "issues": []} 31자만 쓰면 되니까요. factual=false로 지적문을 써야 할 때만 무너집니다.
- 처방을 전부 시도했지만 실패했습니다. repeat_penalty 1.15, temperature 0.7, 모델 권장 샘플링(temp 1.0/top_k 64), 컨텍스트 8k 축소 — 전부 붕괴하거나 파싱되더라도 지적문이 쓰레기였습니다.
- 파싱에 성공한 케이스가 더 위험했습니다. JSON은 통과하는데 지적문이 재부팅-재부팅 같은 상태로 다음 단계에 넘어가 멀쩡한 글을 망가뜨립니다. 판정 불가보다 나쁩니다.
num_ctx는 모델마다 다르게 작동합니다
num_ctx를 지정하지 않으면 서버 기본값 65536이 걸립니다. 판정 프롬프트는 624토큰뿐이라 순낭비입니다. 그래서 줄여봤는데, 효과가 모델마다 갈렸습니다.
| 모델 |
아키텍처 |
64k KV |
축소 효과 |
| gemma4:31b |
dense |
0.8GB |
-20% |
| qwen3-coder:30b |
dense |
3.7GB |
-17% |
| qwen3.6:35b |
MoE |
0.6GB |
없음 |
- 핵심은 "KV 캐시가 비운 VRAM에 가중치가 더 올라가는가"입니다. gemma4:31b는 GPU 적재가 8.2 → 9.0GB로 늘어 20%를 회복했습니다. qwen3-coder:30b는 캐시가 3.7GB나 빠지는데 적재는 10.6 → 10.5GB로 제자리였습니다.
- qwen3.6:35b는 MoE라 KV 캐시가 0.6GB뿐이라 회수할 게 없습니다. 시간은 컨텍스트가 아니라 생성 토큰 수를 따라갔습니다.
- 그래서 초기 벤치의 "오프로드 모델은 컨텍스트가 지렛대가 아니다"라는 일반화는 깨졌습니다. 변수는 오프로드 여부가 아니라 KV 캐시 크기와 dense/MoE입니다.
- 8k가 16k보다 더 빨랐지만 쓰지 않았습니다. 프롬프트 624 + 사고 최대 4000 + 출력 상한 4096 = 8720이라 8192를 넘습니다. 넘치면 컨텍스트 시프트가 나고 그게 바로 위에서 진단한 디제너레이션입니다. 아끼려다 병을 만드는 셈입니다.
완전 적재 모델은 사정이 반대로, 큰 컨텍스트가 거의 공짜였습니다.
| 모델 |
32k |
64k |
128k |
| ornith:9b |
7.3GB |
8.0GB |
9.4GB |
| gemma4:12b |
9.8GB |
10.2GB |
— |
ornith:9b는 128k에서도 9.4GB로 GPU 100%·속도 무손실이었습니다. gemma4:12b는 sliding-window attention 덕에 16k→64k에서 VRAM이 0.3GB만 늘었습니다.
★ 진짜 산출물 — 측정 함정 8가지
같은 대상을 놓고 세운 가설이 연달아 틀렸고, 조건을 바꾸자 결론이 매번 뒤집혔습니다. 전부 측정 설계 결함이었습니다. 이게 이 2주에서 제일 값진 부분입니다.
- 실패를 재현할 수 없는 조건으로 실패를 조사했습니다. gemma4:26b 단독 테스트가 7/7 정상으로 나와 "모델은 멀쩡, 로드 꼬임"이라고 두 번 결론냈습니다. 그런데 그 7회는 전부 factual=true 케이스였고, 그때 출력은 31자라 절대 안 깨집니다. → 판정자를 시험하려면 "틀렸다고 말해야만 하는 입력"을 줘야 합니다.
- 개수만 세고 내용을 안 읽었습니다. 26b 채택 근거였던 "반려 1건"은 issues 배열 길이만 센 것이었습니다. 그 텍스트를 읽었으면 쓰레기인 걸 봤을 겁니다.
- n=1로는 아무것도 확정하지 못합니다. 전 항목 1회 측정으로 낸 판정의 절반이 3회로 늘리자 뒤집혔습니다. 더 나쁜 건 2회로도 부족했다는 점입니다. 8b의 실패가 2차 런에서 사라져 "1회성 사고"로 철회했다가 3차 런에서 그대로 되살아났습니다. 2회의 불일치는 노이즈가 아니라 표본 부족의 신호입니다.
- 속도는 n=1로 충분하고 품질은 아닙니다. tok/s는 3회 편차가 3% 이내인데 설계문서 점수는 4.0↔2.5로 요동칩니다. 측정 예산은 정성 지표 반복에 몰아야 합니다.
- 정성 채점을 정규식에 맡기면 안 됩니다. 한자 정규식([一-鿿])만 자동화해서 3b의 베트남어·영어 누출을 기계적으로 전부 놓쳤습니다. 사람이 원문을 읽고서야 잡혔습니다. 버그 진단 채점도 키워드 Content-Length로 하니 모델이 원본 소스를 되뿌리면 걸려서 3건이 오탐이었습니다. 자동 검사 통과는 "깨끗하다"가 아니라 "그 검사가 보는 것만 없다"는 뜻입니다.
- 대표성 없는 표본으로 상한을 정할 뻔했습니다. 125자짜리 코드로 "컨텍스트 1024면 충분"이라는 값이 나왔는데, 실제 발행 코드 1239자 한 덩이가 1026토큰이었습니다. 그 값을 넣었으면 매 발행마다 코드가 조용히 잘렸을 겁니다. 관측은 운이고 상한은 구조입니다.
- GPU 경쟁 의심은 사후에 증명할 수 없습니다. 시작 시점 스냅샷 하나로 "측정 내내 유휴"라고 썼던 건 근거가 안 됩니다. 이제 5초마다 로드된 모델 목록을 남깁니다.
- 실행 전에 채택 기준을 못박아야 합니다. 샘플링 권장값이 35% 빨랐지만 검출률은 1.0/3으로 동률이었습니다. 35% 빠른 이유가 덜 숙고하고 덜 쓴 것(지적문 2문장 → 1문장)이었습니다. 속도가 좋다고 기준을 바꾸면 결과 보고 골대 옮기기입니다.
여기에 환경 함정도 하나 있습니다. Windows에서 subprocess.run(text=True)는 cp949로 디코드합니다. 모델이 생성한 코드가 한글을 print하면 UnicodeDecodeError로 터지고, try/except에 걸려 벤치는 계속 돕니다. 예외가 잡혀도 그 태스크의 입력이 바뀐 것이므로 측정은 폐기해야 합니다.
최종 라우팅
| 슬롯 |
모델 |
근거 |
| 코딩 |
gemma4:12b |
완전적재·균형 |
| 범용·툴 |
ornith:9b |
툴콜 15/15 |
| 초안 |
qwen3.6:35b |
글쓰기 최상 |
| 코드검토 |
qwen3-coder:30b |
유지 |
| 사실성 판정 |
gemma4:31b |
무붕괴·무환각 |
| 대치 후보 |
qwen3.6:27b |
A/B 대기 |
컨텍스트 권장값은 이렇게 정리했습니다.
| 모델 |
num_ctx |
근거 |
| ornith:9b |
65536~131072 |
128k도 무손실 |
| gemma4:12b |
32768~65536 |
10.2GB 유지 |
| 오프로드 계열 |
16384~32768 |
키워도 손해 |
| 사실성 판정 |
16384 |
64k 대비 -20% |
think는 대부분의 자리에서 껐습니다. ornith:9b는 폭주 리스크, gemma4:31b는 품질 개선 없이 시간 2배, qwen3.6:27b는 5천 토큰 더 쓰고 버그를 놓쳤습니다. 켜서 이득이 확인된 자리가 거의 없었습니다.
삭제 권고
llama3.1:8b(모든 축에서 열위), llama3.3:70b(1.14 tok/s·42GB), deepseek-coder-v2:16b(툴 미지원+롱컨텍스트 실패), gemma2:27b(툴 미지원+ctx 8k 상한), qwen2.5-coder:32b·deepseek-r1:32b(3 tok/s대), mistral-nemo:12b(풀 툴셋 0/15), ornith:35b(9b 대비 이점 0).
정리
20종을 돌려서 기존 세팅은 거의 그대로 남았습니다. 처음엔 실패한 프로젝트처럼 보였는데, 다시 보면 그게 결과입니다. "바꿀 이유가 없다"를 데이터로 확인한 것도 결론입니다.
한 줄로 남길 건 이쪽입니다. 툴 1개로 잰 툴콜은 에이전트 적격을 판정하지 못하고, 통과 케이스만 골라 재면 아무것도 보이지 않으며, 자동 채점이 통과했다는 건 그 검사가 보는 것만 없다는 뜻입니다. 12GB 카드에서 모델을 고르는 일은 결국 적재 여부라는 하드 제약 위에서 툴콜 안정성을 확인하는 작업이었습니다. 나머지 지표는 대체로 그다음이었습니다.