GPU 加速 #

GPU 加速概述 #

GPU vs CPU 性能对比 #

text
┌─────────────────────────────────────────────────────────────┐
│                    GPU vs CPU 性能                           │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  数据集规模: 100万样本, 100特征                              │
│                                                              │
│  CPU (8核):     ████████████████████████████  120秒         │
│  GPU (V100):    ████                          15秒          │
│                                                              │
│  加速比: 8x                                                  │
│                                                              │
│  数据集规模: 1000万样本, 500特征                             │
│                                                              │
│  CPU (8核):     ████████████████████████████  1800秒        │
│  GPU (V100):    ██                            90秒           │
│                                                              │
│  加速比: 20x                                                 │
│                                                              │
└─────────────────────────────────────────────────────────────┘

GPU 加速原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    GPU 加速原理                              │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  CPU: 串行计算                                               │
│  - 逐个特征计算分裂点                                        │
│  - 适合小规模数据                                            │
│                                                              │
│  GPU: 并行计算                                               │
│  - 所有特征同时计算分裂点                                    │
│  - 数千个核心并行处理                                        │
│  - 适合大规模数据                                            │
│                                                              │
│  XGBoost GPU 算法:                                           │
│  - hist: 直方图算法(推荐)                                  │
│  - approx: 近似算法                                          │
│                                                              │
└─────────────────────────────────────────────────────────────┘

CUDA 环境配置 #

检查 CUDA 环境 #

bash
# 检查 NVIDIA GPU
nvidia-smi

# 检查 CUDA 版本
nvcc --version

# 检查 cuDNN
cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

安装 GPU 版本 #

bash
# pip 安装(自动包含 GPU 支持)
pip install xgboost

# 验证 GPU 支持
python -c "import xgboost as xgb; print(xgb.build_info())"

Python 检查 GPU #

python
import xgboost as xgb

def check_gpu_support():
    """检查 GPU 支持状态"""
    try:
        info = xgb.build_info()
        print("XGBoost 构建信息:")
        for key, value in info.items():
            print(f"  {key}: {value}")
        
        # 测试 GPU 训练
        import numpy as np
        X = np.random.rand(1000, 10)
        y = np.random.randint(0, 2, 1000)
        
        dtrain = xgb.DMatrix(X, label=y)
        
        params = {
            'tree_method': 'hist',
            'device': 'cuda',
            'objective': 'binary:logistic'
        }
        
        model = xgb.train(params, dtrain, num_boost_round=10)
        print("\nGPU 训练测试成功!")
        
    except Exception as e:
        print(f"GPU 不支持或配置错误: {e}")

check_gpu_support()

GPU 参数配置 #

基本配置 #

python
import xgboost as xgb
import numpy as np

# 创建数据
X = np.random.rand(10000, 100)
y = np.random.randint(0, 2, 10000)

dtrain = xgb.DMatrix(X, label=y)

# GPU 参数配置
params = {
    'objective': 'binary:logistic',
    'eval_metric': 'logloss',
    
    # GPU 树方法
    'tree_method': 'hist',    # 直方图算法(推荐)
    'device': 'cuda',         # 使用 CUDA
    
    # 其他参数
    'max_depth': 6,
    'eta': 0.1
}

# 训练
model = xgb.train(params, dtrain, num_boost_round=100)

多 GPU 配置 #

python
# 指定 GPU 设备
params = {
    'tree_method': 'hist',
    'device': 'cuda:0',  # 使用 GPU 0
    # 'device': 'cuda:1',  # 使用 GPU 1
    'objective': 'binary:logistic'
}

# 使用环境变量
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1'  # 只使用 GPU 0 和 1

GPU 内存管理 #

python
params = {
    'tree_method': 'hist',
    'device': 'cuda',
    'objective': 'binary:logistic',
    
    # GPU 内存参数
    'gpu_id': 0,                    # GPU 设备 ID
    'n_gpus': 1,                    # 使用的 GPU 数量
    'gpu_page_size': 0,             # GPU 页大小(0 表示自动)
}

