Deep Learning

[NLP] GPT의 구조와 입출력 방식을 알아보자

seoraroong 2024. 11. 1. 14:01

GPT (Generative Pre-trained Transformer)는 OpenAI가 개발한 언어 모델로, 주어진 텍스트의 문맥을 이해해 자연스럽고 연속적인 텍스트를 생성할 수 있는 능력을 가진 모델이다.

GPT는 Transformer 구조를 기반으로, Self-Attention Mechanism을 활용해 시퀀스 데이터를 효율적으로 학습한다.

 

BERT가 MLM, NSP등의 학습 방식과  pre-trained model 사용에 있어 변화를 가져왔다면, GPT는 다음과 같은 변화를 가져왔다고 할 수 있다.

 

- Self-supervised Learning

GPT의 사전 학습 방식은 다음 단어를 예측하는 task라고 할 수 있다.

쉽게 말하면, 주어진 텍스트 시퀀스에서 이전 단어들로부터 다음 단어를 예측하도록 모델이 학습된다.

이를 통해 모델은 Label이 없는 데이터를 통해서도 스스로 예측을 해 언어 패턴을 학습하게 된다.

 

- In-context Learning

GPT 모델에 특정 작업을 수행하게 할 때 모델이 이전에 보지 못한 과제를 처리하기 위해 추가 학습 과정 없이 몇 가지 예시를 프롬프트로 제공한다. 모델은 이 예시를 토대로 특정 task의 패턴을 파악하고, 주어진 입력에 맞는 결과를 생성하게 된다.

In-context Learning은 Zero-shotFew-shot으로 구분할 수 있다.

 

Zero-shot Learning (ZSL)

훈련 데이터가 없는 상태에서, 모델이 학습 과정에서 접하지 못한 새로운 클래스를 인식할 수 있도록 하는 학습 방법이다.

모델은 기존에 학습한 언어 패턴과 지식을 기반으로 추론해 결과를 도출해내게 된다.

 

Few-shot Learning (FSL)

아주 적은 양의 데이터를 이용해 새로운 작업이나 클래스를 학습하도록 설계한 방법이다. 

 

이와 같은 In-context Learning을 이용해 텍스트로 지시를 입력하고 수행하도록 하는 것을 Prompt Engineering이라고 한다.


GPT Architecture

앞서 공부했던 BERT는 Transformer 모델을 기반으로 Encoder 구조를 가져와 모델을 학습했다. 

GPT 또한 Transformer 모델을 기반으로 하는 것은 동일하나, Encoder가 아닌 Decoder 구조로 구성되어 있다.

 

https://wikidocs.net/184363

Transformer Encoder

인코더가 각 토큰의 Embedding을 받게 된다. 그림의 화살표는 Attention Mechanism을 의미하며 특정 단어들이 다른 단어와 어떻게 연관되는지 계산한다.

Encoder에서는 입력의 정보를 담은 출력 벡터를 생성하게 되고, Decoder에 전달되어 문장의 의미나 문맥 정보를 제공하는 데 사용된다.

 

Transformer Decoder

Decoder는 <sos>, I, love와 같은 시작 토큰과 입력 토큰을 받게 된다. 

이 때 Decoder는 Encoder로부터 받은 출력 벡터와 자기 자신의 Self-Attention Mechanism을 결합해 다음 단어인 you를 예측하게 된다.

이후 step에서는 출력된 you라는 단어를 다음 입력으로 넣어 you 이후의 새로운 단어를 예측하게 된다. 

 

https://wikidocs.net/184363 , GPT의 Decoder 구조
https://wikidocs.net/31379, Transformer의 Decoder 구조

- GPT는 Encoder-Decoder Attention이 없다!

앞서 말했듯, GPT는 Transformer 모델의 Decoder만 가져온 구조로 구성되어 있다. 그래서 기존 Transformer의 Decoder에 있던 Encoder-Decoder Attention layer가 빠져 있는 형태임을 알 수 있다.

 

Encoder-Decoder Attention이 어떤 역할을 했는지 되짚어보면 이해하기 쉽다.

 

Transformer의 Decoder에서 Encoder-Decoder Attention은 Decoder의 Masked Self-Attention layer에서 만들어진 문맥 벡터를 Query로 사용해 Encoder에서 받은 Key, Value라는 입력 문장 정보를 결합하는 방식이다.

 

GPT는 단일 방향 자기 회귀 모델로, 단방향으로 다음 단어를 예측하는 텍스트 생성 작업에 맞게 설계되었기 때문에, 위와 같이 입력 정보를 이용해 어떤 단어가 중요한지 판단할 필요가 없게 된다.

 

- Look-ahead Mask와 Causal Mask

GPT의 Decoder 부분을 보면 Masked Self-Attention을 사용하는 것을 볼 수 있다.

Transformer의 Look-ahead Mask와 GPT의 Causal Mask는 모델이 다음에 어떤 단어가 올지 미리 보는 것을 방지 하기 위해 미래 정보를 차단하는 것이 목적이다. 즉, 본질적으로 똑같은 방식으로 작동한다. 

 

