深度学习模型训练往往需要数小时甚至数天时间,而浏览器标签页的意外关闭或网络波动都可能导致前功尽弃。本文将介绍一套在AutoDL平台的Jupyter环境中,利用tmux实现训练任务持久化的完整解决方案。
在云端GPU服务器上训练模型时,我们常遇到几个典型问题:
tmux作为终端复用工具,可以创建持久化的会话,即使关闭浏览器或断开网络连接,训练任务也能继续在服务器后台运行。与简单的nohup方案相比,tmux提供了更强大的功能:
| 特性 | nohup | tmux |
|---|---|---|
| 会话持久性 | 基础 | 完整会话管理 |
| 多窗口支持 | 不支持 | 支持 |
| 日志查看 | 仅文件输出 | 实时交互 |
| 会话恢复 | 不可恢复 | 完整恢复 |
在Jupyter的终端中(Launcher → Terminal),执行以下命令创建新会话:
bash复制tmux new -s model_train
这个命令会创建一个名为"model_train"的新会话。在这个会话中,你可以正常启动训练脚本:
bash复制python train.py --batch_size 32 --epochs 100
需要暂时离开时,按下组合键:
Ctrl+b(tmux的前缀键)d(detach的意思)这样会话会在后台继续运行。要重新连接会话:
bash复制tmux attach -t model_train
查看所有会话:
bash复制tmux ls
终止会话(在会话内部时):
exit或按Ctrl+d强制终止会话(从外部):
bash复制tmux kill-session -t model_train
注意:强制终止可能导致训练数据丢失,建议仅在必要时使用
在AutoDL环境中可能会遇到tmux滚动问题,解决方法:
bash复制# 在~/.tmux.conf中添加
set -g terminal-overrides 'xterm*:smcup@:rmcup@'
同时实现后台运行和日志保存的最佳实践:
bash复制tmux new -s train_session
# 在tmux会话中
python train.py 2>&1 | tee training.log
这样既能在终端实时查看输出,又能将日志保存到文件。退出会话后,可以通过以下命令查看日志:
bash复制tail -f training.log
在tmux会话中创建监控面板:
Ctrl+b然后按" 水平分割窗口Ctrl+b然后按% 垂直分割窗口bash复制# 面板1:训练任务
python train.py
# 面板2:GPU监控
watch -n 1 nvidia-smi
# 面板3:系统资源
htop
窗口切换快捷键:
Ctrl+b → 方向键:在面板间导航Ctrl+b → z:最大化当前面板(再次按恢复)创建一键启动脚本start_train.sh:
bash复制#!/bin/bash
SESSION_NAME="model_train_$(date +%s)"
# 检查是否已有会话存在
if tmux has-session -t $SESSION_NAME 2>/dev/null; then
echo "Session already exists. Attaching..."
tmux attach -t $SESSION_NAME
else
# 创建新会话并启动训练
tmux new -s $SESSION_NAME -d
tmux send-keys -t $SESSION_NAME "conda activate pytorch" C-m
tmux send-keys -t $SESSION_NAME "cd /root/project && python train.py" C-m
echo "New session created. Attaching..."
tmux attach -t $SESSION_NAME
fi
给脚本添加执行权限:
bash复制chmod +x start_train.sh
创建检查脚本check_train.sh:
bash复制#!/bin/bash
# 检查GPU使用情况
echo "=== GPU Usage ==="
nvidia-smi --query-gpu=utilization.gpu,memory.used --format=csv
# 检查运行中的训练会话
echo -e "\n=== Active tmux Sessions ==="
tmux ls
# 检查训练日志更新
echo -e "\n=== Training Log (last 5 lines) ==="
tail -n 5 /root/project/training.log 2>/dev/null || echo "No training log found"
最佳实践是在训练代码中实现检查点保存,然后通过API安全终止:
python复制# 在训练脚本中添加信号处理
import signal
import sys
def save_checkpoint(signum, frame):
print("\nReceived termination signal, saving checkpoint...")
# 保存模型和状态的代码
sys.exit(0)
signal.signal(signal.SIGTERM, save_checkpoint)
signal.signal(signal.SIGINT, save_checkpoint)
会话无法连接:
bash复制# 先尝试软连接
tmux attach -t session_name
# 如果失败,尝试强制连接
tmux attach -t session_name -d
GPU内存泄漏:
bash复制# 查找占用GPU的进程
nvidia-smi
# 终止特定进程
kill -9 PID
磁盘空间不足:
bash复制# 检查磁盘使用
df -h
# 清理缓存
rm -rf ~/.cache/*
在实际项目中,我通常会为每个实验创建独立的tmux会话,命名规则如"exp1_resnet50_bs32",这样即使同时进行多个实验也能清晰管理。一个实用小技巧是在会话描述中记录关键参数:
bash复制tmux set-option -t session_name status-left "# session_name | LR=1e-3 | BS=32"