Reference: "Evaluating Large Language Models Trained on Code" [arxiv]
우리가 매일 사용하는 개발 환경 속엔 사실 코드 생성 인공지능이 조용히 녹아 있다. GitHub Copilot처럼 다음 줄을 예측해주는 자동완성, 코드 스멜을 찾아주는 린터, Pull Request를 리뷰하는 봇까지 모두 코드를 이해하고 생성하는 AI가 핵심에 있다.
과거의 프로그램 합성 시스템은 사람이 직접 설계한 문법 트리와 규칙 기반 템플릿을 조합해 만들었다. 하지만 이 방식은 추상적이거나 복잡한 요구사항에 취약했고 실제 개발자들의 다양한 코딩 스타일을 반영하기 어려웠다.
최근에는 LLM(Large Language Model) 패러다임이 코드 생성 영역에도 본격적으로 적용되고 있다. GPT-3나 Gemini처럼 대규모 파라미터로 학습된 모델들이 자연어뿐 아니라 프로그래밍 언어, 코드 구조, 개발 관습까지 이해하려는 시도를 하고 있다.
OpenAI의 Codex는 이러한 시도의 대표적 사례로 자연어 설명을 코드로 변환하거나 그 반대로 수행한다. 이처럼 코드와 언어의 경계를 허무는 흐름은 프로그래밍 AI 연구의 새로운 장을 열고 있다.
논문이 던진 핵심 질문
OpenAI 연구팀의 질문은 명확했다.
“대규모 언어 모델을 GitHub의 공개 코드로 fine-tuning하면 자연어 설명만으로 기능적으로 올바른 프로그램을 생성할 수 있을까?”
여기서 ‘기능적으로 올바른(functionally correct)’이란 문법적으로만 맞는 코드가 아니라 실제로 실행해봤을 때 요구사항을 만족하는 코드를 의미한다. 이는 기존 연구들이 “정답 코드와 얼마나 비슷한가”를 텍스트 수준에서 비교하던 것과 다른 접근이다.
연구 설계와 방법
연구의 출발점은 단순했다.
“GPT-3의 자연어 이해 능력이 코드 생성에도 도움이 될 것이다.”
Docstring이 본질적으로 자연어이기 때문에 이를 이해할 수 있는 모델이라면 코드도 생성할 수 있다는 가정이었다. Codex는 GPT-3를 기반으로 GitHub의 대규모 Python 코드로 fine-tuning하여 만들어졌다.
평가 방식의 혁신: functional correctness와 pass@k
코드 생성 모델을 평가하는 전통적 방법은 생성된 코드를 정답 코드와 텍스트로 비교하는 것이었다. 기계어 번역에서 널리 쓰이는 BLEU 점수가 대표적이다. 하지만 연구팀은 BLEU가 코드 평가에 근본적으로 부적합하다는 것을 발견했다.
예를 들어 리스트의 합을 구하는 함수가 있다고 하자. 정답 코드는 return sum(lst)처럼 한 줄로 간결할 수 있지만 같은 기능을 하는 코드는 무수히 많다. for 루프로 순회하며 누적하거나 reduce나 재귀를 사용하는 방식 등 모두 기능적으로 동등하다. 그러나 BLEU는 이런 다양한 정답을 인정하지 못한다. 오직 정답 코드와 단어 수준에서 얼마나 비슷한지만 측정하기 때문이다.
더 큰 문제는 잘못된 코드가 높은 BLEU 점수를 받을 수 있다는 점이다. 예를 들어 return sum(1st)처럼 변수명에 오타가 있는 코드는 정답과 거의 같아서 BLEU 점수가 높지만 실행하면 에러가 발생한다. 반대로 완전히 다른 방식으로 구현했지만 완벽하게 작동하는 코드는 낮은 BLEU 점수를 받는다. 연구팀이 Codex-12B가 생성한 수천 개의 코드를 분석한 결과 정답 코드와 오답 코드의 BLEU 점수 분포가 상당히 겹쳤다. 즉 BLEU로는 코드의 올바름을 판단할 수 없다는 것이다.

