第三章:持久会话
SSH 陷阱
合上笔记本,训练就死了
训练死了。
你没有 kill 它,没有按 Ctrl+C,也没有显存不足。SSH 连接断开了——你在那个 SSH 会话里启动的所有进程都收到了 SIGHUP 信号,然后终止了。你那个 14 小时的训练,跑了 47 分钟就死了,原因是你合上了笔记本、WiFi 断了、或者 VPN 抽风了。
这就是 SSH 陷阱,每个研究者至少会踩一次。它是人们在实验室熬夜的原因——坐在终端前面,训练在跑,连笔记本都不敢碰。它是人们在第二块屏幕上保持一个 SSH 窗口死活不关的原因。它是人们在周五晚上离开前启动训练,然后在手机上强迫症般地检查,直到手机上的 SSH 会话也断了的原因。
问题是根本性的:SSH 把你的进程绑定在你的连接上。连接断了,进程就死了。这是设计如此——Unix 会话就是这样工作的。你的训练脚本是 SSH shell 的子进程。杀掉父进程,子进程也跟着死。
你需要一种方法,把进程和 SSH 连接解耦。你需要训练在服务器上独立运行,不管你有没有连着,不管笔记本开没开,不管手机有没有信号,不管你醒没醒。
这个工具叫 tmux。
Tmux 的工作原理
Tmux(终端复用器)用一个简单的架构技巧解决了 SSH 陷阱:它把服务端和客户端分开了。
当你在一台机器上启动 tmux 时,它会在后台创建一个服务端进程。在这个服务端里,你创建会话——每个会话就像一个虚拟终端。你实际的终端(通过 SSH 连上来的那个)只是一个客户端,用来显示会话里正在发生什么。
看起来是这样的:
SSH 客户端
你的终端
SSH 隧道
可断开
tmux 服务端
始终运行
当 SSH 连接断开时,tmux 服务端继续运行,里面的所有进程(训练、评估等)完全不受影响:
SSH 客户端
已断开
连接中断
无所谓
tmux 服务端
继续运行!
当你的 SSH 连接断开时,客户端消失了——但 tmux 服务端继续运行。每个 tmux 会话里的每个进程都像什么都没发生一样继续执行。你的训练脚本不知道也不在乎你断开了。它跟 tmux 服务端通信,不跟你的 SSH 客户端通信。
当你重新 SSH 进来时,你只需要把一个新的客户端连接到同一个 tmux 服务端。你从离开的地方完全接上。终端输出还在那里。进程还在跑。什么都没丢。
这就是为什么 tmux 改变了一切。你的进程不再活在 SSH 连接里,它们活在 tmux 里。SSH 只是你用来查看它们的窗口。
核心命令
你只需要六个命令,不多不少。
创建命名会话
tmux new -s train这会创建一个叫 train 的新 tmux 会话,并自动连入。你会注意到终端底部多了一条绿色状态栏——这是 tmux 的状态栏,确认你已经在会话里面了。
永远给会话命名。不带 -s 的 tmux new 会创建名为 0、1、2 的会话。当你同时跑三个训练时,你得知道哪个是哪个。给它们起名:train、eval、download、experiment01——什么有意义就用什么。
脱离会话
Ctrl+b 然后 d这是一个两步按键序列。先按 Ctrl+b(按住 Ctrl,按 b,松开两个键),然后按 d。会话从你屏幕上消失了——但它还在服务器上运行。你回到了普通的 SSH 命令行。
脱离不是关闭。tmux 会话和里面的一切继续运行。这就是重点。
列出会话
tmux ls显示这台机器上所有运行中的 tmux 会话:
train: 1 windows (created Mon Mar 23 14:30:12 2026)
eval: 1 windows (created Mon Mar 23 15:45:03 2026)两个会话,都在跑。你可以看到每个的创建时间。
重新连入会话
tmux attach -t train你回到了 train 会话里。一切如你离开时一样。你不在时产生的终端输出都在——往上翻就行。
终止会话
tmux kill-session -t train这会真正停止会话并杀死里面的所有进程。当你用完一个会话时用这个——实验跑完了、下载完成了。别让僵尸会话堆在服务器上。
就这些
六个命令:
| 命令 | 功能 |
|---|---|
tmux new -s 名称 | 创建命名会话 |
Ctrl+b d | 脱离(会话继续运行) |
tmux ls | 列出所有会话 |
tmux attach -t 名称 | 重新连入会话 |
tmux kill-session -t 名称 | 终止会话及其进程 |
tmux 还能做的其他事情——分屏、面板、窗口、脚本——有用但不是现在必需的。之后可以慢慢学。这六个命令足以应对本指南的所有场景。
实测验证
证明它能用。这不是选做——你需要亲眼看到。
SSH 到服务器
ssh lab-server创建 tmux 会话
tmux new -s test你现在在一个叫 test 的 tmux 会话里。底部应该能看到绿色状态栏。
启动一个长时间运行的进程
python3 -c "import time; [print(i) or time.sleep(1) for i in range(999)]"你会看到数字一秒一个往上数:0、1、2、3……
至少看到数到 5。这就是你的"训练任务"。如果没有 tmux,你现在关掉 SSH 连接,这个进程立刻就死了。
脱离会话
按 Ctrl+b,然后按 d。
计数消失了。你回到了普通 SSH 命令行。会话还在跑——你只是看不到了。
断开连接
关闭 SSH 连接:
exit然后彻底关闭你的终端。如果你在手机上,关掉 Termius。如果你在笔记本上,关掉终端应用。SSH 连接没了,彻底断了。
等一等
等 30 秒。去倒杯水。看看手机。干点别的。重点是:你跟服务器之间已经没有任何连接了。你的"训练"(计数器)独自在那里。
重新连接
重新打开终端,SSH 回去:
ssh lab-server重新连入
tmux attach -t test见证奇迹
计数器还在跑。它没停过。如果你脱离时数到了 5,等了 30 秒,现在它已经到了 35。你断开的整个过程中它一直在数。
这就是 tmux 的核心承诺:你的进程不会因为断开连接而终止。计数器不知道你离开了,也不知道你回来了。它在 tmux 服务端里一直跑着,完全不在乎你的 SSH 连接状态。
用 Ctrl+C 停掉计数器,然后终止测试会话:
tmux kill-session -t test手机友好的 Tmux
你会通过 Termius 在手机上使用 tmux。小屏幕、没有物理键盘、触屏输入。做几个调整会好用很多。
开启鼠标模式
默认情况下,tmux 对鼠标事件的拦截方式可能会让手机终端感到困惑。开启鼠标模式可以让滑动滚屏和选择文本变得自然。在服务器上,创建或编辑 ~/.tmux.conf:
echo 'set -g mouse on' >> ~/.tmux.conf如果你已经有在运行的 tmux 会话,重新加载配置:
tmux source-file ~/.tmux.conf开启鼠标模式后,你可以在手机上通过滑动来滚屏浏览终端输出——比键盘操作方便多了。
无鼠标滚屏
如果鼠标滚屏在你的终端里不好使(有些手机客户端有兼容性问题),用 tmux 的复制模式:
- 按
Ctrl+b,然后按[—— 进入复制模式。 - 用方向键(或滑动,取决于你的终端)向上翻看输出。
- 按
q退出复制模式,回到正常状态。
复制模式是你在手机上查看报错信息和训练日志的方式。现在就练一练,别等到凌晨两点出事的时候手忙脚乱。
会话名称要短
在手机屏幕上列出会话时,长名字会被截断。保持简短且有意义:
| 好 | 不好 |
|---|---|
train | my-training-experiment-v2 |
exp01 | bert-finetune-lr3e5-bs32 |
dl | downloading-imagenet-dataset |
连入会话后你能看到完整上下文。名字只需要够你从 tmux ls 的列表里选对就行。
Tmux + 训练:每天的固定模式
这是你每天都会用到的模式。简单,好用。
1. SSH 到服务器
ssh lab-server2. 为实验创建命名会话
tmux new -s experiment013. 启动训练
cd /path/to/your/project
conda activate your-env
python train.py --config config.yaml训练在跑了。你能看到 loss 在降,epoch 在增。一切正常。
4. 脱离
按 Ctrl+b,然后按 d。
训练继续跑。你回到了 SSH 命令行。
5. 去过你的生活
关掉 SSH 连接。合上笔记本。回家。吃饭。睡觉。出去玩一个周末。都无所谓。你的训练在服务器的 tmux 里跑着,它不需要你。
6. 用手机随时查看
任何时候——在公交上、在床上、在餐厅——打开 Termius,SSH 进去,查看:
tmux attach -t experiment01你看到最新的训练输出。Loss 还在降。第 47 个 epoch,总共 100 个。一切正常。再脱离:
按 Ctrl+b,然后按 d。
手机操作总用时:15 秒。
7. 跑完了再回来
第二天早上,或者你回到工位时:
ssh lab-server
tmux attach -t experiment01训练跑完了。结果保存好了。你检查结果,清理一下,终止会话:
tmux kill-session -t experiment01整个流程就是这样。创建会话、启动训练、脱离、去过生活、偶尔看看、跑完回来。不用盯着,不用焦虑,不用在实验室熬夜。
这解锁了什么
有 tmux 之前,问题是:"训练在跑,我能离开实验室吗?"
有 tmux 之后,这个问题不存在了。你启动训练然后离开。方便的时候用手机看一眼。还在跑,好。跑完了,好。崩了——好吧,目前你得用手机 SSH 进去,用大拇指修,很痛苦。但那是后面几章要解决的问题。Claude Code 会处理崩溃。Tmux 只负责保证你的进程不会因为你不在就死掉。
从这里开始的每一章都默认 tmux 已经是你工作流的一部分。Claude Code 会在 tmux 里运行。训练会在 tmux 里运行。下载、评估、监控——全部都在 tmux 里。它是让一切成为可能的隐形基础。
持久会话已解锁
在 tmux 里启动一个长时间运行的计数进程。脱离会话,彻底关掉 Termius,等整整一分钟。重新连入。如果计数器在你不在的时候一直在数——你已经解锁了持久会话。从今以后,你的训练再也不会因为断开连接而终止了。