1 搭建mlflow tracking server
1.1 搭建MinIO
搭建MinIO的目的是为了给mlflow提供模型数据的存储后台,此案例的mflow的元数据存储采用mysql。
step 1 安装并启动Docker服务
若已安装docker服务请忽略,若未安装:
# 设置yum源
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装docker 稳定版
yum install docker-ce
# 启动docker
systemctl start docker && systemctl enable docker
# 查看docker是否安装成功
docker version
step 2 拉取并启动MinIO容器
nohup docker run -p 9000:9000 \
-e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
minio/minio server /data &
step 3 登录UI,创建bucket
(1) 访问 http://localhost:9000 (localhost为服务器IP),进入UI界面:
(2) 点击右下角 + 符号,创建bucket,命名为mlflow,用于后续mlflow配置:
1.2 启动mlflow server
step 1 前提:服务器安装有conda
step 2 安装mysql服务
# 安装mysql
yum install mysql
yum install mysql-devel
wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
yum install mysql-server
# 启动mysql服务
systemctl start mysql
# 创建数据库
mysql -u root -p
# 初始没有密码,直接回车
mysql> CREATE DATABASE mlflow_test;
mysql> commit;
# Crtl+C 退出mysql交互界面
step 3 创建虚拟环境,安装依赖
# 创建虚拟环境
conda create -n mlflow-1.11.0 python==3.6
conda activate mlflow-1.11.0
# 安装mlflow server和依赖
pip install mlflow==1.11.0
pip install mysqlclient
pip install boto3
Step 4 添加环境变量
(1) vi ~/.bashrc 在环境变量文件下添加以下内容后,保存退出:
# mlflow server configuration
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export MLFLOW_S3_ENDPOINT_URL=http://localhost:9000
(2)运行 :
source ~/.bashrc
step 5 启动mlflow server
nohup mlflow server --backend-store-uri mysql://root:@localhost/mlflow_test --host 0.0.0.0 -p 5002 --default-artifact-root s3://mlflow &
【注意】: --backend-store-uri 对应的为服务器上的mysql服务。如果你的mysql有设置密码,需要填写对应密码;示例中没有是没有设置密码的情况。
# 查看nohup日志,确认启动正确
tailf nohup.out
[2021-06-08 10:33:50 +0800] [51952] [INFO] Worker exiting (pid: 51952)
[2021-06-08 10:33:50 +0800] [51951] [INFO] Parent changed, shutting down: <Worker 51951>
[2021-06-08 10:33:50 +0800] [51951] [INFO] Worker exiting (pid: 51951)
[2021-06-08 11:02:07 +0800] [53500] [INFO] Starting gunicorn 20.1.0
[2021-06-08 11:02:07 +0800] [53500] [INFO] Listening at: http://0.0.0.0:5002 (53500)
[2021-06-08 11:02:07 +0800] [53500] [INFO] Using worker: sync
[2021-06-08 11:02:07 +0800] [53503] [INFO] Booting worker with pid: 53503
[2021-06-08 11:02:07 +0800] [53567] [INFO] Booting worker with pid: 53567
[2021-06-08 11:02:07 +0800] [53568] [INFO] Booting worker with pid: 53568
[2021-06-08 11:02:07 +0800] [53569] [INFO] Booting worker with pid: 53569
输入 http://服务器ip:5002,查看mlflow server的UI:
2 使用mlflow API跟踪训练
2.1 绑定地址、注册实验
【注意】如果训练服务器和mlflow server不是一台机器,需要在训练环境安装 pip install mlflow以及pip install boto3。 并且安装1.2中step 4的第(1)步配置环境变量,注意localhost需要改成MinIO s3数据库的地址。
import mlflow # 引入头文件
mlflow.set_tracking_uri("http://xxx.xxx.xxx.xxx:5002") # mlflow server的部署地址,本机可填环回地址或默认地址
mlflow.set_experiment("beijing-foreign-0608") # 注册或绑定实验名称
2.2 记录初始参数
mlflow.log_param这个API可以用于记录本次训练的参数,可以任意log你想记录的东西,包括超参、tricks、路径。。。
mlflow.log_param("key", value)
比如,我这里的示例记录了如下参数:
if __name__ == "__main__":
with mlflow.start_run(): # 首先要调用mlflow.start_run(),对应实验的一次运行
# 记录参数
mlflow.log_param("project_root", "192.168.64.22:/data1/yolov4-train-foreign/")
mlflow.log_param("dataset_path", "192.168.64.22:/data5/0_yibiaozhutuxiang/\
beijinggongfutuxiangshibie/yiwuxuangua-yibiaozhu/")
mlflow.log_param("ckpt_path", "./data_gen_and_train/ckpt_0608/")
mlflow.log_param("freeze_batch_size", "8")
mlflow.log_param("freeze_epoch", "50")
mlflow.log_param("freeze_learning_rate", "1e-3")
mlflow.log_param("batch_size", "4")
mlflow.log_param("total_epoch","250")
mlflow.log_param("learning_rate", "2e-4")
mlflow.log_param("tricks", "mosaic, no cosine_lr, no smooth_label")
mlflow.log_param("input_size", "416")
# 开始训练
model = Trainer()
model.train()
对应地,你可以在mlflow server的ui页面里面,看到注册的实验。实验下面的每一个条目对应一次run,里面会保存你log的所有参数、运行启动时间等信息。
2.2 记录动态信息
在你的每个epoch或者step的函数中,利用mlflow.log_metric()记录你想记录的动态信息,比如train loss、val loss和acc等指标等。
mlflow.log_metric("key", val, step)
比如,我这里的示例记录损失值(示例是一些伪代码,仅需要关注在哪里使用mlflow api):
def fit_one_epoch(model, generator, epoch, ...):
train_loss = 0
val_loss = 0
# train
for step_train, batch in generator.train:
...
train_loss += model.loss(batch)
# value
for step_val, batch in generator.value:
model.eval()
...
val_loss += model.loss(batch)
# save model
train_loss = float(train_loss) / (setp_train + 1)
val_loss = float(val_loss) / (step_val + 1)
torch.save(model.stat_dict(), str("model_%d-tloss%.4f-vloss%.4f.pth" \
% (train_loss, val_loss, epoch)))
# log metrics to mlflow
mlflow.log_metric("train_loss", train_loss, epoch)
mlflow.log_metric("val_loss", val_loss, epoch)
对应的,在mlflow server的UI页面里面你可以看到记录的metrics:
你可以点击run的条目,进入详细页面, 然后点击下图红框标示的metric参数,在训练过程监控这个动态指标:
2.3 记录输出
使用mlflow.log_artifacts(“output”)记录输出,将输出传到s3模型存储服务器。该函数的形参为一个路径,可以使模型权重、日志、实验图片的保存路径。
mlflow.log_artifacts(self.ckpt_path)
对应,在mflow server UI上可以查看路径下输出的文件,如果是支持的格式(图片、txt、html、pdf文档等)可以在页面预览:
同时,在mlflow关联的数据库中可以查看文件,本案例关联的是基于MinIO搭建的s3数据库: