Level 2: 수학 기초
📐

Level 2

벡터와 행렬 기초

GPU와 HBM의 비밀 - AI 연산의 95%는 행렬 곱셈!

5분 30초
벡터와 행렬 기초 강의 영상
강의 영상 보기 (새 탭에서 재생)YouTube

학습 내용

벡터와 행렬 기초 + GPU/HBM

학습 목표

이 레슨을 완료하면 여러분은:

  • 벡터가 무엇인지, 왜 AI에서 모든 데이터를 벡터로 표현하는지 이해합니다
  • 행렬이 무엇이고, 신경망의 가중치가 왜 행렬인지 알게 됩니다
  • 행렬 곱셈을 직접 numpy로 계산하고, 이것이 신경망의 핵심임을 체감합니다
  • GPU와 HBM이 왜 AI 시대의 핵심 하드웨어인지 파악합니다

핵심 메시지

"AI 연산의 95%가 행렬 곱셈입니다. 행렬을 이해하면 AI 하드웨어의 비밀이 풀립니다."


1. 벡터란 무엇인가?

비유: 장보기 목록

마트에서 장을 본다고 생각해보세요. "사과 3개, 우유 2개, 빵 1개"를 사야 합니다. 이걸 숫자 목록으로 쓰면 [3, 2, 1]이 됩니다. 이것이 바로 벡터입니다!

벡터는 숫자들의 순서 있는 목록입니다. 순서가 중요합니다. [3, 2, 1]에서 첫 번째는 사과, 두 번째는 우유, 세 번째는 빵이니까요.

비유: 화살표 (방향 + 크기)

벡터를 다른 방식으로 이해할 수도 있습니다. 2차원 벡터 [3, 4]는 "오른쪽으로 3, 위로 4" 가리키는 화살표입니다. 이 화살표의 길이(크기)는 피타고라스 정리로 구할 수 있죠: 5입니다.

관점벡터의 의미예시
목록숫자들의 나열장보기: [사과3, 우유2, 빵1]
화살표방향 + 크기이동: [오른쪽3, 위4]
좌표공간의 한 점위치: (3, 4)

실행해보기: numpy로 벡터 만들기

python
import numpy as np # 장보기 벡터: [사과, 우유, 빵] shopping = np.array([3, 2, 1]) print('장보기 벡터:', shopping) # 2차원 화살표 벡터 arrow = np.array([3, 4]) print('화살표 벡터:', arrow) # 벡터의 크기 (길이) = 피타고라스! length = np.sqrt(arrow[0]**2 + arrow[1]**2) print('화살표 길이:', length) # numpy가 제공하는 편리한 함수 print('numpy로 길이 계산:', np.linalg.norm(arrow))

2. 벡터 연산 -- AI의 기본 도구

비유: 장보기 합치기

월요일에 [사과3, 우유2, 빵1]을 사고, 화요일에 [사과1, 우유3, 빵2]를 샀다면, 이번 주 총 구매량은? 각 항목을 더하면 됩니다: [4, 5, 3]!

벡터 덧셈은 이처럼 같은 위치끼리 더하는 것입니다. 뺄셈도 마찬가지고요.

내적 (Dot Product) -- 가장 중요한 연산!

내적은 "두 벡터가 얼마나 비슷한 방향인가"를 숫자 하나로 알려줍니다. 계산법: 같은 위치끼리 곱하고, 전부 더합니다.

[1, 2, 3] . [4, 5, 6] = 1x4 + 2x5 + 3x6 = 4 + 10 + 18 = 32

신경망에서 뉴런 하나가 하는 일이 바로 이 내적입니다! 입력과 가중치의 내적 = 뉴런의 출력값입니다.

실행해보기: 벡터 연산

python
import numpy as np # 벡터 정의 a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) # 벡터 덧셈: 같은 위치끼리 더하기 print('덧셈:', a + b) # 벡터 뺄셈: 같은 위치끼리 빼기 print('뺄셈:', a - b) # 원소별 곱셈 (element-wise) print('원소별 곱셈:', a * b) # 내적 (dot product) -- AI에서 가장 중요! dot_manual = a[0]*b[0] + a[1]*b[1] + a[2]*b[2] dot_numpy = np.dot(a, b) print('내적 (수동계산):', dot_manual) print('내적 (numpy):', dot_numpy) # AI 연결: 뉴런 하나의 계산 weights = np.array([0.5, -0.3, 0.8]) # 가중치 inputs = np.array([1.0, 2.0, 3.0]) # 입력값 bias = 0.1 # 편향 neuron_output = np.dot(weights, inputs) + bias print('뉴런 출력 (w.x + b):', neuron_output)