그럼 왜 이름을 다르게 쓰는거지?

Causal인과 관계를 의미하는 단어이다. GPT 같은 자기 회귀 모델은 앞에 있는 단어가 원인 (cause)이 되고, 뒤에 나오는 단어들이 결과가 된다.

그래서 이 Mask를 통해 앞에 있는 단어를 통해서만 뒤에 나오는 단어가 결정되도록 하겠다는 의미를 담은 것이다. 

 

- Layer Normalization Layer의 위치가 다르다!

 

먼저 기본 Transformer 모델의 Layer Normalization Layer의 위치를 살펴보도록 하자.

그림을 잘 보면 Layer Normalization이 Residual 연결 후에 위치해 있다.

Residual 연결이란, 입력 값을 그대로 다음 layer로 전달해, 모델이 깊어지더라고 정보 손실을 줄이고 안정적인 학습을 할 수 있도록 하는 방법을 말한다.

Layer를 통과한 출력에 입력을 더해주는 것이다. 

즉, 각 서브 레이어 (Self-Attention, FFNN) 후에 Layer Normalization을 적용한다,

 

도식화 해보면,

(Self Attention) -> Residual 연결 -> Layer Normalization

 

이 방식을 Add&Norm이라고 하며, sub layer의 출력을 원래 입력과 합친 뒤 Layer Normalization을 적용하는 구조이다.

 

이제, GPT 구조에서 Layer Normalization Layer의 위치를 살펴보자.

그림을 잘 보면 Layer Normalization이 Residual 연결 전에 위치해 있다.

Self-Attention과 Feed Forward Network에 들어가기 전 Layer Normalization을 적용하고, Residual 연결을 하게 된다.

이 방식을 Pre-Layer Normalization 이라고도 한다. 

 

도식화 해보면,

Layer Normalization -> (Self Attention) - Residual 연결

 

이 방식은 모델의 안정적인 학습과 성능 향상에 도움을 주며, 특히 큰 모델에서 일반적인 Layer Normalization보다 더 안정적인 학습이 가능하다. 왜?

 

Residual 연결 전에 Layer Normalization을 적용하게 되면, 각 layer에 들어가는 입력 값의 분포가 일정하게 유지되므로 기울기 흐름 또한 일정하게 유지된다.

각 layer가 독립적, 안정적으로 학습할 수 있게 되어 모델이 깊어질수록 발생하는 불안정성을 줄여주게 된다.

 

- Activation Function으로 GELU를 사용한다!

기본 Transformer는 활성화 함수로 ReLU를 사용했다. GPT에서는 GELU (Gaussian Error Linear Unit)을 사용한다.

GELU는 ReLU에 비해 더 부드러운 활성화 함수로, 모델의 표현 능력을 강화하고 언어 모델의 성능 향상에 도움을 준다고 한다. 

 

그래서 GELU가 뭔데?

GELU는 다음 포스팅에서 자세히 알아보도록 하자.

 

ReLU: 입력 값이 양수일 때는 그대로 출력하고, 음수일 때는 0을 출력하는 방식 

ReLU를 기반으로 개발된 ELU: ReLU의 출력에 음수를 포함해 학습 속도를 높인 방식

 

GELU는 기존 ReLU나 ELU와 달리 확률론적 관점에서 뉴런의 출력을 고려해 설계된 방식이다.

입력 값에 따라 뉴런이 활성화될 확률을 계산해 뉴런이 확률적으로 활성화되도록 한다.

 

입력값 x에 대해 표준 정규분포의 누적 분포 함수(CDF) 를 사용

erf: 오차함수 (error function) -> 정규 분포의 누적 분포를 계산할 때 사용

-> 이게 뭔데?

CDF는 입력값 x가 특정 임계치보다 낮거나 높을 확률을 나타낸다.

 

입력 x가 낮을수록 뉴런이 꺼질 확률이 높아지고, x가 높은 값일수록 활성화될 확률이 높아진다. 

 

 

ReLU는 입력값이 음수일 때 출력값이 완전히 0으로 고정된다. -> 그냥 바로 뉴런이 꺼져버린다.

x > 0 구간에서는 출력이 x에 비례해 선형적으로 증가한다. -> 뉴런이 활성화된 상태이다.

 

GELU는 입력값이 음수일 때 완전히 0이 되는 것이 아니고 부드럽게 감소한다 -> 뉴런이 점진적으로 꺼진다.

x > 0 구간에서는 입력값과 출력값이 비슷해지며 뉴런이 활성화되는 것을 알 수 있다. 

 

GELU의 장점

ReLU의 경우 x = 0 지점에서 미분이 불가능하기 때문에 뉴런이 꺼진 상태 (출력 0) 에서 급격하게 활성화 (출력 x)로 변화하는 구간이 존재한다.

-> 이러한 급격한 변화의 경우, 특정 입력값 근처에서 작은 변화에 영향을 미치므로 학습이 불안정해질 수 있다.

 

