파인튜닝 5일이 프롬프트 108자에 졌다
Gemma 4 26B-A4B에 LoRA로 5일을 썼는데 튜닝 안 한 것과 별로 다르지 않았다. 같은 과제를 프롬프트 압축으로 다시 붙여본 결과
하려던 것
공시를 더 잘 요약하게 만들고 싶었다. 그래서 google/gemma-4-26B-A4B-it에 LoRA를 붙였다. 어제 장비를 통째로 죽인 게 이 작업이다.
오늘 결론이 났다. 안 쓰기로 했다.
어떻게 시켰나
먼저 라벨이 필요했다. 공시 원문에 정답 요약을 붙여야 하는데, 그걸 Claude Sonnet API를 불러서 만들었다. 돈이 드는 작업이라, 학습이 잘 안 되면 그 비용이 그대로 날아간다는 게 내내 걸렸다.
최종적으로 라벨 13,206건. 학습에 쓴 건 3천 건 세트고 평균 3,476자, 최대 13,519자다. 만 자 넘는 게 6%인데, 이 6%가 어제 장비를 죽인 그 샘플들이다.
길이 분포를 미리 봤어야 했다는 게 여기서 나온다. 짧은 샘플이 37%, 중간이 40%인데 나머지 소수의 긴 샘플에 맞춰 max_seq_length를 잡아 놨으니, 평소엔 멀쩡하다가 긴 게 걸릴 때만 메모리가 튄다. 평균이 아니라 꼬리가 설정을 결정한다.
어디서 막혔나
학습을 시작하는 것부터 일이었다. Unsloth의 DGX Spark용 이미지로 컨테이너를 띄우는 데서 두 번 막혔다.
하나 — uid 불일치. 이미지 기본 유저가 uid 1001인데 마운트한 작업 디렉터리는 호스트 소유(uid 1000)다. 학습은 다 돌고 나서 저장 단계에서 권한 오류로 죽었다. 제일 아까운 실패 지점이다. --user "$(id -u):$(id -g)"로 해결.
둘 — 캐시 경로. 이미지 env에 HF_HOME=/workspace/.cache/huggingface가 박혀 있어서, 호스트 ~/.cache/huggingface를 관례대로 /root/.cache/huggingface에 마운트하면 캐시를 못 찾고 가중치 48GB를 다시 받는다.
이런 건 어디 안 적혀 있고 한 번씩 밟아야 안다.
그리고 정작 결과가 기대에 못 미쳤다. 손잡이를 하나씩 물어봤다. epoch을 한 번 더 돌리면 어떻겠냐, rank를 올리면서 OOM을 피할 방법은 없냐, 시퀀스를 줄이면 품질이 얼마나 떨어지냐.
돌아온 답은 대체로 “그 손잡이로는 크게 안 바뀐다”였다. 그러면서 매번 근거를 붙여줬는데, 그 근거들이 대체로 그럴듯했다. 문제는 내가 그걸 검증할 방법이 없었다는 거다. 각 조합을 실제로 돌려보려면 또 며칠이다. 답이 맞는지 확인하는 비용이 답을 얻는 비용보다 커지면 그 답은 쓸모가 애매해진다.
“당연한 말이긴 했다. 품질을 더 올리고 싶은 마음인데, 그냥 튜닝 없이 쓰는 것과 현재는 별반 다르지 않아서.”
어떻게 풀었나
파인튜닝을 접고 프롬프트를 줄여봤다. 쓰던 시스템 프롬프트가 277자였는데 108자로 압축했다. n=200으로 재봤고, 정답은 Claude Opus로 붙인 라벨이다.
| 지표 | 값 |
|---|---|
| 처리 시간 | 12.84s → 5.73s (−55%) |
| Opus 라벨 일치 | 73.0% (146/200, 95% CI ±6.1%p) |
| JSON 파싱 성공 | 100% |
말을 줄였더니 두 배 이상 빨라졌고 품질은 안 떨어졌다. 오늘 이 버전을 프로덕션에 넣었다.
5일짜리 학습이 못 한 걸 프롬프트 편집 몇 번이 했다.
왜 안 먹혔을까
확신은 없는데 지금 드는 생각은 이렇다. 요약·감성 분류는 모델이 이미 아는 일이다. 파인튜닝이 크게 먹히는 건 모델이 모르는 것(사내 용어, 특수 포맷, 도메인 특유의 판단 기준)을 가르칠 때다. “공시를 요약해라”는 사전학습 때 이미 수없이 본 과제라, 3천 건을 더 보여줘도 배울 게 별로 없다.
그렇다면 애초에 이 모델이 뭘 아는지부터 재봤어야 했다. 나는 그걸 안 재고 가르치러 갔다.
배운 점
- 파인튜닝 전에 프롬프트부터 다 짜내라. 순서가 반대면 5일이 날아간다.
- 그 전에 모델이 뭘 아는지부터 측정해라. “모른다”는 가정을 검증하는 데는 아마 한나절도 안 걸렸을 것이다.
- 파인튜닝이 값어치 있는 건 모델이 모르는 것을 가르칠 때다. 이미 아는 일을 더 시키는 건 효과가 작다.
- 학습 컨테이너는 uid와 캐시 경로에서 막힌다. 그리고 그 실패는 보통 다 돌고 나서 저장할 때 터진다.
제일 아픈 건 “별반 다르지 않았다”는 결과를 5일 뒤에 알았다는 거다. 200건 재보는 데는 한 시간도 안 걸렸다. 순서만 바꿨어도 됐다.