远程服务器上后台训练网络,再也不用怕由于断网而间断训练

本文分享了一种在远程服务器上稳定训练神经网络的方法,通过使用nohup命令将jupyternotebook进程置于后台运行,即使网络中断也能保持训练不中断。文章详细介绍了如何配置并使用nohup命令,以及如何管理和清理nohup.out文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先说一下情况:

最近在远程使用实验室服务器的GPU训练神经网络的时候,我是用的服务器里面的远程jupyter notebook, 首先是用Xshell连接远程的服务器, 进入conda,激活虚拟环境,然后打开远程jupyter notebook, 当然我这里使用jupyter notebook是自己配置的端口号(怕和别人冲突), 所以输入的命令长这样:

## 用xshell连接远程服务器, 之后首先激活虚拟环境
conda activate tfenv

## 然后进入tfenv的虚拟环境,我一般在这个虚拟环境中写notebook,做一些实验等, 下面打开远程的jupyter notebook
jupyter notebook --config ~/.jupyter/jpconfig.py

通过上面的第二行代码,就可以打开我远程配置的jupyter notebook, 由于我是自己单独配置的端口和密码,所以后面得加上那一串东西。

这样,我回到自己的电脑,打开浏览器,输入服务器的网址:端口号,比如:219.216.65.11:8991, 就可以打开这个远程jupyter notebook了, 使用的服务器中的计算资源,所以起初用起来还是挺方便的。

但是使用远程jupyter会有一个问题的,实时操作还可以,但是如果是要训练一个非常复杂的神经网络,我们肯定不可能看着它训练,一般都是让它自己在那训练然后干别的事情,这时候如果突然断网了, xshell就连不上服务器了,这样导致的问题就是开的那个jupyter notebook的那个进程就不能用了,也就是断了服务。 我们的网络就中断训练了, 这时候即使重新连接也不好使,毕竟我们的jupyter是需要一系列命令才能开启的。

这一直是个很头疼的事情,因为最近我训练的网络一般需要7-8个小时,而每次训练个3-4个小时,网就不稳定,断一下子就前功尽弃,并且xshell是ssh连接的,还非常容易断,对于远程jupyter notebook来讲,这个非常难弄,虽然我训练的网络设置了断点,但是总不能每次都得时不时的看看啥时候断了,然后再连接,然后从断点开始吧,非常容易打乱干别的事情的思路, 所以后来发现了一个方法: 服务器后台训练神经网络,即使断网了,Xshell断了也没有关系了

从网上搜了一些实现上面的方式, 什么screen, tmux这一些都比较好用,但是安装的时候我发现我不是root, 也没有权限,竟然安装不上, 所以我又发现了一个Linux自带的一个命令: nohup命令, 这个解决了我的烦恼,所以我记录一下这个是怎么用的, 把命令放入后台非常之简单:

nohup jupyter notebook --config ~/.jupyter/jpconfig.py &

只需要在我打开jupyter notebook前面加一个nohup,后面加一个&, 这样就把这个操作放入了后台运行,可以用jobs -l看到这个进程
在这里插入图片描述
如果用过jupyter notebook的话,我们知道输入jupyter notebook之后会输出类似这样的一串东西:
在这里插入图片描述
而放入后台之后,很明显发现没有这些东西了, 这样回到自己的电脑上输入网址端口号,就可以愉快的进行训练了,并且也不用担心网断或者xshell断了对神经网络的训练产生的影响。简直太爽。

当然,我们得记得训练完了之后,就关闭这个后台进程, 使用的命令是:

kill -9 PID

这个PID就是上面的那个进程号3905. 这个怎么找呢? 就是jobs -l 然后看看哪个进程号是训练网络的那个命令, 用完了杀死这个进程。

注意,如果是当前的xshell断了,我们重新连上之后, jobs -l命令就不好使了,这时候得用ps ux

