跳到主要内容

BitaHub开发机/开发环境命令中断问题

更新时间:2026-10-15 07:58:00

在 BitaHub 开发机或开发环境中运行深度学习训练、数据预处理或长周期脚本时,经常遇到命令意外中断退出的情况(如断网、合盖休眠或长时间无操作断开)。针对这一问题,本文整理了问题产生原因以及多种实用的解决方案。


一、问题现象与日志特征​

当用户在终端(本地 SSH 客户端、网页端 Web Terminal 或 JupyterLab Terminal)中直接在前台执行任务时:

python -m torch.distributed.run --nproc_per_node=4 train.py

若遇到本地网络抖动断开、电脑休眠锁屏、关闭浏览器终端标签页,或者 SSH 会话因空闲超时断开,训练任务会立即意外终止。

在训练日志中通常会捕获到类似如下的退出日志:

[rank0]: Traceback (most recent call last):
...
ERROR:torch.distributed.elastic.multiprocessing.api:failed (exitcode: -1) ...
INFO:torch.distributed.elastic.agent.server.api:Received signal: 1 (SIGHUP)
INFO:torch.distributed.elastic.agent.server.api:Sending SIGTERM to all child workers...

二、原因分析​

该现象源于 Linux 操作系统的终端会话控制与挂断机制:

  1. 终端绑定关系(TTY/PTS Binding): 在终端前台直接运行命令启动程序时,该进程作为前台进程组直接绑定在当前打开的虚拟终端伪设备(pts/x)上。
  2. SIGHUP(信号 1)触发逻辑: 当发生以下任一情况时,控制终端的连接即告断开:
    • 本地网络出现轻微丢包或切换 Wi-Fi;
    • 个人电脑休眠、合盖或断网锁屏;
    • 关闭浏览器中的 Web Terminal 或 JupyterLab Terminal 页面;
    • SSH 客户端因长时间无交互达到超时阈值断开连接。
  3. 级联终止传播: 终端连接断开后,Linux 内核会向该终端会话控制下的所有前台进程广播发送 SIGHUP(Signal 1,Hangup 挂断信号)。
  4. 框架安全退出响应: 以 torchrun(PyTorch Elastic Agent)为例,其主进程捕获到 signal: 1 (SIGHUP) 后,判定父终端已挂断,出于释放 GPU 资源与显存的安全机制,会主动向所有 Worker 进程分发 SIGTERM 信号并退出。

三、解决方案​

长周期任务建议脱离前台控制终端运行,或为 SSH 连接配置心跳保活。以下方案可根据使用场景选择:

方案一:使用 tmux 终端复用器(强烈推荐)​

tmux 能够创建与当前网络连接解耦的独立虚拟会话。即使本地断网、重启电脑或关闭浏览器,会话进程依然会在开发机后台持续运行。

1. 创建并进入专属训练会话​

创建并命名 tmux 会话
tmux new -s train

2. 在 tmux 窗口中启动训练任务​

在会话中正常启动训练
python -m torch.distributed.run --nproc_per_node=4 train.py

3. 分离挂起会话​

在任务正常运行后:

  • 键盘按下快捷键组合:Ctrl + B,松开后再按下 D(Detach);
  • 终端将返回原始界面,并提示 [detached (from session train)];
  • 此时即可安全关闭终端、关闭浏览器、电脑休眠或关机,后台训练不受影响。

4. 重新接入查看训练进度​

再次连上开发机后,执行以下命令即可恢复当时的实时训练控制台:

重新接入现有会话
tmux attach -t train
常用 tmux 便捷操作
  • 查看当前所有会话:tmux ls
  • 任务结束后退出并销毁会话:在 tmux 内部输入 exit 或执行 tmux kill-session -t train

方案二:配置 SSH 客户端心跳保活​

如果习惯在终端前台运行命令,但经常因几分钟未操作导致 SSH 连接被路由器/网关切断,可以在本地 SSH 客户端中开启自动心跳发送。

方式 A:全局配置文件持久化(推荐)​

在本地电脑的用户主目录下编辑 ~/.ssh/config(Windows 为 C:\Users\<用户名>\.ssh\config),追加以下保活参数:

~/.ssh/config 配置示例
Host *
ServerAliveInterval 30
ServerAliveCountMax 5
TCPKeepAlive yes
参数说明
  • ServerAliveInterval 30:客户端每隔 30 秒自动向开发机发送一次心跳空包,告知中间网络设备连接依然活跃;
  • ServerAliveCountMax 5:若连续 5 次发送心跳均未收到响应,才判定连接彻底断开;
  • 配置后所有新建的 SSH 会话均会自动生效,有效解决空闲断连问题。

方式 B:单次命令行直接附带心跳参数​

通过 SSH 连接时直接在命令中注入保活参数:

SSH 连接时附带心跳参数
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=5 -p <端口> root@<开发机IP>
注意

心跳保活主要解决空闲网络断开问题。若电脑休眠、合盖或断网,SSH 连接仍会物理中断并触发 SIGHUP。对于数小时以上的长时间训练,仍需配合方案一(tmux)或方案三(nohup)使用。


方案三:使用 nohup 结合重定向脱壳运行​

无需交互操作的任务,可以使用 Linux 原生自带的 nohup(No Hangup)命令忽略 SIGHUP 信号,并将输出重定向至日志文件:

1. 后台非阻塞启动训练​

使用 nohup 脱离控制终端运行
nohup python -m torch.distributed.run --nproc_per_node=4 train.py > train.log 2>&1 &
命令参数说明
  • nohup:使操作系统在终端断开并发送 SIGHUP 信号时予以忽略,不终止进程;
  • > train.log:将程序标准输出重定向到 train.log 日志文件中;
  • 2>&1:将标准错误(stderr)合并输出到标准输出(stdout),防止报错信息丢失;
  • &:将任务置入后台异步执行,立即释放当前终端提示符。

2. 追踪查看训练日志​

执行上述命令后,终端会打印生成的后台进程 PID。可以通过 tail 命令实时动态追踪控制台输出:

实时跟踪后台训练输出
tail -f train.log

按 Ctrl + C 退出日志跟踪,此操作不会影响后台实际正在运行的训练进程。


四、排查与进程治理速查​

若需要确认任务是否仍在后台运行,可按以下步骤排查与管理:

  1. 查看 GPU 显卡占用:
nvidia-smi

若下方 Processes 栏依然有 python 进程且显存被占用,说明训练仍在正常计算中。

  1. 检索训练进程 ID:
ps aux | grep train.py
  1. 终止失控或卡死的后台任务:
kill -9 <进程PID>
此页面对您有帮助吗?