3. 행렬이란 무엇인가?

비유: 엑셀 스프레드시트

행렬은 숫자를 행(가로)과 열(세로)로 정리한 표입니다. 엑셀에서 데이터를 행과 열로 정리하는 것과 완전히 같습니다!

예를 들어, 3명의 학생이 2과목 시험을 봤다면:

수학영어
학생A9085
학생B7095
학생C8075

이것이 3x2 행렬 (3행 2열)입니다.

신경망에서 행렬 = 가중치!

신경망의 한 층(layer)에서 입력 3개가 출력 2개로 변환된다면, 가중치는 2x3 행렬입니다. 총 6개의 연결(가중치)이 있는 셈이죠.

용어의미예시
행(row)가로줄행렬의 가로 방향
열(column)세로줄행렬의 세로 방향
크기(shape)행 x 열2x3 = 2행 3열
원소(element)각 칸의 숫자행렬[0][1] = 85

실행해보기: numpy로 행렬 만들기

python
import numpy as np # 시험 성적 행렬 (3명 x 2과목) scores = np.array([ [90, 85], # 학생A: 수학90, 영어85 [70, 95], # 학생B: 수학70, 영어95 [80, 75] # 학생C: 수학80, 영어75 ]) print('성적 행렬:') print(scores) print('행렬 크기 (shape):', scores.shape) # (3, 2) = 3행 2열 # 특정 원소 접근: scores[행][열] print('학생B의 영어 성적:', scores[1][1]) # 95 # 행 단위, 열 단위 평균 print('각 학생의 평균:', np.mean(scores, axis=1)) # 행 방향 print('각 과목의 평균:', np.mean(scores, axis=0)) # 열 방향 # 신경망 가중치 행렬 (2x3): 입력3개 -> 출력2개 W = np.array([ [0.1, 0.2, 0.3], # 첫 번째 출력 뉴런의 가중치 [0.4, 0.5, 0.6] # 두 번째 출력 뉴런의 가중치 ]) print('가중치 행렬 shape:', W.shape) # (2, 3)

4. 행렬 곱셈 -- AI의 핵심 연산!

비유: 대량 주문 계산

빵집에서 3가지 빵을 만드는데, 각 빵에 필요한 재료량이 행렬로 있고, 각 빵의 주문량이 벡터로 있다면, 행렬 곱셈으로 총 재료량을 한 번에 구할 수 있습니다.

행렬 곱셈의 규칙

행렬 곱셈 A x B가 가능하려면: A의 열 수 = B의 행 수 여야 합니다!

결과 행렬의 크기: (A의 행) x (B의 열)

A의 크기B의 크기결과 크기가능 여부
(2x3)(3x2)(2x2)가능
(2x3)(2x3)-불가능 (3 != 2)
(4x5)(5x3)(4x3)가능

실행해보기: 행렬 곱셈 직접 해보기

python
import numpy as np # 2x2 행렬 곱셈을 단계별로 풀어봅시다 A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) # 수동 계산: "행 x 열, 곱하고 더하기!" c00 = A[0,0]*B[0,0] + A[0,1]*B[1,0] # 1*5 + 2*7 = 19 c01 = A[0,0]*B[0,1] + A[0,1]*B[1,1] # 1*6 + 2*8 = 22 c10 = A[1,0]*B[0,0] + A[1,1]*B[1,0] # 3*5 + 4*7 = 43 c11 = A[1,0]*B[0,1] + A[1,1]*B[1,1] # 3*6 + 4*8 = 50 print('수동 계산 결과:') print(f' [{c00}, {c01}]') print(f' [{c10}, {c11}]') # numpy로 한 줄! C = np.matmul(A, B) # 또는 A @ B print('numpy 결과:') print(C) # 검증: 같은지 확인 print('결과 일치:', c00 == C[0,0] and c01 == C[0,1])

