1. Light GBM 簡介
在數(shù)據(jù)挖掘和傳統(tǒng)機(jī)器學(xué)習(xí)領(lǐng)域,提起大名鼎鼎的 XGBoost,相信很多人都聽說過,尤其是在 Kaggle 賽場上,XGBoost 更是風(fēng)光無限,不過今天的主角卻不是 XGBoost,而是 LightGBM (Light Gradient Boost Machine),這是由微軟開發(fā)并且開源的、一個類似于 XGBoost 的梯度提升框架。
在 Github上,LightGBM 是這樣自我介紹的,LightGBM 是一種快速、分布式、高性能梯度提升框架,該框架基于決策樹算法,可用于分類、回歸、排序等多種機(jī)器學(xué)習(xí)任務(wù)。詳細(xì)介紹可以前往 LightGBM 在 Github 的主頁,及官方主頁。
另外,LightGBM 的原理,及其與 XGBoost 的對比分析,可以前往:LightGBM大戰(zhàn)XGBoost,誰將奪得桂冠?
這幾天在使用 LightGBM 訓(xùn)練數(shù)據(jù),由于數(shù)據(jù)量太大,所耗時間比較長,就思考能不能使用GPU 進(jìn)行計(jì)算,并于今天上午成功完成了環(huán)境的搭建。這篇博客主要來源于官方手冊和 Stack Overflow 上相關(guān)問題的提問及回答,并結(jié)合自己在安裝的過程中所遇到的問題。我自己在搭建環(huán)境、搜索相關(guān)的教程的過程中,發(fā)現(xiàn) LightGBM 相關(guān)主題的文章比較張,尤其使用 GPU 進(jìn)行計(jì)算的就更少了,所以才總結(jié)出了這篇文章,與大家分享,期待我們一起學(xué)習(xí),一起進(jìn)步。好了,以下內(nèi)容言歸正傳。
2. LightGBM CPU 版本的安裝
LightGBM CPU 版本的安裝和 Python 其他 Package 的安裝一樣,基本有三種方法:
通過 pip 命令安裝,這是 Python 社區(qū)推薦的安裝方式,安裝命令:
pip install lightgbm通過 Anaconda 進(jìn)行安裝,安裝命令:
conda install lightgbm通過 Github 進(jìn)行安裝,在命令行中輸入
git clone ttps://github.com/Microsoft/LightGBM,等LightGBM包下載完成之后,通過命令行進(jìn)入到.\LightGBM\python-package文件夾,輸入python setup.py install,即可完成安裝。
以上三種安裝方式在使用上沒有差異,但是package管理和更新上有些不同。
pip 安裝是 Python官方社區(qū)的推薦方式。優(yōu)點(diǎn)是各個 package 會首先通過該方式更新,下載速度比較快,package的種類比較多,而且都是經(jīng)過社區(qū)審核的。缺點(diǎn)在于無法批量更新 package,需要手動進(jìn)行各個 package 的更新;無法對python的不同版本環(huán)境進(jìn)行管理,需要使用 virtualenv 等工具進(jìn)行管理。
Anaconda是使用 Python 進(jìn)行科學(xué)計(jì)算方面最常用的管理工具,集成的 conda 不但可以管理各個 package,并解決其依賴關(guān)系,還能管理不同 Python 版本的各自環(huán)境,此外,Anaconda 不僅僅是Python的包管理工具,還可以對 Julia 等其他語言的包和環(huán)境進(jìn)行統(tǒng)一管理。此外,可以使用 “
conda update --all” 命令批量升級 package。缺點(diǎn)是:package 下載速度比較慢,這一點(diǎn)可以通過下載國內(nèi)的鏡像文件進(jìn)行彌補(bǔ),此外就是部分 pip 可以安裝的 package 無法通過 conda 安裝,比如 conda 版本的 XGBoost 只提供了 Linux 和 Mac OS 版本,沒有 Win 版本。以上兩種方式都是使用已經(jīng)編譯好的二進(jìn)制文件進(jìn)行安裝,而 github 的安裝則是使用源代碼進(jìn)行安裝。待會安裝 GPU 版本時,就需要對源代碼進(jìn)行重新編譯和構(gòu)建 (compile and build),采用的就是這種安裝方式。
3. LightGBM GPU 版本的安裝
安裝 GPU 版本的主要思路就是從 Github 上下載源代碼,然后對其進(jìn)行重新編譯 (re-compile),對編譯好的文件,使用 CMake 對其進(jìn)行構(gòu)造 (Build),最后使用 python setup.py install --gpu 命令進(jìn)行安裝。在win平臺,對其源代碼進(jìn)行編譯構(gòu)造,主要有兩種方式:一種是使用 CMake 和 VS Build Tools (或者 Visual Studio),另一種是使用 CMake 和 MinGW。
3.1 使用 Visual Studio 進(jìn)行編譯和構(gòu)建
Win平臺的 Python 是用 Visual Studio 進(jìn)行構(gòu)造和編譯,所以如果使用 Visual Studio 對 LightGBM 進(jìn)行編譯和構(gòu)造的話,可以省去很多麻煩;相反,如果使用
MinGW 對其進(jìn)行編譯和構(gòu)造,則可能會遇到很多意想不到的麻煩,因此推薦使用 VS Build Tools (或者 Visual Studio) 對其進(jìn)行構(gòu)造和編譯。
具體步驟為:
1). 下載并安裝 Git for Win。
詳細(xì)步驟可以參考這篇文章 Git安裝教程(Windows安裝超詳細(xì)教程)
2). 下載并安裝 CMake。
這個安裝過程比較簡單,不過有兩點(diǎn)需要注意。

