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