# 大数据集时可能需要调整
import os
os.environ['XGBOOST_GPU_ALLOCATOR'] = 'default'  # 或 'pytorch'

性能对比 #

CPU vs GPU 基准测试 #

python
import xgboost as xgb
import numpy as np
import time

def benchmark_cpu_vs_gpu(n_samples, n_features):
    """CPU vs GPU 性能对比"""
    
    # 生成数据
    X = np.random.rand(n_samples, n_features)
    y = np.random.randint(0, 2, n_samples)
    
    dtrain = xgb.DMatrix(X, label=y)
    
    # CPU 训练
    params_cpu = {
        'objective': 'binary:logistic',
        'tree_method': 'hist',
        'max_depth': 6,
        'eta': 0.1
    }
    
    start = time.time()
    model_cpu = xgb.train(params_cpu, dtrain, num_boost_round=100)
    cpu_time = time.time() - start
    
    # GPU 训练
    params_gpu = {
        'objective': 'binary:logistic',
        'tree_method': 'hist',
        'device': 'cuda',
        'max_depth': 6,
        'eta': 0.1
    }
    
    start = time.time()
    model_gpu = xgb.train(params_gpu, dtrain, num_boost_round=100)
    gpu_time = time.time() - start
    
    print(f"数据规模: {n_samples} 样本, {n_features} 特征")
    print(f"CPU 时间: {cpu_time:.2f} 秒")
    print(f"GPU 时间: {gpu_time:.2f} 秒")
    print(f"加速比: {cpu_time/gpu_time:.2f}x")
    
    return cpu_time, gpu_time

# 运行基准测试
benchmark_cpu_vs_gpu(100000, 100)
benchmark_cpu_vs_gpu(1000000, 100)

不同数据规模性能 #

python
import matplotlib.pyplot as plt

def plot_gpu_scaling():
    """绘制 GPU 加速比随数据规模变化"""
    
    sample_sizes = [10000, 50000, 100000, 500000, 1000000]
    speedups = []
    
    for n in sample_sizes:
        cpu_time, gpu_time = benchmark_cpu_vs_gpu(n, 50)
        speedups.append(cpu_time / gpu_time)
    
    plt.figure(figsize=(10, 6))
    plt.plot(sample_sizes, speedups, 'o-', linewidth=2, markersize=10)
    plt.xlabel('Sample Size')
    plt.ylabel('Speedup (CPU time / GPU time)')
    plt.title('GPU Speedup vs Data Size')
    plt.grid(True)
    plt.xscale('log')
    plt.show()

plot_gpu_scaling()

GPU 优化技巧 #

数据优化 #

python
# 使用 float32 减少内存占用
X = X.astype(np.float32)

# 使用分批处理大数据
def train_large_data_gpu(X, y, batch_size=100000):
    """分批处理大数据"""
    n_samples = len(X)
    models = []
    
    for i in range(0, n_samples, batch_size):
        X_batch = X[i:i+batch_size]
        y_batch = y[i:i+batch_size]
        
        dtrain = xgb.DMatrix(X_batch, label=y_batch)
        
        params = {
            'tree_method': 'hist',
            'device': 'cuda',
            'objective': 'binary:logistic'
        }
        
        model = xgb.train(params, dtrain, num_boost_round=100)
        models.append(model)
    
    return models

参数优化 #

python
# GPU 优化参数
params = {
    'tree_method': 'hist',
    'device': 'cuda',
    'objective': 'binary:logistic',
    
    # 优化参数
    'max_bin': 256,           # 直方图 bin 数
    'max_depth': 6,
    'eta': 0.1,
    
    # 并行优化
    'nthread': -1,            # CPU 线程数(用于数据预处理)
    'num_parallel_tree': 1,   # 并行树数量
}

内存优化 #