根據(jù)系統(tǒng)是32位還是64位下載相應(yīng)的“.msi”文件

勾選中間那一項(xiàng),對所有用戶都添加到系統(tǒng) path 路徑中, 其他方面就一路 next 就可以了。這是啟動之后的界面:

3). 下載并安裝 VS Build Tools。
VS Build Tools 現(xiàn)在集成在 Visual Studio 之中,沒有提供單獨(dú)下載。Visual Studio 作為商業(yè)軟,自然是收費(fèi)的,但是微軟提供了一個 Visual Studio Community 版本,可以免費(fèi)使用,最新版為 Visual Studio Community 2017。
點(diǎn)擊下載的 ".exe", 會出現(xiàn)一個安裝選擇面板,你可以勾選希望安裝的功能,如果只是用于這次的編譯和構(gòu)造,只需要按下圖進(jìn)行勾選即可,然后安裝即可。

4). 下載安裝相應(yīng)的OpenCL
OpenCL 可以簡單地理解為顯卡的驅(qū)動,所以Intel、Nvidia和AMD需要安裝不同的OpenCL。
- 英特爾集成顯卡 Intel SDK for OpenCL
- AMD APP SDK
- Nvidia CUDA Toolkit
5). 下載安裝 Boost Binaries
選擇和 visual studio 版本對應(yīng)的版本:
Visual Studio 2015:msvc-14.0-64.exe
Visual Studio 2017:msvc-14.1-64.exe
安裝完成之后,會在C盤根目錄下,出現(xiàn) "C:\local\" 這個文件夾,把 "C:\local\boost_1_69_0\"和"C:\local\boost_1_69_0\lib64-msvc-14.1"添加到系統(tǒng)環(huán)境變量 (Note: 根據(jù)安裝的Boost Binaries 版本不同,路徑名稱會有稍微不同)
6). 編譯并構(gòu)造源文件
- 在命令行中,輸入:
Set BOOST_ROOT=C:/local/boost_1_69_0/
Set BOOST_LIBRARYDIR=C:/local/boost_1_64_0/lib64-msvc-14.2
git clone --recursive https://github.com/Microsoft/LightGBM
- 等 LightGBM的源文件下載完成之后,打開剛才安裝的 CMake GUI

最上面的Brower Source 選擇下載的 LightGBM 文件的路徑,然后在其中新建 Build 文件夾,Brower Build 選擇新建的 Build 文件夾,并且勾選 "USE_GPU" 和 "USE_OPENMP"
- Warning:如果你的電腦同時裝有多個顯卡(包括集成顯卡),建議進(jìn)行以下設(shè)置,如果只有一個顯卡,可以跳過該步驟。
點(diǎn)擊 "Add Entry", 并進(jìn)行以下設(shè)置

根據(jù)剛才安裝的 Visual Studio版本進(jìn)行選擇

點(diǎn)擊,左下角的 "Config",會出現(xiàn)