이런 문제의식에서 연구팀은 functional correctness라는 새로운 평가 철학을 도입했다. 코드가 텍스트로서 정답과 얼마나 비슷한지가 아니라 실제로 요구사항을 만족하는지를 직접 확인하는 방식이다. 구체적으로 각 문제마다 unit test를 작성하고 생성된 코드를 실행해 모든 테스트를 통과하는지를 검증했다. 이는 실제 개발자들이 코드를 검증하는 방식과 일치하며 Test-Driven Development 같은 현대적 개발 방법론과도 맞닿아 있다.
하지만 모델이 항상 한 번에 완벽한 코드를 생성할 수 있을까? 실제 개발자도 여러 번 시도하고 수정하면서 올바른 코드에 도달한다. 이런 현실을 반영해 연구팀은 pass@k라는 메트릭을 제안했다.
pass@k는 "k개의 코드 샘플을 생성했을 때 그중 최소 1개라도 정답일 확률"을 의미한다. 수학적으로는 총 n개를 생성했고 그중 c개가 정답일 때 k개를 선택하는 모든 경우의 수 중 최소 하나의 정답을 포함하는 경우의 확률을 구한다.
pass@k = 1 - (n-c choose k) / (n choose k)
실제 Codex-12B의 경우 pass@1은 28.8%에 불과했지만 pass@100은 72.3%에 달했다. 즉 한 번에 맞추기는 어렵지만 100번 시도하면 10번 중 7번은 정답을 찾을 수 있다는 의미다. 이런 접근은 GitHub Copilot 같은 실제 제품에서도 활용된다. 내부적으로 여러 개를 생성한 후 사용자에게 선택권을 주거나 가장 확신도가 높은 것을 자동으로 제시하는 방식이다.
평가를 위한 문제도 새롭게 만들어야 했다. 기존 코딩 테스트 문제들은 이미 인터넷에 수많은 솔루션이 공개되어 있어서 모델이 단순히 암기한 것인지 실제로 문제를 해결한 것인지 구분하기 어려웠다. 연구팀은 164개의 프로그래밍 문제를 직접 수작업으로 작성했고 이를 HumanEval 데이터셋이라 명명했다. 각 문제는 함수 시그니처, 자연어 설명, 그리고 평균 7.7개의 unit test로 구성된다. 난이도는 코딩 면접 수준으로 언어 이해력과 기본적인 알고리즘, 간단한 수학을 요구한다.
데이터셋 구축과 학습 파이프라인
모델 학습의 첫 단계는 방대한 코드를 수집하는 것이었다. 연구팀은 2020년 5월 기준으로 GitHub의 5,400만 개 공개 저장소를 크롤링해 1MB 이하의 Python 파일 179GB를 확보했다. 하지만 이 데이터를 그대로 사용할 수는 없었다. 자동 생성된 파일이나 비정상적인 형식의 코드가 섞여 있었기 때문이다.
필터링은 여러 단계로 진행되었다. 자동 생성 가능성이 있는 파일을 휴리스틱으로 판단하고 평균 줄 길이가 100자를 초과하거나 최대 줄 길이가 1,000자를 넘는 파일을 제거했다. 이런 파일은 대부분 코드가 아니라 JSON이나 CSV 같은 데이터 파일이거나 자동 생성된 설정 파일이었다. 알파벳과 숫자의 비율이 너무 낮은 파일도 제외했다. 최종적으로 159GB의 정제된 학습 데이터를 얻었다.
학습 설정은 GPT-3를 그대로 따랐다. 12B 파라미터 모델을 베이스로 하고 학습률은 GPT-3와 동일하게 유지했다. 초기 175 step 동안은 학습률을 천천히 올리는 warmup 기법을 적용했고 이후에는 cosine decay로 점진적으로 감소시켰다. 총 1,000억 개의 토큰을 학습에 사용했으며 이는 159GB 데이터를 여러 번 반복해서 본 것이다.
흥미로운 최적화 중 하나는 토크나이저 개선이었다. GPT-3의 토크나이저는 자연어에 최적화되어 있어서 Python의 공백 문자를 비효율적으로 처리했다. Python은 들여쓰기로 블록을 구분하기 때문에 공백이 문법적으로 중요하다. 연구팀은 다양한 길이의 공백을 나타내는 특수 토큰을 추가해 코드 표현 효율을 약 30% 개선했다.
학습 과정에서 temperature 최적화도 중요했다. Temperature는 모델이 다음 토큰을 선택할 때 얼마나 다양하게 선택할지를 결정한다. 낮은 temperature는 가장 확률이 높은 토큰만 선택하고 높은 temperature는 다양한 시도를 가능하게 한다. 연구팀은 pass@k의 k 값에 따라 최적 temperature가 달라진다는 것을 발견했다. pass@1은 T=0.2처럼 낮은 값이 좋았고 pass@100은 T=0.8처럼 높은 값이 좋았다. 다양한 시도를 해야 그중 하나라도 맞을 확률이 높아지기 때문이다.

