使用 tmux 在云服务器上稳定运行多场景 3DGS 训练任务

使用 tmux 在云服务器上稳定运行多场景 3DGS 训练任务

摘要

在云服务器上进行 3D Gaussian Splatting、LGDU-Splatting、Mip-Splatting 等三维重建模型训练时,训练过程通常耗时较长。如果仅通过普通 SSH 终端直接运行 python train.py,一旦本地终端关闭或 SSH 连接中断,训练进程可能随之终止。为解决这一问题,本文介绍如何使用 tmux 管理长时间训练任务,并结合多场景并行训练、GPU 状态检查、日志保存与会话恢复等操作,构建一套适用于 3DGS 类任务的稳定训练流程。


1. 问题背景

在进行 3DGS 相关实验时,常见的训练启动方式如下:

bash 复制代码
ssh x3d-server
cd CYN
conda activate conda_envs/lgdu_mip_splatting/
cd LGDU-splatting-lgdu-mip/

python train.py ...

这种方式虽然简单直接,但存在一个明显问题:训练进程依赖当前 SSH 会话。

当本地终端被关闭、网络断开,或者 SSH 会话异常退出时,训练进程可能会收到终端挂断信号,从而被系统终止。对于耗时较长的 3DGS 类训练任务而言,这会造成训练中断、计算资源浪费以及实验结果不完整等问题。

因此,需要一种能够让训练进程脱离本地 SSH 终端生命周期的方式。tmux 正是解决此类问题的常用工具。


2. tmux 的作用

tmux 是一个终端复用工具,可以理解为运行在服务器上的"持久终端"。

普通 SSH 终端的生命周期如下:

text 复制代码
本地终端关闭 → SSH 会话断开 → 训练进程可能终止

使用 tmux 后,训练进程的生命周期变为:

text 复制代码
训练运行在服务器 tmux 会话中
本地终端关闭 → SSH 会话断开 → tmux 会话仍然存在 → 训练继续运行

因此,使用 tmux 后,即使本地关闭终端或网络临时中断,只要服务器本身没有关机、训练进程没有异常退出,任务通常可以继续执行直到结束。


3. 基本训练流程

3.1 登录服务器

首先通过 SSH 登录云服务器:

bash 复制代码
ssh x3d-server

其中 x3d-server 可以是用户在本地 SSH 配置文件中定义的服务器别名。例如,也可以写成:

bash 复制代码
ssh x3d@10.123.1.139

3.2 新建 tmux 会话

为每个训练任务创建一个独立的 tmux 会话:

bash 复制代码
tmux new -s train_XXXX

其中 train_XXXX 是 tmux 会话名称,建议根据训练场景命名。例如:

bash 复制代码
tmux new -s train_kitchen

或:

bash 复制代码
tmux new -s train_playroom

这样在同时训练多个场景时,可以通过会话名快速区分不同任务。


3.3 进入项目目录并激活环境

进入 tmux 会话后,切换到实验目录并激活 conda 环境:

bash 复制代码
cd CYN
conda activate conda_envs/lgdu_mip_splatting/
cd LGDU-splatting-lgdu-mip/

这里需要注意,tmux 本身是系统级终端工具,而 conda 环境是 Python 运行环境。二者并不冲突。实际训练时,是在 tmux 提供的持久终端中激活 conda 环境,然后再运行 Python 训练脚本。

如果在 tmux 中出现 conda activate 无法使用的情况,可以先手动加载 conda 初始化脚本:

bash 复制代码
source /data1/x3d/miniconda3/etc/profile.d/conda.sh
conda activate conda_envs/lgdu_mip_splatting/

具体路径应根据服务器上的 conda 安装位置调整。


4. 训练前查看 GPU 状态

在启动训练前,建议先检查 GPU 使用情况,避免多个任务抢占同一张显卡导致显存不足或训练效率下降。

可以使用如下命令输出格式化的 GPU 状态表:

