콘텐츠로 이동

04. 처음으로 한 번 돌려보기 ⭐#

📚 학습 목표: 더미 데이터로 전체 파이프라인을 한 번 완주하기
⏱️ 소요 시간: 반나절~하루 (학습 대기 시간 포함)
🎯 이 문서의 중요도: ⭐⭐⭐⭐⭐ (가장 중요)


이 문서의 목적#

"실제 데이터 없어도 전체 파이프라인을 한 번 돌려본다"

왜 이게 중요한가: 1. 환경 설정 문제를 미리 발견 2. 각 단계가 뭘 하는지 체감 3. 실제 데이터로 돌리기 전 자신감 획득 4. 학습 시간 감 잡기 (우리 맥미니에서 얼마나 걸리는지)


준비물 체크#

시작 전에 확인:

  • 맥미니 M4 24GB (asfreeas_mini)
  • macOS 최신 (Ventura 13.5 이상)
  • Python 3.10+ 설치됨
  • Homebrew 설치됨
  • 인터넷 연결 (Gemma 4 다운로드용, 약 8GB)
  • 여유 디스크 50GB (모델 + 어댑터 + 변환 파일)
  • 전원 연결 (학습 중 절전 방지)

확인 명령어#

# 하드웨어 확인
uname -m                    # → "arm64" 나와야 함
sysctl hw.memsize | awk '{print $2/1024/1024/1024 " GB"}'  # → 24 GB

# 소프트웨어 확인
python3 --version           # → Python 3.10+ 
brew --version              # → Homebrew 4.x

Phase 1: 환경 설정 (1회, 약 30분)#

1.1 프로젝트 받기#

맥미니에서 (맥북 말고):

cd ~
mkdir -p projects
cd projects

# 프로젝트 압축 해제 (이메일/에어드롭으로 받은 zip)
unzip ~/Downloads/mediconsol-llm.zip
cd mediconsol-llm

# 구조 확인
ls
# → CLAUDE.md, Makefile, README.md, configs/, data/, docs/, notebooks/, scripts/, training/

1.2 기본 패키지 설치#

make setup

뭐가 일어나는지: - pyyaml: YAML 설정 파일 읽기 - huggingface_hub: HuggingFace 모델 다운로드 - datasets: 데이터셋 관리 - requests: HTTP 통신

예상 시간: 2-3분

1.3 MLX 설치 (Apple Silicon 전용)#

make setup-mlx

뭐가 일어나는지: - mlx-lm 설치 - Apple Silicon인지 자동 확인 (Intel이면 에러)

예상 시간: 1-2분

1.4 llama.cpp 설치 (GGUF 변환용)#

맥미니에서 Metal 가속을 활용하려면 llama.cpp를 직접 빌드:

cd ~
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
cmake -B build -DGGML_METAL=ON
cmake --build build --config Release -j

예상 시간: 10-15분 (Metal 빌드 포함)

검증:

ls build/bin/llama-quantize   # 파일 있어야 함

1.5 Ollama 설치#

brew install ollama

# 백그라운드로 실행
brew services start ollama

# 확인
ollama --version
ollama list  # (아직 비어있음)

1.6 Hugging Face 계정 연결#

Gemma 4 다운로드에 필요:

# HuggingFace 홈페이지에서 Read Token 생성
# https://huggingface.co/settings/tokens

huggingface-cli login
# 토큰 입력

Gemma 4 라이선스 동의: - https://huggingface.co/google/gemma-4-E4B-it 방문 - "Acknowledge license" 버튼 클릭


Phase 2: 더미 데이터로 첫 학습 (반나절)#

2.1 더미 데이터 생성#

cd ~/projects/mediconsol-llm
make dummy

뭐가 일어나는지: - scripts/00_generate_dummy.py 실행 - 5개 카테고리별로 50건씩 총 250건 생성 - data/samples/ 에 저장

확인:

ls data/samples/
# 01_nursing/  02_management/  03_medical_terms/  04_consulting/  05_communication/

