728x90
๋ฐ์ํ
๐ ๋ณธ ๊ฒ์๊ธ์ Python 3.11.0 ํ๊ฒฝ์์ ์์ฑ๋์์ต๋๋ค!
Numba๋ Python์ ์ํ Just-In-Time(JIT) ์ปดํ์ผ๋ฌ๋ก, ์ฃผ๋ก ์์น ๊ณ์ฐ ๋ฐ ๊ณผํ์ ์ปดํจํ ์ ์ต์ ํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
Numpy์ ํจ๊ป ์ฌ์ฉ๋ ๋ ํนํ ๊ฐ๋ ฅํ๋ค.
ํน์ง
- JIT ์ปดํ์ผ : ํ์ด์ฌ ์ฝ๋๋ฅผ ์คํ ์๊ฐ์ ์ปดํ์ผ ํ์ฌ ์ฑ๋ฅ์ ํฅ์ํ๋ค.
- Numpy ํธํ : Numpy ๋ฐฐ์ด๊ณผ ๋ง์ ํจ์์ ์ฐ์ฐ์ ์ง์ํ๋ค.
- GPU ์ง์ : NVIDIA GPU์์ CUDA๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ง์ํ๋ค.
- ๊ฐํธํ ์ฌ์ฉ : ๊ธฐ์กด Python ์ฝ๋์ ์ฃผ์์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
์ฅ์
- ์ฑ๋ฅ ํฅ์ : Python ์ฝ๋๋ฅผ C, Fortran๊ณผ ์ ์ฌํ ์๋๋ก ์คํ ํ ์ ์๊ฒ ํ๋ค.
- ์ง๊ด์ ์ธ ์ธํฐํ์ด์ค : ์ฝ๋๋ฅผ ์ต์ํ์ ์์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ด, ํ์ต ๊ณก์ ์ด ๋ฎ๋ค.
- ๋ค์ํ ๊ธฐ๋ฅ : JIT ์ปดํ์ผ ์ธ์๋, ๋ณ๋ ฌ ์ฒ๋ฆฌ, GPU ๊ฐ์, ๋ค์ํ ๋ฐ์ดํฐ ํ์ ์ง์ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
pip install numba
import numpy as np
from numba import njit
import time
def sum_array1(arr):
total = 0.0
for i in range(arr.size):
total += arr[i]
return total
@njit
def sum_array2(arr):
total = 0.0
for i in range(arr.size):
total += arr[i]
return total
# NumPy ๋ฐฐ์ด ์์ฑ
data = np.arange(1, 100000001)
# Numba๋ฅผ ์ฌ์ฉํ ํจ์ ํธ์ถ
start = time.time()
result = sum_array1(data)
print(f"No JIT:{time.time() - start:.3f}sec")
start = time.time()
result = sum_array2(data)
print(f"JIT:{time.time() - start:.3f}sec")
๋์ฉ๋ ์ฐ์ฐ์ ๊ฒฝ์ฐ JIT๋ฅผ ์ฌ์ฉํ๋ฉด ํ์คํ๊ฒ ๋น ๋ฅด์ง๋ง, ์คํ๋ ค ์์ ์ฐ์ฐ์ ๊ฒฝ์ฐ ์ด๊ธฐ ์ปดํ์ผ ์๊ฐ์ด ์์ผ๋ฏ๋ก ํธํ๋ ค ์ฑ๋ฅ์ด ๋จ์ด์ง ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ Numba๋ ๋ชจ๋ Python lib๋ฅผ ์ง์ํ์ง ์๋๋ค. (OpenCV ์ง์ํ์ง ์์...)
๋ฐ์ฝ๋ ์ดํฐ
@njit
- Numba์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ปดํ์ผ๋ฌ
from numba import njit
@njit
def my_function(x):
return x + 1
@jit
- @njit์ ๋์ผํ๋, ์ปดํ์ผ ์ต์ ์ ์ถ๊ฐ ํ ์ ์๋ ์ธ์๋ฅผ ๊ฐ์ง๋ค. no_python=True๋ฅผ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ Python ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ง ์๋๋ก ๊ฐ์ ํ๋ค.
from numba import jit
@jit(nopython=True)
def my_function(x):
return x + 1
@cuda.jit
- CUDA GPU์์ ์คํ ํ ์ ์๋ ์ปค๋ ํจ์๋ฅผ ์ ์ํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. GPU ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
from numba import cuda
@cuda.jit
def gpu_function(a, b, c):
idx = cuda.grid(1)
if idx < c.size:
c[idx] = a[idx] + b[idx
@guvectorize
- ๋ฒกํฐํ๋ ํจ์๋ฅผ ์ ์ํ ๋ ์ฌ์ฉ, ์ ๋ ฅ ๋ฐฐ์ด์ ํํ๋ฅผ ์ง์ ํ๊ณ , ๋ค์ํ ํฌ๊ธฐ์ ๋ฐฐ์ด์ ๋ํด ๋์ผํ ํจ์๊ฐ ์๋ํ๋๋ก ํ๋ค.
from numba import guvectorize
@guvectorize(["(float64[:], float64[:])"], "(n)->(n)")
def vectorized_function(input_array, output_array):
for i in range(input_array.shape[0]):
output_array[i] = input_array[i] * 2
@vectorize
- ๋ฐฐ์ด ์ฐ์ฐ์ ๋ฒกํฐํํ์ฌ ์คํํ๋ ๋ฐ ์ฌ์ฉํ๋ค. ์ค์นผ๋ผ ํจ์๋ฅผ ๋ฒกํฐํํ์ฌ ์ ๋ ฅ ๋ฐฐ์ด์ ๋ํด ์คํ ํ ์ ์๋ค.
from numba import vectorize
@vectorize([float64(float64)])
def vectorized_scalar_function(x):
return x * 2
@stencil
- ๊ฒฉ์ ๋ฐ์ดํฐ์ ๋ํด ์คํ ์ค ์ฐ์ฐ์ ์ํํ ๋ ์ฌ์ฉ๋๋ค. ์ฃผ๋ก ์ด๋ฏธ์ง ์ฒ๋ฆฌ๋ ๊ณผํ์ ๊ณ์ฐ์์ ์ฌ์ฉ๋๋ค.
from numba import stencil
@stencil
def stencil_function(a):
return a[0, 0] + a[1, 0] + a[0, 1] + a[1, 1]
@prange
- ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ฐ๋ณต๋ฌธ์ ์์ฑํ ๋ ์ฌ์ฉ๋๋ค. for๋ฃจํ๋ฅผ ๋ณ๋ ฌ๋ก ์คํ ํ ์ ์๊ฒ ํด์ค๋ค.
from numba import njit, prange
@njit
def parallel_sum(arr):
total = 0.0
for i in prange(arr.size):
total += arr[i]
return total
728x90
๋ฐ์ํ
'Langauge > Python' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Python] Python๊ณผ C++ ์ฐ๋ (0) | 2024.09.25 |
---|---|
[Python] ๋ณ๋ ฌ ์ฒ๋ฆฌ (0) | 2024.09.13 |
[Python] ์ฐ์ฐ ์๋ ์ฌ๋ฆฌ๊ธฐ - ํ๋กํ์ผ๋ง(Profiling) (0) | 2024.09.13 |
[Python] ์ฐ์ฐ ์๋ ์ฌ๋ฆฌ๊ธฐ - ๋ด์ฅ ํจ์ ์ฌ์ฉ (0) | 2024.09.13 |
[Python] ์ฐ์ฐ ์๋ ์ฌ๋ฆฌ๊ธฐ - ๊ฐ์ ๋ฐ ์๊ณ ๋ฆฌ์ฆ๊ณผ ์๋ฃ๊ตฌ์กฐ (0) | 2024.09.12 |