提问者:小点点

用pytorch悬挂的数据库笔记本


我们有一个数据库笔记本问题。我们的一个笔记本单元似乎挂起了,而驱动程序日志确实显示笔记本单元已被执行。有人知道为什么我们的笔记本单元一直挂着,并且没有完成吗?请参阅下面的详细信息。

形势

  • 我们正在数据库笔记本中使用pytorch训练一个ML模型UI
  • 训练使用mlflow注册模型
  • 在单元格的末尾,我们打印一条语句“完成训练”
  • 我们使用单个节点集群
    • 数据库运行时:10.4 LTSML(包括Apache Spark 3.2.1、GPU、Scala 2.12)
    • 节点类型:Standard_NC6s_v3

    意见

    • 在Database ricks笔记本中UI我们看到单元正在运行pytorch训练并显示训练的中间日志
    • 一段时间后,模型在mlflow中注册,但我们在Database ricks笔记本中看不到此日志UI
    • 我们还可以在驱动程序日志中看到打印语句"Done with训练"。我们在Database ricks笔记本中看不到此语句UI

    代码

    from pytorch_lightning import Trainer
    from pytorch_lightning.callbacks.early_stopping import EarlyStopping
    
    trainer = Trainer(gpus=-1, num_sanity_val_steps=0, logger = logger, callbacks=[EarlyStopping(monitor="test_loss", patience = 2, mode = "min", verbose=True)])
    
    with mlflow.start_run(experiment_id = experiment_id) as run:
      trainer.fit(model, train_loader, val_loader)
      mlflow.log_param("param1", param1)    
      mlflow.log_param("param2", param2)    
      mlflow.pytorch.log_model(model._image_model, artifact_path="model", registered_model_name="image_model")
      mlflow.pytorch.log_state_dict(model._image_model.state_dict(), "model")
      
    print("Done with training")
    

    套餐

    mlflow-skinny==1.25.1
    torch==1.10.2+cu111 
    torchvision==0.11.3+cu111
    

    我尝试过的解决方案没有奏效

    • 尝试添加缓存删除,但不起作用
    # Cleaning up to avoid any open processes...  
    del trainer
    torch.cuda.empty_cache()
    # force garbage collection
    gc.collect()
    
    • 尝试强制退出笔记本,但也不起作用
    parameters = json.dumps({"Status": "SUCCESS", "Message": "DONE"})
    dbutils.notebook.exit(parameters)
    

共2个答案

匿名用户

我找到了问题所在。要解决这个问题,请调整torch.utils.data的参数。DataLoader

  1. 禁用pin_memory
  2. num_workers设置为总vCPU的30%(例如1或2表示Standard_NC6s_v3)

例如:

train_loader = DataLoader(
    train_dataset,
    batch_size=32,
    num_workers=1,
    pin_memory=False,
    shuffle=True,
)

此问题似乎与PyTorch有关,是由于死锁问题。请参阅此处的详细信息。

匿名用户

https://stackoverflow.com/a/72473053/10555941

上面的答案还有更多要补充的。当您设置pin_memoryTrue并且num_workers等于节点上的vcpus总数时,它使用IPC供线程通信。这些IPC使用共享内存,它们窒息了VM的共享内存。

这导致进程挂起。DataLoadernum_workers只是为了帮助使用子线程加载数据。也就是说,它不需要是加速数据加载的极值。让它小到vCPUS的30%就足以加载数据。