Transformer Translation

이지민·2024년 5월 23일

aihub에서 한국어,영어 160만 쌍 데이터를 다운받았다.

이를 이용해서 번역 모델을 학습 해보려 했으나,
10%인 16만장 1에포크가 10시간 걸림...
따라서 실제로 학습후 확인은 포기하고
이론대로 코드를 짜고, 오류없이 돌아가는지 확인하는 수밖에

실제로 구현해보니 생각치 못한 부분이 많았다.

1. 실전 예측시에도 마스킹을 사용하는 이유

트랜스포머는 실전 예측시에 decoder의 output을 decoder의 input으로 반복해서 넣으면서 시퀀스의 길이를 늘려 간다.

정확히 설명하자면 decoder의 output시퀀스의 마지막 요소만을
decoder input 시퀀스에 더해가는 방식이다.

하지만 학습시에는 위와 같은 방식이 아닌, 처음부터 target을 decoder에 넣게되고, output으로 자기자신을 만들어서 loss값을 계산한다.
이때 한칸씩 밀려난 시퀀스가 output으로 만들어지도록 하는데

[SOS] I like apple를 넣어서
I like apple [EOS]를 만든다.

[SOS]가 I를 예측하고,
[SOS] I가 like를 예측한다.
이는 마스킹을 통해 구현된다.
https://velog.io/@nrye4286/Transformer-2

실전 예측시에도 학습때처럼 마스킹을 그대로 냅두게 되는데,
output의 마지막 단어는 마스킹의 영향 없이 전체 시퀀스를 모두 사용하게 되고, 이만 필요하기 때문에 문제가 발생하지 않는다.

2. 배치마다 시퀀스 길이가 달라도 문제가 발생하지 않는 이유

어탠션의 아웃풋 시퀀스의 길이는 인풋 시퀀스의 길이와 같다.

어탠션 연산 시 query, key, value로 변환하는 가중치가 필요하다.
각 단어가 따로 연산되며, 시퀀스의 길이가 달라도 단어의 임베딩 크기는 동일하기 때문에 문제가 생기지 않는다.

각 단어에서 query, key, value끼리의 연산은 행렬곱으로 진행되며 학습이 필요한 가중치를 사용하지 않는다.

feedforward계층 또한 각 단어들이 별개로 연산되며, 임베딩의 크기는 고정이므로 문제가 되지 않는다.

3. SOS, EOS, PAD처리

트랜스포머는 인풋으로 임베딩값이 아닌, 라벨값을 넣게 된다.
트랜스포머 안에서 임베딩레이어가 학습을 하게 된다.

라벨링을 해주게 될때, '[SOS]','[EOS]','[PAD]'도 라벨링을 같이 진행해준다.

output으로는 토큰개수 - 2사이즈의 확률벡터를 반환하도록 한다.
('[SOS]','[PAD]'는 예측하지 않게끔 한다.)

4. 패딩을 무시하기 위한 추가적인 마스크

실전 예측시에는 패딩이 들어가지 않는다.
따라서 학습시에 패딩이 영향력을 행사하도록 하면 안된다.
위 마스킹과 같은 원리를 이용한다.

transformer_out = self.transformer(src, tgt, tgt_mask=tgt_mask, src_key_padding_mask=src_pad_mask, tgt_key_padding_mask=tgt_pad_mask)

nn.transformer에 src_key_padding_mask에 마스크를 넣어주면 된다.

def create_pad_mask(self, matrix: torch.tensor) -> torch.tensor:
        return (matrix == '[PAD]' or matrix == '[EOS]')

5. 데이터 전처리 순서

학습 -
문자열 -> 토큰화 -> 배치처리(패딩,sos,eos) -> 라벨링 -> 모델 입력

실전 예측 -
모델 아웃풋: 확률 -> argmax -> 아웃풋을 늘려가며 반복 -> 라벨링 역 변환(토큰)

https://github.com/nrye4286/Study/blob/main/kor_eng.ipynb
(전체 코드)

0개의 댓글