Win10 平台下, LightGBM GPU 版本的安装

1. Light GBM 简介

在数据挖掘和传统机器学习领域,提起大名鼎鼎的 XGBoost,相信很多人都听说过,尤其是在 Kaggle 赛场上,XGBoost 更是风光无限,不过今天的主角却不是 XGBoost,而是 LightGBM (Light Gradient Boost Machine),这是由微软开发并且开源的、一个类似于 XGBoost 的梯度提升框架。

在 Github上,LightGBM 是这样自我介绍的,LightGBM 是一种快速、分布式、高性能梯度提升框架,该框架基于决策树算法,可用于分类、回归、排序等多种机器学习任务。详细介绍可以前往 LightGBM 在 Github 的主页,及官方主页

另外,LightGBM 的原理,及其与 XGBoost 的对比分析,可以前往:LightGBM大战XGBoost,谁将夺得桂冠?

这几天在使用 LightGBM 训练数据,由于数据量太大,所耗时间比较长,就思考能不能使用GPU 进行计算,并于今天上午成功完成了环境的搭建。这篇博客主要来源于官方手册和 Stack Overflow 上相关问题的提问及回答,并结合自己在安装的过程中所遇到的问题。我自己在搭建环境、搜索相关的教程的过程中,发现 LightGBM 相关主题的文章比较张,尤其使用 GPU 进行计算的就更少了,所以才总结出了这篇文章,与大家分享,期待我们一起学习,一起进步。好了,以下内容言归正传。


2. LightGBM CPU 版本的安装

LightGBM CPU 版本的安装和 Python 其他 Package 的安装一样,基本有三种方法:

  1. 通过 pip 命令安装,这是 Python 社区推荐的安装方式,安装命令:pip install lightgbm

  2. 通过 Anaconda 进行安装,安装命令:conda install lightgbm

  3. 通过 Github 进行安装,在命令行中输入 git clone ttps://github.com/Microsoft/LightGBM,等LightGBM包下载完成之后,通过命令行进入到 .\LightGBM\python-package 文件夹,输入 python setup.py install ,即可完成安装。

以上三种安装方式在使用上没有差异,但是package管理和更新上有些不同。

  • pip 安装是 Python官方社区的推荐方式。优点是各个 package 会首先通过该方式更新,下载速度比较快,package的种类比较多,而且都是经过社区审核的。缺点在于无法批量更新 package,需要手动进行各个 package 的更新;无法对python的不同版本环境进行管理,需要使用 virtualenv 等工具进行管理。

  • Anaconda是使用 Python 进行科学计算方面最常用的管理工具,集成的 conda 不但可以管理各个 package,并解决其依赖关系,还能管理不同 Python 版本的各自环境,此外,Anaconda 不仅仅是Python的包管理工具,还可以对 Julia 等其他语言的包和环境进行统一管理。此外,可以使用 “conda update --all” 命令批量升级 package。缺点是:package 下载速度比较慢,这一点可以通过下载国内的镜像文件进行弥补,此外就是部分 pip 可以安装的 package 无法通过 conda 安装,比如 conda 版本的 XGBoost 只提供了 Linux 和 Mac OS 版本,没有 Win 版本。

  • 以上两种方式都是使用已经编译好的二进制文件进行安装,而 github 的安装则是使用源代码进行安装。待会安装 GPU 版本时,就需要对源代码进行重新编译和构建 (compile and build),采用的就是这种安装方式。


3. LightGBM GPU 版本的安装

安装 GPU 版本的主要思路就是从 Github 上下载源代码,然后对其进行重新编译 (re-compile),对编译好的文件,使用 CMake 对其进行构造 (Build),最后使用 python setup.py install --gpu 命令进行安装。在win平台,对其源代码进行编译构造,主要有两种方式:一种是使用 CMake 和 VS Build Tools (或者 Visual Studio),另一种是使用 CMake 和 MinGW。

3.1 使用 Visual Studio 进行编译和构建

Win平台的 Python 是用 Visual Studio 进行构造和编译,所以如果使用 Visual Studio 对 LightGBM 进行编译和构造的话,可以省去很多麻烦;相反,如果使用
MinGW 对其进行编译和构造,则可能会遇到很多意想不到的麻烦,因此推荐使用 VS Build Tools (或者 Visual Studio) 对其进行构造和编译。

具体步骤为:

1). 下载并安装 Git for Win

详细步骤可以参考这篇文章 Git安装教程(Windows安装超详细教程)

2). 下载并安装 CMake

这个安装过程比较简单,不过有两点需要注意。

根据系统是32位还是64位下载相应的“.msi”文件

image