bash 复制代码
nvidia-smi --query-gpu=index,name,memory.used,memory.total,memory.free,utilization.gpu,temperature.gpu,power.draw \
  --format=csv,noheader,nounits | \
awk -F ', ' '
BEGIN {
    printf "%-5s %-28s %-12s %-12s %-12s %-10s %-8s %-10s\n", \
           "GPU", "Name", "Used(MB)", "Total(MB)", "Free(MB)", "GPU-Util", "Temp", "Power"
    printf "%-5s %-28s %-12s %-12s %-12s %-10s %-8s %-10s\n", \
           "---", "----", "--------", "---------", "--------", "--------", "----", "-----"
}
{
    printf "%-5s %-28s %-12s %-12s %-12s %-10s %-8s %-10s\n", \
           $1, $2, $3, $4, $5, $6"%", $7"℃", $8"W"
}'

该命令会显示 GPU 编号、显卡名称、已用显存、总显存、空闲显存、GPU 利用率、温度和功耗等信息。相比直接查看 nvidia-smi,这种表格化输出更加适合在多卡服务器上快速判断当前资源状态。


5. 使用指定 GPU 启动训练

在多 GPU 服务器上,建议使用 CUDA_VISIBLE_DEVICES 为每个训练任务指定独立显卡。例如,将当前任务绑定到 GPU 1:

bash 复制代码
CUDA_VISIBLE_DEVICES=1 PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128 python train.py \
  --source_path "/data1/x3d/CYN/scenes/360_v2/kitchen" \
  --model_path "/data1/x3d/CYN/LGDU-splatting-lgdu-mip/output/kitchen/kitchen_eval_lgdu_smip_nv6_res1" \
  --eval \
  --disable_viewer \
  --data_device cpu \
  --resolution 1 \
  --test_iterations -1 \
  --checkpoint_iterations 7000 15000 30000 \
  --densify_max_points_per_stage 0 \
  --line_tracks_path "/data1/x3d/CYN/lines_file/kitchen/kitchen_nv6/alltracks.txt" \
  --line_min_visible_views 6 \
  --line_confidence_mode visibility \
  --line_confidence_power 1.0 \
  --line_confidence_min 0.05 \
  --line_multiview_edge_support_enable \
  --line_multiview_edge_max_views 32 \
  --line_multiview_edge_min_views 2 \
  --line_confidence_percentile 70 \
  --line_edge_sigma_px 2.0 \
  --line_edge_sample_count 16 \
  --line_edge_min_valid_ratio 0.5 \
  --line_edge_min_projected_length 4.0 \
  --line_photo_reweight_enable \
  --line_photo_lambda_adaptive \
  --line_photo_lambda_target_ratio 0.03 \
  --line_photo_lambda_adaptive_min 0.0 \
  --line_photo_lambda_adaptive_max 0.02 \
  --line_photo_start_iter 3000 \
  --line_photo_end_iter 15000 \
  --line_photo_sample_count 32 \
  --line_photo_mask_dilation_px 2 \
  --line_photo_min_valid_ratio 0.5 \
  --line_photo_min_projected_length 4.0 \
  --line_photo_charbonnier_eps 0.001 \
  --line_densify_mode score \
  --line_densify_start_iter 500 \
  --line_densify_end_iter 15000 \
  --line_densify_score_boost 0.5 \
  --line_densify_confidence_power 1.0 \
  --line_densify_confidence_max 3.0 \
  --line_densify_low_alpha_boost 0.5 \
  --line_unpool_enable \
  --line_unpool_start_iter 3000 \
  --line_unpool_end_iter 12000 \
  --line_unpool_interval 500 \
  --line_unpool_samples_per_line 2 \
  --line_unpool_max_points 512 \
  --line_unpool_candidate_factor 4 \
  --line_unpool_score_threshold 0.10 \
  --line_unpool_opacity_init 0.04 \
  --line_unpool_scale_factor 0.6 \
  --line_unpool_alpha_target 0.08 \
  --line_unpool_low_alpha_boost 0.5 \
  --mip_filter_enable \
  --mip_filter_scale 0.4472135955 \
  --mip_filter_margin 0.15 \
  --mip_filter_update_interval 100 \
  --smip_enable \
  --smip_filter_base_weight 0.0 \
  --smip_filter_gain 1.2 \
  --smip_filter_max_weight 2.0 \
  --smip_opacity_compensation 0.25 \
  --smip_low_alpha_boost 0.5 \
  --smip_alpha_target 0.08 \
  2>&1 | tee train_kitchen.log

