2026-06-12 회고
다시 회고를 쓰기로 했다
오랜만에 회고를 남긴다. 그동안 기록을 하지 않은 이유는 바쁘기만 해서라기보다, 너무 완벽한 글만 남기고 싶다는 마음이 컸기 때문인 것 같다. 결과가 확실히 정리된 뒤에만 기록하고 싶었고, 실패하거나 중간에 방향이 바뀐 과정은 괜히 남기기 애매하다고 느꼈다.
그런데 돌아보니 오히려 그 과정이 가장 의미 있었다. 지난 10일 동안 완성된 결과물은 많지 않았지만, Godot 특화 코딩 모델을 만들기 위해 무엇을 조사했고, 어디서 막혔고, 어떤 판단을 바꿨는지는 꽤 많이 쌓였다. 그래서 오늘은 그동안의 흐름을 한 번 정리해두기로 했다.
로컬 모델 실험
처음에는 RunPod 사용료가 아까워서 로컬 PC에 Qwen 계열 모델을 올려보려고 했다. RTX 3060을 사용 중이라 9B 모델 정도면 어떻게든 WSL에서 돌릴 수 있지 않을까 생각했다.
하지만 실제로는 기대처럼 되지 않았다. 네트워크 연결 속도와 응답 지연 문제가 심했고, 답변 하나를 받기도 전에 사고 단계에서만 5분 이상 걸렸다. 이 상태로는 실험 속도도 너무 느리고, 개발 도구로 붙여 쓰기도 어렵다고 판단해서 로컬 모델 구동은 바로 정리했다.
이 실험에서 얻은 것은 명확했다. 내 환경에서 무리하게 큰 모델을 로컬로 돌리는 것보다, 지금은 데이터셋 구조와 학습 파이프라인을 먼저 설계하는 쪽이 더 중요하다.
Godot 데이터셋 조사
모델을 학습시키려면 먼저 데이터가 필요했다. 그래서 Godot 4 코드 학습에 쓸 수 있는 데이터셋을 찾다가 Hugging Face의 wallstoneai/godot-gdscript-dataset을 확인했다.
처음에는 단순히 .gd 파일을 많이 모아둔 데이터셋이라고 생각했는데, Gemini를 통해 분석해보니 구조가 더 중요했다. 핵심은 GitHub 레포지토리에서 파일을 하나씩 떼어내는 것이 아니라, 하나의 레포지토리를 통째로 펼쳐서 프로젝트 맥락을 보존하는 방식이었다.
이 데이터셋은 레포지토리의 README.md, .gd 파일, 디렉터리 구조를 하나의 텍스트로 병합하고, 그 안에 프로젝트 이름, Godot 버전, 파일 트리, 파일별 내용을 마크다운 형식으로 정리하는 방식으로 보였다. 이렇게 하면 모델이 단일 코드 조각만 보는 것이 아니라 프로젝트 구조와 파일 간 관계를 같이 볼 수 있다.
특히 중요했던 부분은 Godot 3/4 버전 판별 방식이었다. Godot은 일반적인 웹 프로젝트처럼 package.json이나 requirements.txt가 있는 구조가 아니다. 대신 project.godot 파일 안의 config_version, config/features 같은 값을 읽거나, GDScript 문법 차이를 이용해야 한다.
예를 들어 Godot 3에서는 onready var, KinematicBody 같은 표현이 쓰이고, Godot 4에서는 @onready, CharacterBody3D 같은 표현이 쓰인다. 이런 문법 차이를 정규식이나 파서로 잡아내면 JSON 기반 버전 파일이 없는 비주류 언어도 어느 정도 버전 필터링이 가능하다는 인사이트를 얻었다.
데이터셋만으로는 부족했다
이후 유튜브에서 OPL이라는 고전 프로그래밍 언어를 대상으로 파인튜닝하는 영상을 봤다.
하지만 영상을 보고도 감이 완전히 잡히지는 않았다. 데이터셋을 수집하는 과정과 파인튜닝하는 과정이 연결되어야 하는데, “데이터셋만 있으면 무엇을 어떻게 학습시키지?”라는 질문이 계속 남았다.
그래서 SSAFY 코치님께 특정 버전의 비주류 언어 데이터를 수집하고 싶은데 가장 효과적인 방법이 무엇인지 질문했다. 여기서 중요한 답변을 얻었다.
첫 번째는 지금 참고한 데이터셋이 assistant 학습용 데이터셋이라기보다 raw 코드 데이터셋에 가깝다는 점이었다. 내가 만들고 싶은 결과물이 챗봇 형태라면, raw 코드를 그대로 넣는 것만으로는 충분하지 않다.
두 번째는 raw 데이터셋을 기반으로 LLM에게 질문/답변 쌍을 만들게 해야 한다는 점이었다. 이 답변을 듣고 나서야 내가 해야 할 일이 조금 더 분명해졌다. Godot 4 코드만 모으는 것에서 끝나는 것이 아니라, 질문 데이터와 정답 데이터를 생성해서 instruction 데이터셋으로 만들어야 한다.
이 과정을 거치지 않으면 “맵을 설계해줘” 같은 요청을 했을 때 모델이 Godot이 아니라 Python으로 답할 가능성이 높다. 기존 모델들은 Python 데이터를 훨씬 많이 학습했을 것이기 때문이다. 정답 데이터가 명확하지 않으면 구버전 Godot 코드나 엉뚱한 언어가 섞일 가능성도 크다고 판단했다.
instruction 데이터셋과 프롬프팅 고민
instruction 데이터셋 후보로 Magicoder-Evol-Instruct-110K도 찾아봤다.
하지만 대부분 Python 중심으로 작성되어 있었다. 그대로 가져다 쓰면 Godot 4 전용 모델을 만드는 데에는 적합하지 않아 보였다.
이때 “Godot을 굳이 명시해야 할까?”라는 의문이 생겼다. Godot 데이터를 많이 넣으면, 사용자가 굳이 Godot이라고 말하지 않아도 Godot 코드로 답하게 만들 수 있지 않을까 생각했다.
이 부분은 학교 선배님께 자문을 구하면서 방향이 조금 정리됐다. 요즘은 무조건 RAG보다 프롬프팅이나 문서 기반 검색 구조를 잘 설계하는 것이 더 나을 수도 있고, 벡터 기반으로 마크다운 문서를 만들어둔 뒤 모델이 필요한 데이터를 찾을 수 있게 지도를 만드는 방식이 현실적이라는 조언을 받았다.
결국 현재 단계에서는 “맵을 만들어줘”보다 “Godot으로 맵을 만들어줘”처럼 명확한 맥락을 주는 편이 더 정확한 답변을 얻을 가능성이 높다고 정리했다. 기존 모델의 Python 가중치가 크기 때문에, Godot이라는 조건을 프롬프트 앞단에서 강하게 주는 것이 필요하다고 봤다.
아키텍처 재설계
처음에는 아키텍처를 단순하게 생각했다.
데이터셋 수집 -> 질문/정답 데이터셋 생성 -> 모델 학습하지만 곧 이 구조가 너무 위험하다고 느꼈다. Godot 3에서 4로 무엇이 바뀌었는지 내가 충분히 모르는 상태에서 데이터를 수집하면, 잘못된 코드가 정답 데이터로 들어갈 수 있다. 질문/정답 데이터셋을 만든다고 해도 Python 코드나 Godot 3 코드가 섞일 수 있다.
그래서 공식 문서를 먼저 기준점으로 삼는 구조를 떠올렸다. Godot 3에서 4로 넘어가는 마이그레이션 문서와 Godot 4 공식 문서를 크롤링해 RAG 챗봇을 만들고, 이 챗봇을 앞단에 배치해 수집한 코드가 Godot 3인지 4인지, 구버전 API를 쓰는지, Godot 4 코드로 적합한지를 판별하게 하는 방식이다.
첨부한 다이어그램은 이때 정리한 파이프라인 초안이다.

