如何实现服务器离线训练模型,后台执行进程
需求说明:在PC端运行命令,而进程在服务器Linux端,你希望关闭PC端而不影响or Linux端的进程不断,则可以参考这里。
两种方法:tmux和nohup命令,以下分别介绍
1. tmux
原理:利用tmux建立一个会话,该会话只有在你手动关闭时才会退出。那么会话不手动结束,在这个会话中的进程就不会结束,因此实现离线训练模型。
第一步:建立一个tmux会话
tmux new tmux new -s <session-name>
第二步:执行你需要进行的任务
for example:
# 显示进程 top # OR 进行模型训练 python train.py
第三步:离开会话(注意这是离开,不是结束)
# first ctrl+b # second d
就是先ctrl+b
,然后再按d
,前者告诉你的会话你要执行其他的命令。后者d就是detach(我的理解)
然后你就可以回到你建立tmux会话之前的terminal了
并且你关闭这个terminal也可以保证你的.py或者其他进程仍然在继续。
其实到这里就可以结束,但是你得结束tmux会话不是,不然就一直挂载在服务器端了,因此,如下:
第四步:回到会话
tmux attach -t <session-name>
这里-t
表示target,<session-name>
是你的tmux会话名字,不知道名字可以通过tmux ls
查询
第五步:当你结束任务,需要结束会话
# 会话里面 exit # 会话里面和外面都可以 tmux kill-session -t <session-name>
2. nohup
原理:看词说话,nohup就是< no hang up >,就是不要挂断的意思,那么Linux端看见这个命令就知道这行命令是不能停下来的,从而实现进程不断。
第一步:直接敲命令
nohup python -u ./train.py &
说明:
- 执行该命令需要在你需要执行的
train.py
文件内(看下面树状图)
tree |__train.py |__nohup.out |__other
&
表示后台运行,就是个进程是在后台运行的,-u
表示禁用缓冲,直接输出,大白话:如果你的进程有输出,那就会一直输出东西出来。- 输出会默认重定向到一个
nohup.out
文件下,该文件会和train.py
文件在同一级目录,内容是进程的输出。
第二步:结束进程
如果你的代码执行一半你想起参数没改,希望结束重新再来,那就需要中断模型训练。
NOTE!!!以下方法是在你没有结束你的terminal可以执行:
# 找到你的进程or作业 jobs -l # 结束你的进程or作业,下面举列结束作业号为1的 kill %1 # 你想结束所有进程or作业 kill %%
NOTE!!!若你直接结束了terminal或PC直接关机了,现在需要重新中断进程,则jobs -l
可能就查不到你的进程了,因此你需要用下面这个办法:
使用进程的 PID(进程标识符)来结束进程。首先,通过 ps
命令找到你要结束的进程的 PID,然后使用 kill
命令结束该进程。例如:
ps aux | grep 进程名字 kill -9 PID
这里举列:ps aux | grep python
,你就可以看见你用python命令正在执行的命令,找到前面的PID,使用kill PID
, 把PID换成你进程的就可以了
请注意,使用 kill -9
是强制终止进程的方式,慎用,因为它可能导致数据丢失或其他不良影响。
nohup的进阶
如果你想要输出到指定文件,可另外指定输出文件:
nohup python -u ./train.py > out.txt 2>&1 &
说明:
>
: 这是重定向操作符,将命令的标准输出重定向到指定文件。out.txt
: 这是用于存储标准输出的文件名。命令执行时产生的标准输出将被追加到 “out.txt” 文件中。如果文件不存在,则创建它。2>&1
: 这是将标准错误 (stderr) 重定向到标准输出 (stdout) 的语法。这样,标准错误也会被追加到 “myout.txt” 文件中。&
: 这是将命令放到后台运行的符号。整个命令通过&
在后台异步执行,允许你在终端中继续输入其他命令而不必等待该命令完成。
你可以用的测试例子
使用 Python 的 time
模块来实现每隔1秒打印一句 “Hello world!”,为了保证该程序不会一直执行下去,设置循环1000后停止。(因为我有一次测试这个程序就停不下来了,设置1000停止只是保险.)1000s总该够测试了。(万一你不会停怎么办,总不能让这东西一直跑吧,我就有一次停不下来,一直输出hello…)
import time def print_hello_world(): count = 0 while count < 1000: print("Hello world!") count += 1 time.sleep(1) if __name__ == "__main__": print_hello_world()
这是一个.py文件,你可以在终端中运行这个脚本,然后每秒钟就会打印一次 “Hello world!” 直到你手动停止程序或达到1000次。你可以使用这个来做后台运行测试。