GELU는 모든 지점에서 미분이 가능하기 때문에 미세한 입력 변화에도 점진적으로 반응한다.

-> 세밀한 패턴을 학습할 수 있고 연속적인 데이터 처리가 가능하다.


GPT의 입출력 방식

"동해물과 백두산이 마르고 닭도록"

위 문장을 예시로 들어보자.

 

처음에 Input Sequence로 "동해물과"가 들어가게 된다

Input Sequence "동해물과" -> Embedding -> Decoder -> Decoder -> Decoder -> Classifier -> "백두산이" 출력

 

Embedding: 입력된 텍스트 시퀀스의 각 토큰을 벡터로 변환 + Position Encoding을 통해 시퀀스 내 단어 위치 정보 포함

Encoder: 

모델이 추론한 "백두산이"는 다시 Input Sequence가 되어 위 과정을 반복하게 된다.

 

Input Sequence 길이 제한

이론 상 Transformer의 Input Sequence에 길이 제한은 없다. 그런데 왜 길이 제한을 해야 하느냐,

연산 비용과 메모리 사용량을 관리하기 위해서이다.

 

Self-Attention의 연산 복잡도는 O(n^2)이다. 따라서 Input Sequence 길이의 제곱에 비례해 메모리 사용량이 늘어나게 된다.

n은 Input Sequence 길이

 

그래서 다음과 같은 방식을 사용해 길이 제한을 줄 수 있다.

 

1. Sliding Window

긴 텍스트를 일정 길이의 Window로 분할해 입력하고, 연속성을 유지하기 위해 윈도우를 중복해서 입력한다.

장점: 중복을 통해 문맥 정보를 유지할 수 있다.

단점: 중복된 부분이 많아질수록 연산량이 증가해 효율이 떨어질 수 있다.

 

2. Chunking

텍스트를 중복 없이 일정 길이로 나누어 개별 청크(chunk)로 처리한다.

장점: 중복이 없기 때문에 Sliding Window 방식보다 연산량이 적다.

단점: 중복이 없기 때문에 문맥의 연속성이 떨어져 중요한 연결 정보가 손실될 수 있다.

 

3. Truncation (잘라내기)

긴 텍스트에서 가장 중요한 부분만 남기고 나머지를 잘라낸다.

[제목] 경제 회복 신호, 주식 시장에 긍정적인 영향
[첫 문단] 오늘 발표된 경제 지표에 따르면, 지난 분기의 GDP가 2.5% 성장한 것으로 나타났다. 전문가들은 이번 성장이 경기 회복의 신호라고 평가했다.
[두 번째 문단] 특히 소비자 지출이 큰 폭으로 증가하면서 기업들의 실적 개선이 기대되고 있다.
[세 번째 문단] 그러나, 일부 전문가들은 글로벌 시장의 불확실성이 여전히 남아 있어 장기적인 전망에 대해서는 신중해야 한다고 지적했다.

 

만약 위 뉴스 기사에서 [첫 문단][두 번째 문단]만 남기고 나머지를 잘라낸다고 생각해보자.

 

핵심 정보인 경제 성장률과 긍정적인 전망이 포함되어 있기 때문에 중요한 내용을 파악할 수 있다.

그러나,

[세 번째 문단]에 "글로벌 시장의 불확실성"에 대한 정보가 있으므로, 만약 투자 결정을 위한 분석 자료로 사용하게 되면 잘못된 판단을 이끌어낼 수 있다.

 

장점: 중요한 부분만 남기기 때문에 메모리와 연산 자원을 절약할 수 있다.

단점: 잘려나간 부분에 중요한 정보가 포함되어 있다면 모델 성능에 부정적인 영향을 줄 수 있다.

 

4. 메모리 최적화 Attention (Sparse Attention)

기존 Self-Attention 방식은 모든 단어 쌍의 관계를 파악한다면, Sparse Attention은 일부 단어 쌍만 선택해 관계를 계산한다.

 

장점: 메모리 사용량을 줄여 더 긴 텍스트를 처리할 수 있고, 중요한 부분에 집중할 수 있다.

단점: Attention이 제한되어 모든 단어 간의 관계를 파악하기 어렵다.

 

5. Hierarchical Transformer

긴 텍스트를 분할해 하위 계층의 Transformer가 각각 부분적으로 처리한 뒤, 이 결과를 상위 계층의 Transformer에 전달해 최종 출력을 생성한다.

 

장점: 긴 텍스트를 효과적으로 처리할 수 있고, 하위-상위 구조로 정보의 흐름을 유지할 수 있다

단점: 모델 구조가 복잡해져서 학습 및 추론 비용이 증가할 수 있다.

 

그렇다면 GPT 모델은 어떤 방법을 채택하고 있는가?

GPT-2: 1024 토큰

GPT-3: 2048 토큰

GPT-4o: 4096 토큰

이 제한을 초과하는 입력이 들어오게 되면, 초과한 부분을 잘라내는 Truncation 방식을 채택하고 있다.