在无外网服务器中搭建深度学习项目环境

目录

  • 背景介绍
  • 本地Conda环境准备
    • 本地Centos系统准备
    • 安装Anaconda
    • 配置本地Conda环境
  • 打包上传服务器
    • 压缩文件与拆分
    • 切分文件的合并解压
  • 服务器Conda环境构建

背景介绍

各位实践于深度学习中的小伙伴们可能都被配置深度学习环境这一基础工作狠狠滴教育过。但是在无外网的服务器中配置项目运行环境可以用变态来形容了(可以想象一下不使用 pip install / conda install 来配环境)。前一阵项目组申请到几台双V100服务器(Centos 7.4)用于组内算法工程师的学习与测试,就是没有外网,所以基本上就是处于闲置状态。但是强大的算力摆在咱们面前,为了跑一些好玩的AI项目,说啥也得硬着头皮上了。

本地Conda环境准备

环境移植一般分为两种,在不同平台上的移植需要列出项目环境的 requirments.txt ,然后在服务器上根据 requirments.txt 去下载安装到对应环境中。但是对于无外网环境下,就需要自己去搜集对应平台的安装包了。这个工作很难,因为一个包可能会有很多依赖并不在requirments里。另一种在相同平台上的方法,我们只需要将环境打包,安装到服务器上就可以使用了。但是, 要移植的环境所在的系统一定要与服务器的系统版本一致,这样才能最大程度保证移植后的环境可用。想要获得与服务器版本一致的系统有两种办法,一种是在你现有的电脑装双系统,另一种是使用虚拟机,选择哪种就看个人喜好了。虚拟机更简单方便,但是缺点也很致命,无法调用GPU。如果你已经按照项目的requirments在Win或Linux系统中配置过环境,且成功调用GPU并运行了程序。那么你一般就可以按照同样的方式直接在虚拟机里配置环境,在虚拟机中运行测试时忽略GPU就可以了。

虚拟机我使用的是Oracle VM VirtualBox,免费并且很轻量。虚拟机的安装使用我就不介绍了,大家自己搜索吧。

1. 本地Centos系统准备

在服务器终端输入 cat /etc/redhat-release 查看服务器Centos系统版本,输出结果如下
centos版本
可以看到服务器版本为7.4.1708,那么我们就要下载对应的镜像文件。

下载镜像文件不要到Centos官网下载,不仅速度极其的慢,而且还没有老版本的镜像。像我这个7.4的版本就没有。国内有很多镜像网站,我对比了下载速度,直接给大家下载速度最快的网站 https://renwole.com/。这里有各种Linux发行版的镜像,版本号也很齐全。
在无外网服务器中搭建深度学习项目环境_第1张图片

2. 安装Anaconda

由于介绍安装Anaconda的博客很多,我在这就偷个懒省略掉了,给大家放一个参考链接。

需要注意的是,安装时留意一下Anaconda安装的位置(默认是用户目录下),后面移植环境时我们需要手动把环境放在 Anaconda 文件夹中的 envs 里。

3. 配置本地Conda环境

下面我们开始配置conda环境。

首先,创建项目对应的环境名,这里我用xxx代表了。可以指定python版本,不指定一般会安装最新版本。

$ conda create -n xxx [python==x.x.x]
$ conda activate xxx

然后安装python包,一般项目中都会有 requirments.txt 或者是 environment.yaml。但是我使用 environment.yaml 时,里面 -pip: 下的包安装会失败,我就自己创建了一个 requirments.txt 把 -pip 后的包名都放进去,用对应的方法成功安装了。

  • 如果项目中是 environment.yaml 就用 $ conda env create -f environment.yaml
  • 如果项目中是 requirments.txt 就用 $ pip install -r requirments.txt
  • 如果需要安 GitHub上的包就 $ pip install -e git+https://github.com/XXX/YYY.git@master#egg=YYY
    或者在GitHub上把源码的 zip 下载下来解压到项目中的 src 文件夹中然后直接使用源码安装:
    $ pip install -e your_path/src/YYY -e 后面是源码文件夹的路径

没安装上的包单独安装一下,但是一定要注意,安装的版本号是不是和环境中的其他包的版本相匹配,我在这踩了一天的坑[o(╥﹏╥)o]。如果你直接 $ pip install xxx 一定是安装最新版本的包,但是你的项目里大概率都是使用较低的版本。那么你运行代码的时候就有可能出现各种各样的错误信息,而且还是费半天劲解决一个,马上又出现一个新的,永远debug不完。这时候你就得想到,可能是报错的包的版本不对导致的。并且记着,不要想着动代码。