큰 흐름은 다음과 같다.
- Godot 공식 문서와 마이그레이션 문서를 크롤링해 RAG 지식 베이스를 만든다.
- GitHub의 Godot 프로젝트를 레포지토리 단위로 수집한다.
- README, 파일 구조, GDScript 코드를 하나의 컨텍스트로 병합한다.
project.godot설정 파일과 GDScript 문법 차이로 1차 버전 필터링을 한다.- RAG 챗봇으로 Godot 3/4 여부와 구버전 API 사용 여부를 추가 판별한다.
- Godot 4로 정제된 데이터만 instruction/response 데이터셋으로 만든다.
- SFT와 DPO/Preference 데이터로 Godot 4 코딩 모델을 학습한다.
SFT와 DPO 방향
이후 ChatGPT를 통해 추가로 물어보면서 예상하지 못했던 방향도 얻었다. 단순히 “Godot 4 코드를 생성하는 모델”만 생각했는데, 학습 태스크를 더 구체적으로 나눌 수 있었다.
SFT에서는 다음과 같은 태스크를 만들 수 있다.
- Godot 3/4 코드 분류
- Godot 3 코드를 Godot 4 코드로 변환
- Godot 4 코드 생성
- Godot 4 오류 수정
- Godot 3 API 거부 또는 교정
DPO/Preference에서는 나쁜 답변과 좋은 답변을 명확히 만들 수 있다. 예를 들어 Godot 3 문법이 섞인 답변을 나쁜 답변으로 두고, Godot 4 순수 코드로 작성된 답변을 좋은 답변으로 두는 방식이다.
이 관점이 생기면서 “그냥 데이터를 많이 모으자”가 아니라 “무엇을 좋은 답변으로 볼 것인가”를 먼저 정해야 한다는 생각이 들었다.
Godot 공식 문서 크롤링
이 방향을 실제로 시도하기 위해 크롤링 도구를 찾았고, crawl4ai를 사용했다.
- https://github.com/unclecode/crawl4ai
- https://docs.godotengine.org/en/stable/tutorials/migrating/upgrading_to_godot_4.html
Godot 4 공식 문서, Godot 3 -> 4 마이그레이션 문서, Godot 4 class reference, Godot 4 tutorial docs를 포함해 약 1,500페이지 가까이 크롤링하고 문서화했다.
처음에는 너무 많은 양을 크롤링한 것이 아닌가 싶었지만, 전체 모델 컨텍스트 크기와 비교하면 약 3% 정도에 해당하는 규모라고 판단했다. 당장 모델에 전부 넣는 것이 아니라 RAG나 문서 검색 구조로 사용한다면 충분히 다룰 수 있는 양이라고 봤다.
데이터 파이프라인과 I/O 고민
아키텍처를 다시 설계하다 보니 디스크 I/O와 학습 타이밍도 고민이 됐다. 데이터 수집, 전처리, 후처리, 저장, 리인덱싱, 학습이 모두 이어지면 병목이 생길 수밖에 없기 때문이다.
이 부분도 학교 선배님께 자문을 구했다. 얻은 답변은 실시간으로 파인튜닝을 돌리기보다, 데이터 확보와 데이터 가공을 빠르게 처리하고 학습은 배치성으로 수행하는 편이 낫다는 것이었다.
예를 들어 데이터셋이 특정 수치 이상 쌓였을 때만 강화학습이나 파인튜닝을 실행하는 방식이다. 리플리케이션 슬롯처럼 기준치를 넘었을 때 처리하면 I/O 병목을 줄일 수 있고, 실시간성이 중요한 부분은 학습이 아니라 데이터 확보와 가공이라는 관점이었다.
리인덱싱 비용은 구조적으로 완전히 제거하기 어렵다. 그래서 이 비용을 없애려 하기보다, 언제 리인덱싱하고 언제 학습할지 기준을 세우는 것이 더 현실적이라고 정리했다.
오늘의 정리
지난 10일 동안의 흐름을 정리하면, 처음에는 막연히 “Godot 코딩 모델을 만들어야겠다”에서 시작했다. 하지만 지금은 조금 더 구체적인 구조가 생겼다.
raw 코드 데이터셋만으로는 부족하다. Godot 4를 기준으로 정제된 코드 데이터, 공식 문서 기반의 판별 구조, instruction/response 데이터, SFT 태스크, DPO/Preference 기준이 모두 필요하다.
또한 지금 내 기술 수준에서 Qwen 같은 대형 모델 없이 처음부터 코딩 모델을 만드는 것은 현실적으로 어렵다. 초기 로컬 모델과 ChatGPT의 코딩 실력을 비교해보면서, 모델 크기와 사전 학습량의 차이를 무시할 수 없다는 것도 느꼈다.
그래도 방향은 전보다 훨씬 선명해졌다. Godot 4 공식 문서를 기준으로 지식 베이스를 만들고, 수집 데이터를 걸러내고, 좋은 답변과 나쁜 답변의 기준을 세워 학습 데이터로 만드는 흐름을 시도해볼 수 있다.
회고
이번 회고를 쓰면서 가장 크게 느낀 것은 기록의 기준을 낮춰야 한다는 점이다. 완벽한 결과물만 기록하려고 하면, 정작 중요한 과정은 사라진다. 실패한 실험, 애매했던 판단, 중간에 바뀐 아키텍처가 다음 결정을 만드는 재료인데 그걸 남기지 않으면 나중에 왜 이런 선택을 했는지 알 수 없게 된다.
앞으로는 완성된 결과만 올리려 하기보다, 과정 자체를 더 자주 남기려고 한다. 실패했다는 생각이 앞서서 회고를 미루기보다, 실패와 고민을 포함해서 기록하는 것이 더 나은 방향이라고 생각한다.
오늘을 계기로 다시 꾸준히 회고를 남기고 싶다. 완벽한 글이 아니어도 괜찮고, 중간 과정이어도 괜찮다. 중요한 것은 내가 무엇을 시도했고, 무엇을 배웠고, 다음에는 어떤 기준으로 움직일지를 남기는 것이다.