XGBoost에서 GPU(cuda) 사용하는 예제
XGBoost에서 GPU(cuda)를 사용하기 위해 테스트한 과정을 기록해놓았습니다. 선택적으로 필요한 부분만 확인하여 활용하세요.
글 작성에 사용한 XGBoost 버전은 2.0.3입니다.
최초작성 2024. 6. 13
결론부터 적어보면 큰 데이터를 학습/추론할때에는 GPU를 사용시 성능이 개선되었지만 작은 데이터를 학습/추론시에는 GPU를 사용해서 성능이 개선되기는 겨녕 오히려 CPU를 사용할때보다 안좋은 성능을 보였습니다. 우분투의 경우엔 XGBoost에서 GPU 사용 테스트시 문제가 없었지만 윈도우에서는 XGBoost에서 GPU를 제대로 사용못하는 현상이 있었습니다.
CUDA가 설치되어 있는 우분투와 윈도우에서 테스트를 진행했습니다. CUDA 설치 과정은 다음 포스트를 참고하세요. 포스트에선 CUDA 11을 사용했습니다. CUDA 12에선 테스트해보지 않어서 원하는 결과를 얻을 수 있을지 알 수 없습니다.
Ubuntu 22.04에 CUDA 11.8 설치하는 방법
https://webnautes.tistory.com/1844
Windows에 CUDA Toolkit 11.8 cuDNN 8.7.0 Tensorflow 설치하는 방법
https://webnautes.tistory.com/1874
우분투의 경우 설치된 CUDA 버전은 다음처럼 확인할 수 있습니다.
webnautes@webnautes-laptop:~$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Sep_21_10:33:58_PDT_2022
Cuda compilation tools, release 11.8, V11.8.89
Build cuda_11.8.r11.8/compiler.31833905_0
Miniconda로 생성한 파이썬 가상환경에서 테스트를 진행했습니다.
Visual Studio Code와 Miniconda를 사용한 Python 개발 환경 만들기( Windows, Ubuntu, WSL2)
https://webnautes.tistory.com/1842
테스트한 과정은 다음과 같습니다. 우분투를 기준으로 설명하지만 윈도우에서도 거의 동일하게 진행가능합니다.
1. 테스트에 사용할 가상환경 test_xgboost_gpu을 생성합니다. 사용할 파이썬 버전으로는 3.11을 선택했습니다.
webnautes@webnautes-laptop:~$ conda create -n test_xgboost_gpu python=3.11
2. Visual Studio Code에서 새로운 폴더를 열고, Ctrl + Shift + P를 누른 후, Python: Select Interpreter를 입력후 선택하여 인터프리터로 앞에서 생성한 test_xgboost_gpu 선택합니다.
3. Visual Studio Code의 메뉴에서 View > Terminal을 선택하여 터미널을 열고 프롬프트에 앞에서 선택한 인터프리터 이름인 (test_xgboost_gpu) 가 붙어있는지 확인후, 테스트하는데 필요한 xgboost, cupy-cuda11x, scikit-learn 패키지를 설치했습니다. cupy의 경우엔 cuda 11을 앞에서 설치했기 때문에 설치하는 패키지 이름이 cupy-cuda11x입니다.
(test_xgboost_gpu) webnautes@webnautes-laptop:~/test$ pip install xgboost cupy-cuda11x scikit-learn
xgboost는 XGBoost를 사용하기 위해 필요한 패키지입니다.
cupy는 입력을 GPU로 옮겨주어 GPU에서 동작하도록 설정된 XGBoost에서 사용할 수 있도록 해주는 역할을 합니다.
scikit-learn는 데이터 세트 다운로드와 데이터 세트를 Train과 Test로 분할을 위해 사용됩니다.
다음 코드를 사용하여 cupy에서 사용하고 있는 CUDA 버전을 출력할 수 있습니다. CUDA 11.8의 경우 11080이 출력되었습니다.
import cupy as cp
print(cp.cuda.runtime.runtimeGetVersion())
테스트에 사용한 코드입니다. 큰 데이터셋인 Covertype 데이터셋과 작은 데이터셋인 Iris 데이터셋을 사용하여 각각 GPU와 CPU에서 학습/추론 테스트를 진행합니다.
import time import cupy as cp from sklearn.model_selection import train_test_split from sklearn.datasets import fetch_covtype, load_iris import xgboost as xgb def process(X, y): # Create 0.75/0.25 train/test split X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.25, train_size=0.75, random_state=42 ) # Specify sufficient boosting iterations to reach a minimum num_round = 30 print(f'Train 데이터(학습에 사용) 개수 {X_train.shape[0]}') print(f' Test 데이터(추론에 사용) 개수 {X_test.shape[0]}') # GPU clf = xgb.XGBClassifier(device="cuda", n_estimators=num_round) # Train model start = time.time() clf.fit(cp.array(X_train), cp.array(y_train), eval_set=[(cp.array(X_test), cp.array(y_test))], verbose=0) print("GPU Training Time: %s seconds" % (str(time.time() - start))) start = time.time() for i in range(100): clf.predict(cp.array(X_test)) print("GPU Ienference Time: %s seconds" % (str(time.time() - start))) # CPU clf = xgb.XGBClassifier(device="cpu", n_estimators=num_round) start = time.time() clf.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=0) print("CPU Training Time: %s seconds" % (str(time.time() - start))) start = time.time() for i in range(100): clf.predict(X_test) print("CPU Ienference Time: %s seconds" % (str(time.time() - start))) X, y = fetch_covtype(return_X_y=True) y -= y.min() print('Covertype 데이터셋') print(f'샘플개수 {X.shape[0]}') process(X, y) print('='*20) iris = load_iris() X = iris.data y = iris.target print('Iris 데이터셋') print(f'샘플개수 {X.shape[0]}') process(X, y) |
테스트 진행은 리눅스와 윈도우에서 각각 3번씩 실행해봤습니다.
처음 실행시에는 다음 메시지가 중간에 출력된후 대기시간이 길어서 시간측정이 제대로 되지 않았습니다.
/home/webnautes/miniconda3/envs/test_xgboost_gpu/lib/python3.11/site-packages/cupy/cuda/compiler.py:233: PerformanceWarning: Jitify is performing a one-time only warm-up to populate the persistent cache, this may take a few seconds and will be improved in a future release...
jitify._init_module()
다음처럼 대기시간 때문에 길게 측정됩니다.
(test_xgboost_gpu) webnautes@webnautes-laptop:~/test$ /home/webnautes/miniconda3/envs/test_xgboost_gpu/bin/python /home/webnautes/test/test.py
Covertype 데이터셋
샘플개수 581012
Train 데이터(학습에 사용) 개수 435759
Test 데이터(추론에 사용) 개수 145253
/home/webnautes/miniconda3/envs/test_xgboost_gpu/lib/python3.11/site-packages/cupy/cuda/compiler.py:233: PerformanceWarning: Jitify is performing a one-time only warm-up to populate the persistent cache, this may take a few seconds and will be improved in a future release...
jitify._init_module()
GPU Training Time: 63.7108850479126 seconds
GPU Ienference Time: 3.1864495277404785 seconds
CPU Training Time: 6.254998445510864 seconds
CPU Ienference Time: 12.635242462158203 seconds
====================
Iris 데이터셋
샘플개수 150
Train 데이터(학습에 사용) 개수 112
Test 데이터(추론에 사용) 개수 38
GPU Training Time: 0.9736795425415039 seconds
GPU Ienference Time: 0.10793781280517578 seconds
CPU Training Time: 0.028998374938964844 seconds
CPU Ienference Time: 0.05116748809814453 seconds
우분투에서 연속으로 3번 실행한 결과입니다. 위에서 언급한 메시지가 출력된 첫번째 실행은 결과에서 제외되었습니다. GPU에서 학습/추론하는데 걸리는 시간이 CPU에서 학습/추론하는데 걸리는 시간보다 짧은것을 볼 수 있습니다.
(test_xgboost_gpu) webnautes@webnautes-laptop:~/test$ /home/webnautes/miniconda3/envs/test_xgboost_gpu/bin/python /home/webnautes/test/test.py
Covertype 데이터셋
샘플개수 581012
Train 데이터(학습에 사용) 개수 435759
Test 데이터(추론에 사용) 개수 145253
GPU Training Time: 2.1484806537628174 seconds
GPU Ienference Time: 2.8159475326538086 seconds
CPU Training Time: 4.627403736114502 seconds
CPU Ienference Time: 11.368939399719238 seconds
====================
Iris 데이터셋
샘플개수 150
Train 데이터(학습에 사용) 개수 112
Test 데이터(추론에 사용) 개수 38
GPU Training Time: 0.07478809356689453 seconds
GPU Ienference Time: 0.10637688636779785 seconds
CPU Training Time: 0.030617713928222656 seconds
CPU Ienference Time: 0.04819798469543457 seconds
(test_xgboost_gpu) webnautes@webnautes-laptop:~/test$ /home/webnautes/miniconda3/envs/test_xgboost_gpu/bin/python /home/webnautes/test/test.py
Covertype 데이터셋
샘플개수 581012
Train 데이터(학습에 사용) 개수 435759
Test 데이터(추론에 사용) 개수 145253
GPU Training Time: 2.158426523208618 seconds
GPU Ienference Time: 2.7159838676452637 seconds
CPU Training Time: 4.5699849128723145 seconds
CPU Ienference Time: 11.901838541030884 seconds
====================
Iris 데이터셋
샘플개수 150
Train 데이터(학습에 사용) 개수 112
Test 데이터(추론에 사용) 개수 38
GPU Training Time: 0.07544207572937012 seconds
GPU Ienference Time: 0.10796999931335449 seconds
CPU Training Time: 0.03409552574157715 seconds
CPU Ienference Time: 0.04909658432006836 seconds
(test_xgboost_gpu) webnautes@webnautes-laptop:~/test$ /home/webnautes/miniconda3/envs/test_xgboost_gpu/bin/python /home/webnautes/test/test.py
Covertype 데이터셋
샘플개수 581012
Train 데이터(학습에 사용) 개수 435759
Test 데이터(추론에 사용) 개수 145253
GPU Training Time: 2.131716728210449 seconds
GPU Ienference Time: 2.694427251815796 seconds
CPU Training Time: 5.257902383804321 seconds
CPU Ienference Time: 12.042682409286499 seconds
====================
Iris 데이터셋
샘플개수 150
Train 데이터(학습에 사용) 개수 112
Test 데이터(추론에 사용) 개수 38
GPU Training Time: 0.07808732986450195 seconds
GPU Ienference Time: 0.13051939010620117 seconds
CPU Training Time: 0.17010021209716797 seconds
CPU Ienference Time: 0.06617045402526855 seconds
윈도우에서 연속 3번 실행한 결과입니다. 윈도우에서는 설정에 문제가 있었는지 GPU 가속으로 이득이 없었습니다.
(test_xgboost_gpu) C:\Users\webnautes\Desktop>C:/Users/webnautes/miniconda3/envs/test_xgboost_gpu/python.exe c:/Users/webnautes/Desktop/test/test.py
Covertype 데이터셋
샘플개수 581012
Train 데이터(학습에 사용) 개수 435759
Test 데이터(추론에 사용) 개수 145253
GPU Training Time: 12.591835737228394 seconds
GPU Ienference Time: 3.6624064445495605 seconds
CPU Training Time: 4.5167012214660645 seconds
CPU Ienference Time: 9.134859323501587 seconds
====================
Iris 데이터셋
샘플개수 150
Train 데이터(학습에 사용) 개수 112
Test 데이터(추론에 사용) 개수 38
GPU Training Time: 0.21423625946044922 seconds
GPU Ienference Time: 0.3296165466308594 seconds
CPU Training Time: 0.015625 seconds
CPU Ienference Time: 0.049773454666137695 seconds
(test_xgboost_gpu) C:\Users\webnautes\Desktop>C:/Users/webnautes/miniconda3/envs/test_xgboost_gpu/python.exe c:/Users/webnautes/Desktop/test/test.py
Covertype 데이터셋
샘플개수 581012
Train 데이터(학습에 사용) 개수 435759
Test 데이터(추론에 사용) 개수 145253
GPU Training Time: 5.897252798080444 seconds
GPU Ienference Time: 3.4478509426116943 seconds
CPU Training Time: 4.466765642166138 seconds
CPU Ienference Time: 9.083442449569702 seconds
====================
Iris 데이터셋
샘플개수 150
Train 데이터(학습에 사용) 개수 112
Test 데이터(추론에 사용) 개수 38
GPU Training Time: 0.21390438079833984 seconds
GPU Ienference Time: 0.3245573043823242 seconds
CPU Training Time: 0.03125119209289551 seconds
CPU Ienference Time: 0.03317451477050781 seconds
(test_xgboost_gpu) C:\Users\webnautes\Desktop>C:/Users/webnautes/miniconda3/envs/test_xgboost_gpu/python.exe c:/Users/webnautes/Desktop/test/test.py
Covertype 데이터셋
샘플개수 581012
Train 데이터(학습에 사용) 개수 435759
Test 데이터(추론에 사용) 개수 145253
GPU Training Time: 6.304749250411987 seconds
GPU Ienference Time: 3.5036377906799316 seconds
CPU Training Time: 5.248081922531128 seconds
CPU Ienference Time: 9.348411798477173 seconds
====================
Iris 데이터셋
샘플개수 150
Train 데이터(학습에 사용) 개수 112
Test 데이터(추론에 사용) 개수 38
GPU Training Time: 0.22584104537963867 seconds
GPU Ienference Time: 0.3024885654449463 seconds
CPU Training Time: 0.019014835357666016 seconds
CPU Ienference Time: 0.03374123573303223 seconds
참고
https://velog.io/@damianos/cupy-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0