# Live Coding 시나리오: Transformer Block 직접 만들어보기

<br>

> ## 학습 목표 (Learning Objectives)
>
> Transformer의 핵심 구성 요소인 Self-Attention, Multi-Head Attention, Feed-Forward Network를 PyTorch를 사용하여 밑바닥부터(from scratch) 구현함으로써 Transformer의 내부 동작 원리를 깊이 있게 이해합니다.

<br>

> ## 핵심 요약 (Key takeaways)
> 
> Transformer의 핵심 동작 원리를 이해하기 위해, PyTorch를 사용해 주요 구성 요소인 Scaled Dot-Product Attention, Multi-Head Attention, Feed-Forward Network를 직접 구현합니다. 이 과정에서 Q, K, V의 개념과 행렬 연산, 마스킹, 그리고 여러 Attention 헤드를 사용하는 이유를 학습합니다. 최종적으로 이들을 결합하고 잔차 연결(Residual Connection)과 Layer Normalization을 추가하여 완전한 Transformer Block 하나를 조립합니다.
> 
> **대상:** Python 및 PyTorch 기본 문법에 익숙하지만, Transformer의 내부 구조를 더 명확히 알고 싶은 개발자
> 
> **예상 소요 시간:** 45-50분
> 
> **결과물:** `source_code/07_deep_learning/live_coding_transformer_from_scratch.py`

---

<br>

> ## 세션 개요 및 진행 계획
> 
> | 시간 (분) | 내용                                                                      | 핵심 포인트                                                                  |
> | :-------- | :------------------------------------------------------------------------ | :--------------------------------------------------------------------------- |
> | 5         | **도입:** Transformer 아키텍처 개요 및 Live Coding 목표 소개              | "Attention is All You Need", Encoder-Decoder 구조, 오늘 만들 부분(Block) 소개 |
> | 15        | **Part 1: Scaled Dot-Product Attention 구현**                             | Q, K, V의 의미, 행렬 연산, 마스킹(masking)의 역할, 스케일링(scaling)의 중요성 |
> | 15        | **Part 2: Multi-Head Attention 구현**                                     | Attention을 여러 "헤드"로 나누는 이유, `split`과 `concat`을 통한 구현      |
> | 10        | **Part 3: Transformer Block 조립**                                        | 잔차 연결(Residual Connection)과 Layer Normalization의 역할, FFN 추가       |
> | 5         | **마무리:** 완성된 코드 리뷰 및 전체 아키텍처 내에서의 역할 설명, Q&A | Encoder Block과 Decoder Block의 차이점, 다음 학습 단계 제안                 |

---

<br>

> ## Live Coding 상세 시나리오
> 
> ### 1. 도입 (5분)
> 
> - Transformer가 NLP뿐만 아니라 다양한 분야에서 왜 혁신적인지를 간략히 설명합니다.
> - "Attention is All You Need" 논문의 핵심 아이디어(RNN/CNN 없이 Attention만으로 시퀀스 처리)를 강조합니다.
> - 거대한 Transformer 아키텍처 그림을 보여주며, 오늘 우리가 집중할 부분은 이 아키텍처를 구성하는 핵심 부품인 'Encoder Block' 또는 'Decoder Block' 하나라는 것을 명확히 합니다.
> 
> ### 2. Part 1: Scaled Dot-Product Attention (15분)
> 
> - **개념 설명**:
>     - Attention의 직관적 의미를 "Query가 Key와의 유사도를 계산하여 Value의 가중합을 얻는 과정"으로 설명합니다.
>     - Q, K, V 행렬의 형태(shape)와 의미를 설명합니다. `(batch_size, seq_len, d_model)`
> - **코드 구현**:
>     - `torch.matmul(q, k.transpose(-2, -1))` 로 Attention Score를 계산하는 것부터 시작합니다.
>     - 스케일링 팩터 `sqrt(d_k)`로 나누는 이유(gradient 안정화)를 설명하며 코드를 추가합니다.
>     - (선택적) 마스킹이 필요한 이유(padding token 무시, decoder의 look-ahead 방지)를 설명하고, `masked_fill_`을 사용하여 구현합니다.
>     - `torch.softmax`를 적용하여 최종 Attention Weight를 얻고, 이를 `v`와 곱하여 결과(context vector)를 계산하는 코드를 완성합니다.
>     - 입력과 출력의 텐서 형태가 동일하게 유지됨을 확인합니다.
> 
> ### 3. Part 2: Multi-Head Attention (15분)
> 
> - **개념 설명**:
>     - "한 번에 보는 것보다, 여러 관점에서 나누어 보는 것"이 왜 더 효과적인지를 비유적으로 설명합니다. (e.g., "문장의 다른 의미적/문법적 관계를 동시에 파악")
>     - `d_model` 차원의 벡터를 `num_heads`개의 `d_k` (d_model / num_heads) 차원 벡터로 나누는 과정을 설명합니다.
> - **코드 구현**:
>     - 입력으로 들어온 Q, K, V를 각각 `nn.Linear`를 통과시켜 새로운 Q, K, V를 만듭니다.
>     - 이 Q, K, V를 `num_heads`에 맞게 `split`하고 `transpose`하여 `(batch_size, num_heads, seq_len, d_k)` 형태로 변환하는 함수를 작성합니다.
>     - Part 1에서 만든 `scaled_dot_product_attention` 함수를 재사용하여 Attention을 계산합니다.
>     - Attention 계산 후, 흩어졌던 헤드들을 `concat`하고 `nn.Linear`를 통과시켜 최종 출력을 만드는 코드를 완성합니다.
>     - `nn.Module`을 상속받아 `MultiHeadAttention` 클래스로 전체 로직을 캡슐화합니다.
> 
> ### 4. Part 3: Transformer Block 조립 (10분)
> 
> - **개념 설명**:
>     - Add & Norm (잔차 연결 + Layer Normalization)의 역할을 설명합니다. (그래디언트 소실 문제 완화, 학습 안정화)
>     - Position-wise Feed-Forward Network (FFN)의 구조와 역할을 설명합니다. (비선형성 추가)
> - **코드 구현**:
>     - **Sub-layer 1**: `MultiHeadAttention`을 적용한 결과에 `input`을 더하고(`x + self.attention(x)`) `LayerNorm`을 적용합니다.
>     - **Sub-layer 2**: 위 결과물을 `FFN`에 통과시킨 후, 다시 한번 Add & Norm을 적용합니다.
>     - 위 과정을 `EncoderBlock` (또는 `DecoderBlock`) 이라는 `nn.Module` 클래스로 캡슐화합니다.
> 
> ### 5. 마무리 (5분)
> 
> - 오늘 만든 Transformer Block이 어떻게 여러 개 쌓여 전체 Encoder/Decoder를 구성하는지 보여줍니다.
> - Encoder Block과 Decoder Block의 미세한 차이(Masked Multi-Head Attention 사용 여부 등)를 짚어줍니다.
> - 완성된 `live_coding_transformer_from_scratch.py` 코드를 전체적으로 리뷰합니다.
> - `transformers` 라이브러리의 `BertModel`과 같은 실제 구현체와 오늘 만든 코드의 관계를 설명하며, 라이브러리 사용의 중요성을 강조합니다.
> - Q&A 시간을 갖습니다. 