실행해보기: 신경망 한 층의 계산

python
import numpy as np # 신경망 한 층: y = Wx + b # 입력 3개, 출력 2개 W = np.array([[0.1, 0.2, 0.3], # 가중치 (2x3) [0.4, 0.5, 0.6]]) x = np.array([1.0, 2.0, 3.0]) # 입력 (3,) b = np.array([0.01, 0.02]) # 편향 (2,) # 행렬-벡터 곱 + 편향 y = W @ x + b print('입력:', x) print('가중치 행렬 shape:', W.shape) print('출력:', y) print('출력 shape:', y.shape) # 이것이 신경망 한 층이 하는 일의 전부입니다! print() print('--- 풀어서 계산하면 ---') y0 = 0.1*1.0 + 0.2*2.0 + 0.3*3.0 + 0.01 y1 = 0.4*1.0 + 0.5*2.0 + 0.6*3.0 + 0.02 print(f'출력[0] = {y0}') print(f'출력[1] = {y1}')

5. 왜 행렬 곱셈이 신경망의 핵심인가?

신경망의 모든 층(layer)은 결국 이 한 가지를 합니다:

출력 = 활성화함수( 가중치행렬 x 입력 + 편향 )

GPT-4 같은 대형 모델은 수백 개의 층을 가지고 있고, 각 층마다 거대한 행렬 곱셈을 수행합니다. 파라미터(가중치)가 수천억 개라는 것은, 행렬의 숫자가 그만큼 많다는 뜻입니다.

모델파라미터 수행렬 곱셈 규모
작은 신경망수천 개수천 번 곱셈
GPT-215억 개수십억 번 곱셈
GPT-31,750억 개수조 번 곱셈
GPT-4추정 1조+상상 이상

6. GPU와 HBM -- 왜 병렬 처리가 중요한가?

비유: 식당 주방

CPU는 "천재 요리사 1명"입니다. 복잡한 요리를 빠르게 하지만, 한 번에 하나씩만 합니다. GPU는 "보통 요리사 수천 명"입니다. 각자 단순한 일을 하지만, 동시에 처리합니다.

행렬 곱셈은 수백만 개의 단순한 곱셈+덧셈이니까, GPU가 압도적으로 유리합니다!

특성CPUGPU
코어 수8~64개수천~수만 개
각 코어 성능매우 빠름보통
병렬 연산제한적최적화
행렬 곱셈순차 처리동시 처리
AI 학습 속도느림수십~수백 배 빠름

HBM (High Bandwidth Memory)

GPU가 아무리 빨라도 데이터를 메모리에서 가져오는 속도가 느리면 의미가 없습니다. 이것을 메모리 병목(memory bottleneck) 이라고 합니다.

HBM은 이 병목을 해결하기 위해 메모리를 GPU 바로 옆에 수직으로 쌓은 것입니다.

메모리 종류대역폭비유
일반 DDR5~50GB/s일반 도로
GDDR6~500GB/s고속도로
HBM3~3,350GB/s비행기

NVIDIA H100 GPU에는 HBM3 80GB가 탑재되어 있고, GPT-3 (350GB 필요)을 돌리려면 최소 5개의 H100이 필요합니다.

실행해보기: 반복문 vs numpy 행렬 연산 속도 비교

python
import numpy as np import time # 200x200 행렬 두 개 준비 size = 200 A = np.random.randn(size, size) B = np.random.randn(size, size) # 방법 1: 파이썬 반복문 (CPU 순차 처리와 비슷) start = time.time() C_loop = np.zeros((size, size)) for i in range(size): for j in range(size): total = 0 for k in range(size): total += A[i, k] * B[k, j] C_loop[i, j] = total loop_time = time.time() - start # 방법 2: numpy (내부적으로 최적화된 병렬 처리) start = time.time() for _ in range(100): # 100번 반복해야 측정 가능 C_numpy = A @ B numpy_time = (time.time() - start) / 100 print(f'반복문 (순차): {loop_time:.4f}초') print(f'numpy (최적화): {numpy_time:.6f}초') print(f'속도 차이: {loop_time / numpy_time:.0f}배!') print(f'결과 일치: {np.allclose(C_loop, C_numpy)}') # 실제 GPU를 쓰면 이보다 수십~수백 배 더 빠릅니다! print() print('참고: 실제 GPU는 numpy보다도 수십~수백 배 빠릅니다') print(f'200x200 행렬에서도 이런 차이가 나는데,') print(f'GPT-3의 행렬은 수만x수만 크기입니다!')

