397B 모델을 4B 모델로 증류하여 $1.60에 구현했습니다. 이제 하이커의 등산을 막아야 할 33개 중 28개의 공원 경고를 포착합니다.
요약
대규모 언어 모델(Qwen3.5-397B)을 소형 모델(Qwen3.5-4B)로 증류하고 미세 조정하여 공원 경고 감지 시스템의 성능과 효율성을 크게 개선했습니다. 이 시스템은 하이커가 피해야 할 33개 중 28개의 경고를 포착하며, 전체 ML 파이프라인 비용을 $1.60으로 낮췄습니다.
핵심 포인트
- 대규모 모델 증류 및 미세 조정 기법 적용
- 경고 감지 정확도 64.3%에서 74.6%로 향상
- 하이커 위험 경고 포착률이 17개에서 28개로 증가
- 전체 ML 파이프라인 비용을 $1.60으로 효율화
이 글은 Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass에 제출하는 내용입니다.
저는 모든 라이브 National Park Service 경고, 총 627건을 Qwen3.5-397B로 라벨링한 다음, Tinker를 사용하여 이 데이터(숙제)로 Qwen3.5-4B를 미세 조정했습니다. 이때 레인저들이 직접 만든 카테고리를 정답 키로 사용했습니다. 126개의 별도 검증 경고에 대해, 미세 조정된 4B 모델은 하이커의 등산을 막아야 할 경고를 33개 중 17개 포착하는 것에서 33개 중 28개로 늘렸으며, 결정 정확도는 **64.3%에서 74.6%**로 향상되었습니다. 이 성능 향상은 통계적으로 유의미합니다(짝지은 검정, p = 0.015). 비용은 경고 1,000건당 $0.13으로, 교사 모델보다 약 11배 저렴하며 전체 ML 파이프라인 비용은 $1.60입니다.
이 모델의 유일한 임무는 매주 인쇄 가능한 카드 한 장을 생성하는 것이므로, 여러분은 공원 경고를 확인하는 것을 멈추고 밖에 나가셔도 됩니다.
요약 (TL;DR)
- 내용: TrailTruth는 사용자가 관심 있는 공원의 모든 NPS(National Park Service) 경고를 매주 한 번 읽어, 공원당 카드 한 장을 인쇄합니다: 진행 가능(GO), 주의(CAUTION) 또는 진행 불가(NO-GO), 그리고 피해야 할 등산로까지 포함됩니다. 그런 다음 다음 주 금요일까지 조용히 기다립니다.
- Tinker 결과: Qwen3.5-397B-A17B에서 증류한 Qwen3.5-4B에 대한 LoRA는 126개의 별도 검증 경고에 대해 결정 정확도 0.746을 기록했으며, 동일 기본 모델의 0.643과 비교됩니다(+10.3 포인트, 95% CI +3.2 ~ +17.5, 정확한 McNemar p = 0.015). 등산을 막아야 하는 경고에 대해서는 33개 중 28개를 포착했으며, 이는 33개 중 17개와 비교됩니다(p = 0.007).
- 비용: 교사 라벨링 $0.95, LoRA 학습 $0.41, 평가 $0.25. 총 $1.60. 학생 모델은 경고 1,000건당 $0.13으로 운영되며, 교사 모델의 비용은 $1.50입니다.
- 내구성: 주간 실행은 Temporal 워크플로우입니다. 실제 모델을 로드한 상태에서 작업자가 작동 중일 때 강제 종료했습니다: 21개의 경고 중 10개가 충돌 전에 완료되어 보존되었고, 6개의 고아 호출(orphaned calls)이 재시도되었으며, 두 번 실행된 경우는 없었습니다.
- 정직성: 학생 모델이 교사 모델보다 성능이 좋은 부분은 제가 레인저들의 라벨을 향해 학습시켰고, 교사 모델에게는 절대 학습시키지 않았기 때문입니다.
교사(teacher)의 긴 프롬프트가 주어진 기본 모델(base model)과 비교했을 때, 성능 향상은 유의미하지 않습니다 (p = 0.12). 두 결과는 아래 표에 나와 있습니다.
- 모든 것이 공개됨: 코드, 데이터 분할, 예측, 평가 스크립트 및 학습된 어댑터의 경로는 **SoumyaEXE/trailtruth**에서 확인할 수 있습니다.
30초 만에 알아낸 3가지 발견
- 기본 모델은 폐쇄 정보를 읽고도 여전히 "주의해서 가세요"라고 말합니다. 33개의 이동 금지 경보 중 16개를 _주의(caution)_로 분류했습니다. $0.41의 파인튜닝(fine-tuning) 후에도 5개를 놓쳤습니다.
- 프롬프팅이 학습과 같지는 않습니다. 기본 모델에 교사의 규칙 프롬프트(340 토큰 더 김)를 제공하는 것은 비용을 거의 두 배로 늘리지만, 여전히 33개 중 17개만을 포착합니다.
- 정답지에 오타가 있으며, 양쪽 모두 문제가 있습니다. NPS는 Kīlauea 분화를 _정보(Information)_로 분류했고 (따라서 "진행 가능"이 정답으로 채점됨), 말 전용 트레일 폐쇄를 _공원 폐쇄(Park Closure)_로 분류했습니다. 어떤 모델도 100%에 근접하지 못했으며, 저는 제 점수를 높이기 위해 라벨을 수정하지 않았습니다.
어떤 개인 정보도 어딘가로 전송되지 않았습니다. 데이터는
developer.nps.gov의 공개 정부 텍스트입니다. 이 앱은 공원 코드별 경보만 NPS에 요청합니다. 위치, 계정, 추적 기록이 없습니다. 이를 구축하는 데 사용된 API 키는 gitignore 처리된.env파일에 저장되어 있습니다.
이것이 중요한 이유: 627개 경보, 28,760 단어, 아무도 읽지 않는다
공원 포인트(Point Park) 아래 금속 계단 기슭과 크레이븐스 하우스 트레일 사이의 블러프 트레일(Bluff Trail) 구간을 하이킹할 때는 주의를 기울여 주십시오. 영역성 검은솔부엉이(territorial barred owl)가 있을 수 있습니다. 해결책을 마련하는 동안 여러분의 경계심과 인내심에 감사드립니다.
이것은 실제 경보이며, 10월 9일 차타누가(Chattanooga)의 루크아웃 마운틴(Lookout Mountain)에서 발생한 것입니다. "해결책을 마련하는 동안 여러분의 인내심"이라는 문구는 올해 연방 정부가 발표한 문구 중 제가 가장 좋아하는 구절입니다.
이는 270개 이상의 공원에서 발생한 627개의 개방형 경고 중 하나입니다. 이 경고들은 총 28,760단어 분량이며, 약 두 시간 분량의 독서가 필요합니다. 그중 4분의 1 이상은 주차장, 방문자 센터 또는 운영 시간에 관한 내용입니다. 주목할 만한 몇 가지 사례가 있습니다: Kīlauea 정상에서 부풀어 오르고 흔들리고 있어 Halemaʻumaʻu Trail이 폐쇄되었습니다. 올림픽 공원에서는 '광견병에 걸린 박쥐 한 마리가 머리카락에 일시적으로 잡혔었다'는 내용입니다. 옐로스톤의 엘크 관련 조언은 네 단어로 되어 있습니다: '엘크가 돌진하면, 도망치세요.'
이번 주말 하이킹을 계획한다면 이 경고들 중 아마 세 가지만 필요할 것입니다. 모두가 폐쇄 표지판이 붙은 트레일 헤드까지 두 시간 운전해 왔거나, 공원 경고 페이지를 열어 14개의 항목을 보고 '감'으로 결정한 경우입니다.
새로 추가된 기능
| 기존 옵션 | 제공하는 정보 | 알려주지 못하는 것 |
|---|---|---|
| 공원 경고 페이지 | 모든 경고 내용 (전체) | 당신의 하이킹에 중요한 세 가지가 무엇인지 |
| ... |
제가 만든 기능
TrailTruth는 국립공원의 경고 정보를 주머니에 넣을 수 있는 하나의 결정으로 바꿉니다. 사용자가 공원을 한 번 지정합니다. 매주 금요일 오전 7시에 워크플로우가 해당 공원들의 경고를 가져와, 각 내용을 파인튜닝된 4B 모델로 처리하고 카드를 만듭니다. 이것은 10월 10일 실행 결과의 실제 카드입니다:
TRAILTRUTH · week of 2026-10-10 · overall CAUTION
HAIʻI VOLCANOES NATIONAL PARK [CAUTION]
...
이것을 인쇄하거나 스크린샷을 찍으면 바로 떠날 수 있습니다. 피드도 없고, 연속 기록(streak)도 없으며, 하이킹 경험에 대해 묻는 알림도 없습니다. 제가 신경 쓰는 숫자는 앱에서 보내는 시간이 아니라 분입니다.