python
def gpu_memory_efficient_training(X, y):
    """GPU 内存高效训练"""
    
    # 分块处理
    chunk_size = 50000
    n_chunks = len(X) // chunk_size + 1
    
    # 初始模型
    params = {
        'tree_method': 'hist',
        'device': 'cuda',
        'objective': 'binary:logistic',
        'process_type': 'default',
        'refresh_leaf': True
    }
    
    model = None
    
    for i in range(n_chunks):
        start_idx = i * chunk_size
        end_idx = min((i + 1) * chunk_size, len(X))
        
        X_chunk = X[start_idx:end_idx]
        y_chunk = y[start_idx:end_idx]
        
        dtrain = xgb.DMatrix(X_chunk, label=y_chunk)
        
        # 增量训练
        model = xgb.train(
            params,
            dtrain,
            num_boost_round=10,
            xgb_model=model
        )
        
        # 清理 GPU 内存
        del dtrain
        
        print(f"Processed chunk {i+1}/{n_chunks}")
    
    return model

Scikit-Learn API GPU #

python
from xgboost import XGBClassifier, XGBRegressor

# GPU 分类器
clf = XGBClassifier(
    n_estimators=100,
    max_depth=6,
    learning_rate=0.1,
    tree_method='hist',
    device='cuda',
    objective='binary:logistic',
    random_state=42
)

clf.fit(X_train, y_train)

# GPU 回归器
reg = XGBRegressor(
    n_estimators=100,
    max_depth=6,
    learning_rate=0.1,
    tree_method='hist',
    device='cuda',
    objective='reg:squarederror',
    random_state=42
)

reg.fit(X_train, y_train)

GPU 故障排除 #

常见问题 #

python
def troubleshoot_gpu():
    """GPU 故障排除"""
    
    print("1. 检查 CUDA 安装:")
    import subprocess
    try:
        result = subprocess.run(['nvidia-smi'], capture_output=True, text=True)
        print(result.stdout)
    except:
        print("nvidia-smi 未找到,请检查 NVIDIA 驱动安装")
    
    print("\n2. 检查 XGBoost GPU 支持:")
    try:
        info = xgb.build_info()
        print(f"CUDA 版本: {info.get('CUDA_VERSION', 'N/A')}")
        print(f"GPU 支持: {info.get('USE_CUDA', False)}")
    except:
        print("无法获取 XGBoost 构建信息")
    
    print("\n3. 测试 GPU 训练:")
    try:
        X = np.random.rand(1000, 10)
        y = np.random.randint(0, 2, 1000)
        dtrain = xgb.DMatrix(X, label=y)
        
        params = {'tree_method': 'hist', 'device': 'cuda', 'objective': 'binary:logistic'}
        model = xgb.train(params, dtrain, num_boost_round=10)
        print("GPU 训练成功!")
    except Exception as e:
        print(f"GPU 训练失败: {e}")
    
    print("\n4. 常见解决方案:")
    solutions = [
        "确保 NVIDIA 驱动已安装",
        "确保 CUDA Toolkit 已安装",
        "重新安装 xgboost: pip install --upgrade xgboost",
        "检查 CUDA 版本兼容性",
        "设置环境变量: CUDA_VISIBLE_DEVICES"
    ]
    for sol in solutions:
        print(f"  - {sol}")

troubleshoot_gpu()

GPU 最佳实践 #

python
def gpu_best_practices():
    """
    GPU 训练最佳实践
    """
    practices = {
        '数据准备': [
            '使用 float32 减少内存',
            '数据量小时 CPU 可能更快',
            '大数据集 GPU 优势明显'
        ],
        '参数配置': [
            '使用 tree_method="hist"',
            '合理设置 max_bin',
            '监控 GPU 内存使用'
        ],
        '性能优化': [
            '批量处理大数据',
            '使用多 GPU 并行',
            '避免频繁数据传输'
        ],
        '故障处理': [
            '检查 CUDA 版本',
            '监控 GPU 温度',
            '设置内存增长模式'
        ]
    }
    
    for category, items in practices.items():
        print(f"\n{category}:")
        for item in items:
            print(f"  • {item}")

下一步 #

现在你已经了解了 GPU 加速,接下来学习 自定义目标函数 掌握高级定制功能!

最后更新:2026-04-04