GPT-2 를 seq2seq 방식으로 학습시키기

2023. 12. 7. 13:28 · 머신러닝 이모저모
목차
  1. [추가 질문]
  2. Alpaca
  3. Packing

이번 포스팅의 내용은 https://mari970.tistory.com/61 블로그의 내용과 이어진다.

 

dataset 가 source 와 target 으로 이루어져 있을 때 p(y|x) 방식으로 학습시킬 수 있는 방안에 대한 방법론이다.

https://github.com/huggingface/transformers/issues/1464

위 링크가 내가 생각했던 문제와 매우 비슷해서 정리한다. (2019 글)

 

위 issues 에서 화자가 생각하는 question 주제는 모델에 input (”source seq가 포함되어 있는” 이라고 되어있는데, 그건 target 도 같이 넣는다는 의미로 해석) 을 forward 시킬 때 source token 에 대한 loss 는 0 으로 만들어야 하나? 이다.

= 이는 lm_logit 에 포함된 source seq token 을 0 으로 만들어야 하나? 그래서 backward 계산이 되지 않도록?

 

⇒ 답변자: (가 해본 test 에 따르면) 포함시켜도 상관없다고 한다. Total loss 가 좀 더 커지긴 하겠지만..

 

<sos> 와 <eos> 토큰 등을 사용해서 src seq = trg seq text ( ‘=’ 을 사용하는 format 이 input 형태라는 뜻) 이 형식만 잘 사용하면 파인튜닝에 문제는 없는 듯하다고 답변한다.

 

[추가 질문]

(1) <sep> 같은 special token 없으면 추가하라고 warning 뜨잖아 그거 꼭 다 추가해야 하나?

Add a [SOS], [SEP] and [EOS] to the vocabulary (we should train it also!)
tokenizer.add_special_tokens({'start_token': '[CLS]', 'sep_token': '[SEP]', 'end_token': '[EOS]'})
model.resize_token_embeddings(len(tokenizer))  # Update the model embeddings with the new vocabulary size

 

⇒ 니맘대로~.~ 답변자는 (예를 들면) '[', 'E', 'OS', ']' 이런 식으로 (따로 새로운 토큰을 추가하지 않고) already known token 을 이용해서 prompt 처럼 사용했는데 이란 방법도 효과가 있었다고.

따로 추가하려면 이 새로운 token들에 대한 train 을 따로 해야해서 그렇다.

→ 이거는 나도 고려해봐야겠당

 

(2) GPT 나 GPT-2 는 right padding 을 지원하지 않는다고.(이게 [pad] 토큰이 없어서 지원을 하지 않는다는 뜻인 것 같다.) fine-tuning 에서 어떻게 해결하였나?

 

⇒ translation sample 이라고 하면, 랜덤으로 고른 sample (+lables) 들을 concat 해서 1개 input 으로 만든다.

 

Ex) "[SOS] something in English_#1 = something in French_#1 [EOS] [SOS] something in English_#32 = something in French_#32 [EOS] [SOS] .. etc”

이 후 토큰화하고 max_length 로 truncate 한다. 이렇게 하면 모델이 다양한 길이에 대한 sequence 를 학습할 수 있다.

"[SOS] something in English = " 를 인풋 프롬프트로 주고 [EOS] token이 나오면 생성을 끝낸다.

= 이는 (지금은 존재하지 않는 그 당시의) hf의 transformers 의 examples 의 run_lm_finetuning.py 방법과 같다고 한다.

여기서는 모든 input 을 하나의 긴 문자열로 읽은 후 max_length 로 잘라낸다고.

이때 셔플은 없다. (근데 이건 pre-train 방법 아니었나? 라는 의문이 든다.)

 

이후 alpaca (decoder-only model) 에서 의 (2) seq2seq 의 방법론을 구체화한 듯 하다.

 

 

Alpaca

source string 에서도 next-token-prediction 에 대한 loss 가 발생하기 때문에 Alpaca 에서는 이 loss 를 무시한다.

