Python虚拟环境完全指南:venv与conda创建、查看、删除实操
我前阵子带几个做深度学习方向的同学搭实验环境发现十个有八个都卡在第一步——不是 torch 和 tensorflow 装进同一个环境里互相打架就是 pip 装了一堆包最后自己都分不清哪个项目在用哪个。说到底都是没把虚拟环境这层基本功打牢。别人都在跑模型了他还在为版本冲突折腾两天这种亏我吃得太多今天干脆把 Python 虚拟环境的创建、查看、删除整套操作整理成文给刚进实验室的你和所有被环境问题折磨过的人一个能直接照着抄的答案。这篇文章就是围绕深度学习实验里最基础也最要命的环境管理来写的。你学会之后不仅能分清 venv、virtualenv、conda 这些工具各自该什么时候用还能亲手建出一个干净的 PyTorch 或 TensorFlow 环境随时查看自己机器上到底有哪些环境、每个环境里装了什么东西遇到不想要的环境也能利索地删掉不留隐患。不管你是只在本地电脑上做实验还是准备上服务器干活这套东西都通用。1. 深度学习实验为什么要死磕虚拟环境1.1 环境隔离开的是什么很多新手不理解为啥不能把所有 Python 包都装到同一个目录里。我用一个特别直白的类比给你讲清楚你手机里同时装了微信和抖音微信非要某个旧版系统组件才跑得稳抖音又要新版才能启动这时候如果你只有一个系统要么微信崩要么抖音崩二选一。Python 的全局环境就是这个只有一个系统的手机你把 torch 1.13 和 torch 2.0 同时 pip 进去后装的会直接覆盖前装的然后你某个项目的代码还在调用旧版本的 API运行时报错报得你头皮发麻。虚拟环境就是你给每个项目单独开辟出一块独立空间每个空间里有自己的一套 Python 解释器、pip、第三方库互不干扰。深度学习实验的依赖重灾区还不止是 torch 版本cuda 版本、cuDNN、numpy 版本、甚至 opencv 的版本都可能互相牵制。你在环境 A 里做目标检测用 mmdetection环境 B 里跑强化学习用 stable-baselines3两边对 numpy 的版本要求就可能是 1.24 和 1.26 这种不兼容的组合不用虚拟环境你只能在每次切换项目时反复卸了装、装了卸。1.2 选工具的决策逻辑不少人一上来就问venv 和 conda 到底该学哪个我的建议是分情况看没有绝对的答案。如果你只是管理 Python 层面的包那 Python 自带的 venv 模块完全够用零额外依赖、轻量、干净。如果你还要管理 Python 版本本身比如某个项目必须用 Python 3.8另一个项目要 Python 3.10那你用 conda 更省心它连解释器版本一起管了。深度学习场景里还有第三种情况就是依赖里有需要编译的包或者二进制库比如某些旧版 torchvison 对系统底层库有要求用 pip 装可能遇到编译报错而 conda 装的是预编译好的二进制包更省事。所以我个人在深度学习实验里的习惯是快速验证小项目用 venv需要切换 Python 版本或者装带 CUDA 的深度学习框架时用 conda。两者可以共存并不冲突。2. 创建虚拟环境从零到一建起你的深度学习沙盒2.1 用 Python 内置 venv 创建环境venv 是 Python 3.3 之后自带的模块不需要额外安装任何东西。进入你的项目目录执行下面这一行命令python -m venv deep_learning_env这条命令的意思是用当前这台机器上的 Python 解释器在当前目录下创建出一个名为 deep_learning_env 的文件夹这个文件夹就是一个独立的虚拟环境。里面会自动生成 bin 目录Linux 和 macOS或者 Scripts 目录Windows以及 include、lib 等子目录。你的环境名可以自己取我习惯用项目相关的名字比如 face_recognition_env、rl_simulation_env一眼就能看出是干什么的千万不要取 test、venv、env 这种烂大街的名字环境一多你自己都会认错。创建完成后激活它在 Linux 或 macOS 上执行source deep_learning_env/bin/activateWindows 上执行deep_learning_env\Scripts\activate激活之后你会看到命令行提示符前面多了一个环境名类似(deep_learning_env) yournamemachine:~$这就表明你现在已经钻进这个独立沙盒里了。在激活的状态下你所有pip install的包都会装到这个环境的 site-packages 里而不是你的全局 Python 目录。2.2 用 conda 创建带指定版本的 Python 环境如果你需要在深度学习项目里用特定版本的 Python或者想顺便管理 CUDA 相关依赖conda 是更优解。创建一个名为 dl310、Python 版本为 3.10 的环境conda create -n dl310 python3.10命令执行后 conda 会检查当前软件源里的 Python 3.10 包然后列出一堆准备安装的依赖让你确认输入 y 回车就行。这里我强烈建议你加一个参数conda create -n dl310 python3.10 -y加 -y 的意思是自动确认所有询问不需要手动输入 y省一步是一步命令写熟练了之后你会感谢这个参数的。创建完成后激活conda activate dl310你注意看命令行提示符前面会变成(dl310)这和 venv 一样只是后台的实现机制不同。conda的虚拟环境通过环境变量和文件目录实现隔离其实底层更像是把不同版本的解释器、库、包以目录树的形式按环境区分切换环境时只需要调整环境变量指向即可因此切换速度很快包也都在各自环境的目录下不会污染全局。2.3 创建环境时的 Python 版本到底怎么定深度学习项目对 Python 版本的要求不是越新越好哪怕 Python 3.12 已经出了很久很多框架的预编译包对 3.12 的支持依然滞后。我在实际踩坑中总结出的安全区间是PyTorch 官方稳定版对 3.8 到 3.11 支持最好TensorFlow 2.x 对 3.8 到 3.10 最稳如果你在做老项目复现3.7 甚至 3.6 都有可能被用到。所以创建环境前第一件事是去你要用的框架官网上看它声称支持的 Python 版本范围再决定环境版本而不是随手一个 3.11 就往上冲。用 venv 创建环境时它默认使用你当前系统 PATH 里指向的那个 Python 解释器的版本。如果你安装过多个 Python可以用python3.10 -m venv envname这种方式指定用 3.10 来创建。用 conda 就简单很多直接在 create 命令里用python3.10参数指定conda 会自动找对应的解释器版本。3. 查看虚拟环境随时摸清你的实验家底3.1 查看当前处于哪个环境有时候你开着好几个终端窗口每个窗口激活了不同的环境时间一长自己都忘了当前在哪个环境里干活。Linux 或 macOS 下直接用which python它会输出当前 Python 解释器的完整路径如果路径里包含你环境目录的名字说明你就在这个环境里。Windows 上可以用where python效果类似。还有一个更直接的办法看命令行提示符前缀前面带了环境名就一定在环境里但是前提是激活时终端没被其他配置覆盖掉提示符。3.2 查看所有虚拟环境列表venv 创建的环境没有像 conda 那样的集中注册表它就是一个普通目录所以“查看所有环境”这件事全看你把环境目录建在哪。如果你按我的习惯把所有环境集中放在某个固定目录下比如~/venvs/查看时一个ls就解决了ls -la ~/venvs/conda 则提供了官方命令conda env list这条命令会列出所有环境当前被激活的那个前面会带一个星号。执行结果大概长这样# conda environments: # base * /home/yourname/miniconda3 dl310 /home/yourname/miniconda3/envs/dl310 tf210 /home/yourname/miniconda3/envs/tf210看那个带星号的就是当前环境。注意 conda 不管你在哪个目录下执行conda env list它都能列出全部环境因为它维护了一个环境索引这是 venv 做不到的。3.3 查看环境里装了哪些包这个需求在排查依赖冲突时尤其频繁。venv 环境下激活环境后执行pip list它会展示当前环境里所有已安装的包和版本号。如果你只想快速确认某个关键包是否装了、版本是多少pip show torchconda 环境下用conda list也可以看到所有包并且它会额外标注每个包是由 conda 还是 pip 安装的这个细节在排查问题时会很有用conda list我还习惯把环境里的包导出成文件方便别人复现环境这个放到后面常见问题部分一起讲。4. 删除虚拟环境环境清理时的正确姿势4.1 删除 venv 创建的环境venv 环境删除方式极其简单粗暴——直接删目录。但有一个大前提你必须先退出这个环境。还停留在激活状态时你在这个环境目录下删文件会碰到权限问题Linux 下会提示Text file busyWindows 下会提示文件被占用。正确步骤deactivate rm -rf deep_learning_envdeactivate是退出当前虚拟环境的内置命令退出后命令行提示符前面的环境名前缀会消失这时候再删就清净了。如果你用 Windows 且习惯鼠标操作直接在文件管理器里找到对应文件夹按删除键也行但前提同样是确保该环境没有被任何终端窗口激活。我建议养成先deactivate再删除的肌肉记忆因为在 Linux 服务器上你永远是用命令行操作别指望图形界面。4.2 删除 conda 创建的环境conda 提供了官方删除命令这是最不容易出错的方式conda remove -n dl310 --all-n指定环境名--all表示把环境里所有东西连同环境本身一起删除。命令执行后 conda 会把将要删除的包列表列出来让你确认同样可以加-y跳过确认。删除完建议执行conda env list确认一下环境已经从列表里消失了。如果你不小心在环境激活状态下执行删除命令conda 会自动拒绝或者提示你所以一个更稳妥的流程是conda deactivate conda remove -n dl310 --all4.3 删除后为什么还要留意缓存这是个特别容易被忽视的坑。你删了环境只是把实际的包和数据目录清了但缓存不一定会跟着清除。conda 会缓存下载过的安装包位置一般在~/miniconda3/pkgs或~/anaconda3/pkgs目录下删了环境之后这些缓存包还是躺在磁盘上时间一长可能多出来 5 到 10 个 GB。清理命令conda clean -a执行它会把所有缓存、临时文件、未使用的包索引全部清掉。venv 环境没有这种集中缓存机制因为它的包本身就是从 pip 的全局缓存里下载的真正影响磁盘的是 pip 的缓存定时清一下也有必要pip cache purge这一步不是必须做的但我在实践中确实遇到过服务器磁盘被缓存占爆然后训练中途写不了 checkpoint 的惨案所以环境清理时顺手清一把没坏处。5. 用 requirements.txt 和 environment.yml 固化环境5.1 导出当前环境的关键依赖你在自己电脑上好不容易把环境配好跑通了模型过几天上服务器却怎么都复现不出同样的结果这种经历我相信研究过深度学习的人都不陌生。人为复现环境的靠谱做法是把依赖清单保存成文件别人拿到这个文件就能一键装出几乎一致的环境。venv 环境下导出已安装包清单pip freeze requirements.txt生成的 requirements.txt 里每一行就是一个包含版本号的包名比如numpy1.24.3 opencv-python4.8.1.78 torch2.0.1注意pip freeze会把环境中所有通过 pip 安装的包全部列出来包括依赖的依赖虽然有时候不够优雅但对于复现环境来说越全越好。conda 环境则有两种导出方式。一种是只导出 conda 显式安装的包因为很多依赖包是 conda 自动带出来的不需要一条条记录conda env export --from-history environment.yml另一种是导出完整环境的精确快照带上所有依赖的精确版本号适合需要严格复现的场景conda env export environment.yml5.2 从文件恢复环境有 requirements.txt 后创建新环境并一键安装依赖python -m venv new_env source new_env/bin/activate pip install -r requirements.txt有 environment.yml 后直接用 conda 从文件创建新环境conda env create -f environment.yml它会自动创建 environment.yml 里定义的环境名并安装所有依赖。这个方法我经常用来在不同机器之间迁移环境基本能做到一次成功。6. 实操过程与核心环节实现6.1 完整演示为 PyTorch 实验创建环境为了让你看得更清楚我完整模拟一遍我在深度学习实验中最常干的操作。假设我要在一个新服务器上跑一个图像分类实验预期用的是 PyTorch 和 CUDA 11.8系统是 Ubuntu。第一步检查系统里已有的 Python 版本python3 --version假设输出是 3.10我决定就用这个版本直接建 venv 环境。如果你不确定系统 Python 是哪个版本也可以先装一个 conda 再统一管理。这里我演示 venv 流。第二步创建环境并激活mkdir ~/dl_projects cd ~/dl_projects python3 -m venv classification_env source classification_env/bin/activate第三步升级 pip这一步经常被跳过但我每次都提醒要做因为预装的 pip 版本很可能偏旧后续安装包容易出奇怪问题pip install --upgrade pip第四步安装核心依赖pip install torch2.0.1 torchvision0.15.1 torchaudio2.0.1 --index-url https://download.pytorch.org/whl/cu118第五步安装周边常用库pip install numpy matplotlib opencv-python pillow tqdm tensorboard第六步验证环境是否可用python -c import torch; print(torch.__version__, torch.cuda.is_available())如果输出2.0.1 True说明环境装好了且 CUDA 可用。到这里整个环境搭建就算完成了。6.2 完整演示用 conda 管理多版本环境另一种更精细的场景我手头有三个项目一个需要 Python 3.8 TensorFlow 2.4一个需要 Python 3.10 PyTorch 2.0还有一个需要 Python 3.7 老版本 mmcv。这种情况下用 conda 分开建环境最合理。conda create -n tf24 python3.8 -y conda activate tf24 pip install tensorflow2.4.1 conda create -n pt20 python3.10 -y conda activate pt20 pip install torch2.0.1 torchvision0.15.1 conda create -n mmcv01 python3.7 -y conda activate mmcv01 pip install mmcv-full1.4.0每建一个新环境都是独立的互不干扰。你的终端可以在这些环境之间随意切换甚至能同时开三个终端每个终端各自处于不同的环境这也是虚拟环境最爽的使用姿势。6.3 项目目录里到底要不要放环境这是个争论挺多的话题。我的建议是本地个人项目把环境建在项目内部没问题比如my_project/venv优点是项目整个目录拷走环境也一起走不过要注意跨平台拷贝环境有时会失效因为里的路径和链接是写死的。但服务器上的共享项目或者多人协作项目环境必须建在项目目录之外因为你不能把所有协作人的环境都塞进同一个项目目录里而且.gitignore里肯定会把环境目录忽略掉不会提交进仓库。我更习惯的做法是建立一个~/venvs/目录统一存放所有 venv 环境项目目录里只放代码和 requirements.txt、environment.yml。这样既避免了环境目录被版本管理误传又方便一次性查看所有环境。7. 常见问题与排查技巧实录7.1 激活环境后 pip 装的包还是进了全局这个现象真实出现频率极高。你激活了虚拟环境然后pip install某个包最后发现这个包出现在全局 Python 的 site-packages 里而不是环境里。排查顺序先执行which pip看看 pip 到底指向哪里。如果输出路径里没有环境名说明环境没激活成功或者你激活之后又被某个 shell 配置文件的自动激活脚本覆盖了。另一个常见原因是直接用了pip3命令某些系统下pip3和pip指向不同的解释器激活环境后用python -m pip install最保险因为它是通过当前 Python 解释器去调用配套的 pip 模块绝对不会指错。我见过有人在激活环境下执行sudo pip installsudo 之后命令跑在 root 用户的环境里直接装到 root 的全局 Python 去了。记住一条铁律虚拟环境激活状态下所有 pip 命令都不要加 sudo。7.2 环境里的包能 import 但命令行运行时报错比如你激活了环境里面装好了 jupyter此时你在终端执行jupyter notebook却提示command not found。原因通常是环境里的 bin 目录没有出现在你的 PATH 里。排查方式echo $PATH看输出里有没有环境目录下的 bin 路径。正常情况下激活环境时就会把它加到 PATH 最前面如果没加进去极大可能是你用了错误的激活方式比如在写脚本时忘了先source而是直接bash activate。确保你用对命令即可。还需要留意如果你通过某个 IDE 或者系统的自动环境管理工具它们可能在后台改了 PATH这时候直接新开一个干净的终端窗口再试一次往往就能解决。7.3 conda 环境下 pip 和 conda 混装导致冲突这是一种比较常见但是隐患较大的情况。你在 conda 环境里先conda install numpy装了一个版本后来又pip install numpy升级成另一个版本两者可能版本不一致导致某些需要编译扩展的包出现 ABI应用二进制接口不兼容的报错。我的稳妥建议是一旦确立了用 conda 管理这个环境那么核心依赖尽量用 conda 装pip 只装 conda 源里没有的包。如果不可避免要混装至少保证同一时刻同一个包只通过一种方式管理不要来回切换。另外一个小经验在 conda 环境里用 pip 安装包之前最好先升级 pip 到较新版本conda 自带的 pip 可能版本很旧装某些现代包会有 metadata元数据相关的兼容问题。7.4 删除环境时提示目录不存在这种情况通常是环境名写错了。conda 删除时环境名大小写必须完全匹配而且如果环境被软链接到别的位置conda env list看到的路径和实际路径可能不同。先别急着删执行conda env list拿到准确的环境名和路径再用完整路径验证一下该目录是否真实存在。确认之后再用conda remove或直接手动删除对应目录。7.5 虚拟环境磁盘占用过高训练深度学习模型的环境往往会装大量包环境目录动辄 5 到 10 GB。如果你一个项目建了三个实验环境磁盘很快就会被占满。排查哪些环境占得多du -sh ~/venvs/*或用 conda 的方式du -sh ~/miniconda3/envs/*找出最大的环境后确认没用了就删掉。另外如果你习惯在多个环境里都装 torch每个环境都会单独存一套 torch 的库文件这些文件可能占好几个 GB。对于这种场景conda 有一些底层共享机制可以减少开销但 venv 没有。8. 一些我在实际项目中沉淀的环境管理习惯8.1 项目一创建就先固化环境文件我现在的习惯是任何项目第一步不是先写代码而是把虚拟环境建好跑通一个最小验证程序然后立刻导出requirements.txt或environment.yml存到仓库里。这看起来多了一步但是好处极大。后面你再往里加依赖每次加完顺手更新一下这个文件。等换电脑、换服务器或者有队友加入时直接一条命令全部恢复环境不需要靠“记忆”来复现因为你的记忆往往是不完整的。8.2 环境命名里带版本信息和用途我见过有人建环境时直接用env1、env2这种命名等到第三周自己都想不起来env2里到底是什么。我在团队里推的命名规范是项目名_python版本_用途例如face_align_py38 ocr_py39_train detectron2_py310这样conda env list一出来每个环境是干什么的一目了然不需要再猜测。venv 环境的目录名同理。8.3 服务器上禁止随意创建全局环境实验室的多人服务器上经常出现 A 同学说“我好像装坏了什么”然后大家发现全局 Python 的某些包被覆盖了。我的底线是所有人的实验环境必须建在各自家目录下的独立虚拟环境里不允许往系统全局 Python 里装任何深度学习相关的包也不允许对系统 Python 直接做 pip install。这样 A 同学的环境炸了只要删掉重建不会影响其他人。8.4 保持环境最小化我在创建环境时尽量只装项目依赖的包不顺手装一堆可能“以后会用到”的包。装得越多环境间产生隐式依赖的概率越大排查问题的复杂度也会指数上升。曾经遇到一个环境因为多装了一个旧版 scikit-learn导致另一个包在运行时莫名报错定位花了大半天。环境保持干净问题出现时能快速定位。9. 创建、查看、删除虚拟环境的速查对照表我把三种常见工具链的核心命令整理成一张表方便你查漏补缺贴在手边即可操作Python venvconda创建环境python -m venv myenvconda create -n myenv python3.10 -y激活环境source myenv/bin/activateLinux/macOS/myenv\Scripts\activateWindowsconda activate myenv退出环境deactivateconda deactivate查看当前环境which pythonconda env list查看环境里的包pip listconda list删除环境rm -rf myenvconda remove -n myenv --all导出依赖清单pip freeze requirements.txtconda env export environment.yml从文件恢复环境pip install -r requirements.txtconda env create -f environment.yml表格里每一行命令我都亲自在 Linux 服务器、macOS 笔记本、Windows 工作站上跑过标注了系统差异的地方就一定有差异。另有一个值得关注的细节conda activate有时会提示你conda init报错这是在说你当前 shell 还没有配置好 conda 的初始化脚本跑一下conda init bash然后重开终端窗口就好。10. 结尾的一些碎碎念在我带过的人里凡是环境管理做得好的后面项目推进都顺很多凡是环境一塌糊涂的三天两头在群里问“为什么我 import torch 报错”“为什么换个机器就全废了”。这些问题的根源往往不是深度学习模型本身而是最基础的环境隔离没做好。虚拟环境这一套东西理论上一小时就能学会但你省下来的是之后无数个小时的排查时间这笔账怎么算都划算。我自己从刚开始用 venv 记不住命令、到处翻文档到现在闭着眼都能把 conda 环境配好中间踩的坑基本都写在这篇里了希望你能少走这些弯路。