如何将训练好的模型保存至远程MLflow服务器及路径异常排查
问题
我有一台运行MLflow的服务器,端口为8791,启动时设置--default-artifact-root为file:/home/data/mlflow。这台服务器没有GPU,所以我在另一台服务器上训练了模型,现在想用MLflow保存它。执行的代码如下:
mlflow.set_tracking_uri('http://MyServerIP:8791') mlflow.set_experiment('experiment1') with mlflow.start_run() as run: mlflow.log_metric('val loss', 0.23656) mlflow.log_metric('val accuracy', 0.221) mlflow.log_metric('val precision', 0.545) mlflow.log_metric('val recall', 0.221) mlflow.log_metric('val f1', 0.4554) mlflow.pytorch.log_model(model, "model") model_uri: str = f"runs:/{run.info.run_id}/model" registered_model_version: ModelVersion = mlflow.register_model(model_uri, mlflow_model_name)
现在MLflow UI里能看到指标、实验和模型名称,但模型版本表中的source值是file:///home/data/mlflow/4/19b1f0fa0c35492096568e38c095835e/artifacts/model,这个路径在MLflow服务器上根本不存在。请问问题出在哪?怎么从外部服务器把模型保存到MLflow中?
原因分析
- 文件系统不共享:MLflow服务器的
default-artifact-root设为本地文件路径file:/home/data/mlflow,但训练模型的另一台服务器和MLflow服务器没有共享这个文件系统。mlflow.pytorch.log_model默认会先把模型存在训练机器的本地临时目录,然后尝试将文件同步到MLflow服务器的artifact根目录——但因为是本地文件路径,训练机器没法直接写入MLflow服务器的本地磁盘,所以MLflow服务器上根本没有实际的模型文件,只是在数据库里记录了这个路径。 - 注册模型的URI问题:你用
runs:/{run.info.run_id}/model这个URI注册模型,这个URI指向的是训练机器本地的artifact存储位置,MLflow服务器无法访问到这个路径,所以注册后显示的source路径在服务器上不存在。
解决方法
方法一:改用远程共享存储作为Artifact根目录(推荐)
这是最稳妥的方案,让MLflow服务器和训练机器都能访问同一个共享存储:
- 如果是本地集群环境,可以用NFS挂载:在MLflow服务器和训练机器上都挂载同一个NFS目录,然后把MLflow服务器的
--default-artifact-root设置为这个挂载路径(比如file:/mnt/nfs/mlflow-artifacts)。这样训练机器执行mlflow.pytorch.log_model时,会直接把模型写入共享存储,MLflow服务器也能正常读取。 - 如果是云环境,可以用S3、GCS、Azure Blob等云存储:把MLflow服务器的
--default-artifact-root改成云存储路径(比如s3://my-mlflow-bucket/artifacts),然后在训练机器上配置好云存储的访问凭据(比如AWS_ACCESS_KEY_ID等环境变量),这样训练机器就能直接把模型上传到云存储,MLflow服务器也能通过云存储访问模型文件。
方法二:修正代码逻辑(配合共享存储使用)
不需要手动拼接runs:/ URI,直接用mlflow.pytorch.log_model返回的artifact URI来注册模型,确保路径正确:
mlflow.set_tracking_uri('http://MyServerIP:8791') mlflow.set_experiment('experiment1') with mlflow.start_run() as run: # 记录指标 mlflow.log_metric('val loss', 0.23656) mlflow.log_metric('val accuracy', 0.221) mlflow.log_metric('val precision', 0.545) mlflow.log_metric('val recall', 0.221) mlflow.log_metric('val f1', 0.4554) # 记录模型,获取返回的artifact URI model_info = mlflow.pytorch.log_model(model, "model") # 用返回的URI注册模型 registered_model_version = mlflow.register_model(model_info.model_uri, mlflow_model_name)
方法三:手动上传模型(不推荐,繁琐)
如果暂时没法用共享存储,可以先让训练机器把本地生成的模型文件上传到MLflow服务器的/home/data/mlflow对应路径下:
- 训练机器执行代码后,找到本地临时存储模型的路径(可以通过
model_info.model_uri查看,比如file:///tmp/mlflow/artifacts/xxx/model)。 - 用
scp或其他工具把这个模型目录上传到MLflow服务器的/home/data/mlflow/4/19b1f0fa0c35492096568e38c095835e/artifacts/model路径下。 - 重新执行注册模型的代码,此时MLflow服务器就能找到对应的模型文件了。
内容的提问来源于stack exchange,提问作者Rahman
相关产品推荐
相关产品推荐

