우리는 클로드에게 오픈소스 대규모 언어 모델(LLM)을 미세 조정하도록 했습니다.
Hugging Face Skills Training & LLM 파인튜닝 실습 노트
학습 목표
이 노트에서는 Hugging Face 블로그의 "We Got Claude to Fine-Tune an Open Source LLM" 글의 주제(강력한 LLM을 활용해 오픈소스 LLM을 파인튜닝하는 워크플로)1와 Hugging Face LLM 코스에서 제시하는 LLM 활용 흐름2을 참고해, 다음을 직접 실습할 수 있도록 정리합니다.
Hugging Face 생태계(Transformers, Datasets, Hub)를 이용해 LLM을 파인튜닝하는 전체 흐름 이해하기2
강력한 상용/클라우드 LLM(예: Claude, GPT 등)을 "데이터 생성기"로 활용해서 오픈소스 LLM용 학습 데이터를 만드는 아이디어 이해/적용하기1
작은 오픈소스 LLM을 내 데이터(또는 합성 데이터)로 SFT(Supervised Fine-Tuning) 해보기
파인튜닝한 모델을 로컬에서 추론해보고, Hugging Face Hub에 공유하는 과정까지 따라가기2
위 과정에서 얻은 교훈을 10개의 핵심 개념으로 정리하기
사전 지식
다음 정도의 배경지식을 가정합니다.
파이썬: 함수, 클래스, 패키지 임포트, venv/conda 중 하나 사용 가능
기본 딥러닝 개념:
"사전학습된(Pretrained) 모델에 내 데이터를 조금 더 학습시키는 것이 파인튜닝"이라는 정도
손실(loss) 감소, 에폭(epoch), 배치(batch) 등의 용어
Hugging Face 기초:
transformers,datasets를 pip로 설치해본 경험이 있으면 좋음2기본적인 Jupyter Notebook 또는 Google Colab 사용 능력
LLM 개념 (간단히라도 알고 있으면 좋음)2
토크나이저 → 토큰 → 모델 입력/출력
인스트럭션/채팅 형식 프롬프트("사용자 질문 → 모델 답변" 구조)
실습 1: 합성 데이터로 LLM 파인튜닝 워크플로 따라해보기 [기초]
목표: Claude 같은 강력한 LLM을 이용해 "질문-답변 데이터셋"을 만든다고 가정하고, 그 데이터를 사용해 작은 오픈소스 LLM을 Hugging Face에서 파인튜닝하는 전체 틀을 실습합니다. (실제 Claude API 호출 코드는 계정/키마다 다르므로, 여기서는 "이미 만들어진 JSONL/CSV"를 사용한다고 가정합니다.)
1. 환경 준비 및 라이브러리 설치
Colab 또는 로컬(가상환경 추천)에서 다음을 실행합니다.
pip install "transformers>=4.45.0" "datasets>=3.0.0" "accelerate>=1.0.0"
"trl>=0.11.0" peft bitsandbytestransformers: 모델/토크나이저 로딩, 추론, 파인튜닝datasets: 학습/검증용 데이터셋 관리2trl: LLM용 SFT/강화학습 툴킷 (SFTTrainer 등)peft,bitsandbytes: LoRA+저정밀(4bit/8bit) 파인튜닝을 쉽게 하기 위한 라이브러리
체크포인트
import transformers, datasets, trl, peft, bitsandbytes
print(transformers.__version__)에러 없이 버전이 출력되면 준비 완료입니다.
2. (가정) Claude로 생성한 합성 데이터 불러오기
Claude에게 "프로그래밍/ML 관련 Q&A, 튜토리얼, 코드 리뷰 예제" 등 다양한 질문-답변 쌍을 생성하도록 프롬프트를 잘 설계해 JSONL 형식으로 저장했다고 가정합니다. 이 합성 데이터가 "오픈소스 LLM에 주입할 고품질 인스트럭션 데이터" 역할을 합니다. (블로그의 핵심 아이디어와 유사한 방식입니다1.)
예시 형식(data/claude_sft_data.jsonl):
{"instruction": "파이썬에서 리스트와 튜플의 차이점을 설명해줘.", "response": "리스트는 변경 가능(mutable)..."}
{"instruction": "PyTorch에서 DataLoader를 사용하는 예제를 보여줘.", "response": "..."}
...이를 Hugging Face datasets로 불러옵니다.
from datasets import load_dataset
dataset = load_dataset("json", data_files="data/claude_sft_data.jsonl")["train"]
print(dataset[0])체크포인트
{'instruction': "...", 'response': "..."}와 비슷한 dict 출력 확인데이터 개수:
len(dataset)등으로 확인
3. 채팅/인스트럭션 템플릿 정의
LLM은 단순히 instruction와 response를 분리해서 주는 것이 아니라, 하나의 "프롬프트 문자열"로 학습하는 경우가 많습니다2. 예를 들어 아래처럼 간단한 템플릿을 사용합니다.
def format_example(example):
user = example["instruction"].strip()
assistant = example["response"].strip()
prompt = f"""### User:
{user}
### Assistant:
{assistant}"""
return {"text": prompt}
dataset = dataset.map(format_example)
print(dataset[0]["text"])이제 dataset에는 {"text": "...전체 프롬프트+정답..."} 필드가 생겼습니다.
4. 사전학습된 오픈소스 LLM 불러오기
Hugging Face Hub에서 작은 인스트럭션 튜닝용 모델(예: 1~3B 파라미터)을 선택합니다. (예시 모델 이름은 가상의 플레이스홀더 대신, 여러분이 직접 Hub에서 골라 쓰는 것을 권장합니다.)
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "또는-여기에-원하는-llm-모델이름"
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
model = AutoModelForCausalLM.from_pretrained(
model_name,
load_in_4bit=True, # bitsandbytes 활용 (GPU 메모리 절약)
device_map="auto"
)토크나이저는
chat template을 지원할 수도 있지만, 여기선 우리가 직접 문자열을 만들었으니 단순 텍스트로 사용해도 됩니다.load_in_4bit=True는 GPU 메모리가 작을 때 LoRA 파인튜닝에 유용합니다.
5. SFTTrainer로 파인튜닝 실행
trl.SFTTrainer를 사용하면 "텍스트 생성 모델에 대해, 주어진 텍스트를 그대로 예측하도록 지도학습"을 매우 간단히 구현할 수 있습니다.
from trl import SFTTrainer
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir="hf-skills-claude-sft",
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
learning_rate=2e-4,
num_train_epochs=1,
logging_steps=10,
save_steps=100,
bf16=True, # 지원되는 GPU일 때 권장
report_to="none"
)
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=1024,
args=training_args,
packing=True, # 여러 샘플을 한 시퀀스로 패킹해 효율↑
)
trainer.train()예상 결과
콘솔에
loss가 찍히면서 학습이 진행에폭이 끝나면
hf-skills-claude-sft폴더 아래에 체크포인트 및 최종 모델 가중치 저장
6. 파인튜닝된 모델 저장 및 로드
trainer.save_model("hf-skills-claude-sft-final")
tokenizer.save_pretrained("hf-skills-claude-sft-final")다시 불러서 테스트할 수 있습니다.
from transformers import pipeline
pipe = pipeline(
"text-generation",
model="hf-skills-claude-sft-final",
tokenizer="hf-skills-claude-sft-final",
device_map="auto"
)
prompt = """### User:
파이썬에서 제너레이터(generator)가 무엇인지 예제를 들어 설명해줘.
### Assistant:
"""
out = pipe(prompt, max_new_tokens=256, do_sample=True, temperature=0.7)
print(out[0]["generated_text"])체크포인트
Claude로 만든 데이터의 "톤/스타일"이 어느 정도 반영된 답변이 나오는지 확인
특정 도메인(예: 개발 질문)에 더 잘 대답하는지 비교
실습 2: 내 데이터 + 합성 데이터로 LLM 개선하기 [응용]
목표: 실습 1에서 만든 합성 데이터에, 사용자의 실제 데이터(사내 FAQ, 코드 리뷰 코멘트, 교육 자료 등)를 섞어서, 더 실무 친화적인 LLM을 만드는 과정을 연습합니다.
1. 내 도메인 데이터 준비
형식은 Claude 합성 데이터와 비슷하게 맞추는 것이 좋습니다.
예시(data/my_domain_data.jsonl):
{"instruction": "우리 팀 git 브랜치 전략 요약해줘.", "response": "우리 팀은 main/develop/feature 브랜치를 사용하며..."}
{"instruction": "사내 쿠버네티스 클러스터에 새 서비스 배포하는 절차를 알려줘.", "response": "1. GitLab에 MR 생성, 2. CI 파이프라인 확인..."}로드:
my_data = load_dataset("json", data_files="data/my_domain_data.jsonl")["train"]
my_data = my_data.map(format_example) # 앞에서 정의한 format_example 재사용2. 합성 데이터 + 내 데이터 합치기
from datasets import concatenate_datasets
full_train = concatenate_datasets([dataset, my_data]).shuffle(seed=42)
print(len(dataset), len(my_data), len(full_train))필요하면, 비율을 조정(예: 합성:내 데이터 = 3:1)해서 "회사 특화 지식"이 과도하게 왜곡되지 않도록 합니다.
3. 재파인튜닝(또는 추가 파인튜닝)
이미 SFT된 모델이 있다면, 그 모델에서 이어서 학습하거나, 처음부터 full_train으로 SFT를 수행할 수 있습니다.
model = AutoModelForCausalLM.from_pretrained(
"hf-skills-claude-sft-final", # 1단계 결과 모델
load_in_4bit=True,
device_map="auto"
)
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=full_train,
dataset_text_field="text",
max_seq_length=1024,
args=training_args,
packing=True,
)
trainer.train()
trainer.save_model("hf-skills-claude-sft-with-domain")
tokenizer.save_pretrained("hf-skills-claude-sft-with-domain")4. 결과 비교
동일한 프롬프트에 대해:
기본 사전학습 모델
합성 데이터만으로 SFT된 모델
합성 + 내 데이터로 SFT된 모델
3가지를 번갈아 호출하면서, 실제 쓸만한 답변을 내는지, 회사 규칙/도메인 용어를 잘 반영하는지 비교해보세요.
간단한 비교 예제:
test_prompt = """### User:
우리 팀 git 브랜치 전략 설명해줘.
### Assistant:
"""
for ckpt in [
model_name,
"hf-skills-claude-sft-final",
"hf-skills-claude-sft-with-domain"
]:
pipe = pipeline("text-generation", model=ckpt, tokenizer=tokenizer, device_map="auto")
out = pipe(test_prompt, max_new_tokens=256)[0]["generated_text"]
print(f"\n=== 모델: {ckpt} ===\n{out}\n")도전 과제
템플릿 바꾸기
현재 템플릿은 매우 단순합니다. Hugging Face의 chat template 문서를 참고해서 ChatML 등 다른 형식으로 바꿔보세요2.
같은 데이터라도 템플릿에 따라 모델의 대화 스타일이 달라지는지 비교해보세요.
데이터 품질 실험
일부 샘플의
response를 일부러 부정확하게 만들고, 그 데이터를 포함/제외했을 때 성능 차이를 관찰해보세요.Claude(또는 다른 LLM)를 "품질 검수자(judge)"로 사용해, 낮은 점수를 받은 샘플을 제거한 뒤 다시 파인튜닝 해보면 어떤지 실험해도 좋습니다.
작은 모델 vs 큰 모델
1B / 3B / 7B 등 서로 다른 크기의 오픈소스 LLM에 같은 데이터를 학습시켜 보고,
질/속도/자원 사용량의 트레이드오프를 정리해보세요.
Hugging Face Hub에 올리기
trainer.push_to_hub()또는model.push_to_hub()를 사용해 모델을 Hub에 업로드하고2,Gradio Space를 만들어 웹 데모까지 연결해보면, 블로그 글에서 말하는 "모델 공유 및 데모화" 과정과 유사한 경험을 할 수 있습니다.
HF Skills Training & LLM 파인튜닝 핵심 내용 10가지
아래 10가지는 "We Got Claude to Fine-Tune an Open Source LLM"의 주제(강력한 상용 LLM을 활용해 오픈소스 LLM을 훈련하는 스킬 트레이닝)와, Hugging Face LLM 코스에서 설명하는 LLM 활용 흐름12을 바탕으로 정리한 핵심 개념입니다.
강력한 LLM을 "교사 모델"로 활용하기
Claude 같은 상용 LLM은 이미 고품질 능력을 갖춘 모델입니다.
이를 이용해 합성 인스트럭션 데이터를 만들고, 더 작은 오픈소스 LLM을 가르치는 "지식 distillation/스킬 트레이닝"을 할 수 있습니다.
오픈소스 LLM은 "학생 모델"로 사용
학생 모델은 파라미터 수가 작고, 비용이 저렴하며, 온프레미스/프라이빗 환경에 배포하기 쉬운 장점이 있습니다.
Claude가 생성한 높은 품질의 예시를 지도 데이터로 삼아, 학생 모델이 실제로 그 스킬을 모방하도록 파인튜닝합니다.
데이터 품질이 모델 품질을 결정
같은 모델 구조라도, Claude가 생성한 답변이 얼마나 명확하고, 사실에 근거하고, 일관된 스타일을 가지고 있는지가 파인튜닝 후 성능에 직결됩니다.
"나쁜 데이터를 많이" 주는 것보다, "좋은 데이터를 적당히" 주는 것이 훨씬 낫습니다.
인스트럭션 포맷과 채팅 템플릿의 중요성2
instruction,input,response를 어떤 문자열 포맷으로 합칠지(예: ChatML, Alpaca, 자체 포맷)가 매우 중요합니다.훈련 시에 사용한 형식을 추론 시에도 그대로 사용해야 모델이 제대로 동작합니다.
LoRA + 저정밀(4bit/8bit) 파인튜닝으로 비용 절감
전체 모델 파라미터를 모두 업데이트하는 대신, LoRA/PEFT로 소수의 어댑터만 학습하면,
랩톱/Colab 수준의 GPU에서도 1~3B 모델을 충분히 실습해볼 수 있습니다.
SFT(지도 미세조정)로 "도우미 스타일" 주입2
SFT는 모델에게 "이런 질문에는 이렇게 답하는 것이 좋다"는 패턴을 학습시키는 과정입니다.
Claude가 보여주는 답변 스타일(체계적인 설명, 단계별 가이드, 안전한 발화 등)을 학생 모델에 전이할 수 있습니다.
평가(Eval) 루틴을 미리 설계하기
파인튜닝 전/후에
동일한 질문 집합에 대해 답변을 비교하고,
사람이 직접 눈으로 평가하거나 간단한 스코어링 함수를 설계하는 것이 중요합니다.
그렇게 해야 "스킬 트레이닝이 실제로 도움이 되었는지"를 객관적으로 판단할 수 있습니다.
도메인 특화 데이터와 합성 데이터의 밸런싱
Claude로 만든 "일반적인 인스트럭션 데이터"와,
회사/프로젝트에 특화된 "도메인 데이터"를 적절히 섞어야 합니다.
일반 능력 + 도메인 지식 두 축을 모두 고려해야 실용적인 모델이 됩니다.
Hugging Face Hub를 통한 재사용/공유2
학습한 모델을 Hub에 올려두면,
다른 팀원이
from_pretrained한 줄로 재사용할 수 있고,Spaces(웹 데모), 평가 리더보드 등과 연동하기 쉬워집니다.
학습 경로: 기초 NLP/LLM → 실습 중심 HF 코스2
Hugging Face LLM 코스는 토크나이저, Transformers, Datasets, 데모 공유까지 단계별로 설명합니다.
Claude를 활용한 스킬 트레이닝 같은 실전 과제는, 이 코스(특히 1-4장에서 모델 사용과 파인튜닝, 9장에서 데모 공유)를 따른 후에 진행하면 이해가 훨씬 쉽습니다.
자가 점검
"강력한 LLM(Claude)을 이용해 합성 데이터를 만들고, 오픈소스 LLM을 파인튜닝하는" 전체 아이디어를 다른 사람에게 설명할 수 있는가?
datasets로 JSONL 데이터를 로드하고, 텍스트 템플릿으로 변환해본 경험이 있는가?2SFTTrainer또는Trainer를 이용해 최소 1에폭 이상 LLM 파인튜닝을 완료해봤는가?파인튜닝 전후 모델의 답변을 비교해보고, 무엇이 개선/악화되었는지 기록해보았는가?
Hugging Face Hub에 모델이나 결과를 공유해볼 준비가 되었는가?2
참고
1Hugging Face - Blog 목록 (We Got Claude to Fine-Tune an Open Source LLM 포함) - https://huggingface.co/blog
2Introduction - Hugging Face LLM Course - https://huggingface.co/learn/llm-course/en/chapter1/1
