LLM 파인튜닝은 처음 들으면 무섭다.

말도 어렵다.
Fine-tuning. LoRA. vLLM. AutoTune. Judge. Gateway.
뭔가 전부 대문자고, 전부 비싸 보이고, 전부 한 번 잘못 누르면 GPU가 불타오를 것 같다.

그런데 실제로 뜯어보면 이야기는 꽤 단순하다.

우리는 이미 똑똑한 모델 하나를 데려온다.
그리고 우리 회사의 말투, 우리 제품의 지식, 우리 도메인의 예시를 조금 더 가르친다.
마지막으로 정말 더 나아졌는지 시험지를 풀려본다.

llm-forge 데모는 바로 이 과정을 하나의 공장 견학 코스로 보여준다.

소스 코드 받기
  -> 환경 준비
  -> AI 연결 관문 켜기
  -> 좋은 학습 설정 찾기
  -> 모델 학습시키기
  -> API 서버로 띄우기
  -> 원본 모델과 비교하기
  -> 리포트로 남기기

이 글은 LLM 사전 지식이 거의 없는 사람도 따라올 수 있게, 이 공장이 어떤 기계로 돌아가는지 하나씩 풀어보는 안내서다.

먼저, 모델은 신입사원이라고 생각하자

Base 모델은 기본 교육을 받은 신입사원이다.

똑똑하다.
일반 상식도 많다.
문장도 잘 쓴다.

하지만 우리 회사 업무를 모를 수 있다.

예를 들어 “DAC가 뭐야?”라고 물었을 때, 일반 모델은 이렇게 답할 수 있다.

DAC는 디지털-아날로그 변환기를 의미합니다.

틀린 말은 아니다.
하지만 QueryPie 같은 접근 제어 제품 문맥에서는 우리가 기대한 답이 아니다.

우리가 원하는 답은 이런 쪽이다.

QueryPie에서 DAC는 Database Access Control을 의미하며,
데이터베이스 접근 권한, 정책, 감사 로그를 관리하는 기능입니다.

Fine-tuning은 이 간극을 줄이는 일이다.

신입사원에게 회사 업무 매뉴얼과 예시 답변을 보여주며 말하는 것이다.

“일반 상식은 좋은데, 우리 회사에서는 이 단어를 이렇게 써.”

학습 데이터는 문제집이다

모델에게 뭔가를 가르치려면 예시가 필요하다.

이 예시는 보통 질문과 답변 쌍으로 만든다.

{"instruction": "QueryPie DAC란 무엇인가요?", "input": "", "output": "DAC는 Database Access Control의 약자로, 데이터베이스 접근 권한과 감사 로그를 관리하는 기능입니다."}

이런 줄이 여러 개 모이면 학습 데이터가 된다.

llm-forge 데모에서는 파일 두 개가 등장한다.

data/demo_train.jsonl  # 학습용 문제집
data/demo_eval.jsonl   # 시험용 문제집

여기서 .jsonl은 “한 줄에 JSON 하나씩” 들어 있는 파일 형식이다.

{"question": "질문 1", "answer": "답변 1"}
{"question": "질문 2", "answer": "답변 2"}
{"question": "질문 3", "answer": "답변 3"}

엑셀로 비유하면 한 줄이 한 문제다.
다만 CSV 대신 JSON으로 쓴다고 보면 된다.

LoRA는 보충 노트다

큰 모델 전체를 다시 학습하는 건 비싸다.

마치 800페이지짜리 교과서를 통째로 새로 쓰는 일과 비슷하다.
시간도 많이 들고, GPU 메모리도 많이 먹고, 실수하면 원본도 망가질 수 있다.

그래서 많이 쓰는 방법이 LoRA다.

LoRA는 원본 모델 전체를 다시 쓰지 않는다.
대신 작은 보충 노트만 학습한다.

비유하면 이렇다.

Base 모델 = 기본 교과서
LoRA 어댑터 = 우리 회사 업무용 보충 노트
FT 모델 = 교과서 + 보충 노트를 같이 보는 상태

이 방식의 장점은 분명하다.

  • 더 빠르다.
  • GPU 메모리를 덜 쓴다.
  • 원본 모델을 보존할 수 있다.
  • 여러 도메인의 보충 노트를 따로 관리할 수 있다.

llm-forge가 학습을 마치면 보통 adapter/ 같은 결과물이 생긴다.
이게 바로 보충 노트다.

AutoTune은 학습 코치다

학습에는 설정값이 많다.

대표적으로 이런 것들이다.

설정값 쉬운 설명
learning_rate 한 번 배울 때 얼마나 크게 고칠지
lora_rank 보충 노트가 얼마나 많은 정보를 담을지
warmup_steps 초반에 천천히 학습을 시작할 기간
weight_decay 문제집을 너무 달달 외우지 않게 조절하는 값

