토니의 연습장
LLM train/eval/generate 간단한 예시 본문
train 하면서 주기적으로 evaluation 하고 sample text 를 generation
학습하면서 수치적 평가를 병행하며, 동시에 생성 샘플을 통해 성능을 직관적으로 확인해 볼 수 있게 함
def train_model_simple(model, train_loader, val_loader, optimizer, device, num_epochs,
eval_freq, eval_iter, start_context, tokenizer):
# Initialize lists to track losses and tokens seen
train_losses, val_losses, track_tokens_seen = [], [], []
tokens_seen, global_step = 0, -1
# Main training loop
for epoch in range(num_epochs):
model.train() # Set model to training mode
for input_batch, target_batch in train_loader:
optimizer.zero_grad() # Reset loss gradients from previous batch iteration
loss = calc_loss_batch(input_batch, target_batch, model, device)
loss.backward() # Calculate loss gradients
optimizer.step() # Update model weights using loss gradients
tokens_seen += input_batch.numel()
global_step += 1
# Optional evaluation step
if global_step % eval_freq == 0:
train_loss, val_loss = evaluate_model(
model, train_loader, val_loader, device, eval_iter)
train_losses.append(train_loss)
val_losses.append(val_loss)
track_tokens_seen.append(tokens_seen)
print(f"Ep {epoch+1} (Step {global_step:06d}): "
f"Train loss {train_loss:.3f}, Val loss {val_loss:.3f}")
# Print a sample text after each epoch
generate_and_print_sample(
model, tokenizer, device, start_context
)
return train_losses, val_losses, track_tokens_seen
def evaluate_model(model, train_loader, val_loader, device, eval_iter):
model.eval()
with torch.no_grad():
train_loss = calc_loss_loader(train_loader, model, device, num_batches=eval_iter)
val_loss = calc_loss_loader(val_loader, model, device, num_batches=eval_iter)
model.train()
return train_loss, val_loss
def generate_and_print_sample(model, tokenizer, device, start_context):
model.eval()
context_size = model.pos_emb.weight.shape[0]
encoded = text_to_token_ids(start_context, tokenizer).to(device)
with torch.no_grad():
token_ids = generate_text_simple(
model=model, idx=encoded,
max_new_tokens=50, context_size=context_size
)
decoded_text = token_ids_to_text(token_ids, tokenizer)
print(decoded_text.replace("\n", " ")) # Compact print format
model.train()
1. evaluate_model
- 목적: 손실(loss) 계산
모델이 현재 학습 상황에서 얼마나 잘 맞추는지, 학습/검증 데이터셋 일부(eval_iter 배치)로 평균 손실값을 구한다. - 동작:
- calc_loss_loader를 이용해서 train_loader와 val_loader에서 각각 일정 수의 배치를 꺼내 손실 평균을 계산.
- 학습을 멈추고(eval()), 그래디언트 추적 끄고(no_grad()), 평가 끝난 후 다시 train()으로 돌려놓음.
- 출력: 숫자 2개 → (train_loss, val_loss).
즉, 지표 계산용 함수.
2. generate_and_print_sample
- 목적: 텍스트 생성
현재까지 학습된 모델로, 지정한 시작 문맥(start_context)에 이어지는 텍스트를 만들어서 출력. - 동작:
- 시작 문맥을 토크나이즈 후 디바이스로 올림.
- generate_text_simple로 최대 50개 토큰을 새로 생성.
- 이를 디코딩해서 사람이 읽을 수 있는 문자열로 변환.
- 출력 시 줄바꿈을 공백으로 바꿔 한 줄로 보기 좋게 만듦.
- 출력: 실제 문자열 (콘솔에 찍힘).
즉, 샘플 확인용 함수.
차이 요약
항목 | evaluate_model | generate_and_print_sample |
목적 | 손실 측정(성능 평가) | 텍스트 생성(샘플 확인) |
입력 데이터 | train_loader, val_loader (배치 단위 데이터셋) | start_context (텍스트 문자열) |
출력 | 평균 손실 값 (숫자 2개) | 생성된 텍스트 (문자열, 콘솔 출력) |
사용 시점 | 주기적 성능 모니터링 | 에폭 종료 시 모델이 “언어”를 얼마나 배웠는지 감각적으로 확인 |
결과 활용 | 학습 곡선/조기 종료 판단 | 질적 평가(샘플 문장 자연스러움 등) |
- evaluate_model은 수치적 평가를 해주는 함수,
- generate_and_print_sample은 질적(텍스트) 샘플링을 보여주는 함수.
둘을 합쳐 쓰면, “숫자로도 확인 + 실제 출력물로도 확인”하면서 학습 과정을 점검할 수 있음.
'AI 일반 > 모델, 아키텍처, 구현' 카테고리의 다른 글
GPT/Llama 아키텍처 (0) | 2025.09.18 |
---|---|
RLHF / DPO (ft. Pretrained -> SFT -> Reward -> Final model) (0) | 2025.09.05 |
실무에서의 Embedding 모델 종류 (Text Embedding) (0) | 2025.07.17 |
Transformer vs LLaMA 모델 비교 (0) | 2025.06.17 |
pytorch 구현함수 내부 (0) | 2025.06.17 |