콘텐츠로 이동
Data Prep
상세

LLM을 위한 기초 CS 지식

LLM/VLM 기술을 제대로 이해하고 최적화하기 위해 알아야 할 컴퓨터 과학 기초


왜 이 지식이 필요한가?

LLM을 단순히 "사용"하는 것과 "최적화"하는 것은 다름. 최적화를 위해서는:

  • 모델이 GPU에서 어떻게 실행되는지
  • 메모리가 어떻게 관리되는지
  • 숫자가 컴퓨터에서 어떻게 표현되는지

이런 기초를 알아야 왜 양자화가 효과적인지, KV 캐시가 왜 필요한지 이해할 수 있음.


목차

  1. 컴퓨터 기초 - 프로세스, 메모리, CPU vs GPU
  2. 숫자 표현 - FP32, FP16, INT8, 정밀도
  3. 메모리 계층 - RAM, VRAM, 캐시
  4. LLM 핵심 개념 - 토큰, KV 캐시, 배치
  5. 최적화 기초 - 왜 양자화? 왜 배치?

1. 컴퓨터 기초

프로그램 실행 과정

1. 소스코드 - python inference.py 실행

2. 프로세스 생성 - OS가 메모리 공간 할당 - PID 부여

3. 메모리 로드 - 코드 영역: 실행할 명령어 - 데이터 영역: 전역 변수 - 힙: 동적 할당 (모델 가중치!) - 스택: 함수 호출, 지역 변수

4. CPU/GPU 실행 - CPU: 일반 로직, I/O - GPU: 행렬 연산 (LLM 추론)

프로세스 vs 스레드

프로세스 - 메모리: 독립 공간 - 생성 비용: 높음 - 통신: IPC 필요 - 예시: 별도 Python 실행

스레드 - 메모리: 프로세스 내 공유 - 생성 비용: 낮음 - 통신: 직접 공유 - 예시: asyncio, threading

LLM 서빙에서: - 프로세스: vLLM 서버 인스턴스 - 스레드: 동시 요청 처리 - GPU: 별도 메모리 공간 (VRAM)

CPU vs GPU

CPU (Central Processing Unit) - 4-64개의 강력한 코어 - 복잡한 연산, 분기 처리에 강함 - 순차적 작업에 최적화

GPU (Graphics Processing Unit) - 수천 개의 작은 코어 - 단순 연산 대량 병렬 처리 - 행렬 곱셈에 최적화

왜 LLM에 GPU? - Transformer = 행렬 곱셈의 연속 - 70B 모델 추론 = 수조 번의 곱셈/덧셈 - GPU의 병렬 처리가 필수


2. 숫자 표현 (부동소수점)

부동소수점이란?

컴퓨터는 실수를 부호 + 지수 + 가수로 표현함.

index diagram 1

정밀도 비교

FP64 (64비트, 8B) - 정밀도 최고, 범위 매우 넓음 - 용도: 과학 계산

FP32 (32비트, 4B) - 정밀도 높음, 범위 넓음 - 용도: 학습 기본

TF32 (19비트, 4B) - 정밀도 중간, 범위 FP32급 - 용도: A100 학습

FP16 (16비트, 2B) - 정밀도 낮음, 범위 좁음 - 용도: 추론

BF16 (16비트, 2B) - 정밀도 낮음, 범위 FP32급 - 용도: 학습/추론

INT8 (8비트, 1B) - 256단계, 범위 -128~127 - 용도: 양자화

INT4 (4비트, 0.5B) - 16단계, 범위 -8~7 - 용도: 극한 압축

FP16 vs BF16

FP16 (Half Precision) - 구조: 1비트(부호) + 5비트(지수) + 10비트(가수) - 특징: 정밀도 높음, 범위 좁음

BF16 (Brain Float) - 구조: 1비트(부호) + 8비트(지수) + 7비트(가수) - 특징: 범위 FP32급, 정밀도 낮음

BF16이 LLM에 좋은 이유: - FP32와 동일한 지수 범위 → 오버플로우 방지 - 학습 안정성 유지 - 메모리 절반으로 감소

왜 정밀도가 중요한가?

Llama 70B 모델 크기 계산:

  • 파라미터: 700억 개
  • FP32: 70B × 4B = 280GB (불가능)
  • FP16: 70B × 2B = 140GB (A100 2대)
  • INT8: 70B × 1B = 70GB (A100 1대)
  • INT4: 70B × 0.5B = 35GB (RTX 4090 가능!)

3. 메모리 계층

메모리 속도 피라미드

위로 갈수록: 빠름, 작음, 비쌈 아래로 갈수록: 느림, 큼, 저렴

1. GPU 레지스터 (~TB/s) - 가장 빠름, 가장 작음

2. GPU L1/L2 캐시 (~10TB/s) - 자주 사용하는 데이터 임시 저장

3. GPU VRAM (~2TB/s, HBM) - 용량: 24-80GB - 모델 가중치 저장

4. 시스템 RAM (~50GB/s) - 용량: 64-512GB - CPU 작업, 배치 대기