勾选中间那一项,对所有用户都添加到系统 path 路径中, 其他方面就一路 next 就可以了。这是启动之后的界面:

3). 下载并安装 VS Build Tools。

VS Build Tools 现在集成在 Visual Studio 之中,没有提供单独下载。Visual Studio 作为商业软,自然是收费的,但是微软提供了一个 Visual Studio Community 版本,可以免费使用,最新版为 Visual Studio Community 2017

点击下载的 ".exe", 会出现一个安装选择面板,你可以勾选希望安装的功能,如果只是用于这次的编译和构造,只需要按下图进行勾选即可,然后安装即可。

4). 下载安装相应的OpenCL

OpenCL 可以简单地理解为显卡的驱动,所以Intel、Nvidia和AMD需要安装不同的OpenCL。

5). 下载安装 Boost Binaries

选择和 visual studio 版本对应的版本:

Visual Studio 2015:msvc-14.0-64.exe
Visual Studio 2017:msvc-14.1-64.exe

安装完成之后,会在C盘根目录下,出现 "C:\local\" 这个文件夹,把 "C:\local\boost_1_69_0\"和"C:\local\boost_1_69_0\lib64-msvc-14.1"添加到系统环境变量 (Note: 根据安装的Boost Binaries 版本不同,路径名称会有稍微不同)

6). 编译并构造源文件

  1. 在命令行中,输入:
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
  1. 等 LightGBM的源文件下载完成之后,打开刚才安装的 CMake GUI

最上面的Brower Source 选择下载的 LightGBM 文件的路径,然后在其中新建 Build 文件夹,Brower Build 选择新建的 Build 文件夹,并且勾选 "USE_GPU" 和 "USE_OPENMP"

  1. Warning:如果你的电脑同时装有多个显卡(包括集成显卡),建议进行以下设置,如果只有一个显卡,可以跳过该步骤。

点击 "Add Entry", 并进行以下设置

根据刚才安装的 Visual Studio版本进行选择

点击,左下角的 "Config",会出现

记得勾选 "USE_GPU" 和 "USE_OPENMP",再点击左下角的 "Config",没有再出现红颜色之后,点击旁边的 "Genarate"。

之后,使用命令行进入 ".\LightGBM\build", 然后在命令行输入:

cmake --build . --target ALL_BUILD --config Release

这时候,你会发现,LightGBM 文件夹里多了一个Release 文件夹。

然后通过命令行进入 ".\LightGBM\python-package\",并输入:

python setup.py install --gpu

到这里就完成了使用Visual Studio 对 LightGBM 源代码进行重新编译、构造和安装。

3.2 使用 MinGW 进行编译和构造

Win 平台的 Python 是用 Visual Studio 进行构造和编译,如果使用 VS Build Tools 对LightGBM 进行构造和编译的话,可以省去很多麻烦;相反,如果使用 MinGW 对其进行编译和构造,则可能会遇到很多意想不到的麻烦。但是 Stack Overflow 上有人反映说,用 MinGW 编译会比用 VS Studio 更快,并且编译出的文件,安装之后, CPU,GPU 和内存的利用会稍微好一些。

具体步骤和使用 VS 编译差不多:

1)下载并安装 MinGW

如果你的系统是32位的,建议下载安装MinGW
如果你的系统是64位的,建议下载安装MinGW-w64

最好按着这个配置安装。

安装路径使用默认的,安装成功之后,把 "C:\Program Files\mingw-w64\mingw64\bin"(你的路径可能不太一样)添加到系统环境变量中。

为了测试安装是否成功,可以在命令行中输入:"gcc -v",如果安装成功,会出现类似下图的情况

2)下载并安装 Git for Win

详细步骤可以参考这篇 Git安装教程(Windows安装超详细教程)

3)下载并安装 CMake

这个安装过程比较简单,不过有两点需要注意。

根据系统是32位还是64位下载相应的“.msi”文件

勾选中间那一项,对所有用户都添加到系统 path 路径中. 其他方面就一路 next 就可以了。这是启动之后的界面:

4)下载安装相应的OpenCL

OpenCL 可以简单地理解为显卡的驱动,所以Intel、Nvidia和AMD需要安装不同的OpenCL。

5)下载安装 Boost Binaries

安装完成之后,会在C盘根目录下,出现 "C:\local" 这个文件夹,把 "C:\local\boost_1_69_0\"和"C:\local\boost_1_69_0\lib64-msvc-14.2"添加到系统环境变量中。(Note: 根据安装的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

为了构造 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

在编译结束之后,你可以看到类似的情况:

Note:如果出现了问题,你可以尝试从头再试一次。

6)构造并编译源文件

