xgb 및 XGBclassifier를 사용하는 GPU보다 빠른 CPU
초보자이므로 미리 사과드립니다. xgb 및 XGBclassifier를 사용하여 XGBoost로 GPU 대 CPU 테스트를 시도하고 있습니다. 결과는 다음과 같습니다.
passed time with xgb (gpu): 0.390s
passed time with XGBClassifier (gpu): 0.465s
passed time with xgb (cpu): 0.412s
passed time with XGBClassifier (cpu): 0.421s
왜 CPU가 GPU보다 낫지는 않지만 동등한 성능을 보이는지 궁금합니다. 이것은 내 설정입니다.
- 파이썬 3.6.1
- 운영체제 : Windows 10 64bit
- GPU : NVIDIA RTX 2070 Super 8gb vram (드라이버가 최신 버전으로 업데이트 됨)
- CUDA 10.1 설치
- CPU i7 10700 2.9Ghz
- Jupyter 노트북에서 실행
- pip를 통해 xgboost 1.2.0의 야간 빌드를 설치했습니다.
** 또한 pip를 사용하여 미리 빌드 된 바이너리 휠에서 설치된 xgboost 버전을 사용해 보았습니다 : 동일한 문제
다음은 내가 사용중인 테스트 코드입니다 ( 여기 에서 가져옴 ).
param = {'max_depth':5, 'objective':'binary:logistic', 'subsample':0.8,
'colsample_bytree':0.8, 'eta':0.5, 'min_child_weight':1,
'tree_method':'gpu_hist'
}
num_round = 100
dtrain = xgb.DMatrix(X_train2, y_train)
tic = time.time()
model = xgb.train(param, dtrain, num_round)
print('passed time with xgb (gpu): %.3fs'%(time.time()-tic))
xgb_param = {'max_depth':5, 'objective':'binary:logistic', 'subsample':0.8,
'colsample_bytree':0.8, 'learning_rate':0.5, 'min_child_weight':1,
'tree_method':'gpu_hist'}
model = xgb.XGBClassifier(**xgb_param)
tic = time.time()
model.fit(X_train2, y_train)
print('passed time with XGBClassifier (gpu): %.3fs'%(time.time()-tic))
param = {'max_depth':5, 'objective':'binary:logistic', 'subsample':0.8,
'colsample_bytree':0.8, 'eta':0.5, 'min_child_weight':1,
'tree_method':'hist'}
num_round = 100
dtrain = xgb.DMatrix(X_train2, y_train)
tic = time.time()
model = xgb.train(param, dtrain, num_round)
print('passed time with xgb (cpu): %.3fs'%(time.time()-tic))
xgb_param = {'max_depth':5, 'objective':'binary:logistic', 'subsample':0.8,
'colsample_bytree':0.8, 'learning_rate':0.5, 'min_child_weight':1,
'tree_method':'hist'}
model = xgb.XGBClassifier(**xgb_param)
tic = time.time()
model.fit(X_train2, y_train)
print('passed time with XGBClassifier (cpu): %.3fs'%(time.time()-tic))
GPU에서 더 빠른 속도를 얻을 수 있는지 확인하기 위해 Sklearn 그리드 검색을 통합하려고 시도했지만 결국 CPU보다 훨씬 느려졌습니다.
passed time with XGBClassifier (gpu): 2457.510s
Best parameter (CV score=0.490):
{'xgbclass__alpha': 100, 'xgbclass__eta': 0.01, 'xgbclass__gamma': 0.2, 'xgbclass__max_depth': 5, 'xgbclass__n_estimators': 100}
passed time with XGBClassifier (cpu): 383.662s
Best parameter (CV score=0.487):
{'xgbclass__alpha': 100, 'xgbclass__eta': 0.1, 'xgbclass__gamma': 0.2, 'xgbclass__max_depth': 2, 'xgbclass__n_estimators': 20}
75k 관측 데이터 세트를 사용하고 있습니다. GPU를 사용하여 속도가 향상되지 않는 이유는 무엇입니까? GPU를 사용하여 이득을 얻기에는 데이터 세트가 너무 작습니까?
어떤 도움이라도 대단히 감사하겠습니다. 대단히 감사합니다!
답변
흥미로운 질문입니다. 아시다시피 Github와 공식에 언급 된 몇 가지 예가 있습니다 xgboost site.
- https://github.com/dmlc/xgboost/issues/2819
- https://discuss.xgboost.ai/t/no-gpu-usage-when-using-gpu-hist/532
유사한 질문을 게시 한 다른 사람도 있습니다.
- GPU를 지원하는 XGBClassifier를 사용하여 속도 향상 없음
상기 찾고 공식 xgboost문서 , GPU 지원에 대한 광범위한 섹션이 있습니다 .
확인해야 할 몇 가지 사항이 있습니다. 설명서에는 다음 사항이 나와 있습니다.
CUDA 지원 GPU를 사용하여 트리 구성 (훈련) 및 예측을 가속화 할 수 있습니다.
1. GPU CUDA가 활성화되어 있습니까?
예,입니다 .
2. GPU 사용량의 영향을받을 수있는 매개 변수를 사용하고 있습니까?
특정 매개 변수 만 GPU를 사용하면 이점을 얻을 수 있습니다. 사람들은:
네, 그렇습니다. 이들 중 대부분은 하이퍼 파라미터 세트에 포함되어 있습니다.
{subsample, sampling_method, colsample_bytree, colsample_bylevel, max_bin, gamma, gpu_id, predictor, grow_policy, monotone_constraints, interaction_constraints, single_precision_histogram}
3. GPU 지원을 사용하도록 매개 변수를 구성하고 있습니까?
XGBoost 매개 변수 페이지 를 보면 시간 개선에 도움이 될 수있는 추가 영역을 찾을 수 있습니다. 예를 들어, updater
로 설정할 수 있습니다. grow_gpu_hist
(참고, 이것은 tree_method
설정 했기 때문에 문제 이지만 메모에 대한 것입니다) :
grow_gpu_hist : GPU로 나무를 키 웁니다.
매개 변수 페이지의 맨 아래에는 gpu_hist
특히 사용에 대한 추가 매개 변수가 있습니다 deterministic_histogram
(이 기본값이로 설정되어 있으므로 이것은 의문입니다 True
).
GPU에서 결정적으로 히스토그램을 작성합니다. 히스토그램 작성은 부동 소수점 합계의 비연 관적 측면으로 인해 결정적이지 않습니다. 문제를 완화하기 위해 사전 반올림 루틴을 사용하므로 정확도가 약간 떨어질 수 있습니다. 비활성화하려면 false로 설정하십시오.
4. 데이터
몇 가지 데이터로 흥미로운 실험을했습니다. 귀하의 데이터에 액세스 할 수 없었기 때문에 다소 강력한 방식으로 데이터를 생성 하는 sklearn
's를 사용했습니다 .make_classification
스크립트를 몇 가지 변경했지만 변경 사항이 없습니다. gpu 대 cpu 예제에서 하이퍼 파라미터를 변경했습니다.이 작업을 100 회 실행하고 평균 결과를 얻었습니다. XGBoost
일부 분석 속도를 높이기 위해 GPU 대 CPU 기능을 사용한 적이 있었지만 훨씬 더 큰 데이터 세트를 작업 중이었습니다 .
이 데이터를 사용하기 위해 스크립트를 약간 편집 하고 런타임에 미치는 영향을 관찰하기 위해 데이터 세트 ( 및 매개 변수 를 통해)에서 samples
및 수를 변경하기 시작했습니다 . GPU가 고차원 데이터에 대한 학습 시간을 크게 개선하는 것처럼 보이지만 샘플 이 많은 대량 데이터 는 크게 개선되지 않습니다. 아래 내 스크립트를 참조하십시오.features
n_samples
n_features
import xgboost as xgb, numpy, time
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
xgb_gpu = []
xgbclassifier_gpu = []
xgb_cpu = []
xgbclassifier_cpu = []
n_samples = 75000
n_features = 500
for i in range(len(10)):
n_samples += 10000
n_features += 300
# Make my own data since I do not have the data from the SO question
X_train2, y_train = make_classification(n_samples=n_samples, n_features=n_features*0.9, n_informative=n_features*0.1,
n_redundant=100, flip_y=0.10, random_state=8)
# Keep script from OP intact
param = {'max_depth':5, 'objective':'binary:logistic', 'subsample':0.8,
'colsample_bytree':0.8, 'eta':0.5, 'min_child_weight':1,
'tree_method':'gpu_hist', 'gpu_id': 0
}
num_round = 100
dtrain = xgb.DMatrix(X_train2, y_train)
tic = time.time()
model = xgb.train(param, dtrain, num_round)
print('passed time with xgb (gpu): %.3fs'%(time.time()-tic))
xgb_gpu.append(time.time()-tic)
xgb_param = {'max_depth':5, 'objective':'binary:logistic', 'subsample':0.8,
'colsample_bytree':0.8, 'learning_rate':0.5, 'min_child_weight':1,
'tree_method':'gpu_hist', 'gpu_id':0}
model = xgb.XGBClassifier(**xgb_param)
tic = time.time()
model.fit(X_train2, y_train)
print('passed time with XGBClassifier (gpu): %.3fs'%(time.time()-tic))
xgbclassifier_gpu.append(time.time()-tic)
param = {'max_depth':5, 'objective':'binary:logistic', 'subsample':0.8,
'colsample_bytree':0.8, 'eta':0.5, 'min_child_weight':1,
'tree_method':'hist'}
num_round = 100
dtrain = xgb.DMatrix(X_train2, y_train)
tic = time.time()
model = xgb.train(param, dtrain, num_round)
print('passed time with xgb (cpu): %.3fs'%(time.time()-tic))
xgb_cpu.append(time.time()-tic)
xgb_param = {'max_depth':5, 'objective':'binary:logistic', 'subsample':0.8,
'colsample_bytree':0.8, 'learning_rate':0.5, 'min_child_weight':1,
'tree_method':'hist'}
model = xgb.XGBClassifier(**xgb_param)
tic = time.time()
model.fit(X_train2, y_train)
print('passed time with XGBClassifier (cpu): %.3fs'%(time.time()-tic))
xgbclassifier_cpu.append(time.time()-tic)
import pandas as pd
df = pd.DataFrame({'XGB GPU': xgb_gpu, 'XGBClassifier GPU': xgbclassifier_gpu, 'XGB CPU': xgb_cpu, 'XGBClassifier CPU': xgbclassifier_cpu})
#df.to_csv('both_results.csv')
동일한 데이터 세트에서 각각 (샘플, 기능)을 개별적으로 변경하여 함께 실행했습니다. 아래 결과를 참조하십시오.
| Interval | XGB GPU | XGBClassifier GPU | XGB CPU | XGBClassifier CPU | Metric |
|:--------:|:--------:|:-----------------:|:--------:|:-----------------:|:----------------:|
| 0 | 11.3801 | 12.00785 | 15.20124 | 15.48131 | Changed Features |
| 1 | 15.67674 | 16.85668 | 20.63819 | 22.12265 | Changed Features |
| 2 | 18.76029 | 20.39844 | 33.23108 | 32.29926 | Changed Features |
| 3 | 23.147 | 24.91953 | 47.65588 | 44.76052 | Changed Features |
| 4 | 27.42542 | 29.48186 | 50.76428 | 55.88155 | Changed Features |
| 5 | 30.78596 | 33.03594 | 71.4733 | 67.24275 | Changed Features |
| 6 | 35.03331 | 37.74951 | 77.68997 | 75.61216 | Changed Features |
| 7 | 39.13849 | 42.17049 | 82.95307 | 85.83364 | Changed Features |
| 8 | 42.55439 | 45.90751 | 92.33368 | 96.72809 | Changed Features |
| 9 | 46.89023 | 50.57919 | 105.8298 | 107.3893 | Changed Features |
| 0 | 7.013227 | 7.303488 | 6.998254 | 9.733574 | No Changes |
| 1 | 6.757523 | 7.302388 | 5.714839 | 6.805287 | No Changes |
| 2 | 6.753428 | 7.291906 | 5.899611 | 6.603533 | No Changes |
| 3 | 6.749848 | 7.293555 | 6.005773 | 6.486256 | No Changes |
| 4 | 6.755352 | 7.297607 | 5.982163 | 8.280619 | No Changes |
| 5 | 6.756498 | 7.335412 | 6.321188 | 7.900422 | No Changes |
| 6 | 6.792402 | 7.332112 | 6.17904 | 6.443676 | No Changes |
| 7 | 6.786584 | 7.311666 | 7.093638 | 7.811417 | No Changes |
| 8 | 6.7851 | 7.30604 | 5.574762 | 6.045969 | No Changes |
| 9 | 6.789152 | 7.309363 | 5.751018 | 6.213471 | No Changes |
| 0 | 7.696765 | 8.03615 | 6.175457 | 6.764809 | Changed Samples |
| 1 | 7.914885 | 8.646722 | 6.997217 | 7.598789 | Changed Samples |
| 2 | 8.489555 | 9.2526 | 6.899783 | 7.202334 | Changed Samples |
| 3 | 9.197605 | 10.02934 | 7.511708 | 7.724675 | Changed Samples |
| 4 | 9.73642 | 10.64056 | 7.918493 | 8.982463 | Changed Samples |
| 5 | 10.34522 | 11.31103 | 8.524865 | 9.403711 | Changed Samples |
| 6 | 10.94025 | 11.98357 | 8.697257 | 9.49277 | Changed Samples |
| 7 | 11.80717 | 12.93195 | 8.734307 | 10.79595 | Changed Samples |
| 8 | 12.18282 | 13.38646 | 9.175231 | 10.33532 | Changed Samples |
| 9 | 13.05499 | 14.33106 | 11.04398 | 10.50722 | Changed Samples |
| 0 | 12.43683 | 13.19787 | 12.80741 | 13.86206 | Changed Both |
| 1 | 18.59139 | 20.01569 | 25.61141 | 35.37391 | Changed Both |
| 2 | 24.37475 | 26.44214 | 40.86238 | 42.79259 | Changed Both |
| 3 | 31.96762 | 34.75215 | 68.869 | 59.97797 | Changed Both |
| 4 | 41.26578 | 44.70537 | 83.84672 | 94.62811 | Changed Both |
| 5 | 49.82583 | 54.06252 | 109.197 | 108.0314 | Changed Both |
| 6 | 59.36528 | 64.60577 | 131.1234 | 140.6352 | Changed Both |
| 7 | 71.44678 | 77.71752 | 156.1914 | 161.4897 | Changed Both |
| 8 | 81.79306 | 90.56132 | 196.0033 | 193.4111 | Changed Both |
| 9 | 94.71505 | 104.8044 | 215.0758 | 224.6175 | Changed Both |
변경 없음
선형 적으로 증가하는 기능 수
선형 증가 샘플
선형 적으로 증가하는 샘플 + 기능
더 많은 연구를 시작하면서 이것은 의미가 있습니다. GPU는 고차원 데이터로 잘 확장되는 것으로 알려져 있으며 데이터가 고차원 인 경우 학습 시간이 향상되는 것을 볼 수 있습니다 . 다음 예를 참조하십시오.
- https://projecteuclid.org/download/pdfview_1/euclid.ss/1294167962
- GPU 지원으로 고차원 데이터에서 더 빠른 Kmeans 클러스터링
- https://link.springer.com/article/10.1007/s11063-014-9383-4
데이터에 액세스하지 않고는 확실히 말할 수는 없지만 데이터가 지원할 때 GPU의 하드웨어 기능이 상당한 성능 향상을 가능하게하는 것처럼 보일 수 있으며 데이터의 크기와 모양을 고려할 때 그렇지 않을 수 있습니다. 있다.