使用 XGBoost 和 RAPIDS 内存管理器 (RMM) 插件
RAPIDS 内存管理器 (RMM) 库为 NVIDIA GPU 提供了一系列高效的内存分配器。现在可以通过启用 RMM 集成插件,将 XGBoost 与 RMM 提供的内存分配器结合使用。
此目录中的演示特别突出了一个 RMM 分配器:池子分配器(pool sub-allocator)。该分配器通过预先分配一大块内存来解决 cudaMalloc()
速度慢的问题。后续的分配将从已分配的内存池中提取,从而避免直接调用 cudaMalloc()
的开销。有关更多详细信息,请参阅此 GTC 演讲幻灯片。
在运行演示之前,请确保 XGBoost 已编译并启用了 RMM 插件。为此,请使用选项 -DPLUGIN_RMM=ON
运行 CMake(也需要 -DUSE_CUDA=ON
)。
cmake -B build -S . -DUSE_CUDA=ON -DUSE_NCCL=ON -DPLUGIN_RMM=ON
cmake --build build -j$(nproc)
CMake 将尝试在您的构建环境中找到 RMM 库。您可以选择从源代码构建 RMM,或使用 Conda 包管理器安装它。如果 CMake 找不到 RMM,您应该使用 CMake 前缀指定 RMM 的位置。
# If using Conda:
cmake -B build -S . -DUSE_CUDA=ON -DUSE_NCCL=ON -DPLUGIN_RMM=ON -DCMAKE_PREFIX_PATH=$CONDA_PREFIX
# If using RMM installed with a custom location
cmake -B build -S . -DUSE_CUDA=ON -DUSE_NCCL=ON -DPLUGIN_RMM=ON -DCMAKE_PREFIX_PATH=/path/to/rmm
通知 XGBoost 有关 RMM 池的信息
当 XGBoost 与 RMM 一起编译时,大多数大尺寸分配将通过 RMM 分配器进行,但在性能关键区域的一些小分配使用不同的缓存分配器,以便我们可以更好地控制内存分配行为。用户可以通过设置全局配置 use_rmm
来覆盖此行为,并强制所有分配都使用 rmm。
with xgb.config_context(use_rmm=True):
clf = xgb.XGBClassifier(tree_method="hist", device="cuda")
根据内存池大小和分配器类型的选择,这可以增加内存使用的一致性,但可能会对性能产生轻微影响。
多 GPU 不使用设备序号
由于使用 RMM 时内存池是预分配到特定设备上的,因此更改 XGBoost 中的 CUDA 设备序号可能会导致内存错误 cudaErrorIllegalAddress
。请使用 CUDA_VISIBLE_DEVICES
环境变量而不是 device="cuda:1"
参数来选择设备。对于分布式训练,诸如 dask-cuda
之类的分布式计算框架负责设备管理。对于 Scala-Spark,请参阅XGBoost4J-Spark-GPU 教程以获取更多信息。
内存超额订阅
警告
此功能仍在实验中,并处于积极开发阶段。
较新的 NVIDIA 平台,例如 Grace-Hopper,使用 NVLink-C2C,这使得 CPU 和 GPU 能够拥有一致的内存模型。用户可以在最新的 RMM 中使用 SamHeadroomMemoryResource 来利用系统内存存储数据。这可以帮助 XGBoost 利用主机内存进行 GPU 计算,但由于 CPU 内存速度较慢和页面迁移开销,可能会降低性能。