먼저 AI Hub에서 제공하는 행정법 데이터를 다운로드했다.
https://aihub.or.kr/aihubdata/data/view.do?currMenu=115&topMenu=100&&srchDataRealmCode=REALM014&aihubDataSe=data&dataSetSn=71722
이 데이터는 JSON 파일로 형식이고, 파일 개수와 용량도 커서, 로컬 형태에서 다룰 수 없었고, 우리는 데이터를 불러오는 역할과 데이터 전처리하는 팀원의 역할로 나눴기 때문에, 팀 공용으로 접근 가능한 구글 드라이브를 사용하기로 했다. 따라서, 매번 데이터 전달 비용을 줄일 수 있었고, 팀원간 소통을 원활히 할 수 있었다. 이후, 구글 드라이브 파일을 mount하여, 연결 후, 데이터들의 압축 해제를 하였다.

(저기 원천 데이터랑 라벨링 데이터를 둘다 불러오기 했으나, 우리는 라벨링 데이터만 사용할 예정이다. training이랑 validation 라벨링 데이터를 불러온 사진이다. )
1주차에 내가 한 일은 요약하면 이렇다.
AI Hub의 행정법 데이터를 팀원분들이 바로 전처리하고 학습에 사용할 수 있는 상태로 만드는 일.
다음 단계에서는
이 데이터를 기반으로 불러온 json 파일을 SFT 데이터 형식으로 바꿀 예정이다.
{
"id": "QA_00145",
"title": "각급 학교의 의미와 사례",
"question": "청탁금지법 제5조 제1항 제10호의 각급 학교는 무엇입니까?",
"answer": "각급 학교는 초·중등교육법, 고등교육법, 유아교육법 등에 따라 설치된 학교를 의미합니다.",
"commentary":"청탁금지법 제5조에서는 각급 학교의 입학·성적 처리 관련 부정행위를 금지하고있습니다.",
"keyword": "각급 학교",
"reference_rules": "청탁금지법 제5조",
"reference_court_case": null,
"reference_general": "권익위 청탁금지법 해설집(2018)"
}
위 데이터는 ai hub에 있는 데이터 그대로의 형태이다. 이러한 데이터 구조를
{
"question": "청탁금지법 제5조의 각급 학교란?",
"answer": "초·중등교육법, 고등교육법 등에 따른 학교",
"commentary": "입학·성적 처리 관련 부정행위 금지",
"reference_rules": "청탁금지법 제5조"
}
이런식으로 SFT 데이터 형식으로 바꿔야하는 일을 다음 팀원분이 할 예정이다.
여기서부터는 내가 한 부분은 아니지만, 팀원분들의 코드를 보고 과정을 알아가고자 공부한 내용을 적어보았다.
모델 구성을 위한 전체적인 개발 flow를 보여주자면,
AI Hub 판결문/결정문(JSON)
↓
GPT / Gemini (교사 모델)
↓
SFT 학습용 JSONL 데이터
↓
Qwen 2.5 14B + QLoRA 파인튜닝
↓
어댑터 병합
↓
GGUF 변환
↓
로컬 법률 AI
지금은 데이터 전처리 단계이므로, GPT/Gemini를 이용해 SFT 데이터를 만드는 전처리 단계에 대한 부분에 대한 설명이다.
SFT(Supervised Fine-Tuning)는모델에게 이런 질문에는 이렇게 답해라를 직접 가르치는 학습 방식이다.
SFT는 다음과 같은 데이터 구조를 갖는다.
{
"instruction": "질문",
"input": "",
"output": "답변"
}
즉, SFT데이터는 질문과 답변을 학습할 수 있는 최적의 데이터 구조이다.
8만 개 데이터 모두 변환해야하기 때문에, AI로 AI를 가르치기 위한 SFT 데이터 생성을 하였다.
이제 실제 코드를 이해해보겠다. 중요한 코드 위주로 작성해보았다.
!pip install openai pandas tqdm gdown jsonlines -q
SFT 데이터는 JSONL 형식은 한줄을 한 학습 샘플로 처리하고자 호출하는 라이브러리이다.
from google.colab import userdata
api_key = userdata.get('OPENAI_API_KEY')
if not api_key:
api_key = input("API Key 입력: ")
client = OpenAI(api_key=api_key)
API Key를 코드에 직접 쓰지 않고, Colab userdata를 활용하여 보안을 고려하여 설계를 하였다.
SYSTEM_PROMPT = """
너는 'Team DIET'의 법률 데이터 전처리 전문가야.
공무원이 참고할 수 있는 정확한 법률 질의응답 데이터를 생성해야 해.
"""
모델의 역할을 법률 QA 생성기로 설정하였다.
QA_PROMPT_TEMPLATE = """
1. 질문: 실무 공무원이 물어볼 법한 질문
2. 답변:
- 결론 → 법령/판례 근거 → 적용 해석
3. JSON 형식으로 출력
"""
이 프롬프트를 통해 모델은 단순 요약이 아니라 법률 답변의 논리 구조, 두괄식 결론, 근거 중심 설명을 학습용 데이터로 만들어냈다.
def parse_legal_json(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
content = data['info']['Precedent'].get('PrecedentContent', '')
if not content or len(content) < 50:
return None
return content
AI Hub 판결문 JSON은 구조가 복잡하기 때문에, 학습에 필요한 본문 텍스트만 추출하였다. 의미 없는 짧은 데이터는 자동으로 제거하여 학습 품질을 유지했다.
def convert_with_gpt(context_text):
prompt = QA_PROMPT_TEMPLATE.format(context=context_text[:3000])
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": prompt}
],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
여기서 GPT는 판결문을 읽고, 질문을 만들고, 법률 전문가답게 답변을 작성하고, SFT 포맷(JSON)으로 출력한다.
with jsonlines.open(output_file, mode='w') as writer:
writer.write(qa_pair)
이로써, 최종적으로 생성되는 파일은
train_data.jsonl
valid_data.jsonl
이 파일들이 그대로 QLoRA 파인튜닝의 입력 데이터가 된다.
GPT 외에도 Gemini Pro - 2.5 모델을 사용한 버전을 별도로 구성했다.
아마 팀원분이 gpt/gemini 두개의 역할로 나눠 전처리를 진행한 것 같다.
AI Hub의 법률 원천 데이터를 GPT/Gemini를 이용해, SFT 학습에 바로 사용할 수 있는 질의응답(JSONL) 데이터로 자동 변환하는 전처리 과정. 딱 한 문장 최종정리.
사실 이번주는 내가 크게 한 역할이 없다. 데이터 불러오기 역할 밖에 안 해서 다른 팀원분들이 훨씬 더 많은 일을 했을 것이다. 공유된 코랩을 보며, 팀원분들이 데이터 형식을 전처리 하신 부분들을 봤는데, 어려워보였다. 지금 당장 내일의 코어타임을 위해서 코드를 보고, 다시 블로그글을 수정해야겠다.