Xgboost: 在 Mac OSX 上更好地安装 XGBoost?

创建于 2019-05-17  ·  28评论  ·  资料来源: dmlc/xgboost

问题

目前在 MacOS 上安装 python 包的过程如下。

$ brew install gcc<strong i="7">@5</strong>
$ export CC=/path/to/gcc-5; export CXX=/path/to/g++-5; pip install xgboost

问题

我想从更有经验的贡献者那里学到的是,是否有任何计划来简化这个安装过程? 对于依赖于 xgboost 的任何包的自动安装系统,上述内容是站不住脚的。 使 xgboost 与 Apple 的 clang 兼容需要什么。

1.0.0 Blocking

最有用的评论

该公式已被 Homebrew 接受,因此 Mac 用户现在可以执行以下操作:

brew install xgboost

所有28条评论

Apple 的 clang 不支持开箱即用的 OpenMP,因此需要 Homebrew GCC。 所以,不,XGBoost 不会与 Apple 的 clang 兼容。

我认为我们可以通过为 Mac OSX 分发二进制轮子来简化这个过程。 二进制轮子将包含预构建的 libxgboost.dylib,因此用户不需要任何编译器。 (这就是 Windows 用户无需安装 Visual Studio 即可使用 XGBoost 的方式。)

但是,恐怕维护者(包括我自己)目前还不熟悉 Mac OSX 的二进制打包,即如何制作能够广泛兼容多个 OSX 版本的二进制文件。 你有什么建议吗?

现在,您应该考虑使用 conda-forge 在 Mac OSX 上自动安装 XGBoost。

@hcho3感谢您的快速回复! Conda 当然是一种选择,但使用 pip 会简单得多。 我将研究一下 macos 上的二进制打包会是什么样子。 我也不熟悉二进制包装,因此在该领域有经验的任何其他人的意见将不胜感激。

我在这个问题上遇到了一些困难,因为标准编译过程产生的 dylib 对自制 gcc 的库有很强的依赖关系。 如果有人有办法在编译后更改该依赖项(或使其在 gcc 版本中通用),那就太好了,但我不认为 macOS 附带 libgomp(它提供 OpenMP 支持),所以我们可能需要将其打包为好吧,这使生活变得困难。

@Craigacp @hcho3在找到 cmakelists 解决方法之前,我们是否可以考虑这样做。 https://github.com/netket/netket/issues/225#issuecomment -502714445。 我对 xgboost 的内部结构不是很熟悉,OpenMP 对库的性能有多重要。

这似乎也很有希望,但我无法让它工作: https://stackoverflow.com/questions/46414660/macos-cmake-and-openmp。

@adithyabsk @Craigacp OpenMP 对于 XGBoost 的性能非常关键,因为我们希望使用用户系统上常见的多核 CPU 的所有可用内核。 如果没有 OpenMP,您将只能使用一个 CPU 内核。

恕我直言,pip 不是为处理诸如 libomp 之类的外部依赖项而设计的。 另一方面,conda 能够同样轻松地处理非 Python 依赖项。 看到这篇文章: https ://jakevdp.github.io/blog/2016/08/25/conda-myths-and-misconceptions/

Microsoft/LightGBM如何解决这个问题:他们要求用户运行brew install libomp 。 我不确定这是否比安装 GCC 或 Conda 更容易,因为您需要先安装 Homebrew。

@hcho3 brew install libomp 解决方案可能会更好,因为它可以在预安装设置脚本中提供,而目前,必须在 CI 管道中分离 xgboost 以指定适当的 gcc 和 g++ 版本。 当然,就 conda 而言,我同意你的看法,这可能最终成为唯一的解决方案,但我只是想探索其他选项,看看是否还有其他可能。

抱歉这个愚蠢的问题,但运行时需要 OpenMP 吗? 例如,我们是否可以在安装了 OpenMP 的情况下编译 dmlc-core 和 xgboost,然后将该文件捆绑到一个轮子中,这样在安装时就不需要使用诸如audit_wheel 之类的工具进行编译?

