优雅:从系统环境到依赖包的管理
- 1. 当前思考的最终形态
- 2. 思考的过程
- 2. 1 为什么需要系统level/Container
- 2.2 为什么需要conan
- 2.3 为什么需要conda
- 2.4 为什么需要pip
- 3. 再思考:vritualenv vs container
1. 当前思考的最终形态
2. 思考的过程
2. 1 为什么需要系统level/Container
这一层面主要使为了解决不同的系统级环境。例如CUDA\CUDNN。
2.2 为什么需要conan
conan类比conda是C++包的管理器。通过conan包管理C++库更加丝滑。conanfile.py种包含了很多的可自主操作的空间。例如conanfile.py中的函数package_info方法用来定义如何使用这个包。
例如,自己编写了一个library mylib,想把它package成一个conan包供其让人使用,但是别人在使用该library,比如在某一个镜像中某一路径下link一个cublasLt库。可以这样写:
def package_info(self):
...
self.cpp_info.system_libs.append("cublasLt")
self.cpp_info.lib_paths.append("/usr/local/cuda/lib64")
调用该library的用户在使用conan install该库之后,${CONAN_LIBS}就会同时包含my_lib和cublasLt,从而不用在调用层显示的-l cublasLt。这样会让自己的库管理更加优雅。
2.3 为什么需要conda
理论上在用anaconda安装完python之后,conda的指令就很少使用了。但是在实践中,会遇到不同的python版本之间需要共存的情形。这部分可以跳转至优雅:通过env手段,在linux平台上安装多个python环境,提高自己的工作效率 详细查看。
2.4 为什么需要pip
用pip是因为国内的conda源似乎都不维护了。例如,中科大Anaconda 源无限期停止跟新公告。因此pip源是一个很好的替代品。
3. 再思考:vritualenv vs container
virtualenv和container两个都是某种程度上做环境隔离的功能。虽然container算作是系统级别的环境隔离,virtualenv是pypi包级别的环境隔离。如果不涉及cuda/cudnn等系统级别的版本管理,是不是就不需用container呢?我个人认为是可以但不建议这么做。原因如下:
- container的云特性
- container更加完善的服用机制
container的云特性: container一旦你构建镜像之后,随用随取。
同一机器的不同位置:
对于container很方便,且修改不会对镜像中的环境产生影响。
docker run -ti --gpus all --entrypoint=/bin/bash -v 'pwd':'pwd' -w 'pwd' xxx:yyy
对于virtualenv,如果在开发的过程中相对环境进行调整,是会真实的影响环境的。因此很难同时在一台机器的多处使用同一个virtualenv环境。
不同机器上:
对于container,只要将构建的镜像docker push之后,可以随时在其他机器上docker pull,但对于virtualenv没有这种机制。如果想手动对virtualenv进行复制一份到另外一台机器上,也有很大的概率会因为virtualenv内部使用的一些绝对路径而失败。
container更加完善的复用机制: docker通过“镜像层叠”的机制来优化磁盘的存储,一种称之为layer的概念,而virtualenv无相关机制。举一个例子:如果使用virtualenv为huggingface和mmdetection分别建立一个env环境,假如都依赖pytorch2.0。vittualenv会下载两次,并在本地磁盘存储两份。随者研发的时间越来越长,开发环境中会存在大量的env磁盘专用,且很多都是荣誉的包。而container的颗粒度会更细,会公用一份pytorch,这样就大大节省了磁盘空间和操作的时间。
总的来讲,如果使用了container,那么virtualenv是非必要的,这和自己之前重virtualenv轻container的习惯很不相符,需要改变过来。但也有一些少数情形virtualenv也可以使用,例如,virtualenv感觉可用于想临时、首次、快速的搭建一个环境用于某种尝试,或者想隔离container中的python环境。(但感觉都是怪怪的感觉)