# 내용 살짝 보기
head -1 data/samples/01_nursing/*.jsonl | python3 -m json.tool

예상 시간: 5-10초

2.2 데이터 전처리#

make data-dummy

뭐가 일어나는지: - 250건의 데이터를 하나의 train.jsonl로 통합 - 카테고리 태그 추가 - PII 패턴 자동 스캔 - train (225건) / eval (25건) 분할

확인:

wc -l data/processed/train.jsonl data/processed/eval.jsonl
# → 225  data/processed/train.jsonl
# → 25   data/processed/eval.jsonl

# 첫 번째 예시 확인
head -1 data/processed/train.jsonl | python3 -m json.tool

출력 예시:

{
  "messages": [
    {
      "role": "system",
      "content": "당신은 병원 간호 기록(요양·전문·재활 등) AI입니다."
    },
    {
      "role": "user",
      "content": "다음 음성을 SOAP로 정리하세요: ..."
    },
    {
      "role": "assistant",
      "content": "S: 환자 호소 증상...\nO: 활력징후...\nA: ...\nP: ..."
    }
  ],
  "category": "nursing"
}

예상 시간: 5초

2.3 MLX 학습 시작 ⭐ 가장 오래 걸림#

make train-mlx

뭐가 일어나는지:

[1/5] 데이터 MLX 형식으로 준비
  → data/processed/mlx/{train,valid}.jsonl

[2/5] HF 모델 → MLX 변환
  → Gemma 4 E4B 다운로드 (첫 실행 시 ~8GB, 10-20분)
  → outputs/mlx_base/ 생성

[3/5] 4-bit 양자화 (QLoRA)
  → outputs/mlx_base_4bit/ 생성 (약 3GB)

[4/5] LoRA 학습 시작 (예상 3-6시간)
  Iter 10: Train loss 2.451, Learning Rate 2.000e-04
  Iter 20: Train loss 1.982
  Iter 50: Val loss 1.672, Val took 3.142s
  Iter 100: Saved adapter weights  ← 100번마다 체크포인트
  ...

[5/5] 학습된 어댑터로 추론 테스트
  "KPCS가 뭔가요?" → (AI 답변)

실제 시간 (더미 데이터 250건 기준): - Gemma 4 E4B 다운로드: 10-20분 (첫 실행만) - MLX 변환: 5분 - 4bit 양자화: 5분 - 학습 본체: 1-2시간 (더미 250건 + 600 iters 기준) - 추론 테스트: 1분

학습 중 할 일: - 🔌 전원 연결 유지 - 🌬️ 환기 (팬 소음 정상) - 📊 Loss 변화 관찰 (다른 창에서) - ☕ 커피 드세요

2.4 학습 진행 모니터링#

다른 터미널 열어서 모니터링:

# 맥미니 리소스 사용률
top -o cpu

# 또는 더 예쁘게
brew install htop  # 처음 한번만
htop

보면 좋은 것: - 메모리: 10-15GB 사용 중이어야 정상 (E4B 학습) - CPU: 대부분 코어 활성화 - GPU: Activity Monitor → 창 → GPU 히스토리에서 확인

이상 신호: - 메모리 23GB 육박 → 스와핑 위험 (다른 앱 닫기) - Loss가 계속 NaN → 학습 실패 (Ctrl+C 후 재시작) - 1시간 넘게 iter 1에 멈춤 → 뭔가 잘못됨

2.5 학습 완료 확인#

터미널에 이렇게 나오면 성공:

[5/5] 학습된 어댑터로 추론 테스트
==========
Prompt: KPCS가 뭔가요?
Response: Korean Patient Classification System으로, 환자의 간호 요구도를 분류하는 체계입니다...
==========

✅ MLX LoRA 학습 완료

다음 단계:
  1. 어댑터 병합:  bash scripts/03b_fuse_mlx.sh
  2. GGUF 변환:    bash scripts/04_convert_gguf.sh ...
  3. Ollama 등록:  bash scripts/05_create_ollama.sh ...

체크:

ls outputs/mlx_adapter/
# adapters.safetensors  adapter_config.json  ...


Phase 3: 배포까지 (1시간)#

3.1 어댑터 병합 (Fuse)#

make fuse-mlx

뭐가 일어나는지: - Base 모델 + LoRA 어댑터 → 하나의 통합 모델로 합침 - outputs/merged/ 생성 - de-quantize: Q4로 학습했지만 병합 시 FP16으로 복원

예상 시간: 5-10분

3.2 GGUF 변환#

make convert

뭐가 일어나는지: - FP16 통합 모델 → GGUF 포맷 변환 (llama.cpp) - Q4_K_M 양자화 (크기 1/4로 축소) - outputs/mediconsol-v1.Q4_K_M.gguf 생성 (약 3GB)

예상 시간: 10-20분

확인:

ls -lh outputs/*.gguf
# → -rw-r--r--  1 user  staff   3.2G  mediconsol-v1.Q4_K_M.gguf

3.3 Ollama 등록#

make deploy

뭐가 일어나는지: - Modelfile 생성 (시스템 프롬프트 포함) - ollama create mediconsol-v1:1.0.0 실행 - mediconsol-v1:latest 태그도 추가

예상 시간: 1-2분

확인:

ollama list
# NAME                    ID      SIZE    MODIFIED
# mediconsol-v1:latest    abc...  3.2GB   방금
# mediconsol-v1:1.0.0     abc...  3.2GB   방금

3.4 첫 번째 대화!#

ollama run mediconsol-v1

이제 대화 가능:

>>> KPCS가 뭔가요?
Korean Patient Classification System으로...

>>> 다음 음성을 SOAP로 정리해주세요: 환자 김○○ 어르신, 오전 9시 혈압 140/90, 무릎 통증 호소
S: 환자는 무릎 통증을 호소함
O: 혈압 140/90 mmHg (오전 9시)
A: 통증 관리 필요
P: 통증 정도 추가 사정, 필요 시 의료진 보고

>>> /bye

축하합니다! 첫 파인튜닝 완료! 🎉


Phase 4: 품질 평가 (30분)#

4.1 자동 평가 실행#

make evaluate

뭐가 일어나는지: - 5개 카테고리에서 4건씩 총 20건 테스트 - 각 답변을 기준 키워드와 비교 - 결과를 outputs/eval_report.json 저장

예상 시간: 5-10분 (모델이 각 답변 생성)

예시 출력:

==========================================
평가 결과 (mediconsol-v1)
==========================================
[nursing]        키워드 매칭률: 65% (13/20)
[management]     키워드 매칭률: 55% (11/20)
[medical_terms]  키워드 매칭률: 70% (14/20)
[consulting]     키워드 매칭률: 50% (10/20)
[communication]  키워드 매칭률: 60% (12/20)
------------------------------------------
종합 점수: 60%

4.2 결과 해석#

더미 데이터로 60% 나왔다면 정상입니다.

이유: - 더미 데이터는 품질이 낮음 (무작위 생성) - 실제 데이터로는 80%+ 목표 - 파이프라인이 작동한다는 것만 확인하는 게 목표

4.3 실제 대화로 체감 테스트#

ollama run mediconsol-v1

여러 질문 던져보세요:

>>> GODCH 프레임워크가 뭔가요?
>>> 욕창 등급 분류 기준을 알려주세요
>>> 요양병원 적정성 평가 대비 체크리스트
>>> 월간 경영 보고서 목차를 작성해주세요

느낌이 어때요? - 도메인 단어를 "알고 있는" 느낌이 들면 성공 - 완전 엉뚱한 답변이면 데이터 문제


Phase 5: 정리 및 다음 단계#

5.1 학습 결과 백업 (선택)#

# 어댑터만 따로 보관 (작고 중요)
tar -czf backups/v0.1.0_adapter_$(date +%Y%m%d).tar.gz outputs/mlx_adapter/

# 전체 outputs 백업 (큼)
# (선택 사항)

5.2 다음에 할 일 결정#

이제 두 갈래 길:

갈래 A: 더 공부하기 📚#

갈래 B: 실전 데이터 준비 🏥#

추천 순서: A 먼저, 그 다음 B. 개념이 단단해진 다음 실전이 효과적.


🆘 막혔을 때#

에러가 났다면#

  1. 에러 메시지 전체를 복사
  2. Claude Code에게 이렇게 물어보세요:

    "04_FIRST_RUN.md의 Phase 2.3에서 이런 에러가 났어. 어떻게 해결하지? [에러 메시지]"

  3. 06_TROUBLESHOOTING.md 먼저 확인

예상보다 오래 걸리면#

  • 학습이 3시간 넘어가면 정상 범위
  • 5시간 넘어가면 문제일 수 있음
  • 10시간 넘어가면 확실히 문제

결과가 이상하면#

  • 더미 데이터로 60% → 정상
  • 더미 데이터로 90%+ → 오히려 의심 (overfitting)
  • 더미 데이터로 30% 이하 → 데이터 문제

✅ 완료 체크리스트#

  • Phase 1: 환경 설정 완료
  • Phase 2.1: 더미 데이터 생성 완료
  • Phase 2.2: 전처리 완료
  • Phase 2.3: MLX 학습 완료
  • Phase 3.1: 병합 완료
  • Phase 3.2: GGUF 변환 완료
  • Phase 3.3: Ollama 등록 완료
  • Phase 3.4: 첫 대화 성공
  • Phase 4: 평가 실행
  • 이게 다 완료되면 당신은 이제 LLM 파인튜너입니다 🎓

💡 핵심 요약#

오늘 한 일: 환경 설정 + 더미 데이터로 전체 파이프라인 완주
중요한 것: 결과 품질 X → 파이프라인 작동 확인 ⭐
얻은 것: 감. 자신감. 다음엔 진짜 데이터로!