cuda
cuda๋ ํ๋ ๋จธ์ ๋ฌ๋ ํ๊ฒฝ์ ํต์ฌ์ด ๋๋ ๊ธฐ๋ฅ์์ ์ค ํ๋๋ค.
cuda๊ฐ ๋์ฒด ๋ญ๊ฐ?
๊ทธ๋ํฝ์นด๋, GPU๋ ์๋ ์ง์ง ๊ทธ๋ํฝ ์ฐ์ฐ์ ์ํ ์ฅ์น์๋ค. ๋ชจ๋ํฐ ๋ ๋๋งํ๊ณ ๊ทธ๋ฐ๊ฑฐ ๋ง์ด๋ค.
ํ์ง๋ง ๊ทผ๋์ ์์ GPU์ ๋ณ๋ ฌ ์ฒ๋ฆฌ ๋ฅ๋ ฅ์ด ์ฃผ๋ชฉ๋ฐ๊ฒ ๋์๋ค.
GPU๋ ํ๋์จ์ด์ ์ผ๋ก ์๋ฐฑ ์์ฒ๊ฐ์ ์์ ์ฝ์ด๋ก ๊ตฌ์ฑ๋๋๋ฐ, ์ฝ์ด ํ๋ํ๋์ ๋จ์ผ ์ฑ๋ฅ์ CPU๋ณด๋ค ๋ฎ์์ ๋ฒ์ฉ์ผ๋ก ์ฌ์ฉํ๊ธฐ์๋ ๋นํจ์จ์ ์ด๋ค.
ํ์ง๋ง ์ฌ๋ฌ๊ฐ์ ์ซ์(ํนํ float)๋ก ๊ตฌ์ฑ๋๋ ๋ฒกํฐ/ํ๋ ฌ๊ฐ์ ์ฐ์ฐ์ ๋ํด์๋ ๋งค์ฐ ๋ฐ์ด๋ ์ฑ๋ฅ์ ๋ณด์ฌ์ค ์ ์๋ค. CPU๋ ํ๋ํ๋ ๋ฃจํ ๋๋ฉด์ ์ฒ๋ฆฌํด์ผํ๋ ๊ฒ์ GPU๋ ํ๋ฒ์ ๋ฐ์ด๋ฃ๊ณ ๋ณ๋ ฌ์ฒ๋ฆฌ๋ฅผ ํด๋ฒ๋ฆด ์ ์๋ ๊ฒ์ด๋ค.
.PNG?type=w800)
CUDA๋ GPU๋ฅผ ๊ทธ๋ฐ ์ฐ์ฐ๋ค์ ์ง์ํ๊ธฐ ์ํ ์ธํฐํ์ด์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
C/C++๋ก ์์ฑ๋์ด์๋๋ฐ, ์ด๊ฑฐ ์์ฒด๋ ๋๋ฌด rawํ๊ฒ ๋์ด์์ด์ ๋ณดํต์ torch ๊ฐ์ ์ถ์ํ๋ ํ๊ฒฝ์ ํตํด์ ๊ฐ์ ํธ์ถ์ ํ๋๊ฒ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ํํ๋ค.
CUDA์, CUDA ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ๋ ๊ฐ๋ฐํ๊ฒฝ์ด์ผ๋ง๋ก ์๋น๋์์ ์ฃผ๊ฐ๋ฅผ ์งํฑํ๋ ๊ฐ์ฅ ํฐ ๊ธฐ๋ฅ์ด๋ผ ํ ์ ์๋ค.
๋ค๋ฅธ GPU ๊ฐ๋ฐ์ฌ๋ค์ด ์ฑ๋ฅ์ด ๋จ์ด์ ธ์ ๋ฐ๋ฆฌ๋๊ฒ ์๋๋ผ, ์ด ์ํํธ์จ์ด ํ๊ฒฝ ๋๋ฌธ์ ๋ฐ๋ฆฌ๋ ๊ฒ์ด๋ค.
์ฌ์ฉํด๋ณด๊ธฐ
๋น์ฐํ ์๋น๋์ ๊ทธ๋ํฝ์นด๋๋ฅผ ์ฌ์ฉํ ์ ์๋ ํ๊ฒฝ์ด์ด์ผ ํ๋ค.
๋ด ๊ฒฝ์ฐ์๋ AWS EC2์ GPU ํ์
์ ์ฌ์ฉํ๋ค.

์ ๋ณด๋ฅผ ์กฐํํด์, ์ด๋ฐ ์์ผ๋ก ๋์ค๋ฉด ์ฌ์ฉ ๊ฐ๋ฅํ ํ๊ฒฝ์ด๋ค.
lspci | grep -i nvidia

๋๋ผ์ด๋ฒ ๊ตฌ์ฑ์ ๋ณ๋ ํฌ์คํธ๋ฅผ ์ฐธ์กฐํ๋ค.
https://blog.naver.com/sssang97/223867488688
Python torch๋ก cuda ์จ๋ณด๊ธฐ
pytorch๋ฅผ ํตํด์ cuda๋ฅผ ์ค์นํ๊ณ ์ฌ์ฉํด๋ณด๊ฒ ๋ค.

