集群个人用户离线复制管理Python环境的一些问题

项目的Python环境一直没有有效管理,大家都是用的同一个环境。某个包需要特定的版本,必然需要考虑升级会不会影响其他人、其他程序的运行。
在研究WaveGlow代码时,其依赖的torch1.0高于当前的0.4版本,故研究了一下Python环境的复制和管理问题。中间遇到了一些问题,一一解决并决心记录下来。
前置条件:个人非root用户、集群共享存储、离线环境(增加了问题解决的难度)、使用了Anaconda环境(方便了Python环境的复制管理,但是也带来了一些问题)

一. Anaconda环境复制

1. 环境复制

       Anaconda是一个Python环境管理工具,它附带了 conda、Python 和 150 多个科学包及其依赖项。我们一直使用Anaconda来管理Python环境的,但是只用了默认的root环境。可以在很多地方找到复制环境的命令:

  conda create --name lujian --clone root

以上就复制了root环境,并命名新环境为lujian。通过conda env list或conda info -e可以查看所有的环境。

2. 路径配置

       但是,新的环境默认是放置在用户的家目录下的,而家目录并不是集群的共享目录,这样新的环境就只能在本机使用了。通过以下命令:

  conda config --show

该命令可以查看conda的配置信息,其中的envs_dirs参数指示环境的路径,默认为/home/<user>/.conda/envs和/<anaconda-dir>/envs。按照优先级,新建的环境相关文件就放置在/home/<user>/.conda/envs目录下。我们可以通过:

  conda config --append envs_dirs <new-dir>

将新的目录添加到envs_dirs参数中,而该目录可设置成集群共享的目录,这样,当在执行conda create时,新建的环境就位于共享目录了。

3. 在线/离线方式

       有搜索到环境导出和导入的方式来复制环境,命令如下:

  #导出环境
  conda env export --name root > environment.yaml
  #导入环境
  conda env create --name lujian -f environment.yaml

并提到复制的环境只是安装了原来环境里用conda命令直接安装的包,用pip安装的包没有复制过来,需要重新安装。

#导出pip安装的包
pip freeze > requirements.txt
#导入到Python环境
pip install -r requirements.txt

然而conda包和pip包的导入都需要联网,在离线环境下失败。

       通过1中clone的方式可在离线时复制环境,有看到说该方式下复制的新环境也只是安装了原来环境里用conda命令直接安装的包。然而经过实践,源环境中的conda包和pip包都复制过来了。

4. 问题

       但是也发现了一些奇怪的问题,一个是新环境下很多文件都是源环境文件的一个链接。二是同一个包如果有conda和pip两个不同的版本,使用时import的版本可能会和源环境不一样。
       所以,以后安装第三方包可以用conda安装的尽量通过conda安装吧,conda安装还有的优势就是能够自动安装其他的依赖包。

二. Pytorch与Python离线更新

1. Pytorch更新与问题

       新的环境中包含了原来已安装的Pytorch0.4,而我需要的是1.0版本。在仓库https://pypi.org中下载到1.0的离线包后,通过pip install --upgrade安装,会先卸载0.4的包,并安装了1.0的包。通过pip list可以查看安装成功。
       安装的过程很轻松,然而跑waveglow时,却报了错误:

 symbol lookup error: <python-dir>/site-packages/torch/lib/libtorch_python.so: undefined symbol: PySlice_Unpack

搜索这个错误,然后重装Pytorch以及一些依赖包都无效,也考虑了是否复制环境导致的包版本和一些库文件错乱导致的原因。直接在源root环境下通过pip install --user 将Pytorch1.0安装到个人目录下,然而仍然出错。
       最终在https://github.com/pytorch/pytorch/issues/14931中确定了Pytorch1.0在Python3.6.0中存在bug,需要升级Python版本。

2. Python离线更新

       由于是离线环境,没法使用conda update升级Python,所以首先下载了Python3.6.3的离线源码包。
       尝试将Python安装到另外的目录,通过环境变量配置使用其他的Python包,也宣告失败。在https://www.quora.com/What-is-the-best-way-to-update-Python-on-Windows中看到,Python小版本的升级,可以直接通过安装到已有Python目录,自动删除原始版本并安装新的版本。
       由于以上我们创建了个人目录下的新的Python环境,所以Python升级覆盖新环境中的Python版本就可以了。按照安装指示,最后一步make install等待的比较久,应该是将已有的Python第三方包用新版本的Python重新编译了一遍。通过python -V可以看到Python3.6.3已经安装成功。

三. numpy.linalg.svd运行内存出错

1. 问题

       本以为问题都解决了,结果程序一跑还是报了个segmentation fault。调试程序,发现是numpy.linalg.svd内出错。

2. 原因

       搜索一下还是有提到这个问题的,主要是说当传入的参数矩阵比较大可能会出现(虽然我的matrix只有[1024,1026]),而且是由于numpy和scipy编译依赖的openblas出现的问题。当然也有提到很早就解决了这个bug:https://github.com/xianyi/OpenBLAS/issues/225,然而后面在各种环境下这个问题还是有人提及。

3. 解决

       使用conda list可以发现当前环境中有两个版本的scipy。删除已安装的全部scipy和numpy,重新下载离线包并安装,运行后一切正常。

四. 小结

  • 停止使用root环境,尽量为各个项目创建独立环境。
  • 尽量使用conda安装包。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章