
RTX 4070로 로컬 LLM에게 코드를 작성하게 하는 2026년 버전 — Qwen3 Coder와 gpt-oss:20b 실측
요약
RTX 4070(12GB VRAM) 환경에서 보안 이슈를 해결하기 위해 Qwen3 Coder와 gpt-oss:20b 모델을 활용한 로컬 LLM 코드 생성 성능을 비교 분석합니다. Qwen3 Coder는 높은 코드 생성 정밀도를 제공하며, gpt-oss:20b는 MXFP4 양자화를 통해 VRAM 효율성이 뛰어나 병렬 작업에 유리합니다.
핵심 포인트
- 코드 생성 정밀도가 중요하다면 Qwen3 Coder 30B-A3B (MoE) 모델을 권장함
- VRAM 확보 및 다른 작업(예: Whisper)과의 병렬 처리가 필요할 때는 gpt-oss:20b가 적합함
- RTX 4070 환경에서는 Qwen3 Coder 사용 시 Q4_K_M 이상의 양자화 수준을 유지해야 품질 저하를 막을 수 있음
- Ollama를 통해 두 모델 모두 GPU offload를 활용하여 로컬에서 구동 가능함
VRAM 12GB인 RTX 4070을 보유한 개발자분들, 최근 로컬 LLM으로 코드를 작성하게 할 선택지를 정리해 보셨나요?
저는 2026년에 들어서면서 사내 보안 규칙으로 인해 클라우드 AI에 입력할 수 없는 안건이 늘어남에 따라, 로컬 LLM을 이용한 코드 생성에 다시 도전하고 있습니다. 과거에 Qwen 3.5 범용 버전의 모든 모델을 검증한 기사를 작성한 적이 있는데, 그 이후 Qwen3-Coder-Next와 gpt-oss:20b가 Ollama에 올라오면서 RTX 4070에서도 실용적인 속도로 구동할 수 있게 되었습니다.
본 기사에서는 제가 동일한 프롬프트를 두 모델에 입력하여 측정한 생성 속도 · 코드 품질 (HumanEval Pass@1) · 할루시네이션 (Hallucination) 비율의 3가지 축 벤치마크를 공유합니다.
상세 내용에 들어가기에 앞서 결론을 말씀드립니다.
코드 생성 정밀도를 최우선 → Qwen3 Coder 30B-A3B (MoE) -
VRAM을 확보하고 싶을 때 / 다른 작업과 병렬 처리 → gpt-oss:20b -
둘 다 Ollama로 운용 가능 — RTX 4070은 이제 두 모델 시대
저는 한 쪽만 선택할 생각이었으나, 결국 둘 다 Ollama에 두고 구분해서 사용하고 있습니다. 코드 리뷰는 Qwen3 Coder, 옆에서 실행 중인 음성 받아쓰기(Transcription)와 병렬로 돌릴 때는 gpt-oss:20b, 이런 느낌입니다. 처음에는 Qwen3 Coder 하나로 밀고 나갈 생각이었는데, 어느 날 Whisper를 돌리면서 코드 생성을 요청했더니 VRAM이 순식간에 가득 차서 Ollama가 아무 말 없이 종료되었습니다. 그 이후로 한 쪽을 MXFP4로 설정해 두는 습관이 생겼다는 소소한 경위가 있습니다.
실기 구성과 전제 조건입니다.
| 항목 | 값 |
|---|---|
| GPU | RTX 4070 (12GB VRAM) |
| ... |
Ollama는 GPU offload를 자동으로 수행합니다. Qwen3 Coder의 30B-A3B MoE는 RTX 4070 12GB에 통째로 올라가지 않으므로, 전문가 층 (Expert layers)의 일부는 CPU로 넘어갑니다.
처음에는 의욕에 앞서 Qwen3 Coder의 풀 정밀도 버전을 pull 하려다가, SSD 여유 공간이 3분 만에 바닥났습니다. RTX 4070에서 다룰 수 있는 현실적인 해답은 Q4_K_M 또는 Q5_K_M이며, gpt-oss:20b는 공식 MXFP4가 유일한 선택지입니다.
| 양자화 (Quantization) | 사이즈 기준 | VRAM (기준) | 품질 저하 |
|---|---|---|---|
| Q5_K_M | 약 21GB | 올라가지 않음 (CPU offload 큼) | 거의 없음 |
| ... |
저는 Q4_K_M으로 운용하고 있습니다. Q3_K_M까지 낮추면 HumanEval Pass@1이 80%대 초반까지 떨어졌습니다. 이는 "디스크를 절약하려다 시간을 낭비하는" 전형적인 손해 보는 선택이 되기 쉽습니다. 이 부분은 아끼지 않는 것이 결과적으로 작업 시간을 되찾는 길입니다.
# Qwen3 Coder 30B-A3B (Instruct, Q4_K_M)
ollama pull qwen3-coder:30b-a3b-instruct-q4_K_M
# gpt-oss:20b (Native MXFP4)
...
Qwen3 Coder는 2026년 Q1에 Qwen 팀이 출시한 코드 특화 MoE (Mixture of Experts)입니다. 총 파라미터는 30B이지만, 활성(Active) 파라미터는 불과 3B입니다. MoE 덕분에 생성 시 연산량이 억제되어, VRAM 12GB에서도 CPU offload를 병용하면 구동됩니다.
gpt-oss:20b는 OpenAI가 공개한 20B 오픈 웨이트 (Open weights) 모델로, 네이티브 MXFP4 양자화를 통해 13GB 전후로 구동된다는 점이 최대 장점입니다.
첫 번째 축은 초당 토큰 수(tokens per second)입니다. 동일한 "Python으로 500개의 랜덤 정수 퀵 정렬(Quick Sort)을 작성하라"는 프롬프트를 각 5회씩 던져 중앙값을 구했습니다.
| 모델 | 생성 속도 (median) | 기동 레이턴시 (Latency) |
|---|---|---|
| Qwen3 Coder 30B-A3B | 38 tok/s | 약 1.2초 |
| gpt-oss:20b | 29 tok/s | 약 0.9초 |
Qwen3 Coder 30B-A3B는 "3B active의 MoE"이므로, 겉보기의 30B보다 훨씬 가볍게 동작하는 것이 효과를 발휘합니다. 실제 시간으로 100줄의 Python 함수라면 8초 정도면 결과가 돌아옵니다.
gpt-oss:20b는 Dense 모델로 20B이며, Qwen3보다 정직하게 무겁습니다. 다만 MXFP4 덕분에 메모리는 가벼워서, 저는 최근 다른 터미널에서 Whisper를 돌리면서 gpt-oss:20b에게 코드를 작성하게 하는 방식으로 사용하고 있습니다.
체감상으로는 Qwen3 Coder가 사고의 보폭이 더 큰 것인지, 함수 전체를 한 번에 작성하는 동작이 많습니다. gpt-oss:20b는 잘게 나누어 출력하는 만큼 중간에 개입하기는 쉬운 반면, 긴 호흡의 리팩터링 (Refactoring)에는 서툰 인상이었습니다. 그리고 두 모델 모두 풀 가동시키면 팬이 본격적으로 돌기 시작해서, 여름철에는 책상 위에 선풍기를 한 대 더 놓았습니다. 냉각은 농담이 아니라 효과가 확실합니다.
HumanEval 164문제를 돌려, 생성된 코드가 테스트를 통과하는 비율 (Pass@1)을 계산했습니다.
| 모델 | HumanEval Pass@1 |
|---|---|
| Qwen3 Coder 30B-A3B | 87% |
| gpt-oss:20b | 75% |
| 모델 | SWE-bench Verified (공칭) |
|---|---|
| Qwen3 Coder 30B-A3B | 약 65% |
| gpt-oss:20b | 약 42% |
Qwen3 Coder는 코드 특화 모델다운 결과입니다. Python에 관해서는 제 체감상으로도 유의미하게 좋았으며, 특히 표준 라이브러리 (Standard Library)의 API를 착각하는 케이스가 거의 사라졌습니다.
gpt-oss:20b는 범용 모델 중에서는 선전하고 있지만, Qwen3 Coder와의 차이는 명확합니다. "코드를 작성하는 용도 전용"이라면 Qwen3 Coder를 선택해야 합니다.
체감 차이 중 흥미로운 점은 예외 처리 (Exception Handling) 방식입니다. Qwen3 Coder는 try/except 안에서 의미 있는 로그를 남겨주는 경향이 있어, 리뷰에 넘기기 쉬운 코드를 작성해 옵니다. gpt-oss:20b는 "일단 print로 잡고 앞으로 나아가는" 경향이 강해, 본 작업 투입 전에 반드시 제가 예외 설계를 다시 작성해야 하는 수고가 발생했습니다. 참고로 제가 리뷰에서 가장 많이 빨간 펜을 드는 부분도 이곳인데, 인간도 LLM도 똑같은 부분에서 요령을 피우는구나 싶어 묘하게 납득이 갔습니다.
HumanEval Pass@1은 Python 중심의 벤치마크이므로, TypeScript/Go/Rust 등은 별도로 확인할 필요가 있습니다. Qwen3 Coder는 MultiPL-E에서도 범용 버전보다 평균 8-12pt 높다고 Qwen 팀이 공칭하고 있지만, 제 환경에서는 언어별로 체감 차이가 있습니다.
이 부분이 정말 중요한 포인트입니다.
저는 "할루시네이션 (Hallucination) 비율"을 다음과 같이 정의했습니다. 직접 작성한 20문제(사내 실무 프레임워크 및 실무 API를 가정한 문제 세트)에 대해, 존재하지 않는 API나 함수명을 생성한 비율입니다.
| 모델 | 할루시네이션 비율 (20문제 중) | 전형적인 실수 예시 |
|---|---|---|
| Qwen3 Coder 30B-A3B | 2-3문제 / 약 12% | 오래된 API 이름 (예: 폐지된 pandas.append) |
| gpt-oss:20b | 4-5문제 / 약 23% | 가공의 메서드 이름 (db.query_one() 등) |
Qwen3 Coder는 코드 생성 데이터로 학습된 만큼, API 이름이나 모듈 이름의 착오가 적습니다. 그렇다고 해서 제로(0)가 되지는 않습니다.
gpt-oss:20b는 "그럴듯한 함수명"을 만드는 습관이 남아 있는데, 저는 이를 "자신만만하게 존재하지 않는 코드를 작성하는" 모드라고 부릅니다. 구현 내용을 그대로 push했다가는 CI에서 AttributeError의 폭풍을 맞게 됩니다.
어떤 모델을 사용하든, 생성된 코드는 반드시 로컬에서 한 번 실행한다. 로컬 LLM 시대의 코드 생성은, "동작할 때까지가 프롬프트"라고 저는 단정 짓고 있습니다.
할루시네이션 비율을 체감상 억제하기 위해, 최근에는 다음 3가지를 루틴화했습니다.
- 생성 직후 import / API 이름 grep 수행 — 존재하지 않는 모듈 참조를 가장 먼저 걸러냄
- 테스트 퍼스트 (Test-First) — 생성 전에 테스트 케이스를 작성해 두고, 생성 결과에 바로 적용
- 로컬 실행을 반드시 1회 포함 —
python -c "$(cat tmp.py)"로 그 자리에서 바로 돌려보고 판단
이 세 가지만으로 Qwen3 Coder의 할루시네이션 비율은 실질적으로 5% 이하까지 떨어졌습니다. 처음에는 번거롭다고 생각했지만, 이를 건너뛴 날에 한해 CI에서 5개가 연속으로 떨어지며 결국 제 시간을 낭비하게 되었기에 가드를 늘리기로 했습니다. "코드 생성을 신뢰하고 싶다"와 "코드 생성을 맹신하고 싶다"는 비슷해 보이지만 전혀 다른 태도입니다.
RTX 4070 12GB에서 두 모델을 안정적으로 운용하려면, OLLAMA_NUM_GPU 환경 변수와 KV 캐시 (KV Cache) 양자화가 핵심입니다.
# Qwen3 Coder MoE: 일부 레이어를 CPU로 넘기기
export OLLAMA_NUM_GPU=24 # GPU에 올릴 레이어 수. 너무 많으면 OOM 발생
export OLLAMA_KV_CACHE_TYPE=q8_0 # KV 캐시 (KV Cache) 양자화로 약 30% 절약
...
제 환경에서는 Qwen3 Coder의 경우 OLLAMA_NUM_GPU=24로, gpt-oss:20b는 OLLAMA_NUM_GPU=999 (모든 레이어를 GPU에 로드)로 설정했을 때 안정적입니다. nvidia-smi로 확인했을 때 VRAM 사용량이 11GB대로 유지된다면, 데스크톱 작업과 병행해도 중단되지 않습니다.
여담이지만, 욕심을 내서 OLLAMA_NUM_GPU=32로 올렸더니 Blender를 실행하는 순간 OOM (Out Of Memory)이 발생하며 Ollama가 멈춰버렸습니다. 데스크톱 작업과 병행하고 싶다면, VRAM을 의도적으로 10GB대로 맞춰서 1GB 정도의 여유 공간을 남겨두는 것이 안전권입니다. 벤치마크 최고 수치보다는, 끊기지 않는 라인을 찾는 것이 일상적인 개발에서는 더 유용합니다.
같은 실수를 반복하는 분들이 줄어들기를 바라며, 제가 겪었던 문제점들을 공유합니다.
qwen3-coder:30b라고 입력하여 pull을 진행했더니, 일반 30B 모델이 다운로드되어 디스크 용량을 두 배로 소비했습니다. 정답은 qwen3-coder:30b-a3b-instruct-q4_K_M까지 명시하는 것입니다. Ollama Library에서 현재 사용 가능한 태그를 확인한 뒤 실행하는 것이 결과적으로 가장 빠릅니다. ollama list로 중복된 모델을 찾아 지울 때마다 약간의 패배감이 느껴집니다.
OLLAMA_KV_CACHE_TYPE=q8_0 설정을 잊어버리면, 긴 컨텍스트 (Context) 처리 시 VRAM이 순식간에 압박을 받습니다. 저는 4,000 토큰 분량의 리포지토리 요약을 던진 순간, Ollama가 아무 말 없이 프리징(Freezing)되어 터미널 앞에서 5초 정도 굳어버렸습니다. 긴 프롬프트 (Prompt)를 던질 계획이라면 처음부터 이 설정을 적용해 두는 것이 좋습니다.
Qwen3 Coder의 MoE (Mixture of Experts)는 모든 레이어가 GPU에 올라가지 않는다는 전제하에 작동하므로, OLLAMA_NUM_GPU를 조절하며 최적의 지점을 찾아야 합니다. 저는 24 전후에서 안정화되었습니다. 이보다 적으면 CPU 측의 병목 현상 (Bottleneck)으로 인해 느려지고, 너무 많으면 OOM으로 인해 종료됩니다. htop과 nvidia-smi를 나란히 띄워놓고, 생성 중인 CPU 사용률과 VRAM 소비량을 관찰하는 시간이 은근히 많아졌습니다.
저는 로컬 LLM을 '인터넷 사용이 금지된 프로젝트의 서브 브레인'으로 사용하는 것이 가성비 측면에서 최강이라고 생각합니다. 현재 저의 운용 방식은 다음과 같습니다:
- 공개 가능한 코드 $\rightarrow$ Claude Code (Anthropic Opus 4.7) — 정확도와 속도 모두 최강
- 대외비 코드의 초안 $\rightarrow$ 로컬에서 Qwen3 Coder로 작성
- 개념 검증 및 브레인스토밍 $\rightarrow$ gpt-oss:20b에 가볍게 입력
- CI 및 야간 작업 $\rightarrow$ 로컬에서 완결 (API 과금 없음)
Qwen3 Coder는 Ollama를 통해 Claude Code나 Cursor의 커스텀 백엔드로도 연결할 수 있습니다. OLLAMA_HOST=0.0.0.0:11434로 외부 접속을 허용하고, Cursor의 Model Provider를 Ollama 호환 방식으로 설정하기만 하면 됩니다.
Cursor 측의 절차만 적어두겠습니다. 설정의 Models에서 OpenAI compatible을 선택하고, Base URL에 http://localhost:11434/v1을, 모델명에 qwen3-coder:30b-a3b-instruct-q4_K_M을 입력합니다. 최근에는 대외비 리포지토리에서 가상 환경을 구축해 테스트할 때 매우 유용하게 사용하고 있습니다. 클라우드 AI에 입력할 수 없는 코드라도, Cursor의 자동 완성 UI는 그대로 사용할 수 있다는 점이 정말 큰 도움이 됩니다.
로컬 LLM으로 코드를 작성하는 2026년의 선택지, 저의 답은 이렇습니다.
- Qwen3 Coder 30B-A3B — 코드 정확도 및 할루시네이션 (Hallucination) 억제 측면에서 한발 앞서 있음
- gpt-oss:20b — VRAM 사용량이 가볍고, 다른 작업과 병행하고 싶을 때를 위한 보험
- RTX 4070에서도 둘 다 구동 가능한 시대가 됨 — 1년 전에는 불가능했던 일
"로컬에서는 코드 생성이 불가능하다"는 말은 2024년경의 상식이었습니다. MoE의 대중화와 MXFP4 덕분에, 이제 RTX 4070으로도 본격적인 코드 지원을 할 수 있는 시대가 되었습니다.
여러분의 GPU와 사용 중인 모델의 조합을 꼭 댓글로 알려주세요. 저는 다음에 Qwen3 Coder 480B의 원격 (Remote) 구성을 검토 중이지만, 가정용 GPU 1장으로 완결할 수 있는 범위를 어디까지 넓힐 수 있을지에 대해서는 여전히 관심이 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기