该命令中有几个关键点:

  1. CUDA_VISIBLE_DEVICES=1 表示当前训练只使用物理编号为 1 的 GPU。
  2. PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128 用于调整 PyTorch CUDA 显存分配策略,在一定程度上缓解显存碎片问题。
  3. --model_path 指定训练结果输出目录。
  4. --disable_viewer 禁用可视化 viewer,有助于避免端口或图形界面相关问题。
  5. 2>&1 | tee train_kitchen.log 表示同时将标准输出和标准错误输出写入日志文件,并在终端实时显示。

6. 日志记录与查看

训练命令末尾使用:

bash 复制代码
2>&1 | tee train_kitchen.log

可以将训练过程中的输出保存到日志文件中。这样即使后续不进入 tmux 会话,也可以直接通过日志查看训练进度。

查看日志时应使用:

bash 复制代码
tail -f train_kitchen.log

而不是直接使用:

bash 复制代码
tee train_kitchen.log

需要注意:tee 的主要作用是在训练运行时将输出写入日志文件;而查看日志应使用 catlesstail 等命令。对于正在持续写入的训练日志,推荐使用:

bash 复制代码
tail -f train_kitchen.log

退出日志查看时按:

text 复制代码
Ctrl + C

此处的 Ctrl + C 只会退出 tail -f,不会终止 tmux 中正在运行的训练进程。


7. 从 tmux 中安全退出

训练启动后,不应直接关闭 SSH 终端,也不应按 Ctrl + C。如果希望离开当前 tmux 会话但保持训练继续运行,应使用 detach 操作。

标准操作为:

text 复制代码
Ctrl + B

松开后再按:

text 复制代码
D

即:

text 复制代码
Ctrl + B,然后 D

执行成功后,会返回普通 SSH 终端,并看到类似信息:

text 复制代码
[detached from train_kitchen]

此时训练任务仍然在服务器 tmux 会话中继续运行。随后可以安全退出 SSH:

bash 复制代码
exit

或者直接关闭本地终端。


8. 当 Ctrl+B 不起作用时的处理方法

在实际使用中,可能会遇到 Ctrl+B 没有明显反应的情况。首先需要明确,Ctrl+B 本身不会在屏幕上显示任何内容,它只是 tmux 的前缀键。正确操作是先按 Ctrl+B,松开后再按 D

如果仍然无法 detach,可以新开一个本地终端,再次 SSH 登录服务器:

bash 复制代码
ssh x3d-server

查看当前 tmux 会话:

bash 复制代码
tmux ls

例如输出:

text 复制代码
train_kitchen: 1 windows
train_playroom: 1 windows

然后通过命令强制 detach 指定会话:

bash 复制代码
tmux detach-client -s train_kitchen

如果会话名为 train_XXXX,则执行:

bash 复制代码
tmux detach-client -s train_XXXX

这种方式适用于当前 tmux 终端被训练输出占据、快捷键无法正常响应,或者本地终端输入异常的情况。


9. 查看已有训练会话

可以使用以下命令查看当前服务器上属于当前用户的 tmux 会话:

bash 复制代码
tmux ls

示例输出:

text 复制代码
train_playroom: 1 windows (created Wed Jun 24 07:39:17 2026) [124x23]

这说明当前存在一个名为 train_playroom 的 tmux 会话。

重新进入该训练会话:

bash 复制代码
tmux attach -t train_playroom

