Search
moon
sun
โœ…

250217_0954_CUDA Lazy Unloading + nvidia cuda fallback

CUDA Lazy Unloading

1. AI๊ฐ€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ ์ž๋™์œผ๋กœ ๋‚ด๋ ค๊ฐ€๋Š” ์ด์œ 

(1) CUDA Lazy Unloading (์ง€์—ฐ ์–ธ๋กœ๋“œ)

โ€ข
CUDA ์ปค๋„์ด๋‚˜ AI ๋ชจ๋ธ์ด ์‹คํ–‰๋˜์ง€ ์•Š์œผ๋ฉด ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜ ์ž๋™์œผ๋กœ GPU ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์–ธ๋กœ๋“œ๋จ.
โ€ข
NVIDIA ๋“œ๋ผ์ด๋ฒ„ ๋ฐ PyTorch/TensorFlow ๋“ฑ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌ.
โ€ข
torch.cuda.empty_cache() ๊ฐ™์€ ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋˜๋ฉด ๊ฐ•์ œ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Œ.

(2) OS ๋ฐ ๋“œ๋ผ์ด๋ฒ„์˜ ์ „๋ ฅ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ

โ€ข
Windows/Linux์˜ ์ „์› ๊ด€๋ฆฌ ์„ค์ •์— ๋”ฐ๋ผ ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ GPU ์‚ฌ์šฉ์ด ์—†์œผ๋ฉด ํด๋Ÿญ ์†๋„๋ฅผ ๋‚ฎ์ถ”๊ฑฐ๋‚˜ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ด์ œํ•จ.
โ€ข
nvidia-smi --query-gpu=power.limit --format=csv ๋ช…๋ น์–ด๋กœ ํ™•์ธ ๊ฐ€๋Šฅ.

(3) AI ๋ชจ๋ธ์ด ์„ธ์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘

โ€ข
Flask, FastAPI, Django ๊ฐ™์€ ์„œ๋ฒ„ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ AI ๋ชจ๋ธ์„ ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋“œํ–ˆ๋‹ค๊ฐ€ ์ผ์ • ์‹œ๊ฐ„ ํ›„ ์ž๋™์œผ๋กœ ํ•ด์ œ.
โ€ข
K8s(์ฟ ๋ฒ„๋„คํ‹ฐ์Šค)๋‚˜ Docker ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ฐ˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ์š”์ฒญ์ด ์—†์œผ๋ฉด ์ž๋™์œผ๋กœ pod์ด ์ข…๋ฃŒ๋˜๊ฑฐ๋‚˜ scale down๋จ.

(4) Deep Learning ํ”„๋ ˆ์ž„์›Œํฌ์˜ Garbage Collection (GC)

โ€ข
PyTorch, TensorFlow๋Š” ์ผ์ • ์‹œ๊ฐ„๋งˆ๋‹ค ๋ฏธ์‚ฌ์šฉ ํ…์„œ๋ฅผ ํ•ด์ œํ•˜์—ฌ GPU ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ™•๋ณด.
โ€ข
gc.collect() ๋˜๋Š” torch.cuda.empty_cache() ์‹คํ–‰ ์‹œ ๊ฐ•์ œ ์‹คํ–‰๋จ.

2. ์ด ๊ธฐ๋Šฅ์„ ์ผœ๊ฑฐ๋‚˜ ๋Œ ์ˆ˜ ์žˆ๋‚˜?

(1) CUDA Lazy Unloading ๋น„ํ™œ์„ฑํ™”

โ€ข
๊ธฐ๋ณธ์ ์œผ๋กœ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌ๋˜์ง€๋งŒ, CUDA ์ปจํ…์ŠคํŠธ ์œ ์ง€๋ฅผ ์œ„ํ•ด ํŠน์ • ์„ค์ •์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Œ.
โ€ข
Python์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด cudaMalloc์„ ์œ ์ง€ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•ด์ œ๋˜์ง€ ์•Š์Œ:
torch.zeros((1,), device="cuda") # GPU ์ปจํ…์ŠคํŠธ ์œ ์ง€
Python
๋ณต์‚ฌ
โ€ข
๋˜๋Š” CUDA_LAUNCH_BLOCKING=1 ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋ฉด ์ผ๋ถ€ ์ž๋™ ์ตœ์ ํ™”๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋จ:
export CUDA_LAUNCH_BLOCKING=1
Shell
๋ณต์‚ฌ

(2) ์ „๋ ฅ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ ๋น„ํ™œ์„ฑํ™”

โ€ข
NVIDIA ์ „๋ ฅ ๊ด€๋ฆฌ ์„ค์ •์„ Persistent Mode๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์ผ์ • ์‹œ๊ฐ„ ํ›„ ๋ฆฌ์†Œ์Šค ํ•ด์ œ๊ฐ€ ๋ฐฉ์ง€๋จ:
sudo nvidia-smi -pm 1
Shell
๋ณต์‚ฌ
โ€ข
๋ถ€ํŒ…ํ•  ๋•Œ ์ž๋™ ์ ์šฉํ•˜๋ ค๋ฉด /etc/rc.local์— ์ถ”๊ฐ€.