在命令行中,输入:

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:如果你的电脑同时装有多个显卡(包括集成显卡),建议进行以下设置,如果只有一个显卡,可以跳过该步骤。

点击 "Add Entry", 并进行以下设置

根据刚才安装的 MinGW

点击,左下角的 "Config",可能会出现

记得勾选"USE_GPU" 和 "USE_OPENMP",再点击左下角的 "Config",没有再出现红颜色之后,点击旁边的 "Genarate"。

之后,使用命令行进入 ".\LightGBM\build", 然后再命令行输入:

cmake --build . --target ALL_BUILD --config Release

这时候,你会发现,LightGBM 文件夹里多了一个Release 文件夹。
然后通过命令行进入 ".\LightGBM\python-package\",并输入:

python setup.py install --gpu

到这里就完成了使用 MinGW-64 对 LightGBM 源代码进行重新编译、构造和安装。


4. 参数设置

通过上面的步骤,我们已经完成了 LightGBM GPU 版本的安装,接下来我们就要测试一下,安装是否成功了。

使用 GPU 进行计算的代码基本和使用 CPU 进行计算一样,只不过需要设置一个参数 device='gpu', 如果你的电脑只有一个 GPU,这样设置就可以了。但是如果你的电脑有多个 GPU,就需要多设置一些参数。

gpu_platform_id:表示要使用的GPU平台,比如 Intel,Nvidia,AMD
gpu_device_id:表示在这个平台下,要使用哪个GPU

比如我的笔记本有 Intel 的集成显卡和 Nvidia 的独立显卡,如果设置为;

device = 'gpu' 表示使用默认显卡,一般为集成显卡
device='gpu', gpu_platform_id=1, gpu_device_id=0:表示使用第二个GPU平台(我的是Nvidia),第一个显卡,因为我的笔记本上Nvidia的显卡只有一个。

你可以在任意一段使用 LightGBM 的代码中,添加以上一个或者三个参数,如果能顺利运行,就证明安装成功了。如果失败,可以根据提示,到 CSDN 论坛 或者 Stack Overflow 上搜索相关问题。

微软这样的设定可能会让很多人觉得很脑残,确实有那么一点,那么其他可以使用 GPU 进行计算的框架是如何处理的呢?

安装 XGBoost GPU 版本之后,可以通过设置参数 "tree_method" 选择使用 CPU 或 GPU及哪种算法,它的可选参数有 "hist", "exact" (表示使用 CPU), "gpu_hist", "gpu_exact" (表示使用 GPU)。此外还可以通过设置参数 ”n_gpus=1"(表示使用一个 GPU, "n_gpus= -1" (表示使用所有的 GPU). Google 的深度学习框架 TensorFlow 也有 CPU 和 GPU 两个版本, 在只安装 CPU 版本的时候, 电脑只能使用 CPU 进行计算, 但是 如果同时安装了 CPU 和 GPU 两个版本时, TensorFlow 会首先检测 GPU 是否可用, 如果可用, 就默认使用 GPU 进行加速计算, 否则还是使用 CPU.

相比于 XGBoost 和 TensorFlow, LightGBM 调用 GPU 的方式确实不怎样方便, 但是 XGBoost 和 TensorFlow 只能使用 Nvidia 的独显进行加速计算, 而 LightGBM 却可以使用 Intel, Nvidia 和 AMD 三个平台的显卡进行加速计算, 这对于只有 Intel 集显的电脑是非常友好的.

结合这几个计算框架在调用 GPU 时各自的优缺点, 建议 LightGBM 使用Tensor Flow 那样的调用方式, 在 GPU 可用的情况下, 默认使用 GPU, 同时具有集显和独显的时候, 优先调用独显. 这样更能发挥出 GPU 比较强悍的计算并行计算能力, 也能符合用户的使用习惯.


5. 性能提升

安装 GPU 版本是为了提高计算速度,那么使用 GPU 相对与使用 CPU,速度到底提到了多少呢?接下来,我们会用一段程序进行试验。

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))

使用的数据集是微软官方对比 LightGBM 和 XGBoost 性能时,所使用的数据集。

笔记本的配置是:
CPU:Intel Core i7-8550U
GPU:Intel UHD Graphics 620, NVIDIA GeForce®MX150

这是在我的笔记本上的运行的结果,从计算时间上来看,使用 GPU 计算对速度提升还是挺大的。不过出乎我的意料的是,Intel 的集显和 Nvidia 的独显所用时间差不多,可能是我的独显太垃圾了吧。

我本人是用 VS 编译的,所以 MinGW 部分写的有些省略,请大家见谅。

PS:这是我第一次写博客,文章中肯定有很多错误的地方,请大家多多包涵,也欢迎大家指出。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341