或使用简写:

bash 复制代码
tmux a -t train_playroom

查看完训练情况后,如果不想终止任务,应继续使用 detach 操作退出:

text 复制代码
Ctrl + B,然后 D

10. 多场景并行训练

在 3DGS 类实验中,常常需要同时训练多个场景,例如 kitchenplayroomgardenbicycle 等。使用 tmux 时,推荐采用"一个场景一个 tmux 会话"的方式管理训练任务。

例如:

bash 复制代码
tmux new -s train_kitchen

启动 kitchen 场景训练后 detach。

然后新开另一个终端或在普通 SSH 终端中继续创建新会话:

bash 复制代码
tmux new -s train_playroom

再启动 playroom 场景训练。

对于多个任务,应注意以下几点:

10.1 每个任务使用不同的 tmux 会话名

推荐命名方式:

text 复制代码
train_kitchen
train_playroom
train_garden
train_bicycle

这样便于通过 tmux ls 查看和管理。

10.2 每个任务使用不同的输出目录

不同训练任务的 --model_path 必须不同。例如:

bash 复制代码
--model_path "/data1/x3d/CYN/LGDU-splatting-lgdu-mip/output/kitchen/kitchen_eval_lgdu_smip_nv6_res1"

和:

bash 复制代码
--model_path "/data1/x3d/CYN/LGDU-splatting-lgdu-mip/output/playroom/playroom_eval_lgdu_smip_nv6_res1"

如果多个任务写入同一个输出目录,可能导致 checkpoint、point cloud、配置文件或日志互相覆盖,进而影响实验结果的可靠性。

10.3 每个任务使用不同的日志文件

推荐日志命名方式:

text 复制代码
train_kitchen.log
train_playroom.log
train_garden.log

避免多个任务写入同一个日志文件,导致日志内容混乱。

10.4 多 GPU 环境下合理分配显卡

如果服务器有多张 GPU,可以为不同任务指定不同 GPU:

bash 复制代码
CUDA_VISIBLE_DEVICES=0 python train.py ...
bash 复制代码
CUDA_VISIBLE_DEVICES=1 python train.py ...
bash 复制代码
CUDA_VISIBLE_DEVICES=2 python train.py ...

启动任务前应使用前文中的 GPU 状态检查命令或直接执行:

bash 复制代码
nvidia-smi

确认目标 GPU 的显存和利用率。


11. 停止某个训练任务

如果需要停止某个训练任务,推荐先进入对应 tmux 会话:

bash 复制代码
tmux a -t train_kitchen

确认当前界面确实是目标训练任务后,再按:

text 复制代码
Ctrl + C

这样可以终止当前训练进程。

如果需要直接关闭整个 tmux 会话,可以执行:

bash 复制代码
tmux kill-session -t train_kitchen

需要注意,tmux kill-session 会直接关闭指定会话,其中正在运行的训练进程也会被终止。因此该命令应谨慎使用。


12. 推荐的标准化操作流程

综合上述内容,推荐形成如下标准工作流。

12.1 启动训练

bash 复制代码
ssh x3d-server
tmux new -s train_kitchen

cd CYN
conda activate conda_envs/lgdu_mip_splatting/
cd LGDU-splatting-lgdu-mip/

nvidia-smi

