dev.to

I Distilled a 397B Model Into a 4B One for $1.60. It Now Catches 28 of 33 Park Alerts That Should Stop Your Hike.

397B 모델을 1.60달러로 4B에 증류했습니다 — 하이킹을 막아야 할 공원 경보 33건 중 28건을 잡습니다

미국 국립공원관리청(NPS)의 경보 627건을 대형 모델로 분류한 뒤, 그 결과를 바탕으로 Qwen3.5-4B를 LoRA 미세조정했습니다. 보류 데이터 126건에서 정확도는 64.3%에서 74.6%로 올랐고, 하이킹을 막아야 할 경보는 33건 중 28건을 찾아냈습니다. 전체 학습 비용은 1.60달러지만, 라벨 오류와 오탐 가능성도 함께 공개했습니다.

AI 요약

TrailTruth는 미국 국립공원관리청(National Park Service, NPS)의 공개 경보를 매주 읽고, 공원별로 ‘가도 됨’, ‘주의’, ‘가지 말 것’과 피해야 할 트레일을 인쇄용 카드 한 장에 정리하는 프로젝트입니다. 작성자는 Qwen3.5-397B-A17B로 경보 627건을 분류한 뒤, 더 작은 Qwen3.5-4B를 그 결과에 맞춰 LoRA 미세조정했습니다. 정답 기준은 NPS 직원이 지정한 경보 카테고리입니다.

학습 데이터와 방식

NPS 경보 카테고리 Information은 ‘가도 됨’, Caution은 ‘주의’, Danger와 Park Closure는 기본적으로 ‘가지 말 것’에 대응시켰습니다. 다만 주차장이나 방문자 센터처럼 시설만 닫는 경보 23건은 ‘주의’로 처리했습니다. 모델에는 경보 제목과 설명만 입력하고 카테고리는 보여주지 않았습니다. 카테고리를 정답으로 남겨 두어 평가에 활용했습니다.

대형 모델은 627건 모두 유효한 JSON으로 분류했고, 라벨링 비용은 0.95달러였습니다. 작성자는 대형 모델의 판단과 직원 라벨이 다른 235건에서 최종 결정을 직원 라벨에 맞췄습니다. 위험 유형, 트레일 이름, 설명은 대형 모델의 결과를 유지했습니다. 이 데이터를 이용해 Qwen3.5-4B에 rank-32 LoRA를 학습했습니다. 학습 데이터는 501건이며, 배치 크기 16, 3회 학습(epoch), 총 96단계를 거쳤습니다. 학습 시간은 6분 46초, 비용은 0.41달러였습니다. 나머지 126건은 평가용으로 따로 두고, 중복 경보가 학습과 평가 양쪽에 섞이지 않도록 분리했습니다.

평가 결과와 해석

보류한 126건에서 기본 Qwen3.5-4B의 결정 정확도는 64.3%였고, 미세조정 모델은 74.6%였습니다. 차이는 10.3%포인트이며, 95% 신뢰구간은 3.2~17.5%포인트입니다. 동일한 평가 사례에서 결과가 달랐던 항목을 비교한 정확 McNemar 검정의 p값은 0.015였습니다. 특히 ‘가지 말 것’으로 분류해야 하는 경보 33건 가운데 기본 모델은 17건을 잡았지만, 미세조정 모델은 28건을 잡았습니다. 이 비교의 p값은 0.007입니다.

다만 미세조정 모델이 대형 교사 모델보다 본질적으로 더 똑똑하다는 뜻은 아닙니다. 교사 모델은 학습을 거치지 않았고, 학생 모델은 직원 라벨에 맞춰 조정됐습니다. 교사 모델의 정확도는 65.1%였습니다. 작성자는 이 차이가 NPS의 분류 방식에 맞춘 보정에서 일부 나온다고 설명합니다. 기본 모델에 교사 모델의 긴 프롬프트를 제공한 비교에서는 미세조정 모델의 정확도 향상이 통계적으로 유의하지 않았습니다(p=0.12).

비용은 라벨링 0.95달러, LoRA 학습 0.41달러, 평가 0.25달러로 전체 1.60달러입니다. 추론 비용은 경보 1,000건당 학생 모델 0.13달러, 교사 모델 1.50달러로 약 11분의 1입니다. 반면 Tinker 호스팅 환경에서는 모델 크기와 관계없이 p50 응답 시간이 약 2.4초였습니다. 작성자는 자체 호스팅에서 속도 차이가 날 가능성을 언급했지만, vLLM·SGLang·llama.cpp로 내보낸 모델의 속도는 아직 측정하지 않았습니다.

오탐과 데이터의 한계

미세조정 모델은 실제로는 ‘가도 됨’인 경보 61건 중 11건을 ‘가지 말 것’으로 잘못 분류했습니다. 기본 모델의 오분류는 9건이었습니다. 더 많은 위험 경보를 잡는 대신 불필요하게 방문을 막는 경우가 늘어나는 셈입니다. 폐쇄 탐지 F1 점수도 기본 모델 0.889에서 미세조정 모델 0.884로 소폭 내려갔습니다.

정답 라벨 자체에도 문제가 있습니다. NPS는 킬라우에아 화산 분화를 Information으로 분류해, 평가 기준상 ‘가도 됨’이 정답이 되는 사례가 있습니다. 반대로 기승자에게만 닫힌 트레일은 Park Closure로 분류됐지만 보행자에게는 열려 있었습니다. 독성 조류 경보처럼 Danger로 분류됐는데 세 모델이 모두 ‘주의’로 판단한 사례도 있습니다. 작성자는 모델에 유리하도록 라벨을 고치지 않았다고 밝혔습니다.

Temporal로 주간 작업 복구

수집, 분류, 카드 작성은 Temporal 워크플로로 실행합니다. NPS 요청은 지수형 백오프로 재시도하고, 모델 호출은 한 번에 6건씩 처리하며 heartbeat로 멈춘 호출을 감지합니다. JSON이 잘못됐거나 다섯 번째 시도까지 실패하면 키워드 기반 휴리스틱으로 대체하고 카드에 해당 사실을 표시합니다. NPS API가 429와 16시간 넘는 대기 요청을 반환하면 재시도 폭주를 피하고 마지막 캐시 데이터를 사용합니다.

실제 모델을 쓰는 작업 중 워커 프로세스를 강제 종료한 시험에서는 경보 21건 가운데 이미 끝난 10건을 보존했고, 진행 중이던 6건만 다시 시도했습니다. 완료된 작업은 중복 실행되지 않았습니다. 전체 파이프라인은 매주 금요일 실행하도록 Temporal에 예약합니다. 작성자는 카드가 집에서 만들어져 인쇄되므로 트레일에서 통신 신호가 없어도 쓸 수 있다고 설명합니다. 다만 기본 학습과 추론 경로는 Tinker 호스팅 인프라를 이용합니다. 완전한 오프라인 실행은 어댑터를 내려받아 직접 운영할 때 가능합니다.

코드, 데이터 분할, 예측 결과, 평가 스크립트와 학습 어댑터 경로는 공개 저장소에 있으며 MIT 라이선스를 적용했습니다. 이 사례는 작은 모델 증류의 비용과 재현 절차뿐 아니라, 사람의 라벨을 정답으로 삼을 때 생기는 편향, 성능 지표의 해석, 작업 재시도 설계까지 함께 공개합니다.

dev.to 반응

  • @pritam_patra_429a25dedae6 — 좋네요.
    • @soumyadeepdey — 정말 좋네요.
  • @dronzer2code — 🤯

원문: dev.to / 번역·요약: Trawling