마지막으로 실용적 관점에서 중요한 문제가 남았다. 100개의 코드를 생성했는데 사용자에게는 1개만 보여줘야 한다면 어떤 것을 선택해야 할까? 세 가지 전략을 비교했다. 첫째는 무작위 선택으로 성능이 약 20%였다. 둘째는 “신탁(oracle)” 전략으로 모든 샘플을 테스트해 통과하는 것을 선택하는 방식이다. 약 72%의 성능을 보였지만 현실적으로 불가능했다. 테스트가 항상 있는 것도 아니고 100개를 다 실행하는 것도 비현실적이기 때문이다.
연구팀이 제안한 방법은 mean log-probability를 사용하는 것이었다. 모델은 각 토큰을 생성할 때 확률값을 계산한다. 이 확률들의 로그 평균을 구하면 모델이 그 샘플에 대해 얼마나 확신하는지를 측정할 수 있다. 평균을 사용하는 이유는 코드 길이가 다를 때 공정하게 비교하기 위함이다. 이 방식으로 가장 확신도가 높은 샘플을 선택하면 약 44%의 성능을 달성했다. 무작위보다 2배 이상 높고 실제로 구현 가능하며 GitHub Copilot 같은 제품에서도 사용되는 방식이다.

결과: 무엇을 달성했나
Codex-12B 모델은 HumanEval 데이터셋에서 인상적인 성능을 보였다. Temperature 0.8 설정에서 pass@1은 28.8%, pass@10은 46.8%, pass@100은 72.3%를 기록했다. 같은 크기의 GPT-3-12B는 거의 0%에 가까운 성능을 보여 fine-tuning 없이는 코드 생성이 사실상 불가능함을 입증했다. GPT-J 6B는 11.4%를 기록했는데 이는 Codex-85M과 Codex-300M 사이 수준이었다. GPT-J가 학습한 The Pile 데이터셋의 8%가 GitHub 코드였다는 점을 고려하면 약간의 코드 노출만으로도 기본적인 코드 생성 능력이 생긴다는 것을 알 수 있다.
모델 크기별로 보면 12M부터 12B까지 파라미터가 커질수록 성능이 일관되게 향상되었고 loss는 (N / 5.92×10⁷)^(-0.13)에 비례했다. 이는 GPT-3에서 관찰된 패턴과 유사해 코드 fine-tuning 후에도 스케일링 법칙이 유지됨을 보여준다.
샘플 선택 휴리스틱의 실용적 가치도 입증되었다. 100개 샘플에서 mean log-probability로 선택하면 무작위보다 2배 이상 높은 44%의 성능을 얻었다. oracle에는 미치지 못하지만 실제 구현 가능하다는 점에서 의미가 컸다. 또한 모델의 확신도가 실제 정답 여부와 상당히 높은 상관관계를 가진다는 것도 확인되었다.
한계: Codex가 할 수 없는 것들
Codex의 성능은 인상적이지만 한계도 명확했다. 논문은 이를 솔직하게 분석했다.
첫 번째는 샘플 효율성의 문제였다. Codex는 159GB의 데이터를 학습했지만 입문 수준의 컴퓨터 과학을 이수한 학생이 HumanEval에서 더 많은 문제를 해결할 수 있었다. 이는 현재의 학습 방식이 인간의 효율적인 학습과는 근본적으로 다르다는 것을 보여준다.
두 번째는 docstring 길이가 길어질수록 성능이 급격히 떨어지는 점이었다. 연구팀은 이를 측정하기 위해 13개의 기본 문자열 조작 연산을 정의하고 이를 체인 형태로 연결한 문제를 생성했다. 예를 들어 “이 문자열을 소문자로 변환한 다음 모든 e를 제거하고 공백을 !로 바꿔라” 같은 문제였다.
세 번째는 변수-연산 바인딩 문제였다. “y에 3을 더하고 x와 w에서 각각 4를 뺀 다음 네 수의 곱을 반환하라”는 간단한 지시에서도 Codex는 w에서 4를 빼는 것을 누락하고 곱셈도 제대로 수행하지 못했다. 변수와 연산의 개수가 많아질수록 이런 오류가 잦았다.
네 번째는 시스템 레벨 합성이 불가능하다는 점이었다. Codex는 단일 함수나 짧은 코드 블록은 잘 생성하지만 여러 파일에 걸친 복잡한 아키텍처나 고수준 명세로부터 전체 애플리케이션을 설계하지는 못했다. 이는 docstring 길이 한계와도 관련이 있다. 고수준 명세는 필연적으로 많은 요구사항을 담고 있기 때문이다.
경제와 노동시장: Codex가 가져올 변화
Codex는 기술적 성과를 넘어 사회적 영향을 논의하는 부분에서도 흥미로웠다. 특히 경제와 노동시장에 대한 분석이 인상적이었다.
우선 Codex가 프로그래머의 생산성을 극적으로 높일 것이라는 단순한 기대는 현실과 거리가 있다. 소프트웨어 개발에서 코드 작성이 차지하는 비중은 생각보다 작다. 미국 노동통계국에 따르면 개발자들은 협의, 설계 문서 작성, 코드 리뷰, 유지보수 등에 많은 시간을 쓰며 순수한 코드 작성은 전체의 30~40% 정도에 불과하다. 따라서 Codex가 코드 작성 속도를 두 배로 높인다 해도 전체 생산성은 15~20% 정도만 향상된다.
또한 완벽한 코드 생성 모델이 있다 해도 노동 비용이 0이 되지는 않는다. 정확한 프롬프트를 작성하는 데 시간이 들고 생성된 코드를 검토하고 검증하는 과정이 필요하다. 전체 시스템과 통합하거나 테스트를 작성하고 문서화하는 일도 남는다. 오히려 Codex가 더 많은 코드를 빠르게 생성하면 코드 리뷰와 품질 관리에 더 많은 시간이 들 수 있다. 일부 연구자들은 이를 “효율성의 환상”이라고 부른다.
그러나 Codex가 노동시장에 미칠 영향이 전혀 없다는 뜻은 아니다. 장기적으로 일부 프로그래머 역할이 대체될 가능성이 있고 코딩 작업의 성격이 변할 수 있다. 개발자의 역할이 “코드를 직접 작성하는 사람”에서 “AI가 생성한 코드를 검토하고 개선하는 사람”으로 바뀔 수 있다. 특히 주니어 포지션에서 이런 변화가 두드러질 수 있다. 전통적으로 주니어가 맡던 단순 반복적 코딩 작업이 AI로 대체되면 경력 진입이 어려워질 수 있다.
동시에 새로운 직무도 생겨날 수 있다. GPT-3 출시 이후 일부 회사들이 “프롬프트 엔지니어” 포지션을 만든 것처럼 Codex 시대에도 AI 도구를 효과적으로 활용하는 전문가에 대한 수요가 생길 수 있다. 모델이 생성한 코드를 빠르게 평가하고 개선하는 능력, 효과적인 프롬프트를 작성하는 기술이 새로운 역량으로 떠오를 수 있다.
채용 과정도 재고가 필요하다. 현재 많은 기업들이 코딩 테스트로 지원자를 평가하는데 Codex는 이런 문제들을 잘 푼다. 그렇다면 지원자가 좋은 점수를 받았을 때 그것이 실력인지 Codex의 도움인지 구분하기 어려워진다.
고용주는 몇 가지 대응 방안을 고려할 수 있다. 첫째는 더 어려운 문제를 출제하는 것이다. 단순 알고리즘이 아니라 시스템 설계나 아키텍처 결정 같은 Codex가 아직 잘 못하는 영역으로 평가를 옮기는 방식이다. 둘째는 평가 기준 자체를 바꾸는 것이다. 순수한 코딩 능력보다는 AI 도구 활용 능력, 생성된 코드를 비판적으로 평가하고 개선하는 능력, 복잡한 시스템을 설계하는 사고력을 중시하는 방향이다. 셋째는 평가 환경을 통제하는 것이다. 온라인 테스트 대신 대면 화이트보드 코딩으로 전환하거나 AI 도구 사용을 감지하는 시스템을 도입하는 방법이다.
패키지 생태계에 대한 영향도 크다. Codex는 훈련 데이터의 패턴을 반영해 특정 패키지를 더 자주 제안한다. 연구팀의 작은 실험에서 “머신러닝 패키지를 임포트하라”는 프롬프트에 TensorFlow가 6번, PyTorch가 3번 제안되었다. 이런 불균형이 확대되면 이미 인기 있는 패키지가 더욱 지배적이 되고 새로운 패키지는 설사 더 좋아도 채택되기 어려워질 수 있다.
이런 고착화(lock-in) 효과는 다양한 메커니즘으로 강화된다. 모두가 같은 패키지를 사용하면 코드 호환성이 높아지고 문제 해결 자료도 많아지며 다른 개발자의 신뢰도도 높아진다. 전환 비용이 높아지는 것이다. 시간이 지나면 개발자들이 “어떤 패키지를 써야 하지?”라고 검색하기보다 그냥 Codex에게 물어보는 습관이 생길 수 있다. 그리고 Codex가 제안하는 패키지를 선택하게 된다. “어차피 Codex가 이 패키지를 잘 아니까 도움을 더 잘 받을 거야”라는 논리로 말이다.
오픈소스 커뮤니티에도 영향이 예상된다. Codex가 오래된 버전의 API나 deprecated된 메서드를 제안할 수 있는데 이는 패키지 유지보수자들에게 하위 호환성을 유지해야 한다는 압력으로 작용할 수 있다. 하지만 많은 오픈소스 프로젝트는 이미 자원이 부족하다. 이런 추가 부담이 생태계에 어떤 영향을 미칠지는 지켜봐야 할 문제다.
'AI' 카테고리의 다른 글
| [AI 논문 리뷰] SWE-agent (0) | 2026.01.19 |
|---|---|
| [AI 논문 리뷰] SWE-bench: 언어 모델은 실제 GitHub 이슈를 해결할 수 있을까? (0) | 2026.01.19 |
| LLM: 코드를 이해하고 생성하는 AI 의 등장 (0) | 2026.01.19 |