파인튜닝 전에 먼저 해 볼 일
파인튜닝을 시작하기 전에 먼저 해야 할 일은 모델을 불러와 직접 답변을 생성해 보는 것이다. 이 단계에서 모델, 토크나이저, 프롬프트, 생성 파라미터가 어떻게 연결되는지 이해하면 이후 학습 과정도 훨씬 쉽게 따라갈 수 있다.
Unsloth는 FastLanguageModel.from_pretrained()로 모델과 토크나이저를 함께 불러온다. Hugging Face 모델 ID를 사용할 수도 있고, 나중에 학습 후 저장한 로컬 경로를 사용할 수도 있다. 공식 예제에서도 model_name="lora_model"처럼 학습한 모델 경로를 넣어 다시 불러오는 흐름을 보여 준다.1
AI 생성 이미지
모델과 토크나이저 불러오기
처음 실습에서는 작은 Instruct 모델을 고르는 편이 안전하다. 아래 예시는 4bit로 모델을 불러와 GPU 메모리 사용량을 줄인다. Hugging Face 통합 문서에서도 같은 방식으로 FastLanguageModel.from_pretrained()가 모델과 토크나이저를 함께 반환하는 예시를 제공한다.2
from unsloth import FastLanguageModel
max_seq_length = 2048
dtype = None
load_in_4bit = True
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/Llama-3.2-1B-Instruct",
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
)여기서 max_seq_length는 모델이 한 번에 읽을 수 있는 최대 토큰 길이다. 값이 클수록 긴 문맥을 처리할 수 있지만 VRAM을 더 많이 쓴다. dtype은 연산 정밀도다. 처음에는 None으로 두면 환경에 맞게 처리되는 경우가 많다. load_in_4bit=True는 모델 가중치를 4bit로 불러와 제한된 GPU에서도 첫 추론을 시도하기 좋다.
학습 후 저장한 LoRA 모델을 테스트할 때는 model_name만 바꾸면 된다.
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "lora_model",
max_seq_length = 2048,
dtype = None,
load_in_4bit = True,
)추론 모드로 전환하기
모델을 불러온 직후에는 추론 모드로 바꿔야 한다. Unsloth 공식 문서는 FastLanguageModel.for_inference(model)을 호출해 더 빠른 네이티브 추론을 활성화하는 흐름을 안내한다.1
FastLanguageModel.for_inference(model)이 한 줄은 학습이 아니라 응답 생성을 위한 상태로 모델을 준비한다. 이후에는 일반적인 Transformers 방식처럼 토큰화한 입력을 model.generate()에 넣어 답변을 만든다.
프롬프트를 모델 형식에 맞추기
Instruct 또는 Chat 모델은 단순한 문자열보다 대화 형식을 선호한다. system, user, assistant 같은 역할을 모델이 학습한 구조에 맞게 넣어야 답변이 안정된다. 그래서 가능하면 토크나이저의 채팅 템플릿을 사용한다.
messages = [
{"role": "system", "content": "너는 친절하고 간결하게 답하는 한국어 AI 도우미다."},
{"role": "user", "content": "Unsloth를 한 문단으로 설명해 줘."},
]
inputs = tokenizer.apply_chat_template(
messages,
tokenize = True,
add_generation_prompt = True,
return_tensors = "pt",
).to("cuda")토크나이저는 사람이 쓴 문장을 모델이 읽을 수 있는 숫자 토큰으로 바꾼다. 반대로 모델이 만든 토큰을 다시 문장으로 바꾸는 역할도 한다. 모델과 토크나이저가 맞지 않으면 특수 토큰이나 대화 경계가 어긋나 답변 품질이 떨어질 수 있다.
첫 응답 생성하기
이제 generate()로 답변을 만든다. 공식 문서에서는 선택적으로 TextStreamer를 사용해 생성되는 문장을 실시간으로 출력하는 예시를 보여 준다.1
from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer, skip_prompt = True)
_ = model.generate(
input_ids = inputs,
streamer = text_streamer,
max_new_tokens = 128,
temperature = 0.7,
top_p = 0.9,
do_sample = True,
)max_new_tokens는 새로 생성할 답변의 최대 길이다. 짧은 테스트는 64~128 정도면 충분하다. temperature는 무작위성을 조절한다. 낮추면 안정적이고 비슷한 답변이 나오며, 높이면 다양한 표현이 나온다. top_p는 다음 토큰 후보를 어느 범위까지 고려할지 정한다. 첫 추론에서는 temperature=0.7, top_p=0.9 정도로 시작하고, 정확한 답변이 중요하면 값을 낮춰 비교한다.
첫 실습에서 확인할 것
첫 추론의 목표는 좋은 답변 하나를 얻는 것이 아니다. 모델이 정상적으로 로드되는지, 토크나이저가 함께 작동하는지, 채팅 템플릿이 맞는지, 생성 파라미터를 바꾸면 응답이 어떻게 달라지는지 확인하는 것이다.
응답이 너무 길면 max_new_tokens를 줄인다. 답변이 산만하면 temperature를 낮춘다. GPU 메모리가 부족하면 load_in_4bit=True인지 확인하고, 더 작은 모델을 선택하거나 max_seq_length를 줄인다. 이 흐름을 익히면 다음 단계인 데이터셋 준비와 LoRA 파인튜닝에서 무엇을 바꾸고 무엇을 유지해야 하는지 분명해진다.
참고
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.