박주니 개발 정리

openai api 없이 gpt2 model 적용 방법 본문

AI

openai api 없이 gpt2 model 적용 방법

박주니 2024. 4. 30. 16:42
728x90
반응형

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 연결 방법

1. https://docs.anaconda.com/free/miniconda/miniconda-install/ 에서 환경에 맞게 설치합니다. 저는 window환경이여서 windows graphical installer에서 설치했습니다. <figure id="og_1714454229590" contenteditable="false" data-ke-type="

junhee6773.tistory.com

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을 활용해서 유사한 답변 인지시 학습한 내용이 나오게끔 하는 게 효율적이라는 것을 느끼게 되었습니다. 

728x90
반응형
Comments