자연어 처리(NLP) 분야에서 트랜스포머의 등장은 거대한 전환점이 되었습니다. 그 중심에 있는 BERT(Bidirectional Encoder Representations from Transformers)는 구글이 발표한 사전 훈련 기반 모델로, 이미 방대한 텍스트를 학습했기 때문에 적은 데이터만으로도 우리가 원하는 작업에 맞춰 뛰어난 성능을 낼 수 있습니다.
이번 포스팅에서는 허깅페이스(Hugging Face)의 transformers 라이브러리를 활용해, 실제 영화 리뷰 데이터를 바탕으로 긍정과 부정을 분류하는 BERT 미세 조정(Fine-Tuning) 과정을 단계별로 알기 쉽게 살펴보겠습니다.

핵심 요약 3줄
- 트랜스포머 기반의 BERT 모델을 활용해 대표적인 NLP 태스크인 문장 분류 및 감성 분석을 수행합니다.
- Hugging Face 라이브러리를 사용해 토크나이징부터 데이터셋 관리, 모델 로드까지의 파이프라인을 효율적으로 구축합니다.
- PyTorch 환경에서 직접 학습 루프를 제어하며 데이터 로더 구성, 최적화, 최종 성능 평가까지 단계별 코드를 완성합니다.
1. 환경 설정 및 필수 패키지 설치
BERT 모델을 불러오고 데이터를 처리하기 위해 필요한 핵심 라이브러리를 먼저 설치해야 합니다. 터미널이나 주피터 노트북에서 아래 명령어를 실행해 패키지를 준비합니다.
pip install transformers datasets evaluate torch scikit-learn
주요 패키지 역할 안내
| 패키지명 | 주요 역할 | 비고 |
| transformers | 사전 훈련된 BERT 모델 및 토크나이저 제공 | Hugging Face 핵심 라이브러리 |
| datasets | 대규모 NLP 데이터셋의 간편한 로드 및 관리 | 메모리 효율적 데이터 처리 |
| evaluate | 정확도(Accuracy), F1-Score 등 모델 평가 메트릭 제공 | 기존 load_metric 대체 패키지 |
| torch | PyTorch 딥러닝 프레임워크 | 모델 학습 및 텐서 연산 |
| scikit-learn | 머신러닝 평가 지표 연동 및 보조 도구 | evaluate 내부 연산 지원 |
2. IMDB 데이터셋 로드 및 확인
학습에 사용할 데이터는 영화 리뷰로 구성된 유명 감성 분석 데이터셋인 IMDB입니다. 허깅페이스의 datasets 라이브러리를 사용하면 코드 한 줄로 다운로드할 수 있습니다.
from datasets import load_dataset
# IMDB 데이터셋 로드
dataset = load_dataset("imdb")
print(dataset)
데이터셋 구조를 출력해 보면 train과 test로 나뉘어 있고, 각 데이터는 리뷰 본문(text)과 긍정/부정 레이블(label: 긍정 1, 부정 0)을 포함하고 있습니다. 실제 데이터가 어떻게 생겼는지 첫 번째 샘플을 확인해 보겠습니다.
print(dataset["train"][0])
3. BERT 토크나이저 적용
BERT 모델은 일반 텍스트를 그대로 이해할 수 없기 때문에, 모델이 학습한 단위인 '토큰(Token)'으로 문장을 쪼개고 숫자(ID)로 변환하는 과정이 필요합니다. BertTokenizer를 활용해 데이터셋 전체를 변환해 줍니다.
from transformers import BertTokenizer
# 사전 훈련된 토크나이저 불러오기
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
# 토크나이징 함수 정의
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncation=True)
# 데이터셋 전체에 토크나이저 적용 (배치 처리로 속도 향상)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
- padding="max_length": 문장의 길이를 BERT가 수용하는 최대 길이(기본 512 토큰)에 맞춰 모자란 부분은 채워줍니다.
- truncation=True: 최대 길이를 초과하는 긴 리뷰 문장은 뒷부분을 잘라냅니다.
4. PyTorch 데이터 로더(DataLoader) 구성
Hugging Face 데이터셋을 PyTorch 모델에 그대로 넣기 위해서는 텐서(Tensor) 형식으로 포맷을 바꾸고 필요한 컬럼만 남겨야 합니다. 그 후, 데이터를 묶어서 넘겨줄 데이터 로더를 설정합니다.
# PyTorch 텐서 포맷으로 변경 및 불필요한 텍스트 컬럼 제거
tokenized_datasets = tokenized_datasets.remove_columns(["text"])
tokenized_datasets = tokenized_datasets.rename_column("label", "labels")
tokenized_datasets.set_format("torch")
from torch.utils.data import DataLoader
# 배치 사이즈 설정 및 데이터 로더 생성
train_dataloader = DataLoader(tokenized_datasets["train"], batch_size=8, shuffle=True)
test_dataloader = DataLoader(tokenized_datasets["test"], batch_size=8)
5. BERT 모델 로드 및 최적화 설정
문장 분류를 위해 BERT의 출력층 위에 선형 레이어가 결합된 BertForSequenceClassification을 사용합니다. 이어서 모델을 연산 장치(GPU)로 이동시키고 가중치를 수정할 옵티마이저를 정의합니다.
import torch
from transformers import BertForSequenceClassification, AdamW
# 긍정/부정 이진 분류를 위해 num_labels=2 설정
model = BertForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=2)
# GPU 사용 가능 여부 확인 후 모델 이동
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
model.to(device)
# 가중치 최적화를 위한 옵티마이저 설정
optimizer = AdamW(model.parameters(), lr=5e-5)
6. 학습 스케줄러 및 모델 미세 조정(Fine-Tuning)
학습이 진행됨에 따라 학습률(Learning Rate)을 촘촘하게 조정해 주는 스케줄러를 구성하고, 본격적인 학습 루프를 실행합니다.
from transformers import get_scheduler
epochs = 3
num_training_steps = epochs * len(train_dataloader)
# 학습률 스케줄러 설정
lr_scheduler = get_scheduler(
"linear", optimizer=optimizer, num_warmup_steps=0, num_training_steps=num_training_steps
)
# 학습 시작
for epoch in range(epochs):
model.train()
total_loss = 0
for batch in train_dataloader:
# 모든 텐서 데이터를 GPU(또는 CPU)로 이동
batch = {k: v.to(device) for k, v in batch.items()}
# 모델 예측 및 손실 계산
outputs = model(**batch)
loss = outputs.loss
# 역전파 및 가중치 업데이트
optimizer.zero_grad()
loss.backward()
optimizer.step()
lr_scheduler.step()
total_loss += loss.item()
print(f"Epoch {epoch + 1} 완료 | 평균 Loss: {total_loss / len(train_dataloader):.4f}")
7. 모델 성능 평가
학습이 완료된 모델이 새로운 데이터에 대해 얼마나 잘 예측하는지 평가해 볼 시간입니다. evaluate 라이브러리를 사용해 정확도를 측정합니다.
import evaluate
# 검증 메트릭 로드
metric = evaluate.load("accuracy")
model.eval()
for batch in test_dataloader:
batch = {k: v.to(device) for k, v in batch.items()}
with torch.no_grad():
outputs = model(**batch)
logits = outputs.logits
predictions = torch.argmax(logits, dim=-1)
# 예측값과 실제 정답 축적
metric.add_batch(predictions=predictions, references=batch["labels"])
# 최종 정확도 계산 및 출력
final_score = metric.compute()
print("최종 모델 정확도:", final_score)
8. 효율적인 개발을 위한 꿀팁
- Hugging Face Trainer 활용하기: 본 포스팅에서는 개념 이해를 위해 PyTorch 순수 코드로 루프를 구현했지만, Hugging Face에서 제공하는 Trainer API를 사용하면 복잡한 학습 루프와 GPU 분산 학습 설정을 코드 몇 줄만으로 간편하게 대체할 수 있습니다.
- 진행 상황 시각화: 데이터가 크기 때문에 학습 시간이 다소 걸릴 수 있습니다. tqdm 라이브러리를 데이터 로더에 감싸주면 (from tqdm.auto import tqdm) 터미널에서 실시간 진행률 표시줄을 보며 편리하게 모니터링할 수 있습니다.
- 학습률(Learning Rate) 관리: BERT 같은 대형 모델은 학습률에 매우 민감합니다. 일반적인 CNN 모델처럼 $10^{-3}$ 수준의 큰 학습률을 쓰면 가중치가 파괴될 수 있으므로, $2\times10^{-5}$에서 $5\times10^{-5}$ 사이의 작은 값을 사용하는 것이 안전합니다.
9. 흔히 하는 실수와 해결 방법
- OOM (Out Of Memory) 에러 발생: GPU 메모리가 부족하다는 에러가 뜨면 가장 먼저 batch_size를 8이나 4로 줄여야 합니다. 만약 그래도 해결되지 않는다면 tokenize_function에서 문장의 최대 길이를 뜻하는 max_length를 512에서 256이나 128로 줄여서 입력 데이터의 크기 자체를 낮춰야 합니다.
- 텐서 장치 불일치 에러 (Device Mismatch): RuntimeError: Expected all tensors to be on the same device... 에러는 모델은 GPU에 있는데 데이터 텐서는 CPU에 머물러 있을 때 발생합니다. 학습 루프 안에서 배치를 꺼낸 직후 반드시 .to(device) 처리가 누락되지 않았는지 점검하시기 바랍니다.
- load_metric 경고 메시지: 예전 튜토리얼 코드에서 자주 쓰이던 datasets 라이브러리 안의 load_metric 함수는 현재 지원이 중단되어 사용을 권장하지 않습니다. 대신 최신 표준인 evaluate.load() 함수를 사용하는 방향으로 코드를 작성해야 경고나 에러 없이 정상 작동합니다.
10. 마치며
이번 글에서는 Hugging Face 생태계를 활용해 대표적인 사전 훈련 모델인 BERT를 다루고, IMDB 리뷰 데이터셋을 통해 감성 분석 문장 분류 모델을 직접 미세 조정해 보았습니다.
데이터 가공부터 토크나이징, PyTorch 데이터 파이프라인 연동, 그리고 실제 학습과 평가까지의 핵심 흐름을 파악하셨다면 이미 반은 성공한 셈입니다. 이번에 구현한 분류 파이프라인은 텍스트의 카테고리를 분류하는 뉴스 분류, 스팸 메일 필터링, 고객 문의 자동 분류 등 다양한 실무 자연어 처리 태스크에 구조 변경 없이 그대로 대입해 활용할 수 있으니 다양하게 응용해 보시기 바랍니다.
'Python for AI, Embedded > Deep Learning: PyTorch & AI Modeling' 카테고리의 다른 글
| PyTorch와 Hugging Face Transformers 라이브러리로 시작하는 NLP 가이드 (0) | 2026.05.20 |
|---|---|
| RNN을 넘어선 혁신, 트랜스포머(Transformer) 모델 구조와 핵심 개념 완벽 정리 (0) | 2026.05.19 |
| PyTorch로 시작하는 자연어 처리: IMDb 리뷰 감정 분석 및 텍스트 분류 완벽 가이드 (0) | 2026.05.18 |
| PyTorch TorchText 활용한 NLP 데이터셋 로딩 및 전처리 가이드 (IMDB 예제) (0) | 2026.05.17 |
| PyTorch RNN, LSTM, GRU 개념 완벽 정리: 구조부터 차이점까지 한눈에 보기 (0) | 2026.05.16 |