(3) ์„œ๋ฒ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ชจ๋ธ ์œ ์ง€

โ€ข
FastAPI, Flask ๋“ฑ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ชจ๋ธ์„ ํ•ญ์ƒ ๋ฉ”๋ชจ๋ฆฌ์— ์œ ์ง€ํ•˜๋ ค๋ฉด Lazy Loading์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ , ๊ธ€๋กœ๋ฒŒ ๋ณ€์ˆ˜๋กœ ๋ชจ๋ธ์„ ๋กœ๋“œ.
โ€ข
์˜ˆ์ œ (FastAPI์—์„œ AI ๋ชจ๋ธ ์œ ์ง€):
from fastapi import FastAPI import torch app = FastAPI() model = torch.jit.load("model.pth").to("cuda") # ๋ชจ๋ธ์„ GPU์— ํ•ญ์ƒ ๋กœ๋“œ @app.get("/predict") def predict(): return {"status": "model is always in GPU"}
Python
๋ณต์‚ฌ
โ€ข
K8s๋‚˜ Docker ํ™˜๊ฒฝ์—์„œ๋Š” pod autoscaler ๊ธฐ๋Šฅ์„ ๋„๊ฑฐ๋‚˜, ์ตœ์†Œ pod ์ˆ˜๋ฅผ ์„ค์ •.

(4) Garbage Collection ๊ฐ•์ œ ์œ ์ง€

โ€ข
gc.collect() ํ˜ธ์ถœ์„ ์ตœ์†Œํ™”ํ•˜๊ฑฐ๋‚˜, torch.cuda.empty_cache()๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์œผ๋ฉด GPU ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Œ.
โ€ข
TensorFlow์˜ ๊ฒฝ์šฐ:
import tensorflow as tf tf.config.experimental.set_memory_growth(tf.config.list_physical_devices('GPU')[0], True)
Python
๋ณต์‚ฌ

3. ๊ฒฐ๋ก 

โ€ข
AI ๋ชจ๋ธ์ด ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉด GPU ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ž๋™ ํ•ด์ œ๋˜๋Š” ๊ฒƒ์€ CUDA ๋ฐ OS์˜ ์ž์› ๊ด€๋ฆฌ ๊ธฐ๋Šฅ ๋•Œ๋ฌธ.
โ€ข
์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด:
โ—ฆ
nvidia-smi -pm 1๋กœ GPU Persistent Mode ํ™œ์„ฑํ™”
โ—ฆ
AI ์„œ๋ฒ„์—์„œ ๋ชจ๋ธ์„ ๊ธ€๋กœ๋ฒŒ ๋ณ€์ˆ˜๋กœ ์œ ์ง€
โ—ฆ
CUDA ์ปจํ…์ŠคํŠธ๋ฅผ ์œ ์ง€ํ•˜๋Š” ์ž‘์€ ์—ฐ์‚ฐ(torch.zeros((1,), device="cuda")) ์ˆ˜ํ–‰
โ—ฆ
K8s/Docker ํ™˜๊ฒฝ์—์„œ ์ž๋™ scale down ๋น„ํ™œ์„ฑํ™”
์ด ๋ฐฉ๋ฒ•์„ ์ ์šฉํ•˜๋ฉด AI ๋ชจ๋ธ์ด ํ•ญ์ƒ GPU์— ์œ ์ง€๋จ.

nvidia cuda fallback

1. CUDA Fallback์ด๋ž€?

CUDA fallback์€ ์ฝ”๋“œ ์‹คํ–‰ ์‹œ CUDA(์ฆ‰, GPU ๊ฐ€์†)๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ–ˆ์œผ๋‚˜, ์–ด๋–ค ์ด์œ ๋กœ GPU ๊ฐ€์†์ด ๋ถˆ๊ฐ€๋Šฅํ•˜์—ฌ ๋Œ€์‹  CPU๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ƒํ™ฉ์„ ์˜๋ฏธํ•จ.

2. ๋ฐœ์ƒํ•˜๋Š” ์ฃผ์š” ์›์ธ

(1) CUDA ์ง€์›์ด ๋น„ํ™œ์„ฑํ™”๋จ

โ€ข
GPU๊ฐ€ ์—†๊ฑฐ๋‚˜, CUDA ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์น˜๋˜์ง€ ์•Š์Œ.
โ€ข
torch.cuda.is_available() ๋˜๋Š” nvidia-smi ๋ช…๋ น์–ด๋กœ ํ™•์ธ ๊ฐ€๋Šฅ.

(2) CUDA ๋ฒ„์ „ ๋ถˆ์ผ์น˜

