Commit 00587836 authored by insun park's avatar insun park
Browse files

Update lecture materials: Enhance AI course content with new sections on...

Update lecture materials: Enhance AI course content with new sections on FastAPI model serving, advanced RAG techniques, and AI agents, while improving formatting and structure for better readability.
parent 07914407
# 인공지능의 역사: 개념의 진화
---
marp: true
theme: gaia
class:
- lead
- invert
---
<!-- _class: lead -->
<!-- _header: "" -->
<!-- _footer: "" -->
<style>
h1 {
font-size: 2.5em;
font-weight: 600;
}
h2 {
font-size: 2em;
font-weight: 600;
}
h3 {
font-size: 1.6em;
font-weight: 600;
}
h4 {
font-size: 1.3em;
font-weight: 600;
}
h5 {
font-size: 1.1em;
font-weight: 600;
}
h6 {
font-size: 1em;
font-weight: 600;
}
p, li, ul, ol, table {
font-size: 28px;
}
pre, code {
font-size: 24px;
}
</style>
# Part 0.1: AI의 역사와 주요 이정표
## 서론: 생각하는 기계라는 오랜 꿈
......@@ -144,3 +189,8 @@
---
*이 문서는 [IBM의 AI 역사](https://www.ibm.com/think/topics/history-of-artificial-intelligence) 등 여러 AI 역사 관련 자료를 참고하여 개념의 흐름을 중심으로 재구성되었습니다.*
---
**⬅️ 이전 시간: [Part 0: 시작하며 - AI 전문가 양성 과정](./part_0_introduction.md)**
**➡️ 다음 시간: [Part 1: AI 개발 환경 준비](../01_ai_development_environment/part_1_ai_development_environment.md)**
\ No newline at end of file
# Part 1: AI 개발 환경 완벽 구축 가이드
---
marp: true
theme: gaia
class:
- lead
- invert
---
**⬅️ 이전 시간: [Part 0: 시작하며](../00_introduction/part_0_introduction.md)**
<!-- _class: lead -->
<!-- _header: "" -->
<!-- _footer: "" -->
<style>
h1 {
font-size: 2.5em;
font-weight: 600;
}
h2 {
font-size: 2em;
font-weight: 600;
}
h3 {
font-size: 1.6em;
font-weight: 600;
}
h4 {
font-size: 1.3em;
font-weight: 600;
}
h5 {
font-size: 1.1em;
font-weight: 600;
}
h6 {
font-size: 1em;
font-weight: 600;
}
p, li, ul, ol, table {
font-size: 28px;
}
pre, code {
font-size: 24px;
}
</style>
# Part 1: AI 개발 환경 설정
**⬅️ 이전 시간: [인공지능의 역사](../00_introduction/part_0.1_history_of_ai.md)**
**➡️ 다음 시간: [Part 2: 파이썬 핵심 문법](../02_python_core_syntax/part_2_python_core_syntax.md)**
---
......@@ -570,5 +615,5 @@ Hacker News 커뮤니티와 실제 개발자들의 경험을 바탕으로 한
---
**⬅️ 이전 시간: [Part 0: 시작하며](../00_introduction/part_0_introduction.md)**
**⬅️ 이전 시간: [인공지능의 역사](../00_introduction/part_0.1_history_of_ai.md)**
**➡️ 다음 시간: [Part 2: 파이썬 핵심 문법](../02_python_core_syntax/part_2_python_core_syntax.md)**
\ No newline at end of file
......@@ -161,8 +161,13 @@ print(f"학점: {grade}")
> print(f"결과: {status}") # 출력: Pass
> ```
### 7.3. `for`: 순서대로 반복하기
리스트, 튜플, 문자열 등 순회 가능한 객체의 요소를 하나씩 순회합니다. `enumerate`를 사용하면 인덱스와 값을 함께 얻을 수 있습니다.
### 7.3. `for`: 파이썬답게 반복하기 (enumerate, zip)
`for`문은 파이썬에서 가장 많이 사용되는 반복문입니다. 리스트, 튜플, 문자열 등 순회 가능한 객체의 요소를 하나씩 순회하며, `enumerate``zip`과 함께 사용하면 더욱 강력하고 파이썬다운 코드를 작성할 수 있습니다.
#### `enumerate`: 인덱스와 값을 동시에 얻기
`for`문으로 리스트를 순회할 때, 각 요소의 인덱스 번호가 필요할 때가 많습니다. `enumerate`를 사용하면 별도의 변수 없이 인덱스와 값을 함께 얻을 수 있습니다.
```python
fruits = ["apple", "banana", "cherry"]
......@@ -170,6 +175,35 @@ for idx, fruit in enumerate(fruits):
print(f"{idx+1}번째 과일: {fruit}")
```
#### `zip`: 여러 리스트를 나란히 묶기
여러 개의 리스트를 마치 하나의 리스트처럼, 각 리스트의 같은 인덱스에 있는 요소들을 짝지어 반복하고 싶을 때 `zip`을 사용합니다.
```python
names = ['앨리스', '밥', '찰리']
ages = [25, 30, 28]
for name, age in zip(names, ages):
print(f"{name}의 나이는 {age}세입니다.")
```
> [!TIP]
> `zip`은 가장 짧은 리스트의 길이를 기준으로 동작합니다. 리스트들의 길이가 다르면, 짧은 쪽이 끝났을 때 반복도 함께 종료됩니다.
#### `enumerate`와 `zip` 함께 사용하기: 인덱스와 여러 값 동시에 다루기
두 기능을 합치면, 여러 리스트를 순회하면서 동시에 인덱스 번호까지 얻을 수 있습니다. 학생들의 성적을 처리하는 경우를 예로 들어보겠습니다.
```python
names = ['Alice', 'Bob', 'Charlie']
subjects = ['Math', 'English', 'Science']
scores = [95, 88, 76]
for i, (name, subject, score) in enumerate(zip(names, subjects, scores)):
print(f"{i+1}번 학생 {name}{subject} 점수는 {score}점 입니다.")
```
이처럼 `enumerate``zip`을 활용하면 복잡한 반복 로직도 간결하고 읽기 좋은 코드로 표현할 수 있습니다.
### 7.4. `while`: 조건이 만족하는 동안 반복하기
주어진 조건이 `True`인 동안 코드를 계속해서 반복합니다. 조건이 언젠가 `False`가 되도록 만들지 않으면 '무한 루프'에 빠지므로 주의해야 합니다.
......@@ -204,52 +238,63 @@ print(f"홀수만 필터링: {odd_numbers}") # [1, 3, 5]
> `doubled_numbers = [x * 2 for x in numbers]`
> `odd_numbers = [x for x in numbers if x % 2 != 0]`
---
## 8. 코드를 재사용하는 마법, 함수
### 8.4. 파이썬의 모든 것은 객체: 변수와 함수의 동작 원리 (Call by Object Reference)
> **🎯 5일차 목표:** 반복되는 코드를 `[함수(Function)](../../glossary.md#함수-function)`로 묶어 재사용하고, 함수의 입력([매개변수](../../glossary.md#매개변수-parameter와-인자-argument))과 출력([반환 값](../../glossary.md#반환-값-return-value))을 이해합니다.
파이썬의 동작 방식을 깊이 이해하려면 "모든 것이 객체(Object)다"라는 개념을 알아야 합니다. 숫자, 문자열, 심지어 함수까지도 모두 메모리 상의 '객체'이며, 변수는 그 객체를 가리키는 '이름표'일 뿐입니다. 이 개념은 함수에 인자를 전달하는 방식에도 그대로 적용됩니다.
### 8.1. 함수(Function): 나만의 미니 프로그램
[함수]../../glossary.md#함수-function)는 특정 작업을 수행하는 코드 묶음에 이름을 붙인 **'재사용 가능한 레시피'**입니다. `def` 키워드로 정의하고, 이름으로 호출하여 사용합니다.
#### 함수는 1급 객체 (First-class Citizen)
### 8.2. 입력(매개변수)과 출력(반환 값)
- **[매개변수(Parameter)](../../glossary.md#매개변수-parameter와-인자-argument):** 함수에 전달하는 재료(입력 값).
- **[`return`](../../glossary.md#반환-값-return-value):** 함수가 작업을 마친 후 돌려주는 결과물(출력 값).
파이썬에서 함수는 특별한 취급을 받지 않습니다. 숫자나 리스트처럼 변수에 할당할 수 있고, 다른 함수의 인자로 전달하거나, 함수가 함수를 반환할 수도 있습니다. 이를 '함수는 1급 객체'라고 부릅니다.
```python
def add(a, b):
result = a + b
return result
def greeting(name):
print(f"안녕하세요, {name}님!")
# 함수 호출 및 결과 저장
sum_result = add(5, 3)
print(f"5 + 3 = {sum_result}")
# 함수 객체를 변수에 할당
welcome = greeting
welcome("파이썬") # "안녕하세요, 파이썬님!" 출력
# print 함수 자체도 객체이므로 변수에 할당 가능
say = print
say("이것도 print 함수처럼 동작합니다.")
```
함수를 잘 사용하면 복잡한 문제를 여러 개의 간단한 함수로 나누어 해결할 수 있어, 훨씬 체계적인 프로그래밍이 가능해집니다.
이 특징은 데코레이터처럼 함수의 기능을 동적으로 확장하는 강력한 패턴의 기반이 됩니다.
#### Call by Object Reference: 변수는 이름표일 뿐
### 8.3. 한 줄로 끝내는 익명 함수: 람다(Lambda)
`lambda`는 이름 없이 사용하는 간단한 한 줄짜리 함수입니다. '익명 함수'라고도 불리며, 복잡한 `def` 함수 정의가 필요 없는 간단한 작업을 다른 함수의 인자로 전달할 때 매우 유용합니다.
많은 언어에서 '값에 의한 호출(Call by Value)'과 '참조에 의한 호출(Call by Reference)'을 구분합니다. 파이썬은 이 둘을 섞어놓은 듯한 **'객체 참조에 의한 호출(Call by Object Reference)'** 방식을 사용합니다.
- **기본 문법**: `lambda 인자: 표현식`
- 함수에 인자를 전달할 때, 값의 복사본이나 변수의 메모리 주소가 넘어가는 것이 아니라, 변수가 가리키고 있는 **객체의 참조(주소값)가 복사되어** 전달됩니다.
예를 들어, 두 수를 더하는 간단한 함수는 `lambda`를 사용해 다음과 같이 표현할 수 있습니다.
**1. 변경 가능한(Mutable) 객체를 전달할 때 (e.g., 리스트, 딕셔너리)**
함수 안에서 전달받은 객체의 내용을 변경하면, 원본 객체에도 그 변경 사항이 그대로 반영됩니다. 왜냐하면 함수 안과 밖의 변수가 **같은 객체**를 가리키고 있기 때문입니다.
```python
# def add(a, b):
# return a + b
# 위 함수를 람다로 표현
add_lambda = lambda a, b: a + b
print(f"람다 함수 결과: {add_lambda(3, 5)}") # 출력: 람다 함수 결과: 8
# sorted() 함수의 key 매개변수에 활용
points = [(1, 5), (3, 2), (2, 8)]
# 각 튜플의 두 번째 요소를 기준으로 정렬
sorted_points = sorted(points, key=lambda point: point[1])
print(f"두 번째 원소로 정렬: {sorted_points}") # 출력: [(3, 2), (1, 5), (2, 8)]
def add_element(my_list):
my_list.append(4) # 리스트 내용 변경
numbers = [1, 2, 3]
add_element(numbers)
print(f"결과: {numbers}") # 출력: [1, 2, 3, 4]
```
`lambda`는 코드를 더 간결하고 직관적으로 만들어주지만, 복잡한 로직에는 일반적인 `def` 함수를 사용하는 것이 가독성에 더 좋습니다.
> 함수 안과 밖의 `numbers`와 `my_list`는 정확히 동일한 리스트 객체를 가리키므로, 함수 안에서의 변경이 밖에 영향을 줍니다.
**2. 변경 불가능한(Immutable) 객체를 전달할 때 (e.g., 숫자, 문자열, 튜플)**
변경 불가능한 객체는 그 내용을 바꿀 수 없습니다. 만약 함수 안에서 해당 변수에 새로운 값을 할당하면, 그것은 기존 객체를 바꾸는 것이 아니라 **새로운 객체를 만들어** 그 변수가 가리키게 하는 것입니다. 따라서 원본 변수에는 아무런 영향이 없습니다.
```python
def reassign_value(my_var):
my_var = 100 # 새로운 정수 객체를 생성하고 my_var가 가리키게 함
num = 10
reassign_value(num)
print(f"결과: {num}") # 출력: 10 (바뀌지 않음!)
```
> `reassign_value` 함수 안에서 `my_var`는 새로운 객체(`100`)를 가리키게 되지만, 함수 밖의 `num`은 여전히 원래 객체(`10`)를 가리키고 있습니다.
이러한 동작 방식을 이해하는 것은 파이썬 코드가 어떻게 실행되고 데이터가 어떻게 변하는지 정확히 예측하는 데 매우 중요합니다.
---
......
# Part 5: AI 핵심 라이브러리 마스터하기
---
marp: true
theme: gaia
class:
- lead
- invert
---
<!-- _class: lead -->
<!-- _header: "" -->
<!-- _footer: "" -->
<style>
h1 {
font-size: 2.5em;
font-weight: 600;
}
h2 {
font-size: 2em;
font-weight: 600;
}
h3 {
font-size: 1.6em;
font-weight: 600;
}
h4 {
font-size: 1.3em;
font-weight: 600;
}
h5 {
font-size: 1.1em;
font-weight: 600;
}
h6 {
font-size: 1em;
font-weight: 600;
}
p, li, ul, ol, table {
font-size: 28px;
}
pre, code {
font-size: 24px;
}
</style>
# Part 5: AI 핵심 라이브러리: NumPy, Pandas, Matplotlib
**⬅️ 이전 시간: [Part 4: 객체 지향 프로그래밍(OOP)](../04_object_oriented_programming/part_4_object_oriented_programming.md)**
**➡️ 다음 시간: [Part 6: 머신러닝 모델링과 평가](../06_machine_learning/part_6_machine_learning.md)**
**➡️ 다음 시간: [Part 5.5: NumPy로 배우는 선형대수](../05.5_linear_algebra_with_numpy/part_5.5_linear_algebra_with_numpy.md)**
---
......@@ -379,4 +424,4 @@ plt.show()
---
**➡️ 다음 시간: [Part 6: 머신러닝 모델링과 평가](../06_machine_learning/part_6_machine_learning.md)**
\ No newline at end of file
**➡️ 다음 시간: [Part 5.5: NumPy로 배우는 선형대수](../05.5_linear_algebra_with_numpy/part_5.5_linear_algebra_with_numpy.md)**
\ No newline at end of file
# Part 7: Deep Learning
> # Part 7: Deep Learning
<br>
이 파트에서는 인공 신경망의 개념부터 시작하여 CNN, RNN, Transformer 등 주요 딥러닝 아키텍처를 학습하고, PyTorch와 LangChain을 이용해 LLM 애플리케이션까지 구축하는 방법을 다룹니다.
## 📚 학습 자료
<br>
> ## 📚 학습 자료
- **[메인 강의 노트](./part_7_deep_learning.md)**: 딥러닝의 전반적인 개념을 소개합니다.
- **[7.1 순환 신경망 (RNN)](./part_7.1_recurrent_neural_networks.md)**
......@@ -13,11 +17,15 @@
- **[핵심 용어집](../../glossary.md)**
- **[LLM 앱 개발 용어집](./glossary_llm_application.md)**
## 💻 실습 코드
<br>
> ## 💻 실습 코드
- **[딥러닝 예제 코드](../../source_code/07_deep_learning/part_7_deep_learning.py)**
- **[LLM 앱 개발 예제 코드](../../source_code/07_deep_learning/7.3_llm_application_development_with_langchain/part_7.3_llm_application_development.py)**
---
<br>
[↩️ 전체 커리큘럼으로 돌아가기](../../README.md)
\ No newline at end of file
# Live Coding 시나리오: Transformer Block 직접 만들어보기
## 학습 목표 (Learning Objectives)
<br>
Transformer의 핵심 구성 요소인 Self-Attention, Multi-Head Attention, Feed-Forward Network를 PyTorch를 사용하여 밑바닥부터(from scratch) 구현함으로써 Transformer의 내부 동작 원리를 깊이 있게 이해합니다.
> ## 학습 목표 (Learning Objectives)
>
> Transformer의 핵심 구성 요소인 Self-Attention, Multi-Head Attention, Feed-Forward Network를 PyTorch를 사용하여 밑바닥부터(from scratch) 구현함으로써 Transformer의 내부 동작 원리를 깊이 있게 이해합니다.
## 핵심 요약 (Key takeaways)
<br>
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`
> ## 핵심 요약 (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의 차이점, 다음 학습 단계 제안 |
> ## 세션 개요 및 진행 계획
>
> | 시간 (분) | 내용 | 핵심 포인트 |
> | :-------- | :------------------------------------------------------------------------ | :--------------------------------------------------------------------------- |
> | 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의 차이점, 다음 학습 단계 제안 |
---
## 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 시간을 갖습니다.
\ No newline at end of file
<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 시간을 갖습니다.
\ No newline at end of file
......@@ -5,118 +5,140 @@
---
<br>
> [!WARNING]
> 이 파트는 현재 준비 중입니다. GNN의 핵심 개념과 PyTorch Geometric을 사용한 실습 코드가 추가될 예정입니다.
## 1. 학습 목표 (Learning Objectives)
이번 파트가 끝나면, 여러분은 다음을 할 수 있게 됩니다.
- 그래프(Graph) 데이터의 구조와 특징을 이해합니다.
- GNN이 왜 필요한지, 기존의 신경망과 무엇이 다른지 설명할 수 있습니다.
- GNN의 핵심 아이디어인 메시지 패싱(Message Passing)의 기본 개념을 이해합니다.
- PyTorch Geometric 라이브러리를 사용하여 간단한 GNN 모델을 구성할 수 있습니다.
## 2. 핵심 키워드 (Keywords)
<br>
`그래프 신경망(GNN)`, `그래프 데이터(Graph Data)`, `노드(Node)`, `엣지(Edge)`, `인접 행렬(Adjacency Matrix)`, `메시지 패싱(Message Passing)`, `PyTorch Geometric`
> ## 1. 학습 목표 (Learning Objectives)
>
> 이번 파트가 끝나면, 여러분은 다음을 할 수 있게 됩니다.
>
> - 그래프(Graph) 데이터의 구조와 특징을 이해합니다.
> - GNN이 왜 필요한지, 기존의 신경망과 무엇이 다른지 설명할 수 있습니다.
> - GNN의 핵심 아이디어인 메시지 패싱(Message Passing)의 기본 개념을 이해합니다.
> - PyTorch Geometric 라이브러리를 사용하여 간단한 GNN 모델을 구성할 수 있습니다.
## 3. 도입: 관계를 학습하는 모델, GNN
<br>
세상은 연결의 집합입니다.
- **소셜 네트워크**: 사람(노드)들은 친구 관계(엣지)로 연결됩니다.
- **분자 구조**: 원자(노드)들은 화학 결합(엣지)으로 연결됩니다.
- **도로망**: 교차로(노드)들은 도로(엣지)로 연결됩니다.
> ## 2. 핵심 키워드 (Keywords)
>
> `그래프 신경망(GNN)`, `그래프 데이터(Graph Data)`, `노드(Node)`, `엣지(Edge)`, `인접 행렬(Adjacency Matrix)`, `메시지 패싱(Message Passing)`, `PyTorch Geometric`
이처럼 **객체(노드)와 그들의 관계(엣지)로 표현되는 데이터****그래프 데이터**라고 합니다. 기존의 MLP나 CNN, RNN은 이러한 복잡한 관계성을 직접 다루기 어렵습니다.
<br>
**그래프 신경망(Graph Neural Network, GNN)**은 그래프 구조 자체를 입력으로 받아, 노드의 특징과 노드 간의 연결 관계를 종합적으로 학습하는 강력한 아키텍처입니다.
> ## 3. 도입: 관계를 학습하는 모델, GNN
>
> 세상은 연결의 집합입니다.
> - **소셜 네트워크**: 사람(노드)들은 친구 관계(엣지)로 연결됩니다.
> - **분자 구조**: 원자(노드)들은 화학 결합(엣지)으로 연결됩니다.
> - **도로망**: 교차로(노드)들은 도로(엣지)로 연결됩니다.
>
> 이처럼 **객체(노드)와 그들의 관계(엣지)로 표현되는 데이터**를 **그래프 데이터**라고 합니다. 기존의 MLP나 CNN, RNN은 이러한 복잡한 관계성을 직접 다루기 어렵습니다.
>
> **그래프 신경망(Graph Neural Network, GNN)**은 그래프 구조 자체를 입력으로 받아, 노드의 특징과 노드 간의 연결 관계를 종합적으로 학습하는 강력한 아키텍처입니다.
---
## 4. GNN의 핵심 아이디어: 메시지 패싱 (Message Passing)
GNN의 핵심 원리는 "이웃 노드로부터 정보를 받아서 나의 정보를 업데이트한다"는 **메시지 패싱** 아이디어로 요약할 수 있습니다.
![Message Passing](https://distill.pub/2021/gnn-intro/images/gnn-computation-2.gif)
*(이미지 출처: distill.pub)*
1. **메시지 생성**: 각 노드는 자신의 이웃 노드들에게 보낼 '메시지'를 생성합니다.
2. **정보 취합 (Aggregation)**: 각 노드는 이웃들로부터 받은 메시지들을 하나로 모읍니다. (예: 평균을 내거나, 합산)
3. **정보 업데이트 (Update)**: 각 노드는 취합된 정보와 자기 자신의 기존 정보를 바탕으로 새로운 상태(표현 벡터)를 계산합니다.
이 과정을 여러 번 반복(여러 GNN 레이어를 쌓음)함으로써, 노드들은 더 멀리 있는 이웃들의 정보까지 전달받아 자신의 표현을 더욱 풍부하게 만들 수 있습니다.
<br>
> ## 4. GNN의 핵심 아이디어: 메시지 패싱 (Message Passing)
>
> GNN의 핵심 원리는 "이웃 노드로부터 정보를 받아서 나의 정보를 업데이트한다"는 **메시지 패싱** 아이디어로 요약할 수 있습니다.
>
> ![Message Passing](https://distill.pub/2021/gnn-intro/images/gnn-computation-2.gif)
> *(이미지 출처: distill.pub)*
>
> 1. **메시지 생성**: 각 노드는 자신의 이웃 노드들에게 보낼 '메시지'를 생성합니다.
> 2. **정보 취합 (Aggregation)**: 각 노드는 이웃들로부터 받은 메시지들을 하나로 모읍니다. (예: 평균을 내거나, 합산)
> 3. **정보 업데이트 (Update)**: 각 노드는 취합된 정보와 자기 자신의 기존 정보를 바탕으로 새로운 상태(표현 벡터)를 계산합니다.
>
> 이 과정을 여러 번 반복(여러 GNN 레이어를 쌓음)함으로써, 노드들은 더 멀리 있는 이웃들의 정보까지 전달받아 자신의 표현을 더욱 풍부하게 만들 수 있습니다.
---
## 5. 직접 해보기 (Hands-on Lab): (내용 추가 예정)
<br>
PyTorch Geometric 라이브러리를 사용하여 소셜 네트워크의 사용자 직업을 예측하는 GNN 모델을 만들어볼 예정입니다.
> ## 5. 직접 해보기 (Hands-on Lab): (내용 추가 예정)
>
> PyTorch Geometric 라이브러리를 사용하여 소셜 네트워크의 사용자 직업을 예측하는 GNN 모델을 만들어볼 예정입니다.
---
## 6. 되짚어보기 (Summary)
<br>
- **GNN**: 노드와 엣지로 구성된 그래프 구조의 데이터를 직접 처리하기 위한 신경망입니다.
- **핵심 원리**: 이웃 노드와 '메시지'를 주고받으며 자신의 정보를 업데이트하는 **메시지 패싱**을 기반으로 합니다.
- **활용**: 추천 시스템, 신약 개발, 금융 사기 탐지 등 관계 속에서 패턴을 찾아내는 다양한 분야에 활용됩니다.
> ## 6. 되짚어보기 (Summary)
>
> - **GNN**: 노드와 엣지로 구성된 그래프 구조의 데이터를 직접 처리하기 위한 신경망입니다.
> - **핵심 원리**: 이웃 노드와 '메시지'를 주고받으며 자신의 정보를 업데이트하는 **메시지 패싱**을 기반으로 합니다.
> - **활용**: 추천 시스템, 신약 개발, 금융 사기 탐지 등 관계 속에서 패턴을 찾아내는 다양한 분야에 활용됩니다.
---
<br>
**➡️ 다음 시간: [Part 7.5: 강화학습 (Reinforcement Learning)](./part_7.5_reinforcement_learning.md)**
### 참고 자료
<br>
* [A Gentle Introduction to Graph Neural Networks](https://distill.pub/2021/gnn-intro/): GNN에 대한 시각적이고 직관적인 설명이 담긴 distill.pub 아티클
* [PyTorch Geometric 라이브러리](https://pytorch-geometric.readthedocs.io/en/latest/): PyTorch 기반의 GNN 라이브러리
> ### 참고 자료
>
> * [A Gentle Introduction to Graph Neural Networks](https://distill.pub/2021/gnn-intro/): GNN에 대한 시각적이고 직관적인 설명이 담긴 distill.pub 아티클
> * [PyTorch Geometric 라이브러리](https://pytorch-geometric.readthedocs.io/en/latest/): PyTorch 기반의 GNN 라이브러리
---
### ⚠️ What Could Go Wrong? (토론 주제)
GNN은 관계형 데이터를 다루는 강력한 패러다임이지만, 실제 적용 시에는 고유한 기술적 난제들을 마주하게 됩니다.
1. **과잉 평탄화 문제 (Over-smoothing Problem)**
* GNN 레이어를 깊게 쌓았을 때, 여러 홉 떨어진 노드들의 정보가 섞이면서 결국 모든 노드 임베딩이 서로 유사해져 버리는 '과잉 평탄화' 현상이 발생합니다. 이 때문에 깊은 GNN 모델의 성능이 얕은 모델보다 오히려 떨어질 수 있는데, 왜 이런 현상이 발생할까요?
* 이를 해결하기 위해 제안된 방법들(예: Jumping Knowledge, GCNII, Skip-connection)은 어떤 원리로 이 문제를 완화하며, 각각 어떤 장단점을 가질까요?
2. **이웃 폭발 및 확장성 문제 (Neighbor Explosion & Scalability Issues)**
* 하나의 노드 임베딩을 계산하기 위해 이웃 노드들을 재귀적으로 참조하다 보면, 몇 홉만 거쳐도 관련 노드의 수가 기하급수적으로 증가하여 '이웃 폭발'이 발생합니다. 이는 대규모 그래프에서 메모리 부족(Out-of-Memory)과 연산량 폭증의 원인이 됩니다.
* GraphSAGE에서 제안한 '이웃 샘플링(Neighbor Sampling)' 방식은 이 문제를 어떻게 해결하나요? 샘플링이 가져오는 성능과 연산량 간의 트레이드오프는 무엇일까요?
3. **동적 그래프 처리의 어려움 (Difficulty with Dynamic Graphs)**
* 실세계의 많은 그래프(소셜 네트워크, 금융 거래망)는 시간이 지남에 따라 노드와 엣지가 끊임없이 변하는 '동적 그래프'입니다. 새로운 노드가 추가될 때마다 전체 모델을 다시 학습시켜야 할까요?
* 시간의 흐름에 따른 변화를 GNN 모델이 학습하게 하려면 어떤 접근법(예: Temporal GNNs)이 필요하며, 기존 GNN과 비교하여 어떤 점이 더 복잡할까요?
4. **비관계형 데이터에 대한 부적절한 적용 (Inappropriate Application to Non-relational Data)**
* 모든 데이터를 그래프 형태로 표현할 수는 있지만, 그것이 항상 유용한 것은 아닙니다. 노드 간의 '관계'가 명확하지 않거나 의미 없는 데이터를 억지로 그래프로 구성하여 GNN을 적용하면 어떤 문제가 발생할 수 있을까요?
* GNN이 다른 모델(예: CNN, RNN, Transformer)에 비해 확실한 강점을 가지는 데이터의 특징은 무엇이라고 생각하시나요?
5. **그래프 구조 자체의 편향 (Bias in Graph Structure)**
* 소셜 네트워크에서 특정 인구 집단이 다른 집단보다 더 촘촘하게 연결된 '에코 체임버'나 '필터 버블'이 존재할 수 있습니다. 이런 편향된 구조를 학습한 GNN 모델이 소수 집단에 대해 불공정한 예측을 내릴 위험은 없을까요? 이러한 구조적 편향을 어떻게 탐지하고 완화할 수 있을까요?
<br>
> ### ⚠️ What Could Go Wrong? (토론 주제)
>
> GNN은 관계형 데이터를 다루는 강력한 패러다임이지만, 실제 적용 시에는 고유한 기술적 난제들을 마주하게 됩니다.
>
> 1. **과잉 평탄화 문제 (Over-smoothing Problem)**
> * GNN 레이어를 깊게 쌓았을 때, 여러 홉 떨어진 노드들의 정보가 섞이면서 결국 모든 노드 임베딩이 서로 유사해져 버리는 '과잉 평탄화' 현상이 발생합니다. 이 때문에 깊은 GNN 모델의 성능이 얕은 모델보다 오히려 떨어질 수 있는데, 왜 이런 현상이 발생할까요?
> * 이를 해결하기 위해 제안된 방법들(예: Jumping Knowledge, GCNII, Skip-connection)은 어떤 원리로 이 문제를 완화하며, 각각 어떤 장단점을 가질까요?
>
> 2. **이웃 폭발 및 확장성 문제 (Neighbor Explosion & Scalability Issues)**
> * 하나의 노드 임베딩을 계산하기 위해 이웃 노드들을 재귀적으로 참조하다 보면, 몇 홉만 거쳐도 관련 노드의 수가 기하급수적으로 증가하여 '이웃 폭발'이 발생합니다. 이는 대규모 그래프에서 메모리 부족(Out-of-Memory)과 연산량 폭증의 원인이 됩니다.
> * GraphSAGE에서 제안한 '이웃 샘플링(Neighbor Sampling)' 방식은 이 문제를 어떻게 해결하나요? 샘플링이 가져오는 성능과 연산량 간의 트레이드오프는 무엇일까요?
>
> 3. **동적 그래프 처리의 어려움 (Difficulty with Dynamic Graphs)**
> * 실세계의 많은 그래프(소셜 네트워크, 금융 거래망)는 시간이 지남에 따라 노드와 엣지가 끊임없이 변하는 '동적 그래프'입니다. 새로운 노드가 추가될 때마다 전체 모델을 다시 학습시켜야 할까요?
> * 시간의 흐름에 따른 변화를 GNN 모델이 학습하게 하려면 어떤 접근법(예: Temporal GNNs)이 필요하며, 기존 GNN과 비교하여 어떤 점이 더 복잡할까요?
>
> 4. **비관계형 데이터에 대한 부적절한 적용 (Inappropriate Application to Non-relational Data)**
> * 모든 데이터를 그래프 형태로 표현할 수는 있지만, 그것이 항상 유용한 것은 아닙니다. 노드 간의 '관계'가 명확하지 않거나 의미 없는 데이터를 억지로 그래프로 구성하여 GNN을 적용하면 어떤 문제가 발생할 수 있을까요?
> * GNN이 다른 모델(예: CNN, RNN, Transformer)에 비해 확실한 강점을 가지는 데이터의 특징은 무엇이라고 생각하시나요?
>
> 5. **그래프 구조 자체의 편향 (Bias in Graph Structure)**
> * 소셜 네트워크에서 특정 인구 집단이 다른 집단보다 더 촘촘하게 연결된 '에코 체임버'나 '필터 버블'이 존재할 수 있습니다. 이런 편향된 구조를 학습한 GNN 모델이 소수 집단에 대해 불공정한 예측을 내릴 위험은 없을까요? 이러한 구조적 편향을 어떻게 탐지하고 완화할 수 있을까요?
---
## 캡스톤 프로젝트 연계 미니 프로젝트: 소셜 네트워크 기반 친구 추천 시스템
이 챕터에서 배운 GNN의 개념을 활용하여, 15장 캡스톤 프로젝트의 '추천 시스템' 아이디어에 적용해볼 수 있는 미니 프로젝트를 진행합니다. 사용자의 연결 관계(그래프)를 기반으로 새로운 친구를 추천하는 모델을 직접 만들어보면서, GNN의 실용성을 체감하는 것을 목표로 합니다.
### 프로젝트 목표
- `PyTorch Geometric`을 사용하여 소셜 네트워크 데이터를 로드하고 시각화합니다.
- 간단한 GCN(Graph Convolutional Network) 모델을 구축하여, 그래프의 '링크 예측(Link Prediction)' 문제를 해결합니다.
- 특정 사용자가 주어졌을 때, 연결될 가능성이 가장 높은 다른 사용자(새로운 친구)를 추천하는 API의 프로토타입을 구상합니다.
### 개발 과정
1. **데이터셋 선정**: `PyTorch Geometric`에 내장된 `Cora` 또는 `CiteSeer`와 같은 인용 네트워크 데이터셋을 소셜 네트워크라고 가정하고 사용합니다. 각 논문은 '사용자', 인용 관계는 '친구 관계'로 간주합니다.
2. **모델링**:
- 노드(사용자)의 특징을 입력으로 받아, GCN 레이어를 통과시켜 임베딩을 생성합니다.
- 두 노드 임베딩의 내적(dot product)을 계산하여, 두 노드 사이에 링크(친구 관계)가 존재할 확률을 예측하는 모델을 만듭니다.
3. **학습 및 평가**:
- 기존의 링크 중 일부를 일부러 숨기고(train/test split), 모델이 이 숨겨진 링크를 얼마나 잘 예측하는지 평가합니다. (AUC, Accuracy 등)
4. **결과 해석 및 활용**:
- 학습된 모델을 사용하여, 현재 연결되지 않은 노드 쌍 중에서 연결 확률이 가장 높은 쌍을 찾습니다.
- 이를 "사용자 A에게 사용자 B, C, D를 추천합니다"와 같은 기능으로 연결하여, 캡스톤 프로젝트에서 만들 최종 서비스의 그림을 그려봅니다.
### 캡스톤 프로젝트 연계 방안
- **추천 시스템 고도화**: 실제 캡스톤 프로젝트에서는 단순 친구 관계를 넘어, '사용자-상품' 관계, '영화-배우-감독' 관계 등 더 복잡한 그래프를 구축하여 GNN 기반 추천 모델을 만들 수 있습니다.
- **FastAPI 연동**: 이 미니 프로젝트에서 개발한 모델을 `part_8_model_serving_with_fastapi.md`에서 배울 FastAPI를 사용해 API로 서빙하는 기능을 구현해볼 수 있습니다. 예를 들어, `GET /users/{user_id}/recommendations` 와 같은 엔드포인트를 설계할 수 있습니다.
\ No newline at end of file
<br>
> ## 캡스톤 프로젝트 연계 미니 프로젝트: 소셜 네트워크 기반 친구 추천 시스템
>
> 이 챕터에서 배운 GNN의 개념을 활용하여, 15장 캡스톤 프로젝트의 '추천 시스템' 아이디어에 적용해볼 수 있는 미니 프로젝트를 진행합니다. 사용자의 연결 관계(그래프)를 기반으로 새로운 친구를 추천하는 모델을 직접 만들어보면서, GNN의 실용성을 체감하는 것을 목표로 합니다.
>
> ### 프로젝트 목표
> - `PyTorch Geometric`을 사용하여 소셜 네트워크 데이터를 로드하고 시각화합니다.
> - 간단한 GCN(Graph Convolutional Network) 모델을 구축하여, 그래프의 '링크 예측(Link Prediction)' 문제를 해결합니다.
> - 특정 사용자가 주어졌을 때, 연결될 가능성이 가장 높은 다른 사용자(새로운 친구)를 추천하는 API의 프로토타입을 구상합니다.
>
> ### 개발 과정
> 1. **데이터셋 선정**: `PyTorch Geometric`에 내장된 `Cora` 또는 `CiteSeer`와 같은 인용 네트워크 데이터셋을 소셜 네트워크이라고 가정하고 사용합니다. 각 논문은 '사용자', 인용 관계는 '친구 관계'로 간주합니다.
> 2. **모델링**:
> - 노드(사용자)의 특징을 입력으로 받아, GCN 레이어를 통과시켜 임베딩을 생성합니다.
> - 두 노드 임베딩의 내적(dot product)을 계산하여, 두 노드 사이에 링크(친구 관계)가 존재할 확률을 예측하는 모델을 만듭니다.
> 3. **학습 및 평가**:
> - 기존의 링크 중 일부를 일부러 숨기고(train/test split), 모델이 이 숨겨진 링크를 얼마나 잘 예측하는지 평가합니다. (AUC, Accuracy 등)
> 4. **결과 해석 및 활용**:
> - 학습된 모델을 사용하여, 현재 연결되지 않은 노드 쌍 중에서 연결 확률이 가장 높은 쌍을 찾습니다.
> - 이를 "사용자 A에게 사용자 B, C, D를 추천합니다"와 같은 기능으로 연결하여, 캡스톤 프로젝트에서 만들 최종 서비스의 그림을 그려봅니다.
>
> ### 캡스톤 프로젝트 연계 방안
> - **추천 시스템 고도화**: 실제 캡스톤 프로젝트에서는 단순 친구 관계를 넘어, '사용자-상품' 관계, '영화-배우-감독' 관계 등 더 복잡한 그래프를 구축하여 GNN 기반 추천 모델을 만들 수 있습니다.
> - **FastAPI 연동**: 이 미니 프로젝트에서 개발한 모델을 `part_8_model_serving_with_fastapi.md`에서 배울 FastAPI를 사용해 API로 서빙하는 기능을 구현해볼 수 있습니다. 예를 들어, `GET /users/{user_id}/recommendations` 와 같은 엔드포인트를 설계할 수 있습니다.
\ No newline at end of file
# Part 8: Model Serving with FastAPI
---
<h1>Part 8: 모델 서빙 (FastAPI)</h1>
이 파트에서는 훈련된 머신러닝/딥러닝 모델을 빠르고 효율적인 웹 프레임워크인 FastAPI를 사용하여 API로 외부에 제공하는 방법을 학습합니다.
......@@ -9,8 +10,10 @@
## 💻 실습 코드
- **[예제 코드](../../source_code/08_model_serving_with_fastapi/)**: 강의 내용을 직접 실행해볼 수 있는 코드입니다.
- **[예제 코드](../../source_code/part_8_fastapi_project/)**: 강의 내용을 직접 실행해볼 수 있는 코드입니다.
---
[↩️ 전체 커리큘럼으로 돌아가기](../../README.md)
---
\ No newline at end of file
# Part 8: FastAPI를 이용한 모델 서빙
---
marp: true
theme: gaia
class:
- lead
- invert
---
**⬅️ 이전 시간: [Part 7.5: 강화학습 (Reinforcement Learning)](../07_deep_learning/part_7.5_reinforcement_learning.md)**
<!-- _class: lead -->
<!-- _header: "" -->
<!-- _footer: "" -->
<style>
h1 {
font-size: 2.5em;
font-weight: 600;
}
h2 {
font-size: 2em;
font-weight: 600;
}
h3 {
font-size: 1.6em;
font-weight: 600;
}
h4 {
font-size: 1.3em;
font-weight: 600;
}
h5 {
font-size: 1.1em;
font-weight: 600;
}
h6 {
font-size: 1em;
font-weight: 600;
}
p, li, ul, ol, table {
font-size: 28px;
}
pre, code {
font-size: 24px;
}
</style>
# Part 8. FastAPI를 이용한 모델 서빙
**⬅️ 이전 시간: [Part 7.5: 강화학습 (Reinforcement Learning)](../07_deep_learning/part_7.5_reinforcement_learning.md)**<br/>
**➡️ 다음 시간: [Part 9: 프로덕션 레벨 API와 Docker](../09_production_ready_api/part_9_production_ready_api.md)**
---
......@@ -15,11 +60,15 @@
- Pydantic을 사용하여 API의 요청/응답 데이터 형식을 정의하고 자동으로 검증할 수 있습니다.
- FastAPI의 자동 생성 문서(Swagger UI)를 통해 브라우저에서 직접 API를 테스트하고 디버깅할 수 있습니다.
---
## 2. 핵심 키워드 (Keywords)
`모델 서빙(Model Serving)`, `API`, `FastAPI`, `uvicorn`, `Pydantic`, `경로 매개변수(Path Parameter)`, `요청 본문(Request Body)`, `Swagger UI`, `lifespan`
## 3. 도입: 나만 알던 맛집 레시피, 세상에 공개하기 (Introduction)
---
## 3. 도입 (Introduction)
지금까지 우리는 Scikit-learn과 PyTorch로 강력한 AI 모델, 즉 세상에 없는 '비법 레시피'를 개발했습니다. 하지만 이 레시피를 내 서랍 속에만 둔다면 아무도 그 맛을 볼 수 없습니다.
......@@ -218,7 +267,7 @@ def predict_iris(data: IrisFeatures):
---
## ⚠️ What Could Go Wrong? (토론 주제)
## 7. 토론 주제 (Discussion Topics)
FastAPI를 사용하면 매우 빠르게 API를 만들 수 있지만, 실제 프로덕션 환경에서는 간단한 예제 코드에서 보이지 않던 문제들이 발생합니다. 다음 상황들에 대해 함께 토론해보세요.
......@@ -246,41 +295,22 @@ FastAPI를 사용하면 매우 빠르게 API를 만들 수 있지만, 실제 프
- Pydantic은 단순히 데이터 타입을 변환해주는 것 외에, 우리를 위해 어떤 '보이지 않는' 중요한 일들을 해주고 있었을까요? (예: 필수 필드 검사, 타입 강제, 상세한 오류 메시지 리포팅 등)
- Pydantic을 사용하여 명확한 데이터 계약(Data Contract)을 정의하는 것이 프론트엔드와 백엔드 개발자 간의 협업에 어떻게 도움이 될까요?
## 7. 되짚어보기 (Summary)
이번 주에는 FastAPI를 이용하여 머신러닝 모델을 API로 만드는 첫걸음을 떼었습니다.
- **AI 레스토랑**: 모델을 '레시피', API 서버를 '레스토랑'에 비유하여 모델 서빙의 개념을 이해했습니다.
- **FastAPI와 Uvicorn**: 파이썬 웹 서버를 구축하고 실행하는 방법을 배웠습니다.
- **Pydantic과 lifespan**: API의 데이터 형식을 강제하고, 서버 시작 시 모델을 효율적으로 로드하는 방법을 익혔습니다.
- **Swagger UI**: `/docs`의 '스마트 메뉴판'을 통해 API를 쉽고 빠르게 테스트하는 강력한 기능을 체험했습니다.
---
## 8. 트러블슈팅 (Troubleshooting)
- **`uvicorn` 실행 시 `ModuleNotFoundError: No module named 'main'` 오류가 발생하나요?**
- `uvicorn main:app` 명령은 현재 터미널이 위치한 디렉토리에서 `main.py` 파일을 찾으라는 의미입니다. `main.py` 파일이 있는 디렉토리로 이동한 후 다시 명령을 실행해보세요.
- **`/docs` 접속 시 `{"detail":"Not Found"}`가 표시되나요?**
- 이는 주로 URL 주소를 잘못 입력했을 때 발생합니다. `http://12.0.0.1:8000/docs` 가 맞는지, 끝에 `/`가 빠지지는 않았는지 다시 한번 확인해보세요.
- **`Try it out` 실행 시 `422 Unprocessable Entity` 오류가 발생하나요?**
- FastAPI가 Pydantic 모델을 통해 요청 본문을 검증했지만, 형식이 맞지 않아 처리할 수 없다는 의미입니다. 예를 들어, `IrisFeatures` 모델은 `{"features": [1.0, 2.0, 3.0, 4.0]}` 형태의 JSON을 기대하는데, `{"feature": ...}` 와 같이 키 이름을 잘못 입력했거나 리스트의 요소 개수가 맞지 않는 경우 발생합니다.
- **모델을 로드할 때 `FileNotFoundError: [Errno 2] No such file or directory: 'iris_model.pkl'` 오류가 발생하나요?**
- `joblib.load()``iris_model.pkl` 파일을 찾지 못한 경우입니다. `main.py`를 실행하는 위치 기준으로 `iris_model.pkl` 파일이 같은 폴더에 있는지 확인하세요. 만약 다른 위치에 있다면, 절대 경로 또는 올바른 상대 경로를 지정해주어야 합니다.
- **서버 로그에 `ERROR: Traceback (most recent call last):` 와 함께 예상치 못한 오류가 표시되나요?**
- `uvicorn`을 실행한 터미널에 출력되는 로그는 최고의 디버깅 도구입니다. 오류 메시지의 가장 마지막 줄과 그 위의 몇 줄을 자세히 읽어보면, 어떤 코드 라인에서 어떤 종류의 예외(e.g., `AttributeError`, `ValueError`)가 발생했는지에 대한 단서를 얻을 수 있습니다.
더 자세한 문제 해결 가이드나 다른 동료들이 겪은 문제에 대한 해결책이 궁금하다면, 아래 문서를 참고해주세요.
## 8. 되짚어보기 (Summary)
- **➡️ [Geumdo-Docs: TROUBLESHOOTING.md](../../../TROUBLESHOOTING.md)**
이번 파트에서는 FastAPI를 사용하여 머신러닝 모델을 API로 서빙하는 방법을 배웠습니다. 주요 내용은 다음과 같습니다.
- **FastAPI 기본**: `uvicorn`으로 서버를 실행하고, 경로 매개변수와 요청 본문을 처리하는 방법을 학습했습니다.
- **Pydantic 모델**: API의 입출력 데이터 형식을 Pydantic으로 명확하게 정의하고, 데이터 유효성 검사를 자동화했습니다.
- **모델 서빙**: `lifespan` 이벤트를 활용하여 서버 시작 시 모델을 효율적으로 로드하고, 예측 결과를 반환하는 API 엔드포인트를 구현했습니다.
- **자동 API 문서**: FastAPI가 제공하는 Swagger UI를 통해 브라우저에서 직접 API를 테스트하고 사용법을 확인하는 방법을 익혔습니다.
- **프로덕션 고려사항**: `async`의 올바른 사용법, 무거운 모델 로딩 문제, 동시성 이슈 등 실제 운영 환경에서 발생할 수 있는 문제점들을 토론했습니다.
---
## 9. 더 깊이 알아보기 (Further Reading)
- [FastAPI 공식 튜토리얼](https://fastapi.tiangolo.com/tutorial/): FastAPI의 모든 것을 배울 수 있는 최고의 가이드
- [Pydantic 공식 문서](https://docs.pydantic.dev/latest/): 데이터 유효성 검사를 더 깊이 있게 활용하는 방법
- [Serving Machine Learning Models](https://www.manning.com/books/serving-machine-learning-models): 모델 서빙에 대한 전반적인 내용을 다루는 전문 서적
## 9. 참고 자료 (References)
---
- [FastAPI 공식 문서](https://fastapi.tiangolo.com/)
- [Pydantic 공식 문서](https://pydantic-docs.helpmanual.io/)
**➡️ 다음 시간: [Part 9: 프로덕션 레벨 API와 Docker](../09_production_ready_api/part_9_production_ready_api.md)**
---
# 고급 RAG 기법: 검색 증강 생성의 최신 기술과 구현
**⬅️ 이전 시간: [Part 13: 생성형 AI 및 AI 에이전트 심화](./part_13_generative_ai.md)**
**➡️ 다음 시간: [AI 에이전트 심화](./part_13.2_advanced_ai_agents.md)**
## 📋 학습 목표
이 모듈을 통해 다음을 학습하게 됩니다:
......
# AI 에이전트 심화: LLM 기반 자율 에이전트 설계와 구현
**⬅️ 이전 시간: [고급 RAG 기법](./part_13.1_advanced_rag_techniques.md)**
**➡️ 다음 시간: [Part 14: AI 윤리 및 거버넌스 실무](../14_ai_ethics/part_14_ai_ethics.md)**
## 📋 학습 목표
이 모듈을 통해 다음을 학습하게 됩니다:
......
# Part 13: 생성형 AI 및 AI 에이전트 심화
**⬅️ 이전 시간: [Part 12: 대규모 AI 모델 최적화 및 서빙](../12_model_optimization/part_12_model_optimization.md)**
**➡️ 다음 시간: [Part 14: AI 윤리 및 거버넌스 실무](../14_ai_ethics/part_14_ai_ethics.md)**
**➡️ 다음 시간: [고급 RAG 기법](./part_13.1_advanced_rag_techniques.md)**
---
......@@ -352,7 +352,7 @@ LangSmith는 개발 초기 단계의 디버깅부터 프로덕션 환경의 모
---
**➡️ 다음 시간: [Part 14: AI 윤리 및 거버넌스 실무](../14_ai_ethics/part_14_ai_ethics.md)**
**➡️ 다음 시간: [고급 RAG 기법](./part_13.1_advanced_rag_techniques.md)**
### 참고 자료
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment