실습 목표
허깅페이스 tokenizers 라이브러리를 활용하여 BPE 기반의 토크나이저 생성 실습
어휘 집합 구축
BPE 기반 토크나이저를 사용하려면 어휘 집합(token.json)부터 구축
1st - 말뭉치 준비 ( 다운 및 전처리 )
from Korpora import Korpora
nsmc = Korpora.load("nsmc", force_download=True)
import os
def write_lines(path, lines):
with open(path, 'w', encoding='utf-8') as f:
for line in lines:
f.write(f'{line}\n')
write_lines("/content/train.txt", nsmc.train.get_all_texts())
write_lines("/content/test.txt", nsmc.test.get_all_texts())
2nd - 토크나이저 구축
GPT 토크나이저 구축
- GPT 계열 모델이 사용하는 토크나이저는 BPE
- 단, BPE의 단위가 문자 단위가 아닌 유니코드 바이트 단위
- 바이트 수준의 BPE 어휘 집합 구축 결과 저장
from tokenizers import ByteLevelBPETokenizer
bytebpe_tokenizer = ByteLevelBPETokenizer()
bytebpe_tokenizer.train(
files=["/content/train.txt", "/content/test.txt"], #학습 말뭉치
vocab_size=10000, #어휘 집합 크기 조절
special_tokens=["[PAD]"] #특수 토큰 추가
)
bytebpe_tokenizer.save_model("/gdrive/My Drive/nlpbook/bbpe")
BERT 토크나이저 구축
from tokenizers import BertWordPieceTokenizer
wordpiece_tokenizer = BertWordPieceTokenizer(lowercase=False)
wordpiece_tokenizer.train(
files=["/content/train.txt", "/content/test.txt"],
vocab_size=10000,
)
wordpiece_tokenizer.save_model("/gdrive/My Drive/nlpbook/wordpiece")
토큰화 진행
GPT 입력값 만들기
GPT 토크나이저 준비
위에서 만든 어휘 집합 구축 결과(vocab.json, merges.txt)를 가지고 토크나이저 준비
from transformers import GPT2Tokenizer
tokenizer_gpt = GPT2Tokenizer.from_pretrained("/gdrive/My Drive/nlpbook/bbpe")
tokenizer_gpt.pad_token = "[PAD]"
실제 문장을 GPT 토크나이저로 토큰화 해보기(테스트)
sentences = [
"아 더빙.. 진짜 짜증나네요 목소리",
"흠...포스터보고 초딩영화줄....오버연기조차 가볍지 않구나",
"별루 였다..",
]
tokenized_sentences = [tokenizer_gpt.tokenize(sentence) for sentence in sentences]
tokenized_sentences
실제 GPT 모델에 들어갈 입력 토큰 만들기
batch_inputs = tokenizer_gpt(
sentences,
padding="max_length", #문장 최대 길이에 맞춰 패딩 (더미 토큰 [PAD]로 최대 길이 채움)
max_length=12, #한 문장의 최대 토큰 길이
truncation=True, #최대 토큰 넘어가면 문장 잘림 허용
)
batch_inputs은 아래 2가지 key를 가진 딕셔너리
- input_ids: 각 문장의 토큰 인덱스 시퀀스를 나타낸 것
- 인덱싱(indexing)된 결과를 확인 가능: 토큰(문자) -> 정수로 변환한 값
- 0은 더미 토큰([PAD])가 채워진 것
[
[334, 2338, 263, 581, 4055, 464, 3808, 0, 0, 0, 0, 0], #문장1, 토큰 7개
[3693, 336, 2876, 758, 2883, 356, 806, 422, 9875, 875, 2960, 7292], #문장2, 토큰 12개
[4957, 451, 3653, 263, 0, 0, 0, 0, 0, 0, 0, 0] #문장3, 토큰 4개
]
- attention_mask: 일반 토큰이 자리한 곳(1), 패딩 토큰이 자리한 곳(0)을 구분해서 알려주는 것
[[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
BERT 입력값 만들기
BERT 토크나이저 준비
위에서 만든 어휘 집합 구축 결과(vocab.json)를 가지고 토크나이저 준비
from transformers import BertTokenizer
tokenizer_bert = BertTokenizer.from_pretrained(
"/gdrive/My Drive/nlpbook/wordpiece",
do_lower_case=False,
)
실제 문장을 BERT 토크나이저로 토큰화 해보기 (테스트)
sentences = [
"아 더빙.. 진짜 짜증나네요 목소리",
"흠...포스터보고 초딩영화줄....오버연기조차 가볍지 않구나",
"별루 였다..",
]
tokenized_sentences = [tokenizer_bert.tokenize(sentence) for sentence in sentences]
토큰에 있는 ##은 해당 토큰이 어절의 시작이 아님을 나타내는 것
실제 BERT 모델에 들어갈 입력 토큰 만들기
batch_inputs = tokenizer_bert(
sentences,
padding="max_length",
max_length=12,
truncation=True,
)
GPT 모델과 동일하게 batch_inputs이 생성
- input_ids: 각 문장의 토큰 인덱스 시퀀스를 나타낸 것
- 인덱싱(indexing)된 결과를 확인 가능: 토큰(문자) -> 정수로 변환한 값
- 0은 더미 토큰[PAD]
- 2는 문장의 시작을 알리는 토큰[CLS]
- 3은 문장의 종료를 나타내는 토큰 [SEP]
[
[2, 621, 2631, 16, 16, 1993, 3678, 1990, 3323, 3, 0, 0], #문장1
[2, 997, 16, 16, 16, 2609, 2045, 2796, 1981, 1129, 16, 3], #문장2
[2, 3274, 9507, 16, 16, 3, 0, 0, 0, 0, 0, 0] #문장3
]
- attention_mask: 일반 토큰이 자리한 곳(1), 패딩 토큰이 자리한 곳(0)을 구분해서 알려주는 것
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]]
- token_type_ids: 세그먼트(segment) 정보를 표현하는 것
- BERT 모델은 문서 or 문장 2개를 입력 받음
- 문서는 1, 문장은 0에 해당
- 위 실습에서는 문장만 삽입했기에 모두 0으로 표기
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
'CS > NLP' 카테고리의 다른 글
이론 3-2. 트랜스포머 (0) | 2023.11.11 |
---|---|
이론 3-1. 사전 학습된 모델 (0) | 2023.11.10 |
이론 2-3. 워드피스(wordpiece) (0) | 2023.11.10 |
이론 2-2. 바이트 페이 인코딩(BPE) (0) | 2023.11.10 |
이론 2-1. 토큰화 (0) | 2023.11.10 |