今年,大约 220 个团队齐聚开放数据科学大会 (ODSC) 西部,参加 NVIDIA 黑客松竞赛,这是一场 24 小时机器学习 (ML) 竞赛。数据科学家和工程师设计了基于准确性和处理速度进行评估的模型。排名前三名的团队带着奖品礼包离去,其中包括 NVIDIA RTX Ada Generation GPUs 、Google Colab 积分等。为了赢得这些榜单,获胜团队利用 RAPIDS Python APIs 提供了更准确、更高性能的解决方案。
在 ODSC 的演讲中,NVIDIA RAPIDS AI 产品负责人 Nick Becker 强调,AI 的计算需求,加上生成的数据量不断增加,正在推动数据处理成为加速计算的下一阶段。如今,我们每天会生成约 403 million terabytes 的数据,这给数据中心带来了巨大压力,他们必须高效处理更多数据,以实现更高的准确性、隐私性和更快的响应速度。
随着企业端到端运营和简化 AI 系统,他们需要解决相关的数据处理瓶颈。加速计算可为当今日益复杂的工作流程实现更高效的处理。
NVIDIA Hackathon 竞赛展示了数据科学家如何通过 PyData 库利用 GPU 加速来快速处理日益增多的数据,同时使用他们已经知道的语法,无需更改代码。
我们为参与者提供了大约 10GB 的合成表格数据,其中包含 1200 万个主题的信息,每个主题均由 100 多个分类和数字匿名特征进行描述。他们的任务是构建一个回归模型来预测目标变量 y,并最小化根均方误差 (RMSE),以实现准确性和速度。他们有 24 小时的时间来解决问题并优化解决方案。
参与者通过 pandas 或 Polars 利用 RAPIDS cuDF,一些参与者使用 RAPIDS cuML 或 XGBoost 来优化数据处理和模型训练。参与者被鼓励应用 Exploratory Data Analysis (EDA) 和 feature engineering,并 ensemble 多个 ML 算法。
本文介绍了前三名获奖者的见解和策略:Shyamal Shah、Feifan Liu 以及队友 Himalaya Dua 和 Sara Zare,以及 Lorenzo Mondragon。用他们自己的话来说,他们分享了如何应对挑战,以及如何生成更快速、更准确的解决方案的一些提示和技巧。
第一名:Shyamal Shah
NVIDIA 编程马拉松要求我通过 Google Colab 使用功能强大的 NVIDIA GPUs 分析大量表格数据集。我的方法通过几个关键优化来优先考虑计算效率和预测准确性。首先,我利用 cuDF pandas 扩展程序 来利用 NVIDIA RAPIDS 生态系统,该扩展程序可自动加速 GPU 上的 pandas 操作。通过详细的特征分析,我发现 20 个数值特征实际上是重复的,在归一化时具有相同的统计属性。根据这一见解,我只选择了一个具有代表性的数值特征,即“magical”列,该列的空值数量最少。
# Calculate statistics from training data
base_median = train_df[base_feature].median()
Q1 = train_df[base_feature].quantile(0.25)
Q3 = train_df[base_feature].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# Process base feature
df_processed['magical'] = df['magical'].fillna(base_median).clip(lower_bound, upper_bound)
对于高基数分类变量,我使用平滑实现了目标均值编码,而不是传统的独热编码,这将显著增加特征维度。通过将最初的 106 个特征缩小到三个关键预测变量,我在保持预测能力的同时大幅降低了计算开销。
# Calculate robust target encodings for high-cardinality categorical variables
cat_encodings = {}
global_mean = train_df['y'].mean()
for col in ['trickortreat', 'kingofhalloween']:
# Group by category and calculate stats
cat_stats = (train_df.groupby(col)['y']
.agg(['mean', 'count'])
.reset_index())
# Only keep categories that appear more than once
frequent_cats = cat_stats[cat_stats['count'] > 1]
# Strong smoothing factor due to high cardinality
smoothing = 100
# Calculate smoothed means with stronger regularization
frequent_cats['encoded'] = (
(frequent_cats['count'] * frequent_cats['mean'] + smoothing * global_mean) /
(frequent_cats['count'] + smoothing)
)
# Create dictionary only for frequent categories
cat_encodings[col] = dict(zip(frequent_cats[col], frequent_cats['encoded']))
# Process categorical features
for col in ['trickortreat', 'kingofhalloween']:
# Map categories to encodings, with special handling for rare/unseen categories
df_processed[f'{col}_encoded'] = (
df[col].map(cat_encodings[col])
.fillna(global_mean) # Use global mean for rare/unseen categories
)
该实施使用了 Microsoft 的 LightGBM 框架,该框架专为处理大型数据集而选择 GPU 优化和顶级性能提升功能。
通过仔细调整参数和实验迭代,我优化了模型的超参数,以平衡训练速度和准确性。最终解决方案在实现高准确度的同时,仅需 1 分 47 秒即可完成训练和预测周期。此经验表明,在使用大规模数据集时,如何将 GPU 加速计算与周全的特征工程和算法选择相结合,从而获得高效准确的解决方案。
第二名获奖者:Feifan Liu 博士以及队友 Himalaya Dua 和 Sara Zare
在我看来,我认为 cuDF pandas 非常高效且易于使用。熟悉原始 pandas 的用户无需学习新的 API。它使加载和处理大量数据成为可能。
其中一个技巧是避免复杂的预处理,例如 imputation。将缺失值直接分配为 -1 (即在特征空间中创建额外维度) 对性能和效率都有效。
train_df = df.copy()
# train_df = sample_20_df.copy()
categorical_cols = train_df.select_dtypes(include=['object', 'category']).columns.tolist()
numerical_cols = train_df.select_dtypes(include=['number']).columns.tolist()
num_col_only_minus_one = [col for col in numerical_cols if (train_df[col] < 0).sum()
> 0 and (train_df[col] < 0).sum() == (train_df[col] == -1).sum()]
train_df[categorical_cols] = train_df[categorical_cols].astype('category')
train_df[num_col_only_minus_one]=train_df[num_col_only_minus_one].replace(-1, np.nan)
test_df[categorical_cols] = test_df[categorical_cols].astype('category')
test_df[num_col_only_minus_one]=test_df[num_col_only_minus_one].replace(-1, np.nan)
另一个技巧是利用 XGBoost 中的 CUDA 支持来加速训练。
#baseline parameters
xgb_regressor = xgb.XGBRegressor(objective='reg:squarederror', eval_metric = 'rmse',
max_depth= 5, n_estimators=500, random_state=42, device='cuda', enable_categorical=True)
第三名冠军:Lorenzo Mondragon
为了应对这一挑战,我利用 RAPIDS 将 GPU 加速集成到 Polars 和 pandas DataFrames 中。这实现了对 1200 万行表格数据的高效预处理,包括处理缺失值、编码分类特征和采样数据以优化模型训练。
在回归任务中,我利用具有 GPU 支持的 XGBoost (gpu_hist 树方法) 来训练具有针对准确性和性能进行微调的超参数的模型。我专注于:
- 使用列均值填充数字特征,使用
"Unknown"
填充分类特征。 - 将分类数据编码为紧凑的
UInt32
格式,以提高内存效率。 - 通过 Polars 尝试延迟加载和采样,以加快数据提取和操作速度。
# 1. Handle missing values
numeric_cols = train_data.select(cs.numeric()).columns
categorical_cols = [
col for col in train_data.columns
if col not in numeric_cols and col not in ['id', 'y']
]
# Fill missing values
df = train_data.with_columns([
# Fill numeric columns with mean
*[
pl.col(col).fill_null(pl.col(col).mean()).alias(col)
for col in numeric_cols
],
# Fill categorical columns with 'Unknown'
*[
pl.col(col).fill_null("Unknown").alias(col)
for col in categorical_cols
]
])
在评估阶段,用于预处理的 Polars 与 GPU 加速的 XGBoost 相结合,使我能够在模型准确性和推理速度之间取得平衡。虽然我的模型在准确性方面排名第九,但在采用性能指标时,RAPIDS 带来的效率提升使我的解决方案整体排名第三。
- GPU 加速是一项颠覆性技术:使用 RAPIDS 可显著缩短数据预处理和模型训练时间,从而在紧张的时间限制内处理大型数据集。
- 与熟悉的工具无缝集成 :采用 RAPIDS 只需对现有 pandas 和 Polars 工作流程作出极少的更改,这凸显了数据科学从业者可以使用 GPU 加速库。
- 优化需要平衡: 虽然准确性至关重要,但在延迟和资源效率至关重要的真实场景中,针对速度进行优化同样会产生影响。
- 社区和支持至关重要:黑客松期间提供的资源和专家建议非常宝贵,尤其是在使用 Polars GPU 引擎和 RAPIDS 等尖端工具时。
了解详情
如果您不熟悉 RAPIDS,请查看这些 资源以开始使用 ,并试用这些 cuDF pandas 和 Polars 教程。您可以观看网络会议 Unlock Hackathon Success with NVIDIA: Tools and Q&A with NVIDIA Kaggle Grandmaster Jiwei Liu,了解如何使用 cuDF pandas 或 Polars 利用 GPU 加速,探索特征工程技术,并从此 Notebook 中获得见解。此外,您还可以查看为黑客松 创建的示例 Notebook,其中一个用于 cuDF pandas,另一个用于 Polars GPU Engine ,同样由 NVIDIA Kaggle Grandmaster 创建。