문제는 이 설정값이 정답처럼 딱 정해져 있지 않다는 점이다.

너무 세게 배우면 망가질 수 있다.
너무 약하게 배우면 달라지는 게 없다.
보충 노트가 너무 작으면 지식이 부족하고, 너무 크면 비용이 커진다.

그래서 AutoTune이 등장한다.

AutoTune은 학습 코치처럼 말한다.

이번에는 learning_rate를 조금 낮춰보자.
이번에는 lora_rank를 올려보자.
이번 실험은 손실이 좋아졌으니 이 설정을 유지하자.

llm-forge의 Phase 1은 이 작업을 맡는다.

여러 학습 설정을 짧게 실험해보고, 그중 괜찮은 설정을 current.yaml 같은 파일에 남긴다.

Gateway는 통역사다

여기서 또 하나 헷갈리는 친구가 나온다.

Kimi Gateway.
Anthropic Proxy.
LiteLLM.

처음 보면 이름만으로 이미 피곤하다.

하지만 역할은 간단하다.

서로 다른 LLM API의 말투를 맞춰주는 통역사다.

어떤 도구는 Anthropic Messages API처럼 말하고 싶어 한다.
어떤 모델 서버는 OpenAI Chat Completions API처럼 대답한다.
Kimi는 또 Kimi대로 떠 있다.

그 사이를 이렇게 이어준다.

AutoTune
  -> Anthropic Proxy
  -> LiteLLM
  -> Kimi 모델 서버

초보자식으로 말하면 이렇다.

구성요소 비유 실제 역할
Kimi 실제 답하는 사람 AutoTune 추천과 평가에 쓰이는 LLM
LiteLLM 공용 어댑터 여러 LLM을 OpenAI 호환 형태로 감싸줌
Anthropic Proxy 통역사 Anthropic API 형식으로 요청/응답을 바꿈
Gateway 안내 데스크 위 연결 전체의 출입구

그래서 데모 전에 Gateway를 재시작한다.

./utils/run_kimi_gateway.sh restart
./utils/run_kimi_gateway.sh status

이건 학습 결과를 지우는 작업이 아니다.
전화 교환원을 다시 켜는 일에 가깝다.

vLLM은 모델을 상담원으로 만든다

학습된 모델은 그냥 파일이다.

파일 상태의 모델은 질문을 받을 수 없다.
누군가 서버로 띄워줘야 한다.

그 역할을 하는 것이 vLLM이다.

vLLM은 모델을 OpenAI 호환 API처럼 호출할 수 있게 해준다.

사용자 질문
  -> http://localhost:8000/v1/chat/completions
  -> vLLM
  -> 모델 응답

비유하면 이렇다.

모델 파일 = 교육받은 상담원
vLLM = 상담원이 앉아 있는 콜센터 창구
API = 고객이 전화를 거는 번호

llm-forge의 Phase 3가 이 서빙 단계를 맡는다.

재미있는 점은 base 모델과 FT 모델을 비교해야 하므로 둘 다 띄워야 한다는 것이다.
GPU가 넉넉하면 동시에 띄울 수 있고, 부족하면 하나씩 순서대로 띄운다.

그래서 EVAL_DEPLOY_MODE=sequential 같은 설정이 있다.

sequential = base 모델 평가 -> 내림 -> FT 모델 평가
parallel   = base와 FT를 동시에 띄움

초보자에게는 sequential이 더 이해하기 쉽다.
GPU 메모리도 덜 무섭다.

Judge는 시험 감독이다

모델을 학습시켰다고 끝이 아니다.

정말 좋아졌는지 봐야 한다.

사람이 모든 답변을 읽고 평가할 수도 있지만, 반복 실험에서는 너무 오래 걸린다.
그래서 또 다른 LLM을 Judge로 사용한다.

Judge는 base 모델과 FT 모델의 답변을 보고 점수를 준다.

평가 기준
correctness 핵심 판단이 맞는가
completeness 필요한 내용을 충분히 담았는가
quality 답변이 자연스럽고 읽기 좋은가

점수는 보통 1점부터 5점까지다.

여기서 중요한 지표 중 하나는 correctness >= 4 비율이다.
쉽게 말하면 “꽤 맞는 답변을 얼마나 자주 했나”다.

최종 결과는 비교 리포트로 남는다.

comparison_report.md
comparison_report_slack.txt

즉, 데모의 마지막 장면은 이 질문에 답하는 것이다.

“그래서 학습한 모델이 진짜 더 나아졌어?”

전체 파이프라인은 하나의 공장 라인이다

이제 다시 전체 흐름을 보면 덜 무섭다.

Git Clone
  최신 공장 설계도를 가져온다.

Clean Setup
  예전 실험 흔적을 치우고 작업장을 청소한다.