https://stackoverflow.com/a/42106034

@adithyabsk我刚刚尝试使用brew install libomp ,现在我可以使用默认编译器 Apple Clang 编译 XGBoost:

brew install libomp
mkdir build
cd build
cmake ..
make -j10

更重要的是,生成的二进制libxgboost.dylib仅取决于/usr/local/opt/libomp/lib/libomp.dylib和 OSX 系统库。 (不再依赖特定版本的 GCC!万岁!)所以我想brew install libomp是在没有 Conda 的 Mac OSX 上安装 XGBoost 最不痛苦的方式。

然而,分发预编译的二进制文件仍然很棘手。 即使我们要在轮子中包含libomp.dylib ,Mac OSX 也不会使用该文件,因为共享库依赖项是用完整路径指定的:

hcho3<strong i="17">@localhost</strong>: xgboost$ otool -l libxgboost.dylib    # show list of library dependencies

libxgboost.dylib:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777223          3  0x00           6    15       2112 0x00918085
....
Load command 10
          cmd LC_LOAD_DYLIB
      cmdsize 64
         name /usr/local/opt/libomp/lib/libomp.dylib (offset 24)
   time stamp 2 Wed Dec 31 16:00:02 1969
      current version 5.0.0
compatibility version 5.0.0
Load command 11
          cmd LC_LOAD_DYLIB
      cmdsize 48
         name /usr/lib/libc++.1.dylib (offset 24)
   time stamp 2 Wed Dec 31 16:00:02 1969
      current version 400.9.0
compatibility version 1.0.0
Load command 12
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /usr/lib/libSystem.B.dylib (offset 24)
   time stamp 2 Wed Dec 31 16:00:02 1969
      current version 1252.50.4
compatibility version 1.0.0

另一方面,Windows 在查找共享库时更加灵活。 我发现只需在轮子中包含vcomp140.dll (OpenMP 运行时)就足够了。

@hetong007相关说明: brew install libomp还应该在 Mac OSX 上为 CRAN XGBoost 启用多线程

@hcho3我想是的。 XGBoost R 包调用相同的后端 API,因此行为应该相同。

@hcho3这是一个了不起的发展! 已经朝着正确的方向前进,我可以证明,在许多研发实验室中,安装 xgboost 对于那些不熟悉其内部要求的人来说是一个痛点。

跟进此说明:

Mac OSX 不会使用该文件,因为共享库依赖项是用完整路径指定的

也许我们可以更多地研究这个特定的问题,看看是否有任何解决方法可以将 libomp.dylib 放入二进制轮中。

@hcho3也可能是因为扩展本身? 我们是否也应该在 macOS 上使用 .so。 这个问题线程和stackoverflow帖子似乎表明了这一点。
https://stackoverflow.com/questions/2488016/how-to-make-python-load-dylib-on-osx
https://github.com/MoDeNa-EUProject/MoDeNa/issues/1

@adithyabsk考虑到在轮子中运送运行时库(并让它加载)的复杂性,让我们解决brew install libomp

  • Homebrew 已经在高级用户中广泛使用(我认为)。
  • 使用libomp ,我们可以使用 Apple Clang 编译 XGBoost,从而消除对特定版本的 Homebrew GCC 的硬依赖。
  • 此方法已被其他项目验证,例如 LightGBM。

附言。 我正在查看https://iscinumpy.gitlab.io/post/omp-on-high-sierra/以了解 OpenMP 在 Apple Clang 中的使用。

@hcho3

附言。 我正在查看https://iscinumpy.gitlab.io/post/omp-on-high-sierra/以了解 OpenMP 在 Apple Clang 中的使用。

这些 PR 可以帮助您:
https://github.com/microsoft/LightGBM/pull/1501、https://github.com/microsoft/LightGBM/pull/1923

