지난번엔 open ai의 api server를 빌려 gpt 3 turbo 모델을 파인튜닝해 본 적이 있는데, 이번에는 hugging space에 나와있는 여러 오픈 LLM 모델을 을 파인 튜닝 할 수 있게 하는 Unsloth을 활용하여 LLM을 파인튜닝 해보려고 한다. 작업은 google colab에서 실행시켜 보았다.
Unsloth AI - Open Source Fine-tuning & RL for LLMs
Open source fine-tuning & reinforcment learning (RL) for Llama 4, DeepSeek-R1, Qwen3, Gemma 3 and Mistral LLMs! Beginner friendly.
unsloth.ai
Unsloth 은 Llama, Falcon 등 대형 언어 모델을 30배는 빠르고, 10%의 정확도를 향상시켜서 파인튜닝할 수 있는 라이브러리라고 소개한다. 사이트에 들어가면 사용했을 때 이점이 잘 나와있어서 자세히는 적진 않겠지만 파이토치 모델의 연산 과정을 최적화하여서 속도와 메모리를 개선했다고 한다.
GitHub - unslothai/unsloth: Fine-tuning & Reinforcement Learning for LLMs. 🦥 Train Qwen3, Llama 4, DeepSeek-R1, Gemma 3, TTS
Fine-tuning & Reinforcement Learning for LLMs. 🦥 Train Qwen3, Llama 4, DeepSeek-R1, Gemma 3, TTS 2x faster with 70% less VRAM. - unslothai/unsloth
github.com
이번 목표는 IMDB 영화 리뷰 데이터셋을 활용해서 텍스트 생성하는 모델을 만드는 것이다.
stanfordnlp/imdb · Datasets at Hugging Face
WARNING: This review contains SPOILERS. Do not read if you don't want some points revealed to you before you watch the film. With a cast like this, you wonder whether or not the actors and actresses knew exactly what they were getting into. Did they see th
huggingface.co
imdb는 영화관련 리뷰를 모아 둔 것인데, 여기서는 text 데이터만 학습시켜서 내가 어떤 리뷰를 작성하면 모델은 학습된 내용을 기반으로 그 스타일에 맞게 리뷰를 완성키켜주는 작업을 완성할 것이다.