def preprocess(
    sources: Sequence[str],
    targets: Sequence[str],
    tokenizer: transformers.PreTrainedTokenizer,
) -> Dict:
    """Preprocess the data by tokenizing."""
    examples = [s + t for s, t in zip(sources, targets)]  # concatenate source and target strings
    examples_tokenized, sources_tokenized = [_tokenize_fn(strings, tokenizer) for strings in (examples, sources)]
    input_ids = examples_tokenized["input_ids"]
    labels = copy.deepcopy(input_ids)
    for label, source_len in zip(labels, sources_tokenized["input_ids_lens"]):
        label[:source_len] = IGNORE_INDEX  # the source string's loss is ignored with IGNORE_INDEX
    return dict(input_ids=input_ids, labels=labels)

IGNORE_INDEX 가 어떻게 구현되어있는지는 모르겠지만 source string 은 ignore 되고 있다.

 

그렇다면 input 과 target 를 어떻게 model 로 하여금 어떻게 구분하도록 할 것인가?

 

PROMPT_DICT = {
    "prompt_input": (
        "Below is an instruction that describes a task, paired with an input that provides further context. "
        "Write a response that appropriately completes the request.\\n\\n"
        "### Instruction:\\n{instruction}\\n\\n### Input:\\n{input}\\n\\n### Response:"
    ),
    "prompt_no_input": (
        "Below is an instruction that describes a task. "
        "Write a response that appropriately completes the request.\\n\\n"
        "### Instruction:\\n{instruction}\\n\\n### Response:"
    ),
}

위의 예시처럼 ### Response: 를 줘서 target string 을 generate 하도록 한다.

 

Packing

을 통해 training examples 를 묶어 padding 을 방지할 수 있다.

(source->target)[IGNORE_INDEX](source->target)[IGNORE_INDEX]...(source->target)[IGNORE_INDEX])

위는 causal LM

Input: (source)[IGNORE_INDEX](source)[IGNORE_INDEX]...(source)[IGNORE_INDEX]
Target: (target)[IGNORE_INDEX](target)[IGNORE_INDEX]...(target)[IGNORE_INDEX]

위는 seq2seq 방식이다. (이해는 안됨)

 

그렇기에 다음 포스팅에서는 alpaca 와 llama, vicuna 코드를 보고 조금 더 알아봐야겠다.

'머신러닝 이모저모' 카테고리의 다른 글

Precision 개념  (0) 2024.02.18
VScode 에서 tmux 사용하기  (0) 2024.01.03
UserWarning: CUDA initialization: Unexpected error from cudaGetDeviceCount() 에러 처리  (0) 2024.01.03
Ensemble (앙상블 기법)  (0) 2023.09.08
딥러닝 에서의 Bayes’ Rule  (1) 2023.08.09
  1. [추가 질문]
  2. Alpaca
  3. Packing
'머신러닝 이모저모' 카테고리의 다른 글
  • VScode 에서 tmux 사용하기
  • UserWarning: CUDA initialization: Unexpected error from cudaGetDeviceCount() 에러 처리
  • Ensemble (앙상블 기법)
  • 딥러닝 에서의 Bayes’ Rule
섬섬옥수수
섬섬옥수수
컴공 AI 개발자가 되기 위한 노역입니다
아날로그 인간의 컴공 되기컴공 AI 개발자가 되기 위한 노역입니다
섬섬옥수수
아날로그 인간의 컴공 되기
섬섬옥수수
전체
오늘
어제
  • 분류 전체보기 N
    • 백준 단계별 코딩 테스트
    • KB 논문 정리
    • Memory network 논문 정리
    • LLM 관련 논문 정리 N
    • Python 및 Torch 코딩 이모저모
    • Clustering 관련 논문 정리
    • 머신러닝 이모저모
    • 암호학

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 티스토리챌린지
  • e5-v
  • CUDA
  • PEFT
  • ragas
  • 이화여대
  • 코딩테스트
  • efficient and effective vocabulary expansion towards multilingual large language models
  • 문제풀이
  • constituency tree
  • 오블완
  • GIT
  • dependency tree
  • 심재형
  • 백준
  • 하드웨어
  • 인공지능융합기반시스템개론
  • eeve
  • vocabulary expansion
  • 소프트웨어

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
섬섬옥수수
GPT-2 를 seq2seq 방식으로 학습시키기
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.