@adithyabsk这是我的优先事项之一。 我想在 1.0.0 版本之前进行修复。

@hcho3很高兴听到它! 我会看看我是否也可以解决这个问题。

@adithyabsk我遇到brew install libomp的一个微妙问题是 XGBoost 将在没有 OpenMP 的情况下编译,因为 CMakeLists.txt 配置不正确。 (我可以通过在我的 Macbook 上运行中等繁重的作业来判断;如果没有 OpenMP,作业将需要 2-3 倍的时间。)我正在尝试修改 CMakeLists.txt 以正确启用 OpenMP。

@StrikerRUS感谢您的链接。 让构建系统正常工作非常困难,并且有一个参考点(LightGBM)对我有很大帮助。

@adithyabsk我遇到brew install libomp的一个微妙问题是 XGBoost 将在没有 OpenMP 的情况下编译,因为 CMakeLists.txt 配置不正确。 (我可以通过在我的 Macbook 上运行中等繁重的作业来判断;如果没有 OpenMP,作业将需要 2-3 倍的时间。)我正在尝试修改 CMakeLists.txt 以正确启用 OpenMP。

运气好的话? 我问的原因是,即使在通过“brew install libomp”安装 libomp 之后,“pip install xgboost -U”也会失败。

@wel51x我们尚未修改 CMakeLists.txt 以使新解决方案正常工作。 现在,您应该按照https://xgboost.readthedocs.io/en/latest/build.html 中的说明进行操作。

@adithyabsk @Craigacp我找到了https://github.com/matthew-brett/delocate。 这可能是删除硬编码库依赖项的有用解决方案。

万一有人觉得它有帮助...我知道这绝不是一种主流方法,但是可以使用 Nix (https://nixos.org/nix/) 在 MacOS 上安装支持 OpenMP 的最新 xgboost

$ nix-shell -p python3Packages.xgboost

@hcho3 ,我为 XGBoost 创建了一个 Homebrew 公式,以帮助简化 Mac 上的安装,因此用户将来可以运行brew install xgboost 。 它工作得很好,但不幸的是,使用旧版本的 GCC 不会被接受。

讨论: https ://github.com/Homebrew/homebrew-core/pull/43246

一种选择是禁用 OpenMP,但正如您所提到的,它对性能不利。 如果您能够提交更改以使其与libomp一起使用,我可以更新公式,我们可以将其推进。

感谢您的更新。

fwiw,我更新了公式,因此它不再依赖于 GCC,但缺乏对 OpenMP 的支持。 一旦对libomp的支持发布,我们就可以对其进行更新。

该公式已被 Homebrew 接受,因此 Mac 用户现在可以执行以下操作:

brew install xgboost

我使用brew install xgboost ,但仍然无法导入 XGBoost。 实际新安装的 XGBoost 目录中没有 __init__.py 文件或任何内容,因此我无法使用任何 XGBoost 功能。 使用brew安装XGBoost后还有一步吗?

@bnicholl有关临时解决方案,请参阅https://github.com/dmlc/xgboost/issues/4949#issuecomment -542333666。

@hcho3

感谢您的链接。 让构建系统正常工作非常困难,并且有一个参考点(LightGBM)对我有很大帮助。

随着即将到来的 CMake 3.16 版本(现在处于 RC 阶段)它应该更容易:将不需要为 >=Mojave 用户传递额外的参数。 参考https://gitlab.kitware.com/cmake/cmake/merge_requests/3916。

@adithyabsk @Craigacp #5146 现在应该允许您在不安装 Homebrew GCC 的情况下使用 OpenMP。 现在 XGBoost 将只依赖于libomp Homebrew 包。

@ankane因此,我们应该能够提交启用 OpenMP 的下一个 XGBoost (1.0) 版本。

此页面是否有帮助?
0 / 5 - 0 等级