5. SSD/NVMe (~7GB/s) - 용량: 1-8TB - 모델 파일 저장

GPU 메모리 (VRAM)

VRAM 사용 내역 (Llama 70B INT4 추론):

  • 모델 가중치 (INT4): 35GB
  • KV 캐시 (동적): 10-20GB
  • 활성화 메모리: 2-5GB
  • CUDA 컨텍스트: 1-2GB
  • 총 필요: ~50-60GB

A100 80GB: ✅ 가능 RTX 4090 24GB: ❌ 불가능 (작은 모델 필요)

대역폭이 왜 중요한가?

LLM 추론 = 메모리 바운드 (Memory Bound)

추론 속도 계산 예시: - 모델 크기: 70GB (INT8) - VRAM 대역폭: 2TB/s (A100) - 이론상 최대: 2000GB/s ÷ 70GB = ~28 토큰/초

실제로는: - KV 캐시 읽기/쓰기 - 활성화 값 저장 - 실제: ~20 토큰/초

대역폭 2배 → 속도도 ~2배


4. LLM 핵심 개념

토큰 (Token)

토큰화 과정:

  1. 입력: "안녕하세요, 저는 AI."
  2. 토크나이저 (BPE/SentencePiece) 적용
  3. 토큰: ["안녕", "하세요", ",", " 저는", " AI", "", "."]
  4. 토큰 ID: [31245, 8472, 11, 12847, 9583, 29384, 13]

특징: - 한글: 1글자 ≈ 2-3토큰 (비효율적) - 영어: 1단어 ≈ 1-2토큰 - 어휘집 크기: 32K-128K (모델마다 다름)

KV 캐시 (Key-Value Cache)

왜 KV 캐시가 필요한가?

KV 캐시 없이: - "오늘 날씨가" → 전체 계산 → "좋" - "오늘 날씨가 좋" → 전체 재계산 → "습" - 문제: O(n²) 복잡도

KV 캐시 사용: - "오늘 날씨가" → K1, V1, K2, V2 계산 후 캐시 저장 → "좋" - "좋" 추가 → K1~V2는 캐시에서 로드, K3, V3만 새로 계산 → "습" - 효과: O(n²) → O(n)

KV 캐시 메모리 계산:

공식: 2 × 레이어 수 × 시퀀스 길이 × 히든 크기 × 배치 × 정밀도

예시 (Llama 70B, FP16, 배치 1): - 4K 시퀀스: 10.7GB - 8K 시퀀스: 21.4GB - 32K 시퀀스: 85.6GB → VRAM 폭발!

긴 컨텍스트 = 더 많은 메모리 필요

배치 (Batch) 처리

배치 1 (요청 하나씩): - Req 1 → 완료 → Req 2 → 완료 → ... - GPU 활용률: ~30% - 시간: 오래 걸림

배치 8 (동시 처리): - Req 1~8 동시 처리 → 모두 완료 - GPU 활용률: ~90% - 시간: 절반 이하

효과: 처리량 3-5배 향상


5. 최적화 기초

왜 양자화를 하는가?

FP16 → INT4 양자화 효과:

  • 메모리: 140GB → 35GB (75% 감소)
  • 속도: 1x → 2-3x (메모리 대역폭 여유)
  • 품질: 100% → 95-98% (약간의 손실)

트레이드오프 (품질 vs 메모리): - FP16: 100% 품질, 메모리 최대 - INT8: ~98% 품질, 메모리 절반 - INT4: ~95% 품질, 메모리 1/4 - INT2: ~90% 품질, 메모리 최소

최적화 체크리스트

양자화 (INT8) - 난이도: 쉬움 - 효과: 메모리 50% 감소 - 비용: 품질 1-2% 손실

양자화 (INT4) - 난이도: 쉬움 - 효과: 메모리 75% 감소 - 비용: 품질 3-5% 손실

KV 캐시 최적화 - 난이도: 중간 - 효과: 긴 컨텍스트 가능 - 비용: 구현 복잡도

배치 처리 - 난이도: 쉬움 - 효과: 처리량 3-5배 - 비용: 지연시간 증가

Flash Attention - 난이도: 중간 - 효과: 메모리 효율 - 비용: 없음

텐서 병렬화 - 난이도: 어려움 - 효과: 큰 모델 가능 - 비용: 다중 GPU 필요


정리

LLM 최적화를 위해 알아야 할 핵심:

  1. GPU가 핵심 - CPU 아닌 GPU에서 추론
  2. 메모리가 병목 - 연산보다 메모리 대역폭이 한계
  3. 정밀도가 크기 결정 - FP16 → INT4로 4배 압축
  4. KV 캐시가 메모리 잡아먹음 - 긴 컨텍스트 = 더 많은 메모리
  5. 배치가 효율 결정 - 동시 처리로 GPU 활용률 극대화

이 기초를 알면 왜 vLLM이 빠른지, 왜 양자화가 필요한지, 왜 70B 모델에 A100이 필요한지 이해할 수 있음.