記得勾選 "USE_GPU" 和 "USE_OPENMP",再點(diǎn)擊左下角的 "Config",沒有再出現(xiàn)紅顏色之后,點(diǎn)擊旁邊的 "Genarate"。
之后,使用命令行進(jìn)入 ".\LightGBM\build", 然后在命令行輸入:
cmake --build . --target ALL_BUILD --config Release
這時候,你會發(fā)現(xiàn),LightGBM 文件夾里多了一個Release 文件夾。
然后通過命令行進(jìn)入 ".\LightGBM\python-package\",并輸入:
python setup.py install --gpu
到這里就完成了使用Visual Studio 對 LightGBM 源代碼進(jìn)行重新編譯、構(gòu)造和安裝。
3.2 使用 MinGW 進(jìn)行編譯和構(gòu)造
Win 平臺的 Python 是用 Visual Studio 進(jìn)行構(gòu)造和編譯,如果使用 VS Build Tools 對LightGBM 進(jìn)行構(gòu)造和編譯的話,可以省去很多麻煩;相反,如果使用 MinGW 對其進(jìn)行編譯和構(gòu)造,則可能會遇到很多意想不到的麻煩。但是 Stack Overflow 上有人反映說,用 MinGW 編譯會比用 VS Studio 更快,并且編譯出的文件,安裝之后, CPU,GPU 和內(nèi)存的利用會稍微好一些。
具體步驟和使用 VS 編譯差不多:
1)下載并安裝 MinGW
如果你的系統(tǒng)是32位的,建議下載安裝MinGW
如果你的系統(tǒng)是64位的,建議下載安裝MinGW-w64

最好按著這個配置安裝。

安裝路徑使用默認(rèn)的,安裝成功之后,把 "C:\Program Files\mingw-w64\mingw64\bin"(你的路徑可能不太一樣)添加到系統(tǒng)環(huán)境變量中。
為了測試安裝是否成功,可以在命令行中輸入:"gcc -v",如果安裝成功,會出現(xiàn)類似下圖的情況

2)下載并安裝 Git for Win。
詳細(xì)步驟可以參考這篇 Git安裝教程(Windows安裝超詳細(xì)教程)
3)下載并安裝 CMake。
這個安裝過程比較簡單,不過有兩點(diǎn)需要注意。

根據(jù)系統(tǒng)是32位還是64位下載相應(yīng)的“.msi”文件

勾選中間那一項(xiàng),對所有用戶都添加到系統(tǒng) path 路徑中. 其他方面就一路 next 就可以了。這是啟動之后的界面:

4)下載安裝相應(yīng)的OpenCL
OpenCL 可以簡單地理解為顯卡的驅(qū)動,所以Intel、Nvidia和AMD需要安裝不同的OpenCL。
- 英特爾集成顯卡 Intel SDK for OpenCL
- AMD APP SDK
- Nvidia CUDA Toolkit
5)下載安裝 Boost Binaries
安裝完成之后,會在C盤根目錄下,出現(xiàn) "C:\local" 這個文件夾,把 "C:\local\boost_1_69_0\"和"C:\local\boost_1_69_0\lib64-msvc-14.2"添加到系統(tǒng)環(huán)境變量中。(Note: 根據(jù)安裝的Boost Binaries 版本不同,路徑名稱會有稍微不同)
在命令行輸入:
cd C:\local\boost_1_64_0\tools\build
bootstrap.bat gcc
b2 install --prefix="C:\local\boost-build" toolset=gcc cd C:\boost\boost_1_64_0
為了構(gòu)造 Boost 庫,如果你的電腦是單核的,你可以在命令行輸入:
b2 install --build_dir="C:\boost\boost-build" --prefix="C:\boost\boost-build" toolset=gcc --with=filesystem,system threading=multi --layout=system release
如果你的電腦是單核的,你可以在命令行輸入:
b2 install --build_dir="C:\boost\boost-build" --prefix="C:\boost\boost-build" toolset=gcc --with=filesystem,system threading=multi --layout=system release -j 2
在編譯結(jié)束之后,你可以看到類似的情況:

Note:如果出現(xiàn)了問題,你可以嘗試從頭再試一次。
6)構(gòu)造并編譯源文件
在命令行中,輸入:
Set BOOST_ROOT=C:/local/boost_1_69_0/
Set BOOST_LIBRARYDIR=C:/local/boost_1_64_0/lib64-msvc-14.2
git clone --recursive https://github.com/Microsoft/LightGBM
等 LightGBM 的源文件下載完成之后,打開剛才安裝的 CMake GUI

