我想在不同的数据集上测试多个模型。我希望它们在单个 GPU 上同时运行。
一般的 puesdo 代码如下。您可以使用任何虚拟模型或数据集来运行它。
然而,我注意到这通常比仅使用迭代方法慢 20%。我当前的解决方案有什么问题?
def test_model(paths):
model = Model(path to config)
data = DataLoader(*Dataset(path to data)
trainer = PyTorchLightning Trainer(config)
def main():
with ProcessPoolExecutor(max_workers=args.max_processes) as executor:
futures = {executor.submit(test_model, paths): (paths) for path in paths_to models_to_test}
for future in as_completed(futures):
try:
results_from_run = future.result()
full_results_df = pd.concat([full_results_df, results_from_run], ignore_index=True)
except Exception as e:
print(f"An error occurred while processing {futures[future]}: {e}")
GPU 默认情况下一次运行一个内核,并具有最大并行度。这意味着您的多个模型实例相互阻塞,导致执行速度变慢。
您可以尝试使用
joblib
以延迟方式安排流程(请参阅 torchensemble 作为示例),或使用 pytorch cuda 流安排模型。
也就是说,这两种方法都无法为您提供完美的并行化。
如果工作负载足以使 GPU 占用率饱和,GPU 内核仍会阻塞。
CPU(调度 CUDA 内核、数据处理、将数据移动到 CPU)和 I/O(同时从磁盘读取多个数据集)上也存在大量开销,无论 GPU 并行化如何,这都可能会导致速率限制。
在尝试并行方法之前,您应该尝试通过增加批量大小和/或将数据预加载到内存中来优化迭代方法。它最终可能是最快、最简单的方法。