2026-03-25 (수) 개발일지
오늘의 TIL: LLM 파인튜닝 데이터 정제와 멀티프로젝트 컨텍스트 전환
오늘은 세 개의 프로젝트를 오가며 작업했는데, 특히 LLM 파인튜닝 데이터 정제 작업에서 많은 시간을 보냈습니다. 아침부터 저녁까지 정신없이 달렸지만, 데이터 품질의 중요성을 다시 한번 깨닫는 하루였습니다.
otel_project: 가짜 데이터의 함정과 진짜 데이터로의 전환
문제: RCAEval 데이터셋의 “unknown” 서비스 문제
어제부터 진행 중인 Qwen2.5-14B 모델의 RCA(Root Cause Analysis) 파인튜닝 작업에서 이상한 점을 발견했습니다. 학습 데이터 중 rca_rcaeval 데이터셋(709건)을 분석해보니, service 필드가 “unknown”으로 설정된 레코드가 상당수 있었습니다. 이건 실제 장애 분석에서는 절대 나올 수 없는 값인데, 데이터 생성 스크립트의 버그로 인해 발생한 가짜 데이터였습니다.
시도: 데이터 품질 검증과 원인 분석
처음에는 단순히 데이터 수가 부족한 줄 알았는데, 자세히 들여다보니 더 큰 문제가 있었습니다.
# 데이터 검증 스크립트
with open('training/data/rca_rcaeval.jsonl', 'r') as f:
for line in f:
record = json.loads(line)
if record.get('anomaly', {}).get('service') == 'unknown':
print('가짜 데이터 발견!')
결과를 확인해보니, 7,200건 중 상당수가 이 가짜 데이터였습니다. 문제의 원인은 데이터 증강(augmentation) 과정에서 원본 메트릭을 제대로 복사하지 않고 템플릿만 복사한 데 있었습니다.
해결: 데이터셋 v4 완성과 DGX 전송
- 가짜 데이터 완전 제거:
service="unknown"인 모든 레코드를 필터링 - 진짜 데이터 보강: 실제 RCAEval 실험 데이터 709건을 기반으로 합성 증강
- 최종 데이터셋 구성:
- train.json: 3,116건 (이전 7,200건 → 진짜 데이터로 대체)
- valid.json: 389건
- test.json: 390건
- 총 3,895건 (가짜 데이터 완전 제거)
# 사내 GPU 서버로의 데이터 전송 (계정/IP/경로 마스킹)
scp train.json user@<INTERNAL>:<PATH>/sharegpt/
scp valid.json user@<INTERNAL>:<PATH>/sharegpt/
scp test.json user@<INTERNAL>:<PATH>/sharegpt/
처음에는 한 줄로 모든 파일을 전송하려다가 -bash: 그런 파일이나 디렉터가 없습니다 에러를 마주했는데, 경로에 공백이 섞인 문제였습니다. 파일을 하나씩 따로 전송하니 해결되었습니다.
배운 점: 데이터 품질 검증의 중요성
“쓰레기 in, 쓰레기 out”이라는 말을 실감했습니다. 모델 성능이 안 나온다고 해서 무조건 모델 아키텍처나 하이퍼파라미터를 의심하기 전에, 데이터 품질부터 점검해야 합니다. 특히 합성 데이터를 생성할 때는 원본 데이터의 핵심 필드가 제대로 보존되는지 반드시 검증해야 합니다.
LLaMA Factory 학습 설정 최적화
문제: Early Stopping의 부재와 DNS 이슈
학습을 재개하려고 보니 두 가지 문제가 있었습니다:
- 현재 설정에는 early stopping 로직이 없어서 무조건 3 epoch을 전부 돌림
- HuggingFace 연결 시 DNS 문제로
MaxRetryError발생
해결: 설정 추가와 오프라인 모드 전환
# train_config_v4.yaml에 추가
load_best_model_at_end: true
metric_for_best_model: eval_loss
greater_is_better: false
early_stopping_patience: 3
DNS 문제는 이미 캐시된 모델을 사용하도록 오프라인 모드로 전환하여 해결했습니다. “캐시가 있으면 안 돼?”라는 순간적인 의문이 들었지만, 캐시를 삭제하는 것보다 오프라인 모드로 실행하는 것이 더 간단한 해결책이었습니다.
배운 점: 체크포인트 관리의 중요성
trainer_state.json 파일이 체크포인트마다 자동으로 생성/업데이트된다는 사실을 알게 되었습니다. 이 파일에는:
- 최고 성능의 체크포인트 경로
- 학습 중 평가 결과 히스토리
- 전체 학습 스텝 정보
가 저장되어 있어, 학습 중단 후 재개 시 매우 유용합니다. “체크포인트 저장하면 trainer_state.json 생성 안 되는 거 아니야?”라고 걱정했지만, 오히려 체크포인트가 저장될 때마다 업데이트되는 것이었습니다.
멀티프로젝트 컨텍스트 전환의 어려움
문제: 드롭쉬핑 자동화 프로젝트의 긴급 요청
오후쯤 되니 드롭쉬핑 자동화 프로젝트에서 MutBe 고객용 스토어프론트 + Stripe 결제 통합 구현 요청이 들어왔습니다. Shopify 무료 개발 스토어에서는 실제 결제가 불가능하기 때문에 자체 솔루션이 필요했죠.
시도: 기존 코드베이스 분석과 팀 구성 계획
LLM 파인튜닝 작업에 깊이 몰입해 있는 상태에서 갑자기 다른 도메인(이커머스, 결제 통합)으로 전환해야 했습니다. 처음에는 “이걸 지금 다 해야 하나?”라는 압박감이 들었지만, 우선 기존 코드베이스를 빠르게 분석하고 팀을 구성하여 병렬 작업할 수 있는 계획을 세웠습니다.
배운 점: 컨텍스트 전환 비용 관리
한 프로젝트에 깊이 몰입한 상태에서 다른 프로젝트로 전환하는 데는 상당한 정신적 비용이 든다는 것을 다시 한번 느꼈습니다. 이를 최소화하기 위해:
- 현재 작업의 체크포인트를 명확히 기록
- 다음에 돌아왔을 때 빠르게 재개할 수 있도록 문서화
- 긴급하지 않은 작업은 배치 처리
오늘 같은 날에는 작업 전환 시 최소 15-20분의 “멘탈 리부트” 시간이 필요하다는 것을 깨달았습니다.
오늘의 한줄
“데이터 품질 검증을 소홀히 하면, 모델 성능 디버깅으로 돌아오는 삽질의 대가를 치르게 된다.”