์ค์นํ๊ณ , importํด์ ์คํํด๋ณธ๋ค.
import torch
torch.cuda.is_available()
๋๋ผ์ด๋ฒ ๊ตฌ์ฑ์ด ์ ๋๋ก ๋์ด์์ง ์๋ค๋ฉด ์ด๋ ๊ฒ False๊ฐ ๋ ๊ฒ์ด๋ค.
๊ตฌ์ฑ์ด ๋์ด์๋ค๋ฉด True๊ฐ ๋์จ๋ค. ์ด๋์ผ cuda๋ฅผ ์ธ ์ ์๋ค.
torch๋ฅผ ํตํด cuda ๋ฉํ๋ฐ์ดํฐ๋ ์ด๊ฒ์ ๊ฒ ์กฐํํ ์ ์๋ค.
print(f"CUDA ๋ฒ์ : {torch.version.cuda}")
print(f"GPU ๊ฐ์: {torch.cuda.device_count()}")

์ฌ์ฉ๋ฒ์ ๋๋ต ์ด๋ ๋ค. ๋ค์ ์ฝ๋๋ 1000x1000 ํ๋ ฌ์ ๋๋ค์ผ๋ก ๋ง๋ค์ด์ ํ๋ ฌ๊ณฑ์ ๋๋ฆฌ๋ ์์ ๋ค.
x = torch.randn(1000, 1000).cuda()
y = torch.randn(1000, 1000).cuda()
z = x @ y # ํ๋ ฌ ๊ณฑ์
print("GPU ์ฐ์ฐ ์ฑ๊ณต")
print(z)
๊ทธ๋ผ ์ด๋ ๊ฒ ์ ๋์ํ๋ค.
๊ฐ๋จํ ์ฑ๋ฅ ๋น๊ต๋ ํ๋ฒ ํด๋ณด์.
import torch
import time
def bench():
# CPU์์ ํ
์ ์์ฑ
print("\n=== CPU vs GPU ์ฑ๋ฅ ๋น๊ต ===")
size = 5000
print(f"{size}x{size} ํ๋ ฌ ๊ณฑ์
์ํ ์ค...")
# CPU ์ฐ์ฐ ์ํ ๋ฐ ์๊ฐ ์ธก์
start_time = time.time()
a_cpu = torch.randn(size, size)
b_cpu = torch.randn(size, size)
c_cpu = torch.matmul(a_cpu, b_cpu)
cpu_time = time.time() - start_time
print(f"CPU ์ฐ์ฐ ์๋ฃ: {cpu_time:.4f}์ด")
# GPU ์ฐ์ฐ ์ํ ๋ฐ ์๊ฐ ์ธก์
start_time = time.time()
a_gpu = torch.randn(size, size, device='cuda')
b_gpu = torch.randn(size, size, device='cuda')
c_gpu = torch.matmul(a_gpu, b_gpu)
# GPU ์ฐ์ฐ์ด ์๋ฃ๋ ๋๊น์ง ๋๊ธฐ
torch.cuda.synchronize()
gpu_time = time.time() - start_time
print(f"GPU ์ฐ์ฐ ์๋ฃ: {gpu_time:.4f}์ด")
# ๊ฒฐ๊ณผ ๊ฒ์ฆ (CPU์ GPU ๊ฒฐ๊ณผ๊ฐ ์ผ์นํ๋์ง)
c_gpu_cpu = c_gpu.cpu() # GPU ํ
์๋ฅผ CPU๋ก ์ด๋
is_close = torch.allclose(c_cpu, c_gpu_cpu, rtol=1e-3, atol=1e-3)
print(f"CPU/GPU ๊ฒฐ๊ณผ ์ผ์น: {is_close}")
# ์๋ ๋น๊ต
speedup = cpu_time / gpu_time
print(f"GPU ์๋ ํฅ์: {speedup:.2f}๋ฐฐ ๋น ๋ฆ")
print("\n=== ๊ฐ๋จํ GPU ๋ฉ๋ชจ๋ฆฌ ํ
์คํธ ===")
# GPU ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ํํฉ ํ์ธ
print(f"๋ฉ๋ชจ๋ฆฌ ํ ๋น ์ ์ฌ์ฉ๋: {torch.cuda.memory_allocated() / 1e6:.2f} MB")
# ํฐ ํ
์ ์์ฑ์ผ๋ก GPU ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ
large_tensor = torch.ones((1000, 1000, 100), device='cuda')
print(f"๋ฉ๋ชจ๋ฆฌ ํ ๋น ํ ์ฌ์ฉ๋: {torch.cuda.memory_allocated() / 1e6:.2f} MB")
# ๋ฉ๋ชจ๋ฆฌ ํด์
del large_tensor
torch.cuda.empty_cache()
print(f"๋ฉ๋ชจ๋ฆฌ ํด์ ํ ์ฌ์ฉ๋: {torch.cuda.memory_allocated() / 1e6:.2f} MB")
print("\nCUDA Hello World ์๋ฃ!")
bench()
5000x5000์ ๋๋ ธ์ ๋๋ CPU๋ก ๋๋ฆด ๋๋ณด๋ค 4๋ฐฐ ์ ๋ ๋นจ๋๋ค.
์ค์ ์ฌ์ฉ์ฌ๋ก์์๋ ๋ ํฌ๊ณ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๊ธฐ ๋๋ฌธ์, ์ด๊ฒ๋ณด๋ค ๋ ๋ฒ์ด์ง๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ๊ฒ์ด๋ค.