Run Setup
  필요한 도구와 작업실을 설치한다.

Gateway Refresh
  AI 통역사와 안내 데스크를 켠다.

AutoTune
  학습 코치가 좋은 설정을 찾아본다.

Train + Merge
  모델에게 문제집을 풀리고, 보충 노트를 만든다.

Serve
  모델을 API 상담원으로 띄운다.

Eval
  Judge가 base와 FT 모델을 채점한다.

Report
  결과를 사람이 읽을 수 있는 리포트로 남긴다.

실행 명령은 생각보다 짧다.

./run_pipeline.sh \
  --model Qwen/Qwen2.5-1.5B-Instruct \
  --data data/demo_train.jsonl \
  --days 1 \
  --eval-file data/demo_eval.jsonl

물론 실제 운영에서는 GPU, API 키, 모델 크기, 데이터 품질 같은 현실 문제가 따라온다.
하지만 구조 자체는 이 한 줄에 담겨 있다.

로그는 공장 CCTV다

긴 작업은 백그라운드에서 돈다.

그래서 화면에 아무것도 안 나온다고 멈춘 게 아니다.
로그를 봐야 한다.

tail -f saves/ft_<timestamp>/logs/pipeline.log

결과는 세션 폴더에 모인다.

saves/ft_<timestamp>/
  logs/pipeline.log
  autotune/results.tsv
  autotune/current.yaml
  adapter/
  merged/
  serve_ports.json
  eval_results/.../comparison_report.md

이 구조가 좋다.

실험을 한 번 할 때마다 독립된 상자가 생긴다.
오늘 실험과 어제 실험이 섞이지 않는다.
나중에 “그때 어떤 설정으로 돌렸지?”를 추적할 수 있다.

AI 실험에서 재현성은 사치가 아니다.
안전벨트다.

이 데모에서 가장 마음에 드는 점

나는 이 데모의 핵심이 “자동화”보다 “전체 생애주기”에 있다고 본다.

LLM 프로젝트는 종종 한 장면만 과장된다.

“모델을 학습했습니다!”
“성능이 좋아졌습니다!”
“서빙됩니다!”

하지만 실제로 중요한 건 그 사이의 연결이다.

  • 소스 코드는 어디서 왔는가?
  • 환경은 깨끗한가?
  • 어떤 학습 설정을 썼는가?
  • 왜 그 설정이 선택됐는가?
  • 모델은 실제 API로 떠 있는가?
  • base 모델과 비교했는가?
  • 결과 리포트가 남았는가?
  • 다음 사람이 같은 실험을 다시 볼 수 있는가?

llm-forge는 이 질문들을 한 줄로 이어준다.

그게 좋다.

모델 학습은 마법쇼처럼 보이기 쉽지만, 운영 가능한 AI 플랫폼은 마법보다 공정표에 가깝다.
입고, 조립, 검수, 출고, 품질 리포트가 있어야 한다.

초보자가 딱 이것만 기억하면 된다

첫째, Fine-tuning은 모델에게 회사 업무를 추가 교육하는 것이다.

둘째, LoRA는 전체 교과서를 다시 쓰지 않고 보충 노트만 만드는 방식이다.

셋째, AutoTune은 좋은 학습 설정을 찾는 코치다.

넷째, Gateway는 서로 다른 AI API를 연결하는 통역사다.

다섯째, vLLM은 모델을 API 상담원으로 띄우는 콜센터다.

여섯째, Judge는 base 모델과 FT 모델의 답변을 채점하는 시험 감독이다.

일곱째, 최종 목표는 “학습했다”가 아니라 “좋아졌다는 증거를 리포트로 남겼다”다.

마무리: AI 모델을 굽는 작은 빵집

llm-forge를 보고 있으면 작은 빵집이 떠오른다.

Base 모델은 기본 반죽이다.
학습 데이터는 레시피다.
AutoTune은 오븐 온도를 맞추는 제빵사다.
LoRA는 특별한 토핑이다.
vLLM은 진열대다.
Judge는 시식단이다.
comparison report는 오늘의 품질표다.

중요한 건 “빵을 구웠다”가 아니다.

같은 재료로 다시 구울 수 있는가.
어떤 온도로 구웠는지 남아 있는가.
어제 빵보다 오늘 빵이 나아졌는지 설명할 수 있는가.

LLM도 마찬가지다.

멋진 데모는 모델 하나를 띄우는 데서 끝나지 않는다.
처음 코드 받기부터 마지막 비교 리포트까지, 전체 흐름이 다시 실행 가능해야 한다.

그게 llm-forge 데모가 보여주는 가장 실용적인 메시지다.

AI는 마법처럼 보일 수 있다.
하지만 좋은 AI 플랫폼은 마법을 공정으로 바꾸는 일에서 시작한다.