Base model은 Mistral-7B 모델로 LoRA 방식으로 파인튜닝할 것이다
- 환경 설정: 필요한 라이브러리 설치
- 모델 및 데이터셋 로드: 사전 학습된 모델과 IMDb 데이터셋 가져오기
- LoRA(Peft) 설정: 파인튜닝 시 필요한 adapter 레이어 추가
- 트레이너 설정: 파인튜닝 설정 정의 및 학습 시작
- 모델 테스트: 파인튜닝된 모델로 문장 생성 테스트
# 환경 설정: 필요한 라이브러리 설치
!pip install "unsloth[colab] @git+https://github.com/unslothai/unsloth.git"
!pip install "git+https://github.com/huggingface/transformers.git"
!pip install trl
Unsloth을 사용해서 Hugging face 모델을 4bit 나 8bit로 효율적으로 로드하고 파인튜닝이 가능하다. trl은 SFTTrainer 같은 강화 학습 툴을 제공한다.
# IMDb 데이터셋: 영화 리뷰 데이터셋. split="train"으로 훈련 데이터만 사용.
dataset = load_dataset("imdb", split="train")
# 4bit 양자화된 Mistral-7B 모델 사용
# 모델이 한 번에 처리할 수있는 최대 입력 길이
max_seq_length = 2048
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/mistral-7b-bnb-4bit", # base 모델
max_seq_length=max_seq_length,
dtype=None,
load_in_4bit=True #GPU 메모리 절약
)
FastLanguageModel은 Unsoloth 라이브러리에서 제공하는 클래스로, Hugging face 모델을 더 가볍게 사용할 수 있도록 해준다. 여기에는 양자화, Peft 라이브러리를 붙여서 파인튜닝해 주는 등의 기능이 들어가 있다.
model = FastLanguageModel.get_peft_model(
model,
r=16, # 원래 모델 행렬 대신, 작은 행렬을 추가 학습하는 개념
target_modules=["q_proj", "k_proj", "v_proj", "gate_proj", "up_proj", "down_proj"],
lora_alpha=16,
lora_dropout=0,
bias="none",
use_gradient_checkpointing=True,
random_state=3407,
max_seq_length=max_seq_length
)
- r=16
- r가 클수록 학습 성능↑, 메모리/속도↓
- target_modules
- LoRA가 삽입될 모델 내부 레이어 지정.
- q_proj, k_proj, v_proj 등은 Transformer의 핵심인 Attention 부분.
- 여기만 수정하면 모델의 대부분 성능을 잡아냄. 나머지는 그대로 냅둬도 됨.
- lora_alpha=16
- LoRA의 스케일링 계수.
- LoRA의 결과를 얼마나 크게 모델에 적용할지 비율 조정.
- α가 클수록 학습 영향력↑
- lora_dropout=0
- LoRA 레이어의 드롭아웃 비율.
- 일반적으로 파인튜닝 시 regularization 효과 위해 0~0.1 사용 가능.
- 여기선 작은 데이터셋이라 과적합 방지를 안 해서 0으로 둠.
- bias="none"
- 기존 모델의 bias 항은 LoRA 학습에서 제외.
- 이유: bias까지 건드릴 필요 없이 성능을 충분히 올릴 수 있음.
- use_gradient_checkpointing=True
- 메모리 절약 옵션.
- 계산 그래프 일부를 저장하지 않고 다시 계산해서 메모리 사용량↓
- 속도는 조금 느려지지만 작은 GPU에서도 학습 가능.
- random_state=3407
- 랜덤 시드 고정 (재현성 확보)
- max_seq_length
- 위에서 설명한 것처럼 한 번에 처리할 최대 토큰 수.
트레이너 설정 후 학습 시작
trainer = SFTTrainer(
model=model,# base model(FastLanguageModel.get_peft_model()로 만든 모델 객체)
train_dataset=dataset, # imdb dataset
dataset_text_field="text", # text 만 뽑아서
max_seq_length=max_seq_length, # 한 번에 처리할 최대 토큰 길이 (앞서 말한 2048)
tokenizer=tokenizer, # 모델 입력을 토큰화할 Hugging Face 토크나이저.
args=TrainingArguments(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
warmup_steps=10,
fp16=not torch.cuda.is_bf16_supported(),
bf16=torch.cuda.is_bf16_supported(),
logging_steps=1,
output_dir="unsloth-test", # 학습 결과 저장 폴더
optim="adamw_8bit", # 양자화된 옵티마이저로 메모리 절약.
seed=3407,
max_steps=50 # 총 학습 스텝 수
)
)
trainer.train()
Supervised Fine-Tuning 은 보통 입력/출력 쌍이 있는 데이터 셋으로 학습을 해야 하는 것이 아닌가 싶었는데 SFT는 사전학습된 언어모델 위에 특정 태스크를 지도학습시켜서 대부분의 경우 "입력텍스트 -> 다음 토큰 예측" 같은 방식으로 동작한다고 한다.
두 가지 SFT 유형
| 유형 | 설명 | 예시 |
| Sequence → Sequence | 입력/출력 쌍이 있는 데이터셋으로 학습 | 번역(영어 → 한국어), 요약 등 |
| Causal LM | 입력 텍스트 하나로 다음 토큰을 예측하는 방식 | 영화리뷰 → 다음 단어 생성 |
| 입력 시퀀스 | 목표 (예측할 토큰) |
| This | movie |
| This movie | was |
| This movie was | amazing |
| This movie was amazing . | The |
| ... | ... |
덧붙이면 학습 데이터셋이 텍스트만 있는 경우, 모델은 이 텍스트 자체를 입력(input)과 정답(label)으로 사용한다. 즉 데이터를 shift 시켜서 입력과 정답을 스스로 만드는 셈이다. 이런 과정을 통해서 모델은 전체 문장을 재생산할 수 있도록 weight를 미세조정되고 영화 리뷰 텍스트의 문제, 단어 선택, 표현 패턴을 학습한다.
이야기가 조금 셋는데 아무튼 트레이닝을 시작하면 아래 처럼 step 이 올라갈 수록 loss 가 줄어 드는 것을 확인할 수 있었다.

파인 튜닝 모델로 문장 생성 테스트
inputs = tokenizer(
["I really like the movie because it talks about humanity and shows human emotions"],
return_tensors="pt"
).to("cuda")
outputs = model.generate(**inputs, max_new_tokens=128, use_cache=True)
tokenizer.batch_decode(outputs)
입력 "I really like the movie because it talks about humanity and shows human emotions" 이것을 토큰화 시킨다. model 은 GPU에 로드되어 있기 때문에 토큰화된 입력 데이터(CPU)도 같은 GPU에 있어야 되기 때문에. to("cuda") 호출한다. 입력 데이터는 CPU, 모델은 GPU에 두면 CPU와 GPU 사이의 메모리 전송 때문에 속도가 엄청 느려진다.

outputs을 찍어보면 아래와 같은 형태로 출력이 되기 때문에 입력 텍스트를 토큰화하고 model.generate로 텍스트를 생성해야 한다. 생성된 토큰을 텍스르로 디코딩하기 위해서 batch_decode를 하면 아래와 같이 human emotion 다음 문장을 파인 튜닝된 모델이 맞게 생성해 주었다.


정리하면, 파인튜닝 이전의 Mistral-7B는 다양한 일반 언어 데이터셋으로 사전학습되어 영화 리뷰에 특화된 모델은 아니었다. 하지만 파인튜닝을 거친 후에는 영화 감상평과 비슷한 스타일의 텍스트를 자연스럽게 생성할 수 있도록 조정되었다!
'인공지능 > 직접 해보기' 카테고리의 다른 글
| 프롬프팅 구체적으로 작성하는 방법 (0) | 2025.07.03 |
|---|---|
| 대규모 언어 모델(LLM) 양자화해보기 (0) | 2025.06.27 |
| 데이터 추출 시스템 만들어보기 (0) | 2025.06.26 |
| 일론 머스크 트윗 생성 챗봇 개발기: Fine-tuning부터 LangSmith (1) | 2025.06.26 |
| GPT turbo 3 모델로 파인튜닝 해본썰 (0) | 2025.06.25 |