2024. 2. 19. 18:53ㆍDL Life
1. Embedding Vector 추출 모델 ?
AI 동계 강좌를 듣고 온 사이 몇개의 코드 공유 글이 더 올라와서 해당 코드들을 참고해보려고 한다
import numpy as np from sentence_transformers import SentenceTransformer # SentenceTransformer Version 2.2.2 # Embedding Vector 추출에 활용할 모델(distiluse-base-multilingual-cased-v1) 불러오기 model = SentenceTransformer('distiluse-base-multilingual-cased-v1')
Distiluse-base-mulitlingual-cased-v1 모델도 잘 몰라서 찾아보니 (Reference #1)
각 단어의 임베딩 벡터를 만드는 모델이였다. 평가할 때, Cosine similarity 를 활용하기 때문에 사용하는 모델
역시 가장 먼저 파악하는게 필요하다고 생각한 건
→ Baseline 모델 + 점수 평가 코드 : 주어진 코드를 다시 살펴보자!
Import Part
import pandas as pd import numpy as np import torch from transformers import GPT2LMHeadModel, PreTrainedTokenizerFast, AdamW from tqdm import tqdm # CUDA 사용 가능 여부 확인 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") print(f"Using device: {device}")
Data Preprocessing
# 데이터 로드 data = pd.read_csv('train.csv') # 토크나이저 로드 tokenizer = PreTrainedTokenizerFast.from_pretrained('skt/kogpt2-base-v2', eos_token='</s>') # 데이터 포맷팅 및 토크나이징 formatted_data = [] for _, row in tqdm(data.iterrows()): for q_col in ['질문_1', '질문_2']: for a_col in ['답변_1', '답변_2', '답변_3', '답변_4', '답변_5']: # 질문과 답변 쌍을 </s> token으로 연결 input_text = row[q_col] + tokenizer.eos_token + row[a_col] input_ids = tokenizer.encode(input_text, return_tensors='pt') formatted_data.append(input_ids) print('Done.')
→ .encode 로 데이터 수치화
Formatted Data → 해당 질문과 답변을 조합해서 행마다 10개의 Q-A 쌍을 만듦
토크나이저를 통해 QA 쌍을 수치화 하고 Formatted data 에 저장
→ Kogpt 보다 좋은 모델은 뭐가 있을까?
Ko-SOLAR 사용해보기 (https://huggingface.co/yanolja/KoSOLAR-10.7B-v0.3)
Fine-tuning → KoGPT2
- 가장 쉬운 것부터 해보기 : 모델 더 큰 거 로 바꿔보기
# 모델 로드 model = GPT2LMHeadModel.from_pretrained('skt/kogpt2-base-v2') model.to(device) # 모델을 GPU단으로 이동 # 모델 학습 하이퍼파라미터(Hyperparameter) 세팅 # 실제 필요에 따라 조정하세요. CFG = { 'LR' : 2e-5, # Learning Rate 'EPOCHS' : 10, # 학습 Epoch } # 모델 학습 설정 optimizer = AdamW(model.parameters(), lr=CFG['LR']) model.train() # 모델 학습 for epoch in range(CFG['EPOCHS']): total_loss = 0 progress_bar = tqdm(enumerate(formatted_data), total=len(formatted_data)) for batch_idx, batch in progress_bar: # 데이터를 GPU단으로 이동 batch = batch.to(device) outputs = model(batch, labels=batch) loss = outputs.loss loss.backward() optimizer.step() optimizer.zero_grad() total_loss += loss.item() # 진행률 표시줄에 평균 손실 업데이트 progress_bar.set_description(f"Epoch {epoch+1} - Avg Loss: {total_loss / (batch_idx+1):.4f}") # 에폭의 평균 손실을 출력 print(f"Epoch {epoch+1}/{CFG['EPOCHS']}, Average Loss: {total_loss / len(formatted_data)}") # 모델 저장 model.save_pretrained("./hansoldeco-kogpt2") tokenizer.save_pretrained("./hansoldeco-kogpt2")
kmj00825(4245M) → 4GB 정도 사용하는데 이거 Batch size 를 어떻게 늘리지…?
1 Epoch당 4분정도 걸렸다
Model Inference
# 저장된 Fine-tuned 모델과 토크나이저 불러오기 model_dir = "./hansoldeco-kogpt2" model = GPT2LMHeadModel.from_pretrained(model_dir) model.to(device) tokenizer = PreTrainedTokenizerFast.from_pretrained(model_dir) # Inference를 위한 test.csv 파일 로드 test = pd.read_csv('./test.csv') # test.csv의 '질문'에 대한 '답변'을 저장할 리스트 preds = [] # '질문' 컬럼의 각 질문에 대해 답변 생성 for test_question in tqdm(test['질문']): # 입력 텍스트를 토큰화하고 모델 입력 형태로 변환 input_ids = tokenizer.encode(test_question + tokenizer.eos_token, return_tensors='pt') # 답변 생성 output_sequences = model.generate( input_ids=input_ids.to(device), max_length=300, temperature=0.9, top_k=1, top_p=0.9, repetition_penalty=1.2, do_sample=True, num_return_sequences=1 ) # 생성된 텍스트(답변) 저장 for generated_sequence in output_sequences: full_text = tokenizer.decode(generated_sequence, skip_special_tokens=False) # 질문과 답변의 사이를 나타내는 eos_token (</s>)를 찾아, 이후부터 출력 answer_start = full_text.find(tokenizer.eos_token) + len(tokenizer.eos_token) answer_only = full_text[answer_start:].strip() answer_only = answer_only.replace('\n', ' ') preds.append(answer_only)
Inference 130 개 하는데에는 5분 30초
Model Submission
# Test 데이터셋의 모든 질의에 대한 답변으로부터 512 차원의 Embedding Vector 추출 # 평가를 위한 Embedding Vector 추출에 활용하는 모델은 'distiluse-base-multilingual-cased-v1' 이므로 반드시 확인해주세요. from sentence_transformers import SentenceTransformer # SentenceTransformer Version 2.2.2 # Embedding Vector 추출에 활용할 모델(distiluse-base-multilingual-cased-v1) 불러오기 model = SentenceTransformer('distiluse-base-multilingual-cased-v1') # 생성한 모든 응답(답변)으로부터 Embedding Vector 추출 pred_embeddings = model.encode(preds) pred_embeddings.shape submit = pd.read_csv('./sample_submission.csv') # 제출 양식 파일(sample_submission.csv)을 활용하여 Embedding Vector로 변환한 결과를 삽입 submit.iloc[:,1:] = pred_embeddings submit.head() # 리더보드 제출을 위한 csv파일 생성 submit.to_csv('./baseline_submit.csv', index=False)
제출해본 결과 이정도 성능
일단 Ko-SOLAR 모델을 그냥 올려봤더니 메모리가 터졌다. 80기가를 통으로 쓰지 못해서 혹시나 올려봤는데 역시나였다
OutOfMemoryError: CUDA out of memory. Tried to allocate 64.00 MiB (GPU 0; 79.35 GiB total capacity; 45.82 GiB already allocated; 30.19 MiB free; 45.90 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF
64GB 이상은 할당 해줘야하는 것 같다
GPU 2개로 나눠서 올려서 시도해봐야할 것 같고, 서버 바꿔서 해봐야겠다.
일단 모델만 바꿔서 성능 측정해보고 아이디어 하나씩 추가해보는 쪽으로 해야겠다
Prompt tuning 쪽 이야기도 있던데 해당 내용도 살펴보고 진행해야할 듯하다
Reference
#1 https://0goodmorning.tistory.com/61
#2 https://dacon.io/competitions/official/236216/codeshare
#3 https://huggingface.co/yanolja/KoSOLAR-10.7B-v0.3
Link
“이 글은 Obsidian 에서 작성되어 업로드 되었습니다”
'DL Life' 카테고리의 다른 글
Dacon 도배 하자 질의 응답 처리 경진대회 (4)QLoRA + 4bit quantization + LDCC-SOLAR-10.7B(≈9GB vram used) 코드 테스트 (0) | 2024.02.20 |
---|---|
Dacon 도배 하자 질의 응답 처리 경진대회 (3) Ko-SOLAR 모델 테스트 및 Data Parallel (0) | 2024.02.20 |
Dacon 도배 하자 질의 응답 처리 경진대회 (1) 대회 탐색 (0) | 2024.02.12 |
Long-tail Distribution Learning Survey Review (0) | 2024.02.08 |
Contrastive Chain of Thought (1) | 2023.12.01 |