那么解决的大致思路是,首先在你的项目根目录中搜索这个包的名字,看看能不能在某个文件中搜索到 “包名==x.x.x” 这种格式,如果搜索到问题直接就解决了。如果没有搜索到的话问题会复杂一点。这里需要假设一个前提,项目作者在从头开发这个项目时,一般不会特意去指定每个包的版本,也就是说是直接 pip install 的最新版本。那么,根据这个假设我们可以得出,项目中所有包的版本号一定是发布日期最接近的版本。下面我们通过 $ conda list 查看项目中所有包的版本号。
在无外网服务器中搭建深度学习项目环境_第2张图片

查看其中比较重要的包,或者明显与你要安装的包相关的那个包的版本。然后到 pypi.org 中搜索该版本发布的日期。
例:我们欲安装或因故更换下图蓝框中torchmetrics包的版本。
在无外网服务器中搭建深度学习项目环境_第3张图片

从名字可以看出该包与pytorch应该有关系,因此我们查看当前环境中的pytorch版本为1.7.0。接下来我们到pypi官网查找pytorch 1.7.0版本的发行日期。步骤如下图。
[!注意] pytorch的包名为torch
在无外网服务器中搭建深度学习项目环境_第4张图片
在无外网服务器中搭建深度学习项目环境_第5张图片
在无外网服务器中搭建深度学习项目环境_第6张图片
在无外网服务器中搭建深度学习项目环境_第7张图片

我们可以看到该版本的pytorch发行日为2020年10月27日,然后用同样的方法搜索该日期附近的torchmetrics库的版本号。

在无外网服务器中搭建深度学习项目环境_第8张图片
搜索结果显示,torchmetrics最早版本发布于2021年3月12日,与pytorch 1.7.0发行日期最近。所以根据我们的策略,torchmetrics应安装0.2.0版本。但是这里我安装的是0.5.0版本。原因是,在最开始我直接pip install安装了最新的0.9.0版本,导致出现一个错误,百度之后得到答案,安装torchmetrics<=0.5.0版本即可解决。因此我安装了最高的版本,并且解决了该报错。为了实验0.2.0能否work,我安装了一下,得到如下结果。
在无外网服务器中搭建深度学习项目环境_第9张图片
图中显示已安装的 pytorch-lightning 1.4.2 需要 torchmetrics>=0.4.0。因此,我又尝试了0.4.0版本。事实证明0.4.0版本是可以的。
最后的结论就是,如果项目作者犯懒没有把requirments写详细或者忽略了其中某个包,我们只能想尽各种办法来推测这些包的版本是啥。

打包上传服务器

这一步本来没什么复杂的,总体来说就三步:

  1. 压缩文件(Windows:winRAR Linux:zip、p7zip)
  2. 上传服务器(secureFX 或 XX文件管理终端)
  3. 解压文件(Windows:winRAR Linux:zip、p7zip)

难点在于,这个传输过程很有可能是不稳定的并且速度也不是很快。如果项目中有几个G的模型文件,我们打包项目后会得到一个比较大的压缩包。此时,我们很自然会想把大压缩包拆分为多个小压缩包分别上传后,以此降低不稳定的传输造成的重传风险。然后在服务器上再合并解压成一个文件。虽然最后事实证明这对我来说根本没必要,因为我使用的文件管理终端可以断点续传,很少会出现传了一半断了又需要从头传的事(只有我两次失误造成了这个结果,续传的时候文件夹选错了,结果再回到正确的文件夹也从头开始传了)。但是在这我也把我研究合并解压文件这几天踩的坑给大家都讲一下,以免大家真的有这种需求时又踩一遍,真的是步步艰辛啊[再o(╥﹏╥)o]。

压缩文件与拆分

 1. Windows

在windows下很简单,两个过程直接都能在压缩软件里一步搞定(不管什么软件都有这个功能,这里以WinRAR为例),方法如图所示。设置好切分的大小就行。(但是最好不要用windows切分,下面会说到)
在无外网服务器中搭建深度学习项目环境_第10张图片

 2. Linux

在Linux中我们需要先压缩,再拆分。命令如下:

$ zip new_fileName.zip fileName
$ split new_fileName.zip splitName.z -b 1G -d

执行该命令后原来的fileName文件会被拆分为每个1GB的如下文件

splitName.z00
splitName.z01
splitName.z02
...

zip 命令第一个参数是生成的压缩包文件名,‘.zip’不写也可以,命令会自动补。第二个参数是要压缩的文件名。
split 命令中的第一个参数是要拆分的文件名。第二个参数是拆分后文件名的前缀,可以不写,文件名就只有编号。
  -b:用于指定拆分后每个文件的大小,如果不指定,每个包会随机拆分为200-300KB大小。
  -d:用于将文件的编号变为数字编号,如果不指定,编号为 以 x 开头 a-z作为符号的26进制数字,如xaa,xab,xac,…xaz,xba,xbb,…。
