LightGBMをGPUで速度検証
LightGBMとは
Microsoftが公開しているGradient Boosting Decision Tree(GBDT)の実装です。
GBDTの実装で一番有名なのはxgboostですが、LightGBMは2016年末に登場してPython対応から一気に普及し始め、 最近のKaggleコンペではxgboostよりも、Winning Solutionで多く見る気がしています。
私もQuoraコンペではお世話になりました
ニートなので金がない
在職中は会社のマシンで回してたりしたので、気軽に32コアぐらい使ってましたが、
ニートで自費で借りると破産しかねないのでGPUで高速にならないかなーと思って検証しました。
環境構築
AWSのp2.xlargeでAnaconda3系使って検証しました。
基本はここに従います。
LightGBM/GPU-Tutorial.md at master · Microsoft/LightGBM · GitHub
マニュアルに書いてないですが
python setup.py install時に–gpuオプションが必須です。
これでしばらく詰んだので皆様忘れずに。
# 諸々入れて sudo apt-get update sudo apt-get install --no-install-recommends nvidia-375 sudo apt-get install --no-install-recommends nvidia-opencl-icd-375 nvidia-opencl-dev opencl-headers # 再起動して sudo init 6 # また諸々いれて sudo apt-get install --no-install-recommends git cmake build-essential libboost-dev libboost-system-dev libboost-filesystem-dev # 本体を入れる git clone --recursive https://github.com/Microsoft/LightGBM cd LightGBM mkdir build ; cd build cmake -DUSE_GPU=1 .. make -j$(nproc) cd .. cd python-package/ python setup.py install --gpu # ここのオプション忘れずに!
成功すると、起動時にこんなログが流れます
[LightGBM] [Info] This is the GPU trainer!! [LightGBM] [Info] Total Bins 50745 [LightGBM] [Info] Number of data: 6767336, number of used features: 283 [LightGBM] [Info] Using requested OpenCL platform 0 device 0 [LightGBM] [Info] Using GPU Device: Tesla K80, Vendor: NVIDIA Corporation [LightGBM] [Info] Compiling OpenCL Kernel with 256 bins... [LightGBM] [Info] GPU programs have been built [LightGBM] [Info] Size of histogram bin entry: 12 [LightGBM] [Info] 248 dense feature groups (1600.55 MB) transfered to GPU in 1.454054 secs. 16 sparse feature groups.
速度検証
同一タスクをCPUと検証
ここを見る限り2~3倍高速化する模様
LightGBM/GPU-Performance.md at master · Microsoft/LightGBM · GitHub
問題サイズ
項目 | 値 |
---|---|
データサイズ | 行数: 8,474,661, 列数: 269 |
パラメータ | {‘max_depth’: 5, ‘learning_rate’: 0.01, ‘min_data_in_leaf’: 10, ‘feature_fraction’: 0.7, ‘metric’: ‘binary_logloss’, ‘bagging_fraction’: 0.9, ‘lambda_l1’: 1, ‘max_bin’: 500, ‘min_split_gain’: 0, ‘device’: ‘gpu’, ‘gpu_platform_id’: 0, ‘gpu_device_id’: 0} |
100ラウンド固定の場合
環境 | 時間 | logloss |
---|---|---|
p2.xlarge (GPU K80) | 3m41s | 0.256575 |
p2.xlarge (4 CPU) | 7m29s | 0.256574 |
c4.4xlarge (16 CPU) | 1m58s | 0.256574 |
4CPUには大体2倍ぐらいの高速化。16 CPUよりは倍ぐらい遅い
max_bins=63に変更した場合
max_binsが小さいとき(推奨63)により速いと書いてるので検証
環境 | 時間 | logloss |
---|---|---|
p2.xlarge (GPU) | 3m28s | 0.256575 |
p2.xlarge (4 CPU) | 6m27s | 0.256574 |
今回のデータだと、binサイズを上げてもあんまり関係ないみたいです。
early stoppingの場合
early_stopping_rounds=30にして80%で学習、20%で精度検証
環境 | 時間 | logloss | Best Round数 |
---|---|---|---|
p2.xlarge (GPU K80) | 11m27s | 0.243065 | 808 |
p2.xlarge (4 CPU) | 26m53s | 0.243078 | 750 |
c4.4xlarge (16 CPU) | 8m16s | 0.243078 | 750 |
100ラウンドの時と異なり、c4.4xlargeとくらべてRound数考慮するとほぼ同程度の速度が出ています。
GPUなので最初のオーバーヘッドがあると思われます。
10,000ラウンドぐらいの結果が気になりますが、気が向いたらアップデートします。
結論
GPU(K80)だとc4.4xlarge(16 CPU)程度の性能が出ることがわかりました。
スポットインスタンス価格だとp2.xlargeもc4.4xlargeも$0.2ぐらいで変わりませんが、
家にGTX 1080とかある人は、CPUに投資するよりDNNとかも出来るGPUに資金を集中出来て良さそうです。
さらにGPU拡張はマージされたばかりなので、速度向上が見込めるので将来有望です