Deep Learning & Machine Learning/XGBoost

XGBoost에서 GPU(cuda) 사용하는 예제

webnautes 2024. 6. 15. 22:48
반응형

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 

 

https://xgboost.readthedocs.io/en/stable/python/gpu-examples/cover_type.html#sphx-glr-python-gpu-examples-cover-type-py 




반응형