即:linux下杀死nohup提交到后台运行的程序

  • 方法1:
    如果没有退出客户端界面,可以先通过 “jobs” 命令查看程序是否在运行,此时只有序号没有PID号;
    输入命令 “jobs -l” 会显示程序的PID号,然后通过 “kill -9 PID”杀死程序;
    输入命令 “jobs” 查看程序是否被杀死。
  • 方法2:
    如果退出过客户端界面,输入 “jobs” 命令查不到正在运行的程序;
    输入 “ps ux” 来查看所有程序的进程号PID,然后再通过 “kill -9 PID” 杀死程序;
    输入 “ps ux” 来查看程序是否被杀死。

再介绍一个nohup.out维护管理方法(清空nohup.out), 因为我们发现,后台运行的这个jupyter notebook会把那些日志,就是我们平时启动jupyter notebook的那一串东西输出到了一个nohup.out文件中了。 如果出现了超大号的文件简直是令人讨厌的事情,而且nohup.out会一直一直自己增长下去,如果你的服务器硬盘不给力的话,很容易把应用也挂掉(硬盘没空间 ,啥都玩不转),但是又不能一味的直接删。因为直接删除,可能会造成应用无法打印后续的错误日志,该问题常见于weblogic服务器,jboss服务器等这些大型中间件,这个在生产环境上要尤为注意。

因此就有了我们不停止服务直接,清空nohup.out文件的方法。
两个可以不用停止WEB服务就可以清空nohup.out的命令。

  • 第一种:cp /dev/null nohup.out
  • 第二种:cat /dev/null > nohup.out

好了, 今天的记录到这里结束,关于screen和tmux我没用过,所以不能乱写, 而今天的这个nohup我亲测过,所以记录一下。

参考博客:

### 点续传模块的实现方式 点续传是一种在网络传输过程中允许中后再继续的功能,通常用于大文件上传或下载场景。其实现涉及前端和后端的设计与配合。 #### 设计思路 在设计阶段,需明确 Chrome 提供的 API 功能及其参数含义[^1]。这些参数决定了如何分割文件以及如何标记已上传的部分以便后续恢复。此外,还需绘制功能流程图以清晰展示整个过程中的各个步骤。 #### 前端逻辑实现 前端的主要职责在于处理文件分块上传逻辑。这包括但不限于读取本地文件、将其拆分为多个较小的数据包,并逐一发送至服务器。如果某个部分失败,则记录该位置的信息,在网络条件改善或者用户重新启动操作时能够从此处接着执行而不是重头再来。 ```javascript function uploadFile(file, chunkSize) { let chunks = []; for (let i = 0; i < file.size; i += chunkSize) { const end = Math.min(i + chunkSize, file.size); chunks.push(file.slice(i, end)); } function sendChunk(index) { if (index >= chunks.length) return; fetch('/upload', { method: 'POST', body: chunks[index], headers: {'X-Index': index} }) .then(response => response.json()) .then(data => { console.log(`Uploaded chunk ${data.index}`); sendChunk(index + 1); // Continue with next chunk after successful upload. }); } sendChunk(0); } ``` 此代码片段展示了基本的文件切片机制及异步逐块上传的方法。 #### 后端逻辑实现 而后端则专注于接收从前端传来的一系列数据块并将它们存储起来。当所有预期数量的数据块都到达之后再组合成完整的原始文件。对于未完成的任务,应该维护一份状态表用来跟踪哪些部分已经成功接收到从而支持真正的“点”特性。 ```java public class FileServiceImpl implements IFileService { @Override public void savePart(String fileName, int partNumber, byte[] content){ String filePath = getFilePath(fileName,partNumber); try(FileOutputStream fos=new FileOutputStream(filePath)){ fos.write(content); }catch(IOException e){ throw new RuntimeException(e.getMessage(),e); } } private String getFilePath(String fileName,int partNumber){ return "/path/to/save/"+fileName+"_"+String.valueOf(partNumber)+".tmp"; } } ``` 上述 Java 方法 `savePart` 展示了一个简单的保存文件某一部分到临时目录下的例子[^4]。 ### 框架支持情况 考虑到实际应用环境可能基于特定的技术栈构建,比如 C# RPC 架构下模拟的服务调用可以很好地适应现有系统的约束条件[^2];而对于 Python 开发者而言,Scrapy Redis 的插件提供了分布式爬虫的能力同时也包含了某些形式上的电保护措施[^3]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值