3장. 좋은 로컬 코딩 모델의 조건
3.1 모든 LLM이 코딩을 잘하는 것은 아니다
처음 로컬 모델을 고를 때 가장 흔한 실수는 “유명한 모델이면 코딩도 잘할 것”이라고 생각하는 것입니다. 언어 모델은 비슷해 보이지만, 실제 능력은 학습 데이터, 후처리 방식, 지시 따르기 능력, 코드 데이터 비중, 컨텍스트 처리 방식에 따라 많이 달라집니다. 일반 대화에 강한 모델이 코드 자동완성에서는 느리거나 부정확할 수 있고, 코딩에 강한 모델이 한국어 설명은 딱딱할 수 있습니다.
코딩 모델은 단순히 코드를 많이 학습한 모델이 아닙니다. 개발자가 던지는 요청을 이해하고, 기존 코드 스타일을 따라가고, 컴파일 가능한 결과를 만들고, 테스트를 염두에 두고 답해야 합니다. 예를 들어 “이 함수에 캐시를 추가해 주세요”라는 요청은 코드를 새로 쓰는 문제가 아닙니다. 기존 함수의 입력과 출력, 부작용, 에러 처리, 스레드 안전성, 테스트 방식까지 고려해야 합니다.
로컬 모델을 평가할 때는 대화 품질과 코드 품질을 따로 봐야 합니다. 모델이 설명을 그럴듯하게 한다고 해서 코드가 맞는 것은 아닙니다. 특히 AI는 자신감 있게 틀릴 수 있습니다. 존재하지 않는 라이브러리 옵션을 말하거나, 오래된 API를 제안하거나, 프로젝트에 없는 함수 이름을 만들어 낼 수 있습니다. 이 현상을 줄이는 가장 좋은 방법은 모델 선택과 함께 테스트 기반 검증 습관을 갖는 것입니다.
이 책에서 말하는 좋은 코딩 모델의 조건은 세 가지입니다. 첫째, 작업 지시를 잘 따릅니다. 둘째, 기존 코드의 제약을 존중합니다. 셋째, 결과를 실행 가능한 형태로 냅니다. 여기에 속도와 메모리 효율이 더해지면 로컬 코딩 모델로 쓸 가치가 커집니다.
3.2 일반 모델, 코딩 특화 모델, 추론 모델 비교
일반 모델은 넓은 작업에 강합니다. 문서 요약, 설명, 아이디어 정리, 간단한 코드 질문에 유용합니다. 프로젝트 기획 문서를 읽고 기능을 정리하거나, 개발 블로그 초안을 쓰거나, API 문서를 쉽게 설명할 때 좋습니다. 다만 코드 생성에 특화된 모델보다 문법 오류나 API 착각이 많을 수 있습니다.
코딩 특화 모델은 개발 작업에 더 잘 맞습니다. 함수 생성, 테스트 작성, 코드 리팩터링, 자동완성, 에러 메시지 분석에서 강점을 보입니다. 특히 fill-in-the-middle, 즉 코드 중간을 채우는 능력을 학습한 모델은 IDE 자동완성에 유리합니다. 자동완성은 단순히 다음 문장을 쓰는 것이 아니라, 앞뒤 코드 사이에 자연스럽게 들어갈 코드를 만들어야 하기 때문입니다.
추론 모델은 문제를 단계적으로 생각하는 데 초점을 둔 모델입니다. 복잡한 알고리즘, 디버깅, 설계 비교처럼 여러 조건을 따져야 하는 작업에 도움이 될 수 있습니다. 그러나 로컬 환경에서 추론 모델은 응답이 길어지고 느려질 수 있습니다. 자동완성에는 과할 수 있고, 간단한 질문에도 생각 과정을 길게 늘어놓을 수 있습니다. 따라서 추론 모델은 모든 작업에 쓰기보다 어려운 문제를 풀 때 선택적으로 쓰는 편이 좋습니다.
[표 3-1] 일반 모델, 코딩 특화 모델, 추론 모델 비교.
3.3 파라미터 수가 크면 무조건 좋은가
파라미터 수는 모델 규모를 설명하는 대표적인 숫자입니다. 1.5B, 7B, 14B, 32B 같은 표기를 자주 보게 됩니다. 여기서 B는 billion, 즉 10억을 뜻합니다. 7B 모델은 대략 70억 개의 파라미터를 가진 모델이라는 의미입니다. 일반적으로 파라미터 수가 큰 모델은 더 많은 패턴을 담을 수 있고, 복잡한 문제에서 더 나은 답을 할 가능성이 있습니다.
하지만 로컬 코딩에서는 “큰 모델이 무조건 좋다”가 아닙니다. 모델이 커지면 메모리 사용량이 늘고, 로딩 시간이 길어지고, 응답 속도가 느려집니다. 자동완성처럼 즉시성이 중요한 작업에서는 큰 모델보다 작은 모델이 더 쾌적할 수 있습니다. 개발자가 코드를 입력하는 속도보다 늦게 제안이 뜨면 자동완성 기능은 오히려 방해가 됩니다.
또한 모델 품질은 파라미터 수만으로 결정되지 않습니다. 학습 데이터, 코딩 데이터 비중, 지시 튜닝, 컨텍스트 처리 능력, 양자화 품질이 모두 영향을 줍니다. 잘 튜닝된 7B 코딩 모델이 평범한 13B 일반 모델보다 코딩 작업에서 더 나을 수 있습니다. 그래서 모델을 고를 때는 파라미터 수를 출발점으로 보되, 실제 작업 테스트를 반드시 해야 합니다.
실무에서는 “가장 큰 모델”보다 “내 장비에서 매일 쓸 수 있는 가장 좋은 모델”이 중요합니다. 로딩이 오래 걸리고 응답이 느려서 하루에 몇 번 못 쓰는 모델보다, 적당히 똑똑하고 빠르게 자주 쓸 수 있는 모델이 생산성을 더 높일 때가 많습니다.
3.4 작은 모델이 실무에서 더 유리한 순간
작은 모델이 유리한 순간은 생각보다 많습니다. 첫째, 자동완성입니다. 자동완성은 짧은 시간 안에 제안을 내야 하므로 작은 모델이 유리합니다. 둘째, 반복적인 코드 변환입니다. 변수명 정리, 주석 생성, 간단한 테스트 초안처럼 패턴이 분명한 작업은 큰 모델까지 필요하지 않을 때가 많습니다. 셋째, 노트북 환경입니다. 전력과 발열이 제한된 장비에서는 작은 모델이 더 안정적입니다.
작은 모델은 실수도 합니다. 그러나 작업 범위를 작게 주면 꽤 쓸 만합니다. “이 파일 전체를 개선해 주세요”보다 “아래 함수에서 예외 처리만 추가해 주세요”가 좋습니다. “이 앱을 만들어 주세요”보다 “이 React 컴포넌트의 props 타입을 보강해 주세요”가 좋습니다. 작은 모델에게는 작은 일을 명확하게 맡기는 것이 핵심입니다.
작은 모델을 잘 쓰는 개발자는 프롬프트가 구체적입니다. 출력 형식을 정해 주고, 변경하지 말아야 할 것을 말하고, 테스트 기준을 알려 줍니다. 예를 들어 “기존 함수 이름과 매개변수는 바꾸지 마세요. 외부 패키지는 추가하지 마세요. 변경된 코드 블록만 출력해 주세요”라고 지시하면 작은 모델의 실패 가능성이 줄어듭니다.
[실습 3-1] 같은 요청을 작은 모델과 큰 모델에서 각각 비교
3.5 모델 벤치마크를 읽는 법
모델을 고를 때 벤치마크는 도움이 됩니다. HumanEval, LiveCodeBench, SWE-bench 같은 이름을 자주 보게 됩니다. HumanEval은 함수 설명을 보고 Python 코드를 생성한 뒤 테스트를 통과하는지 보는 대표적인 코드 생성 벤치마크입니다. LiveCodeBench는 시간에 따라 새 문제를 수집해 데이터 오염을 줄이고, 코드 생성뿐 아니라 self-repair, 실행, 테스트 출력 예측 같은 다양한 코드 능력을 보려는 목적을 갖습니다. SWE-bench는 실제 GitHub 이슈와 Pull Request를 바탕으로 모델이 코드베이스를 수정해 문제를 해결할 수 있는지 평가합니다.
벤치마크를 볼 때는 숫자만 보면 안 됩니다. 어떤 언어를 평가하는지, 문제 난이도는 어떤지, 모델이 단순 함수를 만드는지, 실제 프로젝트를 수정하는지 봐야 합니다. HumanEval 점수가 높다고 해서 대규모 레거시 코드 리팩터링을 잘한다는 뜻은 아닙니다. SWE-bench 점수가 높다고 해서 자동완성 지연 시간이 낮다는 뜻도 아닙니다.
또한 벤치마크는 실행 환경과 프롬프트 방식의 영향을 받습니다. 같은 모델도 평가 프롬프트, 샘플링 설정, 테스트 하네스에 따라 결과가 달라질 수 있습니다. 로컬에서는 양자화 버전을 쓰기 때문에 원본 모델 벤치마크와 실제 체감이 다를 수 있습니다. 따라서 벤치마크는 후보를 좁히는 용도로 쓰고, 최종 선택은 내 프로젝트에서 직접 테스트해야 합니다.
[표 3-2] 주요 코드 벤치마크 읽는 법.
3.6 HumanEval, LiveCodeBench, SWE-bench를 맹신하면 안 되는 이유
HumanEval은 코드 생성 벤치마크의 기준점처럼 쓰여 왔습니다. 그러나 비교적 짧은 Python 함수 문제에 초점을 둡니다. 실제 회사 프로젝트에서는 함수 하나보다 더 복잡한 맥락이 많습니다. 인증, 권한, 데이터베이스 트랜잭션, 프론트엔드 상태 관리, 배포 설정 같은 요소는 단일 함수 테스트만으로 평가하기 어렵습니다.
LiveCodeBench는 더 최신 문제를 수집하고 다양한 코드 능력을 보려고 하지만, 그래도 대회형 문제의 성격이 있습니다. 알고리즘 문제 해결 능력이 좋은 모델이 실무 코드 스타일과 팀 규칙을 잘 따르는지는 별개의 문제입니다. 또한 대회형 문제는 입출력과 정답이 명확하지만, 실제 개발 요청은 요구사항이 애매한 경우가 많습니다.
SWE-bench는 실제 GitHub 이슈 기반이라는 점에서 실무와 가깝습니다. 그러나 특정 언어와 저장소 구성에 영향을 받습니다. 또한 평가를 잘하려면 모델이 코드베이스를 읽고, 관련 파일을 찾고, 테스트를 실행하는 에이전트 환경이 필요합니다. 즉 SWE-bench 점수는 모델 자체뿐 아니라 에이전트 시스템의 품질도 함께 반영할 수 있습니다.
따라서 벤치마크는 “이 모델이 어떤 종류의 문제에 강할 가능성이 있는가”를 보는 자료입니다. “내 프로젝트에서 반드시 잘한다”는 보증서는 아닙니다. 가장 안전한 방법은 내 업무에서 자주 나오는 5개 작업을 정해 모델별로 테스트하는 것입니다. 예를 들어 “React 컴포넌트 생성”, “API 클라이언트 함수 리팩터링”, “Python 테스트 작성”, “에러 로그 분석”, “README 기반 사용법 설명” 같은 작업입니다.
3.7 한국어 설명 능력과 코드 생성 능력은 다르다
한국어 사용자에게는 모델의 한국어 능력이 중요합니다. 설명을 이해하기 쉬워야 하고, 요구사항을 한국어로 입력해도 잘 따라야 합니다. 하지만 코딩 모델을 평가할 때 한국어 답변이 자연스럽다는 이유만으로 선택하면 안 됩니다. 실제 코드가 맞아야 합니다.
가장 좋은 조합은 한국어 지시를 잘 이해하면서 코드 품질도 안정적인 모델입니다. 그러나 둘 중 하나를 선택해야 한다면 작업에 따라 우선순위가 달라집니다. 초보자 교육, 코드 설명, 문서화에는 한국어 설명력이 중요합니다. 자동완성, 테스트 생성, 리팩터링에는 코드 정확도가 더 중요합니다.
프롬프트를 작성할 때는 한국어와 코드 용어를 섞어도 괜찮습니다. 예를 들어 “아래 함수에서 nullable 입력을 처리하고, return type은 기존과 동일하게 유지해 주세요”처럼 한국어 설명과 영어 타입 용어를 함께 쓰면 됩니다. 모델이 한국어 설명을 잘 못하는 경우에도 출력 형식을 코드 중심으로 제한하면 실용성이 올라갑니다.
[실습 3-2] 같은 모델에게 한국어 요청과 영어 요청을 각각 입력해 결과를 비교.