두 가지 실습을 진행

  • 실습 1. DPO 데이터 전처리
  • 실습 2. DPO 데이터 생성하기


[실습 1. DPO 데이터 전처리]

Contents

  1. Import Packages
  2. Load Datasets
  3. EDA
  4. 중복 제거 (Deduplicate)
  5. 예시 확인


1. Import Packages

from datasets import load_dataset
import pandas as pd
from datasketch import MinHash, MinHashLSH
from tqdm import tqdm
import re


2. Load Datasets

DPO를 위한 dataset을 load한다.

  • DPO 데이터셋: 선호 (1) & 비선호 (0) 답변 존재


총 7576개의 데이터가 존재한다.

data= load_dataset('DopeorNope/New_DPO_dataset')
train_df= pd.DataFrame(data['train'])
print(len(train_df))
7576

3. EDA

데이터셋이 어떻게 생겼는지 확인하기!

train_df.head()

figure2


일부 데이터셋의 경우, 중복된 질문이 있음을 알 수 있다.

train_df['question'].value_counts()

figure2


약 182개의 중복된 데이터셋 (duplicate_questions)이 존재함을 알 수 있다.

duplicate_questions = train_df['question'][train_df['question'].duplicated(keep=False)]
print(len(duplicate_questions))
182


4. 중복 제거 (Deduplicate)

중복 제거 방법: MinHash LSH.

기준 설정하기!

SIMILARITY_THRESHOLD = 0.8
NUM_PERMS = 256
SHINGLE_SIZE = 5


전처리를 위해 필요한 함수 불러오기

def preprocess(string, maxlen=500):
    return ''.join(e for e in string[:maxlen] if e.isalnum()).lower()
    
def _shingle(string, shingle_size=4):
    return {string[i : i + shingle_size] for i in range(len(string) - shingle_size + 1)}


LSH (Locality-Sensitive Hashing)

lsh = MinHashLSH(threshold=SIMILARITY_THRESHOLD, num_perm=NUM_PERMS)
minhashes = {}
for i, doc in tqdm(enumerate(train_df['question'])):
    shingles = _shingle(preprocess(doc), shingle_size=SHINGLE_SIZE)
    minhash = MinHash(num_perm=NUM_PERMS)
    for shingle in shingles:
        minhash.update(shingle.encode('utf8'))
    lsh.insert(f'doc_{i}', minhash)
    minhashes[f'doc_{i}'] = minhash


제거하기

to_remove = set()

for i, minhash in minhashes.items():
    dups = lsh.query(minhash)
    # 인덱스 추출 및 비교
    dups = [int(dup.split('_')[1]) for dup in dups if int(dup.split('_')[1]) > int(i.split('_')[1])]  
    to_remove.update(dups)


지워야 할 duplicated된 데이터 확인하기

len(to_remove)
387


제거하기

removed_df = train_df.loc[list(to_remove)]
removed_df=removed_df.reset_index(drop=True)


5. 예시 확인하기

question_to_check='발에 물집이 생겼다.'

matched_rows = removed_df[removed_df['question'].str.contains(re.escape(question_to_check), regex=True)]
print(matched_rows)

figure2


[실습 2. DPO 데이터 생성하기]

Contents

  1. vllm 패키지 소개
  2. Import Packages
  3. Load Datasets
  4. EDA
  5. 중복 제거 (Deduplicate)
  6. 예시 확인


1. vllm 패키지 소개

위의 실습에서 사용한 DPO 데이터셋를 얻는 방법은?

( = 선호 (1), 비선호 (0) 답변을 얻는 방법은? )

  • 선호 답변: 실제 정답 label을 사용하면 됨
  • 비선호 답변: LLM (모델)의 output으로 사용하기


vllm 패키지

  • LLM의 고속 추론을 가능하게 하는 오픈소스 라이브러리
  • 주로 효율적인 메모리 관리병렬 처리 기술을 활용해, 빠르고 확장성 있는 LLM 추론을 제공
from vllm import LLM

llm = LLM(model="meta-llama/Llama-2-7b-chat-hf")
output = llm.generate("Hello, how are you?")
print(output)

2. Import Packages

from datasets import load_dataset
import vllm
from vllm import LLM, SamplingParams
import pandas as pd
from typing import List
from vllm.outputs import RequestOutput


3. Load Datasets

data= load_dataset('DopeorNope/Ko-Optimize_Dataset_train')
df= pd.DataFrame(data['train'])


모델에 넣을 프롬프트 생성

prompts = list(map(lambda x: 
    f"아래는 문제를 설명하는 지시사항과, 구체적인 답변 방식을 요구하는 입력이 함께 있는 문장입니다. 이 요청에 대해 적절하게 답변해주세요.\n\n###지시사항:\n{x['instruction']}\n\n###입력:\n{x['input']}\n\n###답변:\n"
    if x['input'] else
    f"아래는 문제를 설명하는 지시사항입니다. 이 요청에 대해 적절하게 답변해주세요.\n\n###지시사항:\n{x['instruction']}\n\n###답변:\n", 
    df.to_dict('records')))


4. Load Model

LLama3 모델을 불러온다.

base_model= 'DopeorNope/Single_GPU_Llama3-8B'
gpu_num = 4
max_token = 4096
model = LLM(model=base_model, tensor_parallel_size=gpu_num, max_model_len=max_token, gpu_memory_utilization=0.6)


5. 생성 (Sampling)

Hyperparameters

sampling_params = SamplingParams(top_k=5, top_p=1, max_tokens=max_token,
                                     stop=['<|endoftext|>', '</s>', '<|im_end|>','<|end_of_text|>'])


생성하기

outputs: List[RequestOutput] = model.generate(prompts, sampling_params)


예시 확인

outputs[0].prompt
'아래는 문제를 설명하는 지시사항입니다. 이 요청에 대해 적절하게 답변해주세요.\n\n###지시사항:\nk > 0,$ 의 배율로 팽창을 나타내는 행렬을 $\\mathbf{D}$ 라 하고, 원점을 중심으로 시계 반대 방향으로 $\\theta$ 의 각도로 회전하는 것을 나타내는 행렬을 $\\mathbf{R}$ 이라 합니다.  다음과 같은 경우\n\\[\\mathbf{R} \\mathbf{D} = \\begin{pmatrix} 8 & -4 \\\\ 4 & 8 \\end{pmatrix},\\]라면 $\\tan \\theta.$를 구합니다.\n\n###답변:\n'


최종 생성 결과 정리

extracted_prompts = list(map(lambda x: x.prompt, outputs))
extracted_generated_texts = list(map(lambda x: x.outputs[0].text, outputs))


Reference

https://fastcampus.co.kr/data_online_gpu

Categories: , ,

Updated: