可视化工具wandb & tensorboard在使用远程服务器时的离线同步

@可视化工具wandb & tensorboard在使用远程服务器时的离线同步

wandbtensorboard是两个机器学习项目进行可视化的重要工具。但在进行机器学习训练时,我们接入的远程服务器集群因为安全等原因只能通过局域网接入,而无法连接到互联网。这导致服务器无法直接通过使用tensorboard或者wandb等可视化工具进行实时数据上传和可视化。我们分别针对两种工具讨论解决方法:

Tensorboard

对于tensorboard,我们可以通过端口映射将数据映射到本地进行查看。

步骤

  1. 源代码 :确定加载训练数据的文件夹
  2. 运行源代码:训练数据log将根据路径保存
  3. 远程服务器terminal运行tensorboard服务器:在本地terminal中连接远程服务器,并输入 tensorboard --logdir $logdir(log的目录) --port=Remote_port 链接到本地端口
  4. 本地terminal运行ssh服务并进行端口映射:ssh -L $Local_port:127.0.0.1: $Remote_port $Remote_user@ $Remote_ip -p $Remote_port
    注意:这里需要输入远程服务器的password进行登录,但如果采用sshpass工具可以进行自动登录。具体可查阅sshpass相关用法
  5. 本地主机:打开地址 http://127.0.0.1:6006/ 即可获得在线更新的tensorboard数据

参考网址:链接: https://zhuanlan.zhihu.com/p/687904515.

缺点

对于远程服务器具有多个计算节点的情形,每运行一次代码每次都需要确定在哪个计算节点上进行运行,以进行端口的映射。

Wandb

我们可以通过Wandb离线模式解决以上困难。编写一个脚本通过拉取远程服务器上的文件,和文件变化列表来进行可视化数据的上传。

步骤

  1. 代码:确定加载训练数据的文件夹,并设置Wandb offline 模式
  2. 同步python代码fetch_file.py:根据本地和remote服务器的部署路径,维护一个列表,包含当前需要同步的数据路径和最新修改时间

wandb生成的同步目录均以‘offline-run’开头,找到所有需要离线目录的目录路径

def get_all_offline_run_directories(path):
    offline_run_dirs = []
    for root, dirs, files in os.walk(path):
        for dir_name in dirs:
            if dir_name.startswith('offline-run'):
                offline_run_dirs.append(os.path.join(root, dir_name))
    return offline_run_dirs

返回目录最新修改时间

def get_modification_time(path):
    return os.path.getmtime(path)

定义目录修改时间保存格式

def format_time(epoch_time):
    return datetime.fromtimestamp(epoch_time).strftime('%Y-%m-%d %H:%M:%S')
def parse_time(time_str):
    return datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')

读取存储同步路径和最新修改时间的列表

def read_csv(file_path):
    dirs_with_mtime = []
    with open(file_path, 'r') as file:
        reader = csv.reader(file)
        next(reader)  # Skip header
        for row in reader:
            dirs_with_mtime.append((row[0], datetime.strptime(row[1], '%Y-%m-%d %H:%M:%S')))
    return dirs_with_mtime
if __name__ == '__main__':

    remote_path = $Remote_path/results #远程结果目录

    local_path = $Local_path/results #本地映射的结果目录

    last_file = remote_path + "last_file.csv" #上次同步的结果目录
    sync_file = remote_path + "sync_file.txt" #本次需要同步的目录

    offline_run_directories = get_all_offline_run_directories(remote_path)

    new_dirs = [(directory, format_time(get_modification_time(directory))) for directory in
                               offline_run_directories]

    if not os.path.exists(last_file):
        # 如果CSV文件不存在,则将当前目录及其修改时间保存到CSV文件
        with open(last_file, 'w', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(['Directory', 'Last Modified'])
            for directory, mtime in new_dirs:
                writer.writerow([directory, mtime])
        print(f"Directory and modification times saved to {last_file}")
    else:
        # 读取之前保存的CSV文件
        old_dirs = read_csv(last_file)

        last_dirs = {dir: mtime for dir, mtime in old_dirs}

        dirs_to_sync = []
        for directory, mtime in new_dirs:
            mtime = parse_time(mtime)
            if directory not in last_dirs.keys() or last_dirs[directory] != mtime:
                directory = directory.replace(remote_path, local_path)
                dirs_to_sync.append(directory)

        if dirs_to_sync:
            with open(sync_file, 'w') as file:
                for dir in dirs_to_sync:
                    file.write(dir + '\n')
            print(f'路径列表已保存到 {dirs_to_sync}')

        with open(last_file, 'w', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(['Directory', 'Last Modified'])
            for directory, mtime in new_dirs:
                writer.writerow([directory, mtime])
        print(f"CSV 文件已更新 {last_file}")
  1. 本地wandb login:terminal输入wandb login,复制粘贴自己的api编号登录
  2. 本地自动拉取脚本sync_wandb.sh
#!/bin/bash

# 定义远程服务器信息
REMOTE_USER= $Remote_user
REMOTE_HOST= $Remote_ip
REMOTE_DIR= "$Remote_path/results"
LOCAL_DIR= "$Local_path/results"
INTERVAL=120  # 同步拉取时间间隔:2分钟
SYNC_FILE="${LOCAL_DIR}sync_file.txt"
FETCH_SCRIPT="${REMOTE_DIR}fetch_file.py"
SSH_PASSWORD= $Remote_password

# 捕捉中断信号
trap "echo 'Script interrupted. Exiting...'; exit" SIGINT SIGTERM

# 无限循环
while true; do
  # 运行远程脚本

  sshpass -p $SSH_PASSWORD ssh ${REMOTE_USER}@${REMOTE_HOST} "python3 $FETCH_SCRIPT"

  sshpass -p "$SSH_PASSWORD" rsync -avzhe "ssh" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" "$LOCAL_DIR/"
  
  # 检查 sync_file.txt 是否存在
    if [ -f "$SYNC_FILE" ]; then
      echo "读取 sync_file.txt 中的路径并处理"
      while IFS= read -r dir; do
        echo "处理目录: $dir"
        # 在这里添加你需要对每个目录执行的 wandb 操作
        # 假设是使用 wandb 命令同步目录
        wandb sync "$dir"
      done < "$SYNC_FILE"
      # 删除 sync_file.txt
      rm "$SYNC_FILE"
      echo "文件 $SYNC_FILE 已删除"
    else
      echo "文件 $SYNC_FILE 不存在"
    fi

  # 等待两分钟
  sleep $Interval
done

  1. 给予可执行权限:chmod +x sync_wandb.sh
  2. 运行同步脚本:./sync_wandb.sh
  3. 退出:ctrl + c

以上在macos中进行测试,windows中的命令行用法会稍有不同。

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值