Abstract:
- 이 글의 핵심은 Magicoder라는 새로운 코드 특화 대형 언어 모델(LLM) 시리즈를 소개하고, 이 모델들을 학습시키기 위해 OSS-INSTRUCT라는 기법을 제안하고 있음.
- Magicoder 모델 시리즈:
- 완전 오픈소스(코드, 가중치, 데이터 모두 공개) 형태로 개발된 LLM.
- 파라미터 수는 최대 7B(70억 개) 정도로, 상대적으로 작은 규모를 유지하면서도 높은 성능을 목표로 함.
- 75K(7만 5천 개) 규모의 합성(Instruct) 데이터로 학습되었음.
- OSS-INSTRUCT 기법:
- 오픈소스 소프트웨어(OSS)에서 가져온 코드 스니펫을 활용해 다양한 형태의 코드 지시문(instruction) 데이터를 생성하는 새로운 데이터 합성 방식.
- 기존 합성 데이터가 하나의 모델에서만 생성될 경우, 특정 모델의 편향이 그대로 반영되는 한계가 있음 -> 실제 오픈 소스의 코드를 참고해서 만들기 때문에 더 다양한 데이터를 만들 수 있었다고 함.
- 실제로 코사인 유사도를 통해서 만들어진 데이터를 분석해보면 Self-Instruct: 평균 유사도 0.169, Evol-Instruct: 평균 유사도 0.131, OSS-INSTRUCT: 평균 유사도 0.105 (가장 낮음) 이라고 함.
- 다른 합성 데이터 생성 기법(Evol-Instruct 등)과도 상호 보완적으로 결합할 수 있다고 함.
- Magicoder 및 MagicoderS의 성능:
- 비슷하거나 더 큰 규모의 최신 코드 생성 모델들을 다양한 벤치마크에서 능가하는 성능을 보였다고 함.
- 특히 MagicoderS-CL-7B(CODELLAMA 기반)는 HumanEval+ 벤치마크에서 ChatGPT보다도 pass@1 지표가 높은 결과(66.5 vs. 65.9)를 달성했다고
Introduction:
- 기존 접근 방식의 문제점(Evol-Instruct, Code Alpaca) - 다양성의 부족:
- Code Alpaca 는 21개의 시드 태스크만을 사용하고, Evol-Instruct는 5개의 휴리스틱만 사용하여 데이터셋을 확장시킴.
- 너무 적은 개수로만 데이터의 다양성을 확보시키는 전략이기 때문에 LLM 의 편향이 두드러질 확률이 높다고 함.
- 이를 오픈소스 코드 데이터의 다양성으로 이 논문은 해결하려고 함.
- 이에 따라, 이 논문은 오픈 소스 코드 스니펫에서 직접 학습하여 다양한 창의적 코드 지시문을 작성할 수 있는 OSS-INSTRUCT를 제안.
- OSS-INSTRUCT를 통해, LLM은 오픈 소스 코드를 활용하여 새로운 코딩 문제를 자동으로 생성하고, 결과적으로 75K개의 합성 데이터를 생성하여 CODELLAMA-PYTHON-7B 모델을 튜닝해서 Magicoder-CL을 만든다고.
OSS-INSTRUCT 접근법:
- 오픈 소스 데이터 활용:
- OSS-INSTRUCT는 오픈 소스에서 쉽게 수집할 수 있는 시드 코드 스니펫을 기반으로 시용함. 이 연구에서는 StarCoder가 학습된 데이터셋인 The Stack(Kocetkov et al., 2022)의 필터링된 버전인 starcoderdata를 시드 코퍼스로 직접 채택했다고 함. starcoderdata는 광범위하게 사용되며, 다양한 프로그래밍 언어로 작성된 고품질 코드 스니펫이 대량으로 포함되어 있을 뿐만 아니라, 데이터 정화 작업이 완료된 자료를 제공하는게 특징임.
- 코퍼스의 각 코드 문서에서 1-15개의 연속된 줄을 무작위로 추출하여 모델이 이를 기반으로 영감을 얻어 코딩 문제를 생성하도록 했음.
- 총 80,000개의 초기 시드 스니펫이 수집되었으며, 파이썬에서 40,000개, C++, 자바, TypeScript, Shell, C#, Rust, PHP, 그리고 Swift 각각에서 5,000개씩 확보했다고 함.
- 이후, 각 수집된 시드 코드 스니펫은 부록 A.1에 제시된 프롬프트 템플릿에 적용되며, 이 템플릿을 입력으로 받아 교사 모델이 코딩 문제와 그 해결책을 출력함.
- 데이터 정제 및 오염 제거 작업:
- 동일하거나 같은 시드 코드 스니펫을 공유하는 샘플들을 제외했음.
- 불완전한 해결책(incomplete solution)과 같은 노이즈가 있는 샘플들은 의도적으로 유지했다고 함. Honovich et al. (2023)의 연구를 참고하여, 이러한 노이즈 데이터도 학습에 가치 있는 정보라고. 실제로 노이즈 데이터가 있으면 HumanEval+ 에서 55.5 의 점수를 얻었는데, 없다면 54.9 정도를 얻음.
- 또 StarCoder의 방식 (Li et al. (2023)) 을 따라 벤치마크 데이터셋과 중복되는 내용 제거했다고 함. 근데 StarCoder 즉 시드 코퍼스(starcoderdata)가 이미 엄격한 데이터 오염 제거 과정을 거쳤기 때문에 9개 정도만 제거를 했다고.
- LLM 을 이용한 데이터 합성:
- 예를 들어, 쉘 스크립트 예시에서는 단 한 줄의 쉘 스크립트로 LLM이 파이썬 코딩 문제를 생성
- 라이브러리 import 예시에서는 LLM이 몇 개의 import 문만으로 현실적인 머신러닝 문제를 만들어 내보고
- 'class' 시그니처 사례는 'SpringBootApplication'과 같은 주석 및 'bank'라는 키워드가 포함된 불완전한 클래스 정의에서 영감을 얻어 완전한 은행 시스템을 구현해야 하는 문제를 생성해보고
- OSS-INSTRUCT는 다양한 코드 구조와 의미를 통해 알고리즘 도전 과제, 현실 문제, 단일 함수 코드 생성, 라이브러리 기반 프로그램 완료, 전체 프로그램 개발, 심지어 전체 애플리케이션 구축 같은 다양한 코딩 태스크를 창출
- HumanEval과 OSS-INSTRUCT를 포함한 여러 방법으로 생성된 합성 데이터의 코사인 유사도를 보여줌.
Ablations Study - Impact of the Language Distribution:
- 전체 코드 데이터는 75k 정도인데 파이썬이 43k, 비파이썬이 32k 정도였다고 함.
- 주요 발견:
- 전이학습 효과: 비파이썬 데이터로만 학습을 해도 파이썬 성능은 이전보다 올라감. (프로그래밍 언어의 능력 자체가 올라가는 효과가 있음)
- 두 종류 데이터 모두 학습하면 파이썬 성능은 훨씬 올라가나, 비파이썬 데이터로만 학습한 다중 프로그래밍 언어 능력보다는 약간 감소. (38.3점 vs 37.8점 정도의 차이)
- 이렇게 되는 이유는 훈련 데이터의 불균형으로 인한 편향 때문임. 그 쪽 언어로 좀 더 취우쳐지는거임.
- 그리고 모델의 용량(Capacity) 도 고려해야함. 여러가지 일을 더 잘하려면 이 용량이 커야함.
Ablations Study - OSS-INSTRUCT vs. Direct Finetuning:
- OSS-Instruct 방식은 오픈 소스의 일부 코드에서 영감을 받아서 새로운 코드 데이터를 생성하는 역할이라면, Direct Finetuning 은 함수 docstring 과 주석으로 예측해서 함수를 생성하도록 하는 훈련 데이터를 말함.
- Direct Finetuning 으로의 훈련 방법은 모델의 성능에 영향을 주지 않았다고 함
- 데이터의 노이즈, 데이터의 불일치 때문: 주석과 코드의 불일치, 코드의 품질 문제 주석의 불안정성
Implementation Details:
- Figure 4에서 OSS-INSTRUCT의 프롬프트 템플릿을 볼 수 있음. 템플릿은 3개 섹션으로 구성:
- 첫 번째: 태스크의 상위 수준 설명
- 두 번째: 코드 스니펫 포함
- 세 번째: 응답에 대한 가이드라인
- Figure 5는 Figure 2를 확장하여 더 많은 예시를 제공한거임. 다양한 유형의 코드 입력을 받음.
- gpt-3.5-turbo-1106 모델을 교사 모델로 채택: 비용 효율적이기 때문.
- 데이터 생성 프로세스:
- starcoderdata에서 각 코드 문서마다 1-15줄을 무작위 추출
- GPT-3.5로 독립적인 코딩 문제와 해답 생성
- 생성된 문제와 해답 간의 일관성을 최대화하기 위해 greedy decoding 사용
추가 생각 포인트들 정리:
- 특정 프레임워크나 언어(예: Python의 TensorFlow vs. PyTorch)로 치우친 편향은 어떻게 제어할 수 있을까?
- 만약 오픈소스 생태계 안에도 내재된 편향(특정 언어·플랫폼의 과다 사용 등)이 있다면, 그 편향은 어떻게 보정할 수 있을까?
- 오픈소스 자체에도 잘못된 코드나 안티패턴(Anti-pattern)이 섞여 있을 수 있는데, 이런 것들이 모델 성능에 어떤 영향을 줄까?
- Quality filtering(코드 실행 테스트, 정적 분석, 커뮤니티의 별점/스타 수 등)을 통해 ‘좋은 스니펫’만 골라낼 수 있는 방법과 그 효과는?
- 모델 한 개로 여러 언어를 다루는 방식과, 언어별로 특화된 모델을 여러 개 두는 방식(Expert Model)의 장단점은 무엇일까?
- LoRA, Mixture-of-Experts(MoE), Prompt Tuning 등 모델 병렬화·모듈화 기법을 적용하면 트레이드오프를 줄일 수 있지 않을까?
- 언어 간 간섭(Interference) 문제, 단순성, 최적화 관점에서 생각
- 수백~수천 줄에 달하는 대규모 애플리케이션 레벨의 문맥(Context)을 어떻게 처리할 것인가?
- 함수·메소드 레벨 뿐 아니라, 여러 파일 간 의존성까지 고려하는 고급 문제(Ex: “Microservices 아키텍처에서 User Service와 Payment Service가 협력해야 하는 시스템 만들기”) 생성이 가능할까?
대규모·저품질 데이터 vs. 소규모·고품질 데이터, 어느 쪽을 선호해야 할까? (어떤 모델을 만들 것이냐에 따라 다르겠지)