보통 transformers에서 커스텀 LLM 모델을 만들 때, tokenizer도 미리 pretrained되어있는 모델을 주로 사용한다.
예를들어 RobertaTokenizer를 사용한다고 가정해보자.
from transformers import RobertaTokenizer
#tokenizer
tokenizer = RobertaTokenizer.from_pretrained('roberta-base',sep_token = '<sep>')
보통은 텍스트 데이터를 모델에 입력할 때, 모든 텍스트의 길이를 통일시켜 주는 경우가 많다.
하지만 문장의 길이가 모두 다르기 때문에 통일을 시켜 주는데, 이때 해주는 작업이 padding 작업이다.
Padding은 짧은 문장을 길게 늘일때 사용하는 기법으로, 예를들어 입력 문장의 길이를 10으로 맞춘다고 가정하면
'Hello python'이라는 문장을 토큰화 한 경우 [11,22] 로 표현할 수 있지만 길이가 2이기 때문에 padding_idx = 1을 추가 해 줌으로 써, 임의로 더 긴 token sequence를 만들어 준다. 즉 [11,22]를 [11,22,1,1,1,1,1,1,1,1,]로 만들어 주게 된다.
반대로 더 긴 문장의 경우는 간단히 앞에서부터 문장의 최대 길이(10)까지만 입력 문장으로 사용하면 된다.
즉, [10,20,30,40,50,60,70,88,99,100,102] 는 [10,20,30,40,50,60,70,88,99,100]까지만 사용하면 된다.
이를 Python으로 구현하면 아래와 같이 구현해 볼 수 있다.
import numpy as np
def add_padding(text,seq_length,padding_idx):
if seq_length <= len(text):
text = text[:seq_length]
else:
pad_seq = np.array([padding_idx] * (seq_length - len(text)))
text = np.concatenate([text,pad_seq])
return text
이걸 바로 사용해도 되기는 하지만, Transformers에서도 이미 관련 기능을 제공하고 있기 때문에 그 방법에 대해 정리해보고자 한다.
우선, Transformers에서는 긴 token sequence를 줄여주는 truncation 옵션과, 짧은 token sequence를 길게 늘려주는 padding 옵션을 각각 제공해준다.(즉,위에서 구현한 if따로, else따로 제공해준다.)
문장의 길이에 따라 어떻게 리턴해주는지 살펴보자.
우선, 짧은 문장의 경우부터 살펴보면 다음과 같다.
간단히 문장의 최대 길이를 10으로 주었다.
짧은 문장의 경우, 단순히 encode를 하게 되면 각 단어별로 토큰화가 되었다. (참고로 [0,31414,232,50265]를 decode하면
'<s>Hello world <sep>'이 된다.)
다음으로 padding 옵션을 주게 된다면, 기존에 길이가 4인 토큰에 padding이 6개가 추가로 붙어서 우리가 설정한 길이가 10으로 encoding이 되었다. 또한 Attention mask도 padding은 Attention연산 시 계산하지 않으므로 padding이 추가된 만큼 0이 추가되었음을 볼 수 있다.
반대로 truncation(긴 문장을 짧게) 옵션을 준 경우에는 max_length를 10으로 설정했음에도 불구하고 길이가 4로 encoding이 되었다. truncation 옵션만 준 경우에는 최대길이 이상인 경우에만 잘라주는것 같다. 개인적으로 코드를 짜면서 착각하기 쉬운 부분같다.
반대로 긴 문장의 경우를 살펴보자.
문장의 길이가 긴 경우에는 단순히 encode를 하게 되면 입력한 문장의 길이만큼 encoding이 되는 모습을 볼 수 있다.
(길이 : 11)
다음으로 padding 옵션만 준 경우에는 max_length를 10으로 주었음에도 불구하고 입력한 문장의 길이만큼 encoding이 되었음을 알 수 있다. 짧은 문장과는 반대로 max_length보다 작은 경우에만 padding을 붙여주고 그렇지 않은 경우에 대해서는 아무런 작업을 하지 않음을 알 수 있다.
마지막으로 truncation 옵션을 준 경우에는 max_length에 맞춰서 encoding이 되었음을 알 수 있다.(길이 10)
여기서 또 눈여겨 볼 점은 줄어든 token이다.
단순하게 생각하면 길이가 11에서 10으로 줄어들었으니까 길이가 11에서 제일 마지막에 있는 토큰이 없어지고 그 앞에 있는 토큰까지만 올 것이라고 생각할 수 있지만, 맨 마지막 토큰은 사라지지 않았다.
실제로 decoding을 해 보면 다음과 같다.
보게 되면 제일 마지막에 special token이 있음을 알 수 있다. 즉, 길이가 줄어들면 special token을 지우는게 아니라 입력한 문장의 토큰을 지우게 된다는 뜻이다.
마지막으로, 짧은 문장은 길게 늘리면서 긴 문장을 짧게 줄이고 싶을 때는 지금까지 다룬 옵션들을 합치면 된다!
위 결과와 같이 짧은 문장은 길게 늘려주면서, 긴 문장은 짧게 encoding이 됨을 알 수 있다.
똑같지만 다음과 같이 pad_to_max_length 옵션을 줄 수도 있다!
[참고 자료]
[2] https://huggingface.co/docs/transformers/pad_truncation
'파이썬(Python) > 파이썬 관련' 카테고리의 다른 글
GPU 메모리 확보하기 (0) | 2023.06.13 |
---|---|
Selenium으로 웹사이트(디시인사이드) 크롤링하기 (16) | 2023.04.15 |
Pytorch 버전 확인하기 (0) | 2021.11.05 |
[Python] 가상환경(Virtual Environment) 세팅하기 (0) | 2021.08.04 |