: 순차적 처리(순환 신경망)나 반복 연결 없이도
긴 시퀀스를 빠르고 효율적으로 다룰 수 있는 구조
• 핵심 아이디어: 셀프-어텐션(Self-Attention)
• 학습 방식
오토인코딩(Auto-Encoding, 양방향 인코더)
문장 일부를 빈칸 토큰으로 만든 뒤, 해당 토큰을 예측하도록 학습
자가회귀(Auto-Regressive, 단방향 디코더)
주어진 앞쪽(또는 앞뒤) 토큰을 보고 다음 토큰을 순차적으로 예측
→ 인코더는 주로 이해(분류·추론), 디코더는 주로 생성(번역·생성) 작업에 활용
• 인코더–디코더 구조
여러 개의 Transformer Block으로 구성
각 블록 내부 :
멀티-헤드 셀프 어텐션(Multi-Head Self-Attention)
: 입력 시퀀스의 각 위치에 대해 Query·Key·Value를 생성.
토큰 간 유사도(어텐션 가중치)를 계산하여 값(Value) 벡터를 가중합.
순방향 FFN & 레지듀얼 연결
: 어텐션 출력에 선형층·비선형 활성화(ReLU) 적용.
레지듀얼(잔차) 연결 및 층 정규화(LayerNorm)
위치 인코딩(Positional Encoding)
: 셀프 어텐션 자체는 토큰 순서를 구분하지 못하기 때문에,
입력 임베딩에 순서 정보를 추가 (소스 위치 정보 인코딩)
인코더와 마찬가지로 여러 Transformer Block으로 구성
각 블록 내부 :
마스크드 멀티-헤드 셀프 어텐션
: 미래 토큰 정보가 보이지 않도록 마스킹하여 자동회귀 생성.
인코더-디코더 어텐션
: 디코더의 Query가 인코더 출력(Key·Value)에 어텐션을 수행하여
소스 문맥 반영.
순방향 FFN & 레지듀얼 연결
Transformer는 RNN/CNN과 달리 순차 처리 없이 병렬로 입력 시퀀스를 처리하므로, 단어의 위치(순서) 정보가 모델에 제공되지 않음.
→ 각 토큰 임베딩에 ‘위치 정보’를 더해 주어야 순서 관계를 학습할 수 있음.
각 위치 pos 와 임베딩 차원 인덱스 i 를 입력으로,
사인·코사인 함수를 사용해 벡터를 계산
짝수 인덱스 차원에는 sin, 홀수 인덱스 차원에는 cos를 적용
분모의 스케일링 인자 를 통해 다양한 주기의 주기적 신호 생성
초기화 단계 :
max_len (최대 시퀀스 길이)와 d_model (임베딩 차원)을 입력 받아, 크기 [max_len, 1, d_model] 의 텐서 pe를 미리 계산.
torch.sin, torch.cos 로 각 위치·차원별 값을 채워 두고 register_buffer("pe", pe) 로 학습 대상이 아니게 등록.
forward 단계 :
입력 임베딩 x (크기 [seq_len, batch, d_model])에,
미리 계산된 pe[:seq_len]을 더함
그 뒤 Dropout을 적용하여 순서 정보가 결합된 최종 입력을 생성
문장 구조 표시 :
<BOS> : 문장의 시작 표시<EOS> : 문장의 끝 표시미등록·패딩 처리 :
<UNK> : 어휘 사전에 없는 알 수 없는 토큰 처리<PAD> : 짧은 문장을 일정 길이로 맞추기 위해 뒤에 채워 넣는 토큰마스킹(Masking) :
토큰화 & 인덱싱
입력 문장을 어휘 사전(vocabulary) 토큰 시퀀스로 변환
각 토큰에 0부터 V−1까지 정수 인덱스 부여
원-핫(one-hot) 표현
어휘 사전 크기 V인 벡터에서 해당 토큰 인덱스 위치만 1, 나머지 0
ex. “트랜스포머” 인덱스 i → [0,…,0,1,0,…,0] (길이 V)
임베딩 룩업
크기 [V, d] 임베딩 행렬 E 준비 (d는 임베딩 차원)
원-핫 벡터 × E → 길이 d의 실수 벡터 (토큰 임베딩)
전체 시퀀스 S토큰 → [S, d] 크기 텐서
모델 전 계층 공유
얻은 임베딩 텐서는 Transformer의 인코더·디코더 전 블록에서
동일하게 사용
임베딩된 입력을 세 개의 선형층으로 변환하여
쿼리(Q) · 키(K) · 값(V) 벡터 생성
각 토큰의 Q·K 내적을 √d로 스케일링 후
소프트맥스로 어텐션 스코어를 계산
어텐션 스코어로 원본 값(Value) 벡터를 가중합 → 셀프 어텐션된 벡터 생성
이 과정을 여러 개(헤드) 동시 수행
→ 결과를 이어 붙여(concat) 하나의 벡터로 합침
최종 인코더 블록의 출력 벡터들을 디코더로 전달
→ 디코더의 인코더–디코더 멀티-헤드 어텐션에서 Key·Value로 사용
→ 양쪽이 키·값 벡터를 주고받아 문맥적 생성 및 번역 성능 강화
−inf) 마스크 적용.마지막 블록의 출력에 선형 투영 및 소프트맥스 적용
→ 각 위치마다 다음 토큰의 예측 확률 산출
예측된 토큰을 순차적으로 생성하며,
빈 자리는 PAD 토큰으로 채워서 다음 단계 입력으로 사용
: 어휘 사전 크기(Vocab size)와 임베딩 차원(emb_size)을 받아 nn.Embedding(vocab_size, emb_size) 로 토큰 인덱스를 벡터로 변환
벡터 크기를 √emb_size 만큼 스케일링
: 최대 시퀀스 길이(max_len)와 임베딩 차원(d_model)을 받아
각 위치(pos)와 차원 인덱스(i)에 대해
미리 계산한 위치 인코딩(pe)을 등록버퍼로 저장
순전파 시 입력 임베딩에 pe 를 더하고 드롭아웃
초기화
src_tok_emb(소스), tgt_tok_emb(타깃) : TokenEmbedding
positional_encoding : PositionalEncoding
self.transformer = nn.Transformer(...)
self.generator = nn.Linear(emb_size, tgt_vocab_size)
: 디코더 최종 출력을 어휘 크기만큼의 로짓(logit)으로 변환
순전파(forward)
src)와 타깃(trg) 토큰 인덱스를 임베딩 → 위치 인코딩src_emb = positional_encoding(src_tok_emb(src))
tgt_emb = positional_encoding(tgt_tok_emb(trg))
self.transformer 에 소스/타깃 임베딩,
마스크(mask)·패딩(padding) 마스크 전달
디코더 출력(outs)을 self.generator 에 통과시켜 최종 로짓 반환
인코더·디코더 분리
def encode(self, src, src_mask):
return transformer.encoder(pos_enc(src_tok_emb(src)), src_mask)
def decode(self, tgt, memory, tgt_mask):
return transformer.decoder(pos_enc(tgt_tok_emb(tgt)), memory, tgt_mask)
encode : 소스→임베딩+위치→인코더 블록 → 메모리
decode : 타깃→임베딩+위치 + 메모리 → 디코더 블록
: 디코더 셀프-어텐션에서 현재 위치 이후의 토큰을 보지 못하게
(미래 정보 차단)하여 오토리그레시브 생성 인과성(causality)을 보장.
: 실제 토큰과 패딩(PAD_IDX)을 구분하여,
모델이 패딩 토큰을 연산에 포함하지 않도록 함.
[S_src, 1] 형태의 source_tensor 생성.src_mask를 [S_src, S_src] 크기의model.encode(source_tensor, src_mask) 호출 →ys 초기화max_len = num_tokens + 5 만큼 반복[BOS, y1, y2, …, yT, EOS]ys.flatten() → NumPy 배열vocab_transform[TGT_LANGUAGE])의 lookup_tokens(...)로 토큰 문자열 리스트 변환<bos>·<eos> 제거' '로 join → 최종 번역문 반환Transformer 디코더만을 여러 겹 쌓아 만든 언어 생성 모델
대규모 텍스트 말뭉치로 사전 학습(pre-training)한 후,
특정 자연어 처리 작업에 맞게 미세 조정(fine-tuning).
자연어 생성·기계 번역·질의응답·요약 등 다양한 작업에서 뛰어난 성능
Transformer의 디코더(Decoder) 블록만 12개 쌓음.
인코더-디코더 어텐션 없이,
디코더 내부의 마스크드 멀티헤드 셀프 어텐션만 사용.
단방향(Unidirectional) : 이전 토큰들만 보고 다음 토큰을 예측.
<start> 토큰, 마지막에 <extract> 토큰 등 특수 토큰 삽입–inf 채우기단방향(Self-Attention, 마스크드 멀티헤드 어텐션)
: 미래 토큰 정보는 볼 수 없도록 마스크 처리,
이전 토큰들만 활용해 다음 토큰 예측.
토큰 임베딩 + 위치 인코딩 → 디코더 첫 블록 입력
연산량 절감을 위해 Sparse Attention(희소 어텐션)과 일반 어텐션 혼합 사용
장점
단점
기본 구조 : GPT-3의 디코더 전용 Transformer 아키텍처 계승
추가 학습 기법 : RLHF(Reinforcement Learning from Human Feedback) 도입
목표 : 모델이 더 자연스럽고 유용한 답변을 생성하도록 보강
Supervised Fine-Tuning (SFT)
Reward 모델 학습
최종 강화학습 (Policy Optimization)
환각(Hallucination)
MMLU(BigBench 계열) 벤치마크
: GPT-2를 이용한 문장 분류(Sequence Classification)
주요 구성 요소
wte (token embedding)wpe (position embedding)drop (dropout)h (12개 디코더 블록)ln_f (마지막 LayerNorm)lm_head (출력 로짓을 만드는 linear layer): pipeline(task="text-generation", model="gpt2") 로
생성 파이프라인 인스턴스 생성
주요 파라미터
text_inputs : 프롬프트(입력 문장)max_length : 생성할 최대 토큰 길이num_return_sequences : 출력 시퀀스 개수pad_token_id : 자유 생성(open-end)을 위해torchtext.datasets.CoLA로 train/dev/test 분할 불러오기.
AutoTokenizer.from_pretrained("gpt2") 사용,
GPT-2는 pad 토큰이 없으므로
tokenizer.pad_token = tokenizer.eos_token 으로 설정
collator 함수
tokenizer(..., padding="longest", truncation=True, return_tensors="pt") 로 토크나이즈input_ids, attention_mask, labels 텐서 생성 및 디바이스로 이동패딩 토큰 설정
: GPT-2 토크나이저에는 원래 pad 토큰이 없으므로
model.config.pad_token_id = model.config.eos_token_id
로 EOS 토큰을 패딩 토큰으로 대체
CoLA 데이터(8,550개 학습 샘플)만으로도 약 74% 정확도를 달성