MLflow训练任务日志Artifacts遇filedescriptor错误及内核无响应问题求助
问题定位与解决方案建议
核心问题分析
ValueError: filedescriptor out of range in select()错误源于Python旧版本select模块的限制——它不支持处理编号大于1024的文件描述符。当进程打开的文件、套接字等资源数量超过这个阈值时,就会触发该错误。结合你观察到的Spark py4j网关反复初始化、CPU系统占用拉满的现象,大概率是训练过程中积累了大量未关闭的文件句柄,或是MLflow/Databricks Recipe在日志Artifacts阶段创建了过多Spark连接、文件资源,导致文件描述符耗尽,进而引发py4j网关连接处理逻辑崩溃,最终造成Python内核无响应。
针对性排查与修复步骤
调整文件描述符上限
先查看当前进程的文件描述符限制:ulimit -n若结果为默认的1024,临时调高至更大值(如4096)后重试:
ulimit -n 4096若临时调整有效,需在系统层面永久修改限制(例如编辑
/etc/security/limits.conf文件)。优化MLflow Artifacts日志策略
- 避免在训练循环中频繁调用
mlflow.log_artifact或mlflow.log_artifacts,改为批量日志——比如每N个epoch执行一次,或训练结束后一次性提交所有Artifacts。 - 避免递归日志过大的目录,明确指定需要日志的文件路径,减少不必要的文件句柄占用。
- 避免在训练循环中频繁调用
修复Spark连接泄漏
- 检查代码中是否重复创建SparkSession或py4j连接且未正确关闭,训练完成后显式调用
spark.stop()释放资源。 - 将py4j版本升级至0.10.10及以上,新版本修复了部分文件描述符相关的bug,同时兼容了更大范围的文件描述符编号。
- 检查代码中是否重复创建SparkSession或py4j连接且未正确关闭,训练完成后显式调用
优化Databricks Recipe配置
- 检查Recipe的日志配置,关闭过于冗余的日志项或重复日志逻辑,减少额外资源消耗。
- 尝试临时禁用非核心Artifacts的日志(如部分中间文件),排查是否是特定类型的Artifacts触发了问题。
进一步排查所需信息
若上述步骤未解决问题,需收集以下信息辅助定位:
- 训练进程PID,执行
lsof -p <PID>查看打开的文件句柄数量、类型,确认是否存在异常的资源占用。 - 设置环境变量
MLFLOW_LOG_LEVEL=DEBUG后重新运行训练,收集MLflow详细日志,重点关注Artifacts日志阶段的操作细节。 - 查看系统
dmesg日志,确认是否存在文件描述符耗尽的系统级报错。
内容的提问来源于stack exchange,提问作者Zxxxxx
相关产品推荐
相关产品推荐