最上面的Brower Source 選擇你下載的LightGBM文件的路徑,然后在其中新建Build文件夾,Brower Build選擇新建的Build文件夾,并且勾選"USE_GPU" 和 "USE_OPENMP"
Warning:如果你的電腦同時裝有多個顯卡(包括集成顯卡),建議進(jìn)行以下設(shè)置,如果只有一個顯卡,可以跳過該步驟。
點(diǎn)擊 "Add Entry", 并進(jìn)行以下設(shè)置

根據(jù)剛才安裝的 MinGW

點(diǎn)擊,左下角的 "Config",可能會出現(xiàn)

記得勾選"USE_GPU" 和 "USE_OPENMP",再點(diǎn)擊左下角的 "Config",沒有再出現(xiàn)紅顏色之后,點(diǎn)擊旁邊的 "Genarate"。
之后,使用命令行進(jìn)入 ".\LightGBM\build", 然后再命令行輸入:
cmake --build . --target ALL_BUILD --config Release
這時候,你會發(fā)現(xiàn),LightGBM 文件夾里多了一個Release 文件夾。
然后通過命令行進(jìn)入 ".\LightGBM\python-package\",并輸入:
python setup.py install --gpu
到這里就完成了使用 MinGW-64 對 LightGBM 源代碼進(jìn)行重新編譯、構(gòu)造和安裝。
4. 參數(shù)設(shè)置
通過上面的步驟,我們已經(jīng)完成了 LightGBM GPU 版本的安裝,接下來我們就要測試一下,安裝是否成功了。
使用 GPU 進(jìn)行計(jì)算的代碼基本和使用 CPU 進(jìn)行計(jì)算一樣,只不過需要設(shè)置一個參數(shù) device='gpu', 如果你的電腦只有一個 GPU,這樣設(shè)置就可以了。但是如果你的電腦有多個 GPU,就需要多設(shè)置一些參數(shù)。
gpu_platform_id:表示要使用的GPU平臺,比如 Intel,Nvidia,AMD
gpu_device_id:表示在這個平臺下,要使用哪個GPU
比如我的筆記本有 Intel 的集成顯卡和 Nvidia 的獨(dú)立顯卡,如果設(shè)置為;
device = 'gpu' 表示使用默認(rèn)顯卡,一般為集成顯卡
device='gpu', gpu_platform_id=1, gpu_device_id=0:表示使用第二個GPU平臺(我的是Nvidia),第一個顯卡,因?yàn)槲业墓P記本上Nvidia的顯卡只有一個。
你可以在任意一段使用 LightGBM 的代碼中,添加以上一個或者三個參數(shù),如果能順利運(yùn)行,就證明安裝成功了。如果失敗,可以根據(jù)提示,到 CSDN 論壇 或者 Stack Overflow 上搜索相關(guān)問題。
微軟這樣的設(shè)定可能會讓很多人覺得很腦殘,確實(shí)有那么一點(diǎn),那么其他可以使用 GPU 進(jìn)行計(jì)算的框架是如何處理的呢?
安裝 XGBoost GPU 版本之后,可以通過設(shè)置參數(shù) "tree_method" 選擇使用 CPU 或 GPU及哪種算法,它的可選參數(shù)有 "hist", "exact" (表示使用 CPU), "gpu_hist", "gpu_exact" (表示使用 GPU)。此外還可以通過設(shè)置參數(shù) ”n_gpus=1"(表示使用一個 GPU, "n_gpus= -1" (表示使用所有的 GPU). Google 的深度學(xué)習(xí)框架 TensorFlow 也有 CPU 和 GPU 兩個版本, 在只安裝 CPU 版本的時候, 電腦只能使用 CPU 進(jìn)行計(jì)算, 但是 如果同時安裝了 CPU 和 GPU 兩個版本時, TensorFlow 會首先檢測 GPU 是否可用, 如果可用, 就默認(rèn)使用 GPU 進(jìn)行加速計(jì)算, 否則還是使用 CPU.
相比于 XGBoost 和 TensorFlow, LightGBM 調(diào)用 GPU 的方式確實(shí)不怎樣方便, 但是 XGBoost 和 TensorFlow 只能使用 Nvidia 的獨(dú)顯進(jìn)行加速計(jì)算, 而 LightGBM 卻可以使用 Intel, Nvidia 和 AMD 三個平臺的顯卡進(jìn)行加速計(jì)算, 這對于只有 Intel 集顯的電腦是非常友好的.
結(jié)合這幾個計(jì)算框架在調(diào)用 GPU 時各自的優(yōu)缺點(diǎn), 建議 LightGBM 使用Tensor Flow 那樣的調(diào)用方式, 在 GPU 可用的情況下, 默認(rèn)使用 GPU, 同時具有集顯和獨(dú)顯的時候, 優(yōu)先調(diào)用獨(dú)顯. 這樣更能發(fā)揮出 GPU 比較強(qiáng)悍的計(jì)算并行計(jì)算能力, 也能符合用戶的使用習(xí)慣.
5. 性能提升
安裝 GPU 版本是為了提高計(jì)算速度,那么使用 GPU 相對與使用 CPU,速度到底提到了多少呢?接下來,我們會用一段程序進(jìn)行試驗(yàn)。
import lightgbm as lgb
import xgboost as xgb
import time
dtrain = lgb.Dataset('higgs.csv')
params = {'max_bin': 63,
'num_leaves': 255,
'learning_rate': 0.1,
'tree_learner': 'serial',
'task': 'train',
'is_training_metric': 'false',
'min_data_in_leaf': 1,
'min_sum_hessian_in_leaf': 100,
'ndcg_eval_at': [1, 3, 5, 10],
'sparse_threshold': 1.0,
'device': 'cpu'
}
print("*****************************")
t0 = time.time()
gbm = lgb.train(params, train_set=dtrain, num_boost_round=10,
valid_sets=None, valid_names=None,
fobj=None, feval=None, init_model=None,
feature_name='auto', categorical_feature='auto',
early_stopping_rounds=None, evals_result=None,
verbose_eval=True,
keep_training_booster=False, callbacks=None)
t1 = time.time()
print('cpu version elapse time: {}'.format(t1-t0))
time.sleep(20)
print("*****************************")
params = {'max_bin': 63,
'num_leaves': 255,
'learning_rate': 0.1,
'tree_learner': 'serial',
'task': 'train',
'is_training_metric': 'false',
'min_data_in_leaf': 1,
'min_sum_hessian_in_leaf': 100,
'ndcg_eval_at': [1, 3, 5, 10],
'sparse_threshold': 1.0,
'device': 'gpu',
'gpu_platform_id': 1,
'gpu_device_id': 0
}
t0 = time.time()
gbm = lgb.train(params, train_set=dtrain, num_boost_round=10,
valid_sets=None, valid_names=None,
fobj=None, feval=None, init_model=None,
feature_name='auto', categorical_feature='auto',
early_stopping_rounds=None, evals_result=None,
verbose_eval=True,
keep_training_booster=False, callbacks=None)
t1 = time.time()
print('gpu version elapse time: {}'.format(t1-t0))
time.sleep(20)
print("*****************************")
params = {'max_bin': 63,
'num_leaves': 255,
'learning_rate': 0.1,
'tree_learner': 'serial',
'task': 'train',
'is_training_metric': 'false',
'min_data_in_leaf': 1,
'min_sum_hessian_in_leaf': 100,
'ndcg_eval_at': [1, 3, 5, 10],
'sparse_threshold': 1.0,
'device': 'gpu'
}
t0 = time.time()
gbm = lgb.train(params, train_set=dtrain, num_boost_round=10,
valid_sets=None, valid_names=None,
fobj=None, feval=None, init_model=None,
feature_name='auto', categorical_feature='auto',
early_stopping_rounds=None, evals_result=None,
verbose_eval=True,
keep_training_booster=False, callbacks=None)
t1 = time.time()
print('gpu version elapse time: {}'.format(t1-t0))
使用的數(shù)據(jù)集是微軟官方對比 LightGBM 和 XGBoost 性能時,所使用的數(shù)據(jù)集。

筆記本的配置是:
CPU:Intel Core i7-8550U
GPU:Intel UHD Graphics 620, NVIDIA GeForce?MX150
這是在我的筆記本上的運(yùn)行的結(jié)果,從計(jì)算時間上來看,使用 GPU 計(jì)算對速度提升還是挺大的。不過出乎我的意料的是,Intel 的集顯和 Nvidia 的獨(dú)顯所用時間差不多,可能是我的獨(dú)顯太垃圾了吧。
我本人是用 VS 編譯的,所以 MinGW 部分寫的有些省略,請大家見諒。
PS:這是我第一次寫博客,文章中肯定有很多錯誤的地方,請大家多多包涵,也歡迎大家指出。