CUDA_VISIBLE_DEVICES=1 PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128 python train.py \
  --source_path "/data1/x3d/CYN/scenes/360_v2/kitchen" \
  --model_path "/data1/x3d/CYN/LGDU-splatting-lgdu-mip/output/kitchen/kitchen_eval_lgdu_smip_nv6_res1" \
  --eval \
  --disable_viewer \
  --data_device cpu \
  --resolution 1 \
  --test_iterations -1 \
  --checkpoint_iterations 7000 15000 30000 \
  --densify_max_points_per_stage 0 \
  --line_tracks_path "/data1/x3d/CYN/lines_file/kitchen/kitchen_nv6/alltracks.txt" \
  --line_min_visible_views 6 \
  --line_confidence_mode visibility \
  --line_confidence_power 1.0 \
  --line_confidence_min 0.05 \
  --line_multiview_edge_support_enable \
  --line_multiview_edge_max_views 32 \
  --line_multiview_edge_min_views 2 \
  --line_confidence_percentile 70 \
  --line_edge_sigma_px 2.0 \
  --line_edge_sample_count 16 \
  --line_edge_min_valid_ratio 0.5 \
  --line_edge_min_projected_length 4.0 \
  --line_photo_reweight_enable \
  --line_photo_lambda_adaptive \
  --line_photo_lambda_target_ratio 0.03 \
  --line_photo_lambda_adaptive_min 0.0 \
  --line_photo_lambda_adaptive_max 0.02 \
  --line_photo_start_iter 3000 \
  --line_photo_end_iter 15000 \
  --line_photo_sample_count 32 \
  --line_photo_mask_dilation_px 2 \
  --line_photo_min_valid_ratio 0.5 \
  --line_photo_min_projected_length 4.0 \
  --line_photo_charbonnier_eps 0.001 \
  --line_densify_mode score \
  --line_densify_start_iter 500 \
  --line_densify_end_iter 15000 \
  --line_densify_score_boost 0.5 \
  --line_densify_confidence_power 1.0 \
  --line_densify_confidence_max 3.0 \
  --line_densify_low_alpha_boost 0.5 \
  --line_unpool_enable \
  --line_unpool_start_iter 3000 \
  --line_unpool_end_iter 12000 \
  --line_unpool_interval 500 \
  --line_unpool_samples_per_line 2 \
  --line_unpool_max_points 512 \
  --line_unpool_candidate_factor 4 \
  --line_unpool_score_threshold 0.10 \
  --line_unpool_opacity_init 0.04 \
  --line_unpool_scale_factor 0.6 \
  --line_unpool_alpha_target 0.08 \
  --line_unpool_low_alpha_boost 0.5 \
  --mip_filter_enable \
  --mip_filter_scale 0.4472135955 \
  --mip_filter_margin 0.15 \
  --mip_filter_update_interval 100 \
  --smip_enable \
  --smip_filter_base_weight 0.0 \
  --smip_filter_gain 1.2 \
  --smip_filter_max_weight 2.0 \
  --smip_opacity_compensation 0.25 \
  --smip_low_alpha_boost 0.5 \
  --smip_alpha_target 0.08 \
  2>&1 | tee train_kitchen.log

12.2 离开 tmux 但保持训练运行

text 复制代码
Ctrl + B,然后 D

12.3 查看已有 tmux 会话

bash 复制代码
tmux ls

12.4 重新进入训练会话

bash 复制代码
tmux a -t train_kitchen

12.5 查看日志

bash 复制代码
tail -f train_kitchen.log

12.6 从另一个终端 detach 指定会话

bash 复制代码
tmux detach-client -s train_kitchen

13. 总结

在云服务器上运行 3DGS 类训练任务时,直接依赖普通 SSH 终端存在训练中断风险。通过 tmux 可以将训练任务放入服务器端持久会话中,使训练过程不再依赖本地终端的连接状态。

在实际实验中,推荐采用以下规范:

  1. 每个训练场景创建一个独立的 tmux 会话;
  2. 每个任务使用独立的输出目录;
  3. 每个任务使用独立日志文件;
  4. 多 GPU 环境下使用 CUDA_VISIBLE_DEVICES 指定显卡;
  5. 训练启动前使用 nvidia-smi 检查 GPU 状态;
  6. 使用 tee 保存训练日志,使用 tail -f 查看训练日志;
  7. 离开训练界面时使用 Ctrl+B 后接 D,而不是关闭终端或按 Ctrl+C

通过上述流程,可以较为稳定地管理多个 3DGS 训练任务,提高服务器资源利用率,并降低因 SSH 断开导致训练中断的风险。