7. AI와의 연결: 모든 것은 행렬 곱셈이다

지금까지 배운 내용을 정리하면:

  1. AI의 데이터는 벡터로 표현됩니다 (이미지, 텍스트, 음성 모두)
  2. 신경망의 가중치는 행렬입니다
  3. 신경망의 각 층은 행렬 곱셈을 수행합니다
  4. 행렬 곱셈은 병렬 처리에 최적화되어 있습니다
  5. 그래서 GPU가 AI에 필수적입니다
  6. GPU가 빠르게 동작하려면 HBM 같은 고속 메모리가 필요합니다
python
import numpy as np # 간단한 3층 신경망 시뮬레이션 np.random.seed(42) # 입력: 4개 특성 x = np.array([0.5, 0.3, 0.8, 0.1]) print('입력:', x, ' shape:', x.shape) # 1층: 4 -> 8 (가중치 8x4) W1 = np.random.randn(8, 4) * 0.5 b1 = np.zeros(8) h1 = np.maximum(0, W1 @ x + b1) # ReLU 활성화 print('1층 출력:', np.round(h1, 3), ' shape:', h1.shape) # 2층: 8 -> 4 (가중치 4x8) W2 = np.random.randn(4, 8) * 0.5 b2 = np.zeros(4) h2 = np.maximum(0, W2 @ h1 + b2) # ReLU 활성화 print('2층 출력:', np.round(h2, 3), ' shape:', h2.shape) # 3층 (출력): 4 -> 3 (가중치 3x4, 3개 클래스 분류) W3 = np.random.randn(3, 4) * 0.5 b3 = np.zeros(3) logits = W3 @ h2 + b3 # softmax로 확률 변환 exp_logits = np.exp(logits - np.max(logits)) probs = exp_logits / np.sum(exp_logits) print('출력 (logits):', np.round(logits, 3)) print('확률 (softmax):', np.round(probs, 3)) print('확률 합계:', round(np.sum(probs), 4)) print() print('--- 핵심 ---') print('모든 층에서 하는 일: 행렬곱 + 편향 + 활성화함수') print('행렬 곱셈 횟수: 3번 (3개 층)') total_params = W1.size + b1.size + W2.size + b2.size + W3.size + b3.size print(f'총 파라미터 수: {total_params}개') print('GPT-3는 이런 파라미터가 1,750억 개입니다!')

핵심 요약

개념설명AI에서의 역할비유
벡터숫자들의 순서있는 목록데이터/임베딩 표현장보기 목록
내적곱하고 더하기뉴런의 핵심 연산유사도 측정
행렬숫자를 행x열로 배열가중치 저장엑셀 스프레드시트
행렬 곱셈행x열, 곱하고 더하기신경망 층의 연산대량 주문 계산
GPU수천 코어 병렬처리행렬 연산 가속요리사 수천 명
HBM고대역폭 적층 메모리메모리 병목 해결GPU 옆 초고속 창고

학습 체크리스트

  • 벡터가 "숫자들의 순서있는 목록"임을 안다
  • 내적(dot product)이 "곱하고 더하기"이며 뉴런의 핵심 연산임을 안다
  • 행렬을 numpy로 만들고 곱셈할 수 있다
  • 신경망 한 층의 계산이 y = Wx + b (행렬 곱셈)임을 안다
  • GPU가 AI에 필수인 이유 (병렬 처리)를 설명할 수 있다
  • HBM이 메모리 병목을 해결하는 고대역폭 메모리임을 안다

다음 강의 예고

"확률의 기초" AI가 예측하는 방법! 조건부 확률과 베이즈 정리를 배웁니다.

레슨 정보

레벨
Level 2: 수학 기초
예상 소요 시간
5분 30초
참고 영상
YouTube 링크

💡실습 환경 안내

코드 블록의 ▶ 실행 버튼을 누르면 브라우저에서 바로 Python을 실행할 수 있습니다.

별도 설치 없이 NumPy, Matplotlib 등 기본 라이브러리를 사용할 수 있습니다.