대시보드(Next.js + BoardUI)는 설정 및 호기심이 많은 사람들을 위한 것입니다. 평상시에는 필요하지 않을 것입니다.
데모 (Demo)
전체 스택(stack)은 단일 명령어로 로컬에서 실행하거나, 리포지토리의 Blueprint를 통해 Render에서 실행할 수 있습니다:
git clone https://github.com/SoumyaEXE/trailtruth && cd trailtruth
cp .env.example .env # NPS_API_KEY, TINKER_API_KEY (선택 사항; 키워드 휴리스틱으로 폴백(fallback)합니다)
...
코드 (Code)
GitHub logo SoumyaEXE / trailtruth
TrailTruth
627개 국립공원 경고 → 인쇄 가능한 '진행/보류(go/no-go)' 트레일 카드. 한 번 확인하고, 그리고 밖에 나가세요.
TrailTruth는 모든 실시간 미국 국립공원 서비스(NPS) 경고(블러프 트레일의 올빼미, 키라우아 지진 활동으로 인한 할레마우마우 폐쇄, 유실된 다리 등)를 읽어 사용자가 관심을 갖는 공원들에 대한 단일 주간 카드로 변환합니다.
- Tinker를 사용한 증류(Distilled with):
Qwen3.5-397B가 627개의 경고를 모두 라벨링했습니다 →Qwen3.5-4B의 LoRA 파인튜닝을 진행했습니다. 126개의 테스트용 경고에 대해, 4B 모델(학생)은 결정 정확도가 **64.3%에서 74.6%**로 향상되었으며 (교사: 65.1%), 경고당 비용은 약 11배 낮아졌습니다. 전체 파이프라인 비용은 ~$1.60입니다. - Temporal을 사용한 내구성 확보(Durable with): 플래키한 NPS/모델 호출에 대한 재시도, 캐시로의 429 폴백 처리, 그리고 매주 금요일 스케줄링을 통해 가져오기 → 분류 → 구성 → 게시하는 과정을 구현했습니다. 작업 중 워커를 종료해도 완료된 작업을 다시 수행하지 않고 재개됩니다.
- Entire로 개방 구축(Built in the open with): 코드 뒤에 있는 에이전트 세션은 체크포인트로 기록됩니다.
작성 문서: docs/POST.md · 결과: ml/results/eval.json
레이아웃 (Layout)
…
ml/ 폴더에는 데이터 파이프라인, 교사 라벨링(teacher labelling), Tinker 학습 및 평가가 포함되어 있습니다. agent/ 폴더에는 Temporal 워크플로우, 워커 및 API가, 그리고 web/ 폴더에는 대시보드가 들어있습니다. 본 게시물의 모든 숫자는 ml/results/eval.json, ml/results/predictions.jsonl, ml/results/spend.json 또는 agent/demo_logs/의 기록에서 가져온 것입니다. MIT 라이선스입니다.
구축 방법 (How I Built It)
모든 것의 규칙은 이렇습니다: 대형 모델이 가르치고, 소형 모델이 작동하며, 레인저가 평가합니다.
레인저들이 이미 데이터를 라벨링했습니다
모든 NPS 경고에는 레인저가 선택한 카테고리가 있습니다: 정보(Information), 주의(Caution), 위험(Danger) 또는 **공원 폐쇄(Park Closure)**입니다. 이는 실제 정부 텍스트에 붙은 인간의 레이블로, 해커톤 데이터셋에서는 보기 드문 경우입니다. 저는 이를 하이커의 결정으로 매핑합니다: 정보 → 이동 가능(go), 주의 → 주의 필요(caution), 위험 및 트레일 폐쇄 → 이동 불가(no-go). 모델은 카테고리를 절대 보지 못하고, 오직 제목과 설명만 봅니다. 카테고리가 정답 키입니다.
| NPS 카테고리 | 경고 건수 | 결정 등급 |
|---|---|---|
| Information | 308 | go |
| ... |
각 경고는 엄격한 JSON 판결이 됩니다:
{
"hazard_type": "closure",
"severity": 3,
...
Tinker를 이용해 397B를 4B로 증류하기
교사 모델인 Qwen3.5-397B-A17B는 경고문을 잘 읽습니다. 하지만 매주 모든 사용자에게 비용을 지불하고 싶지 않고, 노트북에서도 실행되지 않습니다. 그래서 저는 이를 한 번 사용했습니다:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기



