告别训练中断:Linux 模型训练会话持久化方案
在深度学习模型训练过程中,训练任务通常需要持续数小时甚至数天。在 Linux 服务器环境下,网络中断、SSH 连接断开等问题经常导致训练进程异常终止,造成计算资源和时间的浪费。
为了解决这个问题,Linux 提供了多种会话管理解决方案,可以让训练任务在后台持续运行。本文将简单介绍四种主流的 Linux 会话管理工具的使用:Screen、Tmux、Nohup 和 Systemd。
1、Screen
Screen 是一个经典的终端复用工具,允许在单个终端中创建多个会话和窗口,程序可以在后台持续运行即使断开连接,特别适合长时间运行的任务如机器学习训练。
基本会话管理
# 创建命名会话
screen -S <会话名称>
screen -S llm_train # 创建名为 llm_train 的会话
# 列出所有 screen 会话
screen -ls # 显示所有会话及其状态
screen -list # 同上,完整形式
# 重新连接到会话
screen -r llm_train # 连接到指定会话
screen -r 123456 # 也可以用进程 ID 连接
# 强制连接到会话(即使已被连接)
screen -d -r llm_train # 先分离再连接
screen -D -r llm_train # 强制分离其他连接,然后连接
# 共享会话(多人同时查看)
screen -x llm_train # 共享连接,多个用户可同时查看
# 创建会话并立即分离(后台创建)
screen -dmS llm_train # 创建会话但不进入
# 杀死指定会话
screen -S llm_train -X quit # 或者在会话内输入 exit
# 向会话发送命令
screen -S llm_train -X stuff "python train.py\n"
窗口和面板操作
Ctrl+a d # 分离当前会话(detach)
Ctrl+a c # 创建新窗口
Ctrl+a n # 切换到下一个窗口
Ctrl+a p # 切换到上一个窗口
Ctrl+a " # 显示窗口列表
Ctrl+a A # 重命名当前窗口
2、Tmux
Tmux(Terminal Multiplexer)是 Screen 的现代化替代品,功能更加强大,支持更灵活的窗格分割、会话管理和自定义配置,是目前最流行的终端多任务管理工具。
基本会话管理
# 创建新会话
tmux new -s llm_train
tmux new-session -d -s llm_train
# 查看会话列表
tmux ls
tmux list-sessions
# 连接会话
tmux a -t llm_train
tmux attach-session -t llm_train
# 重命名会话
tmux rename-session -t old_name new_name
# 创建带有预定义布局的会话
tmux new-session -d -s llm_train
tmux split-window -h
tmux split-window -v
tmux attach-session -t llm_train
# 发送命令到指定会话
tmux send-keys -t llm_train:0 'cd /project && python train.py' Enter
# 捕获面板内容到文件
tmux capture-pane -t llm_train:0 -p > llm_training_log.txt
实际应用示例
# 创建一个多面板的深度学习训练环境
tmux new-session -d -s train
# 分割窗口:左侧训练,右上监控GPU,右下查看日志
tmux split-window -h
tmux split-window -v
# 在各个面板中执行不同命令
tmux send-keys -t train:0.0 'python train.py' Enter
tmux send-keys -t train:0.1 'watch -n 1 nvidia-smi' Enter
tmux send-keys -t train:0.2 'tail -f train.log' Enter
# 连接到会话
tmux attach-session -t train
窗口和面板操作
Ctrl+b d # 分离会话
Ctrl+b c # 创建新窗口
Ctrl+b , # 重命名当前窗口
Ctrl+b n # 下一个窗口
Ctrl+b p # 上一个窗口
Ctrl+b % # 垂直分割面板
Ctrl+b " # 水平分割面板
Ctrl+b o # 切换面板
Ctrl+b x # 关闭当前面板
配置文件示例
可以通过创建 ~/.tmux.conf
文件来自定义 Tmux 的行为和外观。以下是一个示例配置文件:
# 设置前缀键为 Ctrl+a(类似Screen)
set -g prefix C-a
unbind C-b
# 启用鼠标支持
set -g mouse on
# 设置历史缓冲区大小
set -g history-limit 10000
# 快速重载配置文件
bind r source-file ~/.tmux.conf \; display "Config reloaded!"
# 状态栏配置
set -g status-bg blue
set -g status-fg white
3、Nohup
Nohup(no hang up)是一个简单而强大的命令行工具,允许进程在用户退出终端后继续运行,通过忽略 SIGHUP 信号来实现进程的持久化运行。
基本使用方法
# 基本语法
nohup command &
# 启动训练脚本(输出默认重定向到 nohup.out)
nohup python train.py &
# 重定向输出到指定文件(推荐用法)
nohup python train.py > train.log 2>&1 &
# 同时启动多个训练任务
nohup python train_model1.py > model1.log 2>&1 &
nohup python train_model2.py > model2.log 2>&1 &
nohup python train_model3.py > model3.log 2>&1 &
# 批量启动(使用循环)
for i in {1..5}; do
nohup python train_fold_$i.py > fold_$i.log 2>&1 &
done
# 设置进程优先级
nohup nice -n 10 python train.py > train.log 2>&1 &
# 避免产生默认的 nohup.out 文件
nohup python train.py > /dev/null 2>&1 &
进程管理和监控
# 查看当前shell的后台任务
jobs
# 查看所有python相关进程
ps aux | grep python
# 查找特定训练进程
ps aux | grep train.py
pgrep -f train.py # 只显示进程ID
pgrep -fl train.py # 显示进程ID和命令
# 查看进程详细信息
ps -ef | grep python
# 实时查看输出日志
tail -f train.log
# 查看日志最后几行
tail -n 50 train.log
# 搜索日志中的关键信息
grep -i "error" train.log
grep -i "epoch" train.log
# 同时监控多个日志文件
tail -f model1.log model2.log model3.log
进程终止和清理
# 根据进程名停止后台任务
kill $(pgrep -f train.py)
# 停止所有包含特定关键词的进程
pkill -f train.py
# 强制终止进程(使用PID)
kill -9 PID
# 强制终止进程(使用进程名)
pkill -9 -f train.py
# 检查进程是否还在运行
if pgrep -f train.py > /dev/null; then
echo "训练进程正在运行"
else
echo "训练进程已停止"
fi
# 清空过大的日志文件
> nohup.out
> train.log
实用脚本示例
# 启动训练并记录启动信息
start_training() {
echo "开始训练: $(date)" >> train.log
nohup python train.py >> train.log 2>&1 &
echo "训练进程PID: $!" >> train.log
}
# 检查训练状态
check_training() {
if pgrep -f train.py > /dev/null; then
echo "训练正在进行中..."
echo "最新日志:"
tail -n 5 train.log
else
echo "训练已完成或停止"
fi
}
# 优雅停止训练
stop_training() {
PID=$(pgrep -f train.py)
if [ -n "$PID" ]; then
echo "正在停止训练进程 $PID..."
kill -TERM $PID
sleep 5
if pgrep -f train.py > /dev/null; then
echo "强制停止进程..."
kill -9 $PID
fi
echo "训练已停止"
else
echo "未找到训练进程"
fi
}
4、Systemd
Systemd 是现代 Linux 系统的系统和服务管理器,它不仅可以管理系统启动过程,还可以作为强大的进程管理工具来运行和监控长时间任务。
基本服务管理
# 查看所有服务状态
systemctl list-units --type=service
systemctl status # 系统整体状态
# 查看特定服务状态
systemctl status llm-training
systemctl is-active llm-training # 检查服务是否运行
systemctl is-enabled llm-training # 检查服务是否开机启动
# 启动、停止、重启服务
systemctl start llm-training
systemctl stop llm-training
systemctl restart llm-training
systemctl reload llm-training # 重载配置(如果服务支持)
# 启用、禁用开机自启动
systemctl enable llm-training
systemctl disable llm-training
# 查看服务日志
journalctl -u llm-training
journalctl -u llm-training -f # 实时跟踪日志
journalctl -u llm-training --since "1 hour ago"
创建自定义服务
创建服务文件 /etc/systemd/system/llm-training.service
:
[Unit]
Description=LLM Training Service
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=mluser
Group=mluser
WorkingDirectory=/home/mluser/project
Environment=CUDA_VISIBLE_DEVICES=0,1
ExecStart=/usr/bin/python3 /home/mluser/project/train.py
ExecStop=/bin/kill -SIGTERM $MAINPID
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
# 资源限制
LimitNOFILE=65536
MemoryMax=32G
CPUQuota=400%
[Install]
WantedBy=multi-user.target
高级服务配置
# 重载 systemd 配置
systemctl daemon-reload
# 创建用户级服务(运行在用户会话中)
mkdir -p ~/.config/systemd/user
# 将服务文件放在 ~/.config/systemd/user/ 目录
systemctl --user daemon-reload
systemctl --user start llm-training
systemctl --user enable llm-training
# 设置服务依赖关系
# 在服务文件中添加:
# After=gpu-driver.service
# Requires=database.service
实际应用示例
创建一个完整的深度学习训练服务:
# /etc/systemd/system/distributed-training.service
[Unit]
Description=Distributed Deep Learning Training
After=network.target docker.service
Requires=docker.service
[Service]
Type=forking
User=root
WorkingDirectory=/opt/ml-training
ExecStartPre=/usr/bin/docker pull pytorch/pytorch:latest
ExecStart=/usr/bin/docker run -d \
--name training-container \
--gpus all \
-v /opt/ml-training:/workspace \
-v /data:/data:ro \
pytorch/pytorch:latest \
python /workspace/distributed_train.py
ExecStop=/usr/bin/docker stop training-container
ExecStopPost=/usr/bin/docker rm training-container
Restart=on-failure
RestartSec=30
TimeoutStartSec=300
# 环境变量
Environment=NCCL_DEBUG=INFO
Environment=MASTER_ADDR=localhost
Environment=MASTER_PORT=12355
# 安全和资源限制
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/opt/ml-training /tmp
MemoryMax=64G
[Install]
WantedBy=multi-user.target
服务监控和调试
# 查看服务运行时间和资源使用
systemctl show llm-training --property=ActiveState,SubState,ExecMainPID
systemctl show llm-training --property=MemoryCurrent,CPUUsageNSec
# 检查服务配置
systemctl cat llm-training
systemctl show llm-training
# 分析服务启动时间
systemd-analyze blame
systemd-analyze critical-chain llm-training.service
# 监控系统资源
systemctl status
systemd-cgtop # 类似 htop,显示 cgroup 资源使用情况
定时任务和依赖管理
# 创建定时器(替代 cron)
# /etc/systemd/system/model-backup.timer
[Unit]
Description=Model Backup Timer
Requires=model-backup.service
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
# 启用定时器
systemctl enable model-backup.timer
systemctl start model-backup.timer
systemctl list-timers # 查看所有定时器
日志管理
# 配置日志大小和保留时间
# 编辑 /etc/systemd/journald.conf
SystemMaxUse=1G
MaxRetentionSec=1month
# 查看和管理日志
journalctl --disk-usage # 查看日志占用空间
journalctl --vacuum-time=2weeks # 删除2周前的日志
journalctl --vacuum-size=100M # 限制日志大小到100MB
# 导出日志
journalctl -u llm-training -o json > training.log
Systemd 相比 Screen 和 Tmux 的优势在于提供了系统级的进程管理、自动重启机制、资源控制、安全隔离和结构化日志记录,特别适合生产环境中的长时间运行任务和服务部署。