โ€ข
์„ค์น˜๋œ PyTorch ๋˜๋Š” TensorFlow๊ฐ€ ์ง€์›ํ•˜๋Š” CUDA ๋ฒ„์ „๊ณผ ์‹œ์Šคํ…œ์˜ CUDA ๋“œ๋ผ์ด๋ฒ„ ๋ฒ„์ „์ด ๋งž์ง€ ์•Š์Œ.
โ€ข
์˜ˆ: PyTorch๊ฐ€ CUDA 11.8์„ ํ•„์š”๋กœ ํ•˜์ง€๋งŒ, ์‹œ์Šคํ…œ์—๋Š” CUDA 10.2๋งŒ ์„ค์น˜๋จ.
โ€ข
nvcc --version ๋ฐ torch.version.cuda๋กœ ํ™•์ธ.

(3) CUDA ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ

โ€ข
GPU VRAM ๋ถ€์กฑ์œผ๋กœ CUDA ์ปค๋„์ด ์‹คํ–‰๋˜์ง€ ๋ชปํ•˜๊ณ  CPU๋กœ ์ „ํ™˜๋จ.
โ€ข
torch.cuda.memory_summary() ๋˜๋Š” nvidia-smi๋กœ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ.
โ€ข
ํ•ด๊ฒฐ์ฑ…: torch.cuda.empty_cache() ์‹คํ–‰ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ ๋ฐฐ์น˜ ํฌ๊ธฐ ์ค„์ด๊ธฐ.

(4) CUDA ์—ฐ์‚ฐ ์ง€์›๋˜์ง€ ์•Š์Œ

โ€ข
ํŠน์ • ์—ฐ์‚ฐ์ด GPU์—์„œ ์ง€์›๋˜์ง€ ์•Š์•„ CPU์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ.
โ€ข
์˜ˆ: ์ผ๋ถ€ CPU ์ „์šฉ ์—ฐ์‚ฐ(torch.symeig() ๊ฐ™์€ ํ•จ์ˆ˜)์€ GPU์—์„œ ์‹คํ–‰ ๋ถˆ๊ฐ€.
โ€ข
ํ•ด๊ฒฐ์ฑ…: CPU ์ „์šฉ ์—ฐ์‚ฐ์ธ์ง€ ํ™•์ธ ํ›„ ๋Œ€์ฒด ๋ฐฉ๋ฒ• ๊ณ ๋ ค.

(5) PyTorch ๋˜๋Š” TensorFlow๊ฐ€ CPU ๋ชจ๋“œ์—์„œ ์‹คํ–‰๋จ

โ€ข
PyTorch ๋˜๋Š” TensorFlow๊ฐ€ CPU ๋ชจ๋“œ๋กœ ๋นŒ๋“œ๋จ.
โ€ข
torch.backends.cudnn.enabled ๋˜๋Š” torch.cuda.is_available()๋กœ ํ™•์ธ.
โ€ข
ํ•ด๊ฒฐ์ฑ…: GPU ์ง€์› ๋ฒ„์ „ ์žฌ์„ค์น˜.

3. ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ์š”์•ฝ

โ€ข
torch.cuda.is_available() ๋˜๋Š” nvidia-smi๋กœ CUDA ์ธ์‹ ์—ฌ๋ถ€ ํ™•์ธ
โ€ข
nvcc --version๊ณผ torch.version.cuda๋กœ ๋ฒ„์ „ ๋ถˆ์ผ์น˜ ์ฒดํฌ
โ€ข
GPU ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์‹œ torch.cuda.empty_cache() ์‹คํ–‰ ํ›„ ์žฌ์‹œ๋„
โ€ข
GPU์—์„œ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ์—ฐ์‚ฐ์ธ์ง€ ํ™•์ธ ํ›„ CPU ์‹คํ–‰์ธ์ง€ ์ฒดํฌ
โ€ข
PyTorch ๋˜๋Š” TensorFlow๊ฐ€ CPU ์ „์šฉ ๋นŒ๋“œ์ธ์ง€ ํ™•์ธ ํ›„ ์žฌ์„ค์น˜
์ถ”๊ฐ€์ ์œผ๋กœ ๋กœ๊ทธ๋‚˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ์œผ๋ฉด ๋” ์ •ํ™•ํ•œ ์›์ธ ๋ถ„์„ ๊ฐ€๋Šฅ.

์•ˆ๋…•ํ•˜์„ธ์š”๐Ÿ˜Š

โ€ข
๊ด€๋ จ ๊ธฐ์ˆ  ๋ฌธ์˜์™€ R&D ๊ณต๋™ ์—ฐ๊ตฌ ์‚ฌ์—… ๊ด€๋ จ ๋ฌธ์˜๋Š” โ€œglory@keti.re.krโ€๋กœ ์—ฐ๋ฝ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

Hello ๐Ÿ˜Š

โ€ข
For technical and business inquiries, please contact me at โ€œglory@keti.re.krโ€