split 命令的其他参数大家可以参照下表进行尝试,我就不一一讲解了。

参数 参数说明
-a, --suffix-length=N 生成长度为N的后缀(默认值2)
-b, --bytes=SIZE 每个拆分文件的大小,大小是一个整数和可选单位。单位是K,M,G,T,P,E,Z,Y(可以小写,换算单位为1024),如果使用KB,MB,… 换算单位为1000
-C, --line-bytes=SIZE 每个输出文件最多放置行的大小字节
-d, --numeric-suffixes[=FROM] 使用数字后缀代替字母;从更改开始值(默认为0)
-e, --elide-empty-files 不使用“-n”生成空输出文件
–filter=COMMAND 写入shell命令;文件名为$file
-l, --lines=NUMBER 为每个输出文件设置行数
-n, --number=CHUNKS 生成CHUNKS输出文件
-u, --unbuffered 立即用“-n r/…”将输入复制到输出
–verbose 在打开每个输出文件之前打印诊断
–help 显示此帮助并退出
–version 显示此帮助并退出

切分文件的合并解压

刚开始我认为这是一件非常简单的事,因为我以前用Ubuntu系统的时候就合并过拆分压缩包,也没出什么问题。当时就是将拆分的压缩包用cat命令先合并,然后再unzip解压:

$ cat xxx.z* > xxx-all.zip
$ unzip xxx-all.zip

但是这一次我用尽各种方式都没有成功,原因我大致猜测是Windows下拆的文件并不是简单地split,而是在每个包中加入了一点控制信息(仅仅是猜测)。稳妥的方法还是在linux中切分,就可以使用上面的两条命令解压。

下面是一些踩坑过程,主要是我为了解压windows拆分的包都折腾了些啥,可以跳过。

我想要上传的项目是latent-diffusion,一个text2image的模型,其中包含一个 5.72GB 的模型文件。开始我直接将整个项目以1GB 为单位压缩切分,经历了两天漫长的上传过程,我在服务器上使用上述两条命令解压,解压过程中直接报错。错误信息大致是

error: invalid compressed data to inflate file #14: bad zipfile offset > (local header sig)。

查找了十多篇博客,尝试了各种合并顺序都没有解决问题。(顺序不同对报错的结果是有影响的,cat xxx.z*会导致xxx.zip在最后合并,得到的东西直接就不是压缩包。只有手动按照cat xxx.zip xxx.z01 xxx.z02…才会报offset的错)。也尝试了zip -F修复,但是使用的方法不对也没成功。其中看到一篇博客,说Windows的切分压缩包根本不能解压,他通过搭建Samba服务器,借用Windows的WinRAR,直接将文件解压缩到Linux里了(链接)。当时绝望的我直接删除了辛辛苦苦上传的5个多G文件,但是看到下一篇博客又给了我希望,他描述的情况和解决办法非常符合我的需求(链接)。直接使用zip -F xxx.zip,修复.zip后缀的那个文件,再直接unzip xxx.zip解压该文件即可。当时我为了测试该方法,以100M为单位,拆分了一个457MB的压缩包上传到了服务器,结果居然成功了。然后我立刻把此方法复制到我之前5.72GB的模型文件上,居然失败了,解压出来的东西少了500多B???最后我只好老老实实地去我Centos虚拟机上split了。

服务器Conda环境构建

首先,确认你的服务器上安装了anaconda,没安装的按上面在本地安装Anaconda的同样方法安装。

在之前,我们已将在本地配置好了项目的conda环境。现在我们只需要把这个环境也打包上传到服务器的conda环境上。
首先,将本地conda环境打包:

$ conda pack -n env_name [-o new_name.tar.gz]

其中env_name为我们要移植的环境名,new_name 为指定的压缩包名,如果不指定默认为 env_name.tar.gz。压缩包位置为你的当前位置,你也可以在 -o 后加上路径改变输出压缩包位置。

然后,我们将 new_name.tar.gz 上传到服务器。找到目录 anaconda3/env/ 的位置(),在其中创建env_name文件夹

$ mkdir env_name

然后将环境压缩包解压到 env_name 文件夹中

$ tar -zxvf env_name.tar.gz -C env_name

接下来我们使用如下命令查看系统 conda 环境,可以看到env_name已经存在

$ conda env list

最后,激活环境。

$ conda activate env_name

我们终于可以愉快地运行我们的项目了。

你可能感兴趣的