일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- miniconda
- jquery
- nginx
- chatGPT
- nodejs
- pagination
- 오블완
- exceljs
- Kaikas
- 배포
- Python
- NextJS
- Laravel
- Remix
- 회고
- 블록체인
- Ai
- Setting
- polygon
- 티스토리챌린지
- node
- metamask
- nft
- CSS
- 라라벨
- 공연티켓
- netfunnel
- PM2
- threejs
- React
- Today
- Total
박주니 개발 정리
openai api 없이 gpt2 model 적용 방법 본문
gpt2 model 적용 코드 설명
1. 필요한 라이브러리와 클래스의 임포트
import torch
from transformers import GPT2LMHeadModel, GPT2Tokenizer, Trainer, TrainingArguments
from torch.utils.data import Dataset
from torch.optim import AdamW
- `torch`: PyTorch 라이브러리, 딥러닝 모델을 구현하고 훈련하는 데 필요.
- `transformers`: Hugging Face의 transformers 라이브러리, 사전 훈련된 모델과 토크나이저를 제공.
- `Dataset`: PyTorch의 데이터셋을 정의할 때 사용하는 클래스.
- `AdamW`: 옵티마이저 중 하나로, 모델의 파라미터를 업데이트하는 데 사용.
2. 데이터셋 클래스 정의
class MenuDataset(Dataset):
def __init__(self, tokenizer, texts, max_length=512):
self.tokenizer = tokenizer
self.inputs = []
self.attn_masks = []
self.labels = []
for text in texts:
encodings_dict = tokenizer(text, truncation=True, max_length=max_length, padding="max_length")
self.inputs.append(torch.tensor(encodings_dict['input_ids']))
self.attn_masks.append(torch.tensor(encodings_dict['attention_mask']))
self.labels.append(torch.tensor(encodings_dict['input_ids']))
- `MenuDataset`: 입력된 텍스트 데이터를 모델이 처리할 수 있는 형태로 변환하는 사용자 정의 데이터셋.
- 입력 텍스트는 토크나이저를 사용하여 숫자 ID로 변환되고, 이는 모델이 학습할 수 있는 형태입니다.
3. 모델 및 토크나이저 로딩 및 설정
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
tokenizer.add_special_tokens({'pad_token': '[PAD]'})
model = GPT2LMHeadModel.from_pretrained('gpt2')
model.resize_token_embeddings(len(tokenizer))
- GPT-2 모델과 토크나이저를 불러오고, 특수 토큰(PAD 토큰)을 추가합니다.
- 모델의 토큰 임베딩 크기를 조정하여 특수 토큰을 포함시킵니다.
4. 학습 설정 및 실행
optimizer = AdamW(model.parameters(), lr=5e-5)
train_dataset = MenuDataset(tokenizer, texts)
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=3,
per_device_train_batch_size=2,
warmup_steps=100,
weight_decay=0.01,
logging_dir='./logs',
logging_steps=10,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
optimizers=(optimizer, None)
)
trainer.train()
- `TrainingArguments`: 훈련 중 사용할 설정을 정의합니다.
- `Trainer`: 모델 훈련을 담당하는 클래스로, 설정된 훈련 인자와 데이터셋을 사용하여 모델을 훈련시킵니다.
5. 학습된 모델을 사용한 텍스트 생성
prompt = "User: Show me the menu."
inputs = tokenizer(prompt, return_tensors='pt')
outputs = model.generate(
inputs['input_ids'],
max_length=50,
num_return_sequences=1,
no_repeat_ngram_size=2,
pad_token_id=tokenizer.pad_token_id,
temperature=0.7,
top_k=50,
top_p=0.95
)
answer = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(answer.encode('utf-8').decode('utf-8'))
- 모델이 사용자의 입력에 대한 응답을 생성합니다.
전체 코드
import torch
from transformers import GPT2LMHeadModel, GPT2Tokenizer, Trainer, TrainingArguments
from torch.utils.data import Dataset
from torch.optim import AdamW
class MenuDataset(Dataset):
def __init__(self, tokenizer, texts, max_length=512):
self.tokenizer = tokenizer
self.inputs = []
self.attn_masks = []
self.labels = []
for text in texts:
encodings_dict = tokenizer(text, truncation=True, max_length=max_length, padding="max_length")
self.inputs.append(torch.tensor(encodings_dict['input_ids']))
self.attn_masks.append(torch.tensor(encodings_dict['attention_mask']))
self.labels.append(torch.tensor(encodings_dict['input_ids'])) # labels are the same as input_ids for LM
def __len__(self):
return len(self.inputs)
def __getitem__(self, idx):
return {
'input_ids': self.inputs[idx],
'attention_mask': self.attn_masks[idx],
'labels': self.labels[idx] # ensure labels are returned
}
texts = [
"User: Show me the menu. Waiter: Here's the menu: hamburger, cola.",
]
# 토크나이저와 모델 로드
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
# 특수 토큰 추가
tokenizer.add_special_tokens({'pad_token': '[PAD]'})
model = GPT2LMHeadModel.from_pretrained('gpt2')
# 토큰 임베딩 크기 재조정
model.resize_token_embeddings(len(tokenizer))
optimizer = AdamW(model.parameters(), lr=5e-5)
train_dataset = MenuDataset(tokenizer, texts)
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=3,
per_device_train_batch_size=2,
warmup_steps=100,
weight_decay=0.01,
logging_dir='./logs',
logging_steps=10,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
optimizers=(optimizer, None)
)
# 학습 시작
trainer.train()
# 학습된 모델로 질문에 답변
prompt = "User: Show me the menu."
# 입력을 토크나이저로 처리
inputs = tokenizer(prompt, return_tensors='pt')
# 답변 생성
outputs = model.generate(
inputs['input_ids'],
max_length=50,
num_return_sequences=1,
no_repeat_ngram_size=2,
pad_token_id=tokenizer.pad_token_id, # PAD 토큰 ID 사용
temperature=0.7,
top_k=50,
top_p=0.95
)
# 생성된 출력을 텍스트로 디코드
answer = tokenizer.decode(outputs[0], skip_special_tokens=True)
# 인코딩 문제를 해결하기 위해 UTF-8을 명시적으로 사용
print(answer.encode('utf-8').decode('utf-8'))
현재 이코드를 vscode에서 임의로 파일 생성해서 붙여놓습니다.
- 추가 설명: 저는 gpt2.py로 해서 생성했습니다.
이제 해당 파일을 실행하는 방법을 알려드리겠습니다.
실행 방법
1. miniconda 환경을 셋팅합니다.
- 추가 설명: 설정하는 방법을 모르시는 분은 먼저 하단에 miniconda 설치 및 vscode 연결 방법을 하고 오시길 바랍니다. 이유는 gpt2를 연결하기 위해 python에서 torch를 import해야하는데 conda환경에서 진행해야하기 때문입니다.
- https://junhee6773.tistory.com/entry/miniconda-%EC%84%A4%EC%B9%98-%EB%B0%8F-vscode-%EC%97%B0%EA%B2%B0-%EB%B0%A9%EB%B2%95
2. 터미널 conda 연결된 상태에서 새 python 환경을 셋팅합니다.
conda create -n myenv python=3.7
- 추가 설명:
- myenv: 새 환경 이름 - 원하시는 이름으로 변경하시면 됩니다.
- python=3.7: 원하시는 python 타입으로 변경하시면 됩니다.
3. 새 python 환경이 정상적으로 추가가 되었는지 확인합니다.
conda info --envs
4. 2번에 설명에서 python: select interpreter을 클릭해서 myenv를 선택합니다.
5. torch, transformers, accelerate, accelerate를 설치합니다.
pip install torch transformers accelerate
- 추가 설명: 현재 torch, transformers 연결된 것만 설치하고 python을 실행할경우 하단에 추가적으로 설치할 accelerate가 나오게 됩니다.
6. python gpt2 적용파일을 실행합니다.
gpt2 model 사용 후기)
openai api를 이용해서 gpt3.5 model 기반 langchain 및 llm을 이용할 때에는 간단한 학습으로도 의도에 맞는 출력이 가능한데 gpt2 model은 질문을 아예 이해하지 못할뿐더러 fine-tuning도 답이 없기 때문에 gpt2 model을 사용하는 것보다는 few shot learning을 활용해서 유사한 답변 인지시 학습한 내용이 나오게끔 하는 게 효율적이라는 것을 느끼게 되었습니다.