tkm2261's blog

研究員(OR屋) → データ分析官 → MLエンジニア → ニート → 米国CS PhDが諸々書いてます

LightGBMをGPUで速度検証

LightGBMとは

Microsoftが公開しているGradient Boosting Decision Tree(GBDT)の実装です。

github.com

GBDTの実装で一番有名なのはxgboostですが、LightGBMは2016年末に登場してPython対応から一気に普及し始め、 最近のKaggleコンペではxgboostよりも、Winning Solutionで多く見る気がしています。

私もQuoraコンペではお世話になりました

https://www.slideshare.net/tkm2261/quora-76995457

ニートなので金がない

在職中は会社のマシンで回してたりしたので、気軽に32コアぐらい使ってましたが、

ニートで自費で借りると破産しかねないのでGPUで高速にならないかなーと思って検証しました。

環境構築

AWSのp2.xlargeでAnaconda3系使って検証しました。

基本はここに従います。

LightGBM/GPU-Tutorial.md at master · Microsoft/LightGBM · GitHub

マニュアルに書いてないですが

python setup.py install時にgpuオプションが必須です。

これでしばらく詰んだので皆様忘れずに。

github.com

# 諸々入れて
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拡張はマージされたばかりなので、速度向上が見込めるので将来有望です