
1. 从一次“环境装崩了”说起上周三下午隔壁工位的同事抱着笔记本过来找我说他的 YOLOv8 训练脚本昨天还能跑今天换了台机器就报ModuleNotFoundError: No module named ultralytics重装了三遍还是原地打转。我打开他的终端看了一眼pip list里躺着 80 多个包numpy 是 2.0torch 是 1.13Python 是 3.12——三个版本互相打架能跑起来才怪。这就是典型的“全局环境一把梭”后遗症装得越多冲突越密最后谁都不敢删删了怕别的项目崩。conda 虚拟环境要解决的就是这件事。它给每个项目切出一块独立的房间房间里有自己的 Python 解释器、自己的第三方库、自己的依赖版本A 项目用 Python 3.9 torch 1.13B 项目用 Python 3.11 torch 2.1两边互不干扰删掉一个不会波及另一个。这篇内容我把它定位成一份从装到删的完整操作手册覆盖conda 创建虚拟环境、查看环境和删除虚拟环境这三类最基础也最高频的命令顺带把conda init 报错、换源、环境迁移、DLL 初始化失败这些实际会卡住人的坑一并说清楚。刚接触 conda 的新手可以照着敲用了两三年但总在报错里打转的人也能从排查章节里找到对应线索。2. 装 conda 前先想明白的三件事2.1 Miniconda 还是 Anaconda别装完才后悔很多人第一次接触 conda 是从 Anaconda 开始的几个 G 的安装包下载下来装完预置了两三百个科学计算包看着挺大方。但这些包全部塞在 base 环境里你后面建项目环境时根本用不到白白占着几个 G 的磁盘。我现在的习惯是直接用Miniconda安装包 100 MB 出头装完只有一个 base 环境和 conda 本身需要什么自己装干净利落。判断标准很简单如果你只是想要一个 Python 加几个常用库选 Miniconda如果你懒得折腾、磁盘也宽裕、而且明确知道 base 环境里那些包你都会用到比如做数据分析离不开 pandas、scipy、jupyter那 Anaconda 也不是不行。但千万别在 base 环境里跑项目这是很多人的坏习惯。base 环境动了之后一旦某个包升级破坏了 conda 自身的依赖你会遇到连conda install都用不了的尴尬局面那时候修复起来相当难受。提示base 环境只用来管 conda 本身项目一律新建独立环境这是使用 conda 最重要的一条纪律。2.2 安装路径里不要有空格和中文Windows 上默认会装到C:\Users\你的用户名\anaconda3或者C:\ProgramData\Anaconda3。如果用户名是中文路径里带着中文字符某些老版本的构建工具链会在编译扩展包时报出一堆莫名其妙的编码错误。我一般会手动改到D:\dev\miniconda3这种纯英文、无空格的短路径。路径短还有个好处Windows 对路径长度有 260 字符的限制conda 的环境路径本来就深envs\项目名\Lib\site-packages\...\一层套一层路径太长时装某些包会直接失败。Linux 和 macOS 上默认装到~/miniconda3或~/anaconda3这个一般没问题但如果你打算把环境和包放在大容量数据盘上安装时可以指定前缀装完之后再通过envs_dirs和pkgs_dirs两个配置项把环境目录和包缓存目录指过去。这两个配置后面第 8 节会细讲因为它们直接决定了你 C 盘会不会被吃满。2.3 安装时那个Add to PATH到底勾不勾Windows 安装向导里有个选项叫Add Anaconda3 to my PATH environment variable官方推荐的默认是不勾理由是这样不会干扰系统里其他 Python。但很多人第一次装完打开终端敲conda发现提示不是内部或外部命令就是因为没勾。我的做法是不勾装完之后手动配置。手动配置也简单。Windows 下打开环境变量在用户变量的Path里加上三条D:\dev\miniconda3 D:\dev\miniconda3\Scripts D:\dev\miniconda3\Library\bin第三行Library\bin经常被漏掉但它是必须的否则你运行conda init或者某些带原生扩展的包时会报 DLL 找不到。Linux 和 macOS 下安装脚本最后会问你要不要自动初始化选 yes 会往~/.bashrc或~/.zshrc里写一段初始化代码如果你选了 no就手动执行~/miniconda3/bin/conda init bashzsh 就换成 zsh。改完配置文件记得source ~/.bashrc让它生效不然当前终端还是老样子。3. 创建虚拟环境把参数一个个拆开讲3.1 conda create 最常用的一条命令建环境的核心命令就一条conda create -n myenv python3.9-n后面跟的是环境名myenv你换成自己喜欢的但建议用纯英文小写加下划线因为环境名会变成环境目录的名字中文和特殊符号在某些场景下会出问题。python3.9是显式指定版本这里有个细节值得展开如果你只写python不写版本conda 会给你装它当前 channel 里最新的版本如果你写python3.9conda 会在这个大版本下找它能拿到的最新小版本比如 3.9.18。指定版本时用单个等号就够了两个等号在 conda 里表示精确匹配版本号必须完全一致三个等号是模糊匹配不指定具体 build。日常用单个等号最省心。命令敲下去之后conda 会先做依赖求解Solving environment把要装的东西算清楚然后列一个清单让你确认输入y回车就开始下载安装。整个流程背后 conda 做的是 SAT 求解它会通盘考虑所有包的依赖约束这也是 conda 比 pip 更容易一次装齐的原因——pip 是逐个包独立解析装到一半才发现冲突是常有的事。3.2 建环境时顺手把常用包装上建环境的时候可以一次把需要的包都列上conda create -n nlp python3.11 numpy pandas jupyter -c conda-forge这样比先建空环境再一个个装要快因为 conda 只做一次依赖求解而不是每次装包都重新解一遍。实测下来装十几个包的时候这个差别能到几分钟。-c conda-forge是指定从 conda-forge 这个 channel 拉包conda-forge 社区维护、更新及时很多新版本的包在默认的defaultschannel 里还没有但那边已经有了。-c这个参数写在命令结尾比较符合习惯它的优先级是命令行里后指定的 channel 优先级更高。如果你要同时用多个 channel可以按优先级从低到高依次写-c defaults -c conda-forge意思是 conda-forge 优先。这个顺序别搞反搞反了会装到旧版本还找不到原因。3.3 环境建到别的盘去-p 参数的用法默认情况下环境都建在安装目录下的envs文件夹里。如果你 C 盘紧张可以用-p直接把环境建到指定路径conda create -p /data/envs/proj_a python3.10这个-p建出来的环境在概念上是一样的但激活方式不同——它没有名字激活时要写路径conda activate /data/envs/proj_a。有些 IDE 对这个路径形式的环境识别会有点小别扭所以更推荐的做法是修改默认环境目录让-n建出来的环境也落到大容量盘上。具体是执行conda config --add envs_dirs /data/envs conda config --add pkgs_dirs /data/pkgs加完之后conda config --show envs_dirs能看到这个路径已经排在列表里。需要注意的是如果envs_dirs里第一个路径不可写比如权限不对conda 会自动跳到第二个所以如果你发现新环境还是建在 C 盘多半是权限没给对chmod一下或者换个目录就行。已经建好的环境想换位置不能简单复制粘贴因为环境里的脚本写死了原路径硬搬会全部失效正确做法见第 8 节的环境迁移。4. 查看与激活每天都要摸的几个命令4.1 我到底有哪些环境两个命令都能列环境conda env list conda info --envs输出长得一样第一列是环境名第二列是路径当前激活的环境前面有个星号*。我习惯用conda env list短一点。如果输出里 base 那行前面有星号说明你现在正在 base 环境里这时候装包会污染 base赶紧conda deactivate退出来。conda info单独用则是看 conda 自身的状态包括版本、base 环境路径、channel 列表、envs_dirs、pkgs_dirs、平台信息。排查问题时这个命令应该第一个敲因为它能一次性告诉你 conda 认为自己是哪来的、环境会装到哪去、包从哪个源下很多配置层面的问题看一眼输出就清楚了。另外环境的实际信息存在两处一是envs目录下的文件夹二是envs.txt这个登记文件。偶尔会遇到文件夹还在但conda env list里不显示或者反过来显示了但目录被删了的情况这时候conda info --envs会标注出来手动把envs.txt里对应那行删掉就能修复列表。4.2 激活环境与 conda init 报错激活命令是conda activate myenvWindows 的 CMD 和 PowerShell、Linux 和 macOS 的 bash 与 zsh 都支持。但初次使用很容易撞上这个报错CommandNotFoundError: Your shell has not been properly configured to use conda activate. To initialize your shell, run $ conda init SHELL_NAME这不是 conda 坏了而是你的 shell 还没有把 conda 的初始化脚本加载进来。解决办法就是照它说的执行conda init bash # 或者 zsh / powershell / cmd.exe执行完它会改你的 shell 配置文件bash 是~/.bashrczsh 是~/.zshrcPowerShell 是 profile 脚本往里面写一段带conda initialize标记的代码块。然后必须重开一个终端或者source ~/.bashrc新配置才会生效。重开之后conda activate就能用了。注意conda init改的是配置文件如果之前你自己手动往.bashrc里加过 conda 的 PATH可能会和初始化脚本打架导致 PATH 里出现两份 conda。排查时敲which -a conda看看是不是有多条路径有的话把手工加的那条删掉。还有一个经常被忽略的场景在脚本或者 cron 任务里调用 conda因为那种环境不加载.bashrcconda activate会直接失效。稳妥的写法是用绝对路径的sourcesource /home/user/miniconda3/etc/profile.d/conda.sh conda activate myenv python train.py这段写法比conda init更适合放进自动化脚本因为它不依赖交互式 shell 的配置。4.3 看看环境里到底装了什么进入环境之后统计已安装的包conda list输出是四列包名、版本、build、channel。重点看最后一列pypi表示这个包是 pip 装的其他表示 conda 装的。如果你要排查版本冲突先看这一列因为 pip 装的包 conda 是不管的conda 做依赖求解时看不到它们冲突就藏在这里。也可以用pip list看但pip list只列 pip 视角下的包conda 装的某些包它可能显示不全。不想激活环境就查它的包列表加-nconda list -n myenv这个在实际排查时特别有用。我之前有个环境一激活就报错根本没机会在里面敲命令就是靠conda list -n从外面看出某个包的版本和它依赖的 numpy 完全对不上删掉重装才好。5. 换源把下载速度从龟速拉回正常5.1 .condarc 该怎么写默认源在国外下载几十 MB 的包经常卡在几 KB/s。换成国内镜像源是最直接的优化。配置写在~/.condarc这个文件里Windows 上是C:\Users\用户名\.condarc直接编辑channels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloudshow_channel_urls: true会让conda list和安装日志里显示包的真实来源地址排查到底从哪个源装的时非常方便建议一直开着。改完文件可以用conda config --show channels验证一下有没有被正确读取。如果不想手写文件命令行也可以conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --set show_channel_urls yes但用命令行加 channel 时要注意顺序--add是往列表头部插插多次会和你预期相反的顺序。相比之下我更推荐直接编辑.condarc一目了然。5.2 换源后仍然很慢或者报错的几种情况换完源还是慢先检查conda info里的 channel URLs 是否真的是镜像地址。有时.condarc写错缩进YAML 对缩进敏感必须用空格不能用 Tabconda 会静默忽略整份配置回退到默认源你看着像换了其实没换。另一个常见现象是加了镜像源之后出现了以前没有的报错比如某个包在镜像上同步滞后版本比官方源旧导致依赖求解失败。这时候可以临时指定用官方源conda install -c defaults some-package镜像同步一般滞后半天到一天急着用新版本时不要死磕镜像。还有一种是企业内网环境机器走统一的网络出口镜像源反而被限制这种情况就得用内部私有源或者离线包思路是conda install --offline配合本地包缓存或者用conda install /path/to/package.tar.bz2直接装本地的包文件。提示内网机器同步环境可以走conda-pack打包见第 8.3 节不需要逐台联网下载。6. 删除环境与清理缓存把磁盘抢回来6.1 删环境的两条命令删干净一个环境conda env remove -n myenv或者等价写法conda remove -n myenv --all推荐用conda env remove语义更明确不容易误操作。删之前先conda deactivate退出来否则在 Linux 上可能因为文件被占用删不干净Windows 上更是经常报文件正在被另一个进程使用。如果删到一半失败去envs目录下手动删文件夹再检查envs.txt里有没有残留的登记行有的话一起清掉。这里有个非常容易踩的坑conda remove -n myenv numpy这种不带--all的写法删的是环境里的某个包不是环境本身。我有次想删环境结果手滑少打参数把环境里的 numpy 删了那个环境直接废掉只能重建。所以删环境时一定确认有没有--all或者用conda env remove。6.2 conda clean缓存才是真正的磁盘杀手环境删了磁盘却没见涨多半是包缓存没清。conda 每次下载的包都会存在pkgs_dirs目录里一个包可能被多个环境共用所以删环境不会连带删掉这些缓存。清理命令conda clean --all这个会清掉索引缓存、未使用的包、tar 包、日志等。更温和的做法是按类型清命令清理对象建议频率conda clean -p未被任何环境引用的包目录删完环境后执行conda clean -t下载的 tar.bz2 压缩包每月一次conda clean -i索引缓存换源后执行conda clean --all以上全部加日志磁盘紧张时我在一台长期跑实验的机器上清过一次--all直接回收了 40 多 G。但要注意清完之后下次装同样的包要重新下载如果网络不好可以只清-t保留解压好的包目录这样重建环境时直接硬链接秒装。6.3 环境迁移别用复制粘贴想把自己配好的环境搬到另一台机器不要直接拷贝 envs 目录。环境里的可执行脚本、activate脚本都写死了创建时的绝对路径换台机器路径一变python 解释器都启动不了。正确的迁移方式有两种第一种是导出为 yml 文件在目标机器重建conda env export environment.yml conda env create -f environment.yml如果希望跨平台兼容导出时用--no-builds去掉 build 号因为 build 号是跟平台绑定的Windows 是 h 开头Linux 是 h 或别的带上去会导致在另一个平台上找不到对应 build。更干净的写法是--from-history只导出你显式装过的包不导出那一大堆依赖重建出来的环境更精简但需要网络。conda env export --from-history environment.yml第二种是网络不通的离线场景用conda-pack打包整个环境conda install -n base -c conda-forge conda-pack conda pack -n myenv -o myenv.tar.gz把 tar 包拷到目标机器同操作系统的环境上解压然后执行./bin/conda-unpackWindows 是Scripts\conda-unpack.exe它会自动把包里的绝对路径改写成当前路径。这个方案对无网环境特别友好我在几台隔离的机器之间倒腾环境都是这么干的。7. 报错实录那些真正卡住人的问题7.1 conda 不是内部或外部命令这是新手第一道坎。根因就一个conda 的可执行文件不在 PATH 里。先确认你的安装目录Windows 上找anaconda3\Scripts\conda.exe找到之后把这个目录和上一级安装目录都加进环境变量。加完重开终端再试已经开着的终端不认新 PATH。Linux 和 macOS 上大概率是没跑初始化或者跑完没重开 shell。~/miniconda3/bin/conda是存在的但 shell 没加载 profile。执行~/miniconda3/bin/conda init bash然后重开终端即可。还有一个隐蔽情况用 sudo 装的、或者系统里装了多个 condaPATH 指向了错的那个。用where condaWindows或which -a condaLinux/macOS看看到底解析到了哪个。7.2 求解环境卡死或失败现象是卡在Solving environment: ...转圈几分钟甚至更久最后报failed with initial frozen solve。这是 conda 自带的经典求解器在大依赖树上算不动。两个方向解决一是加--no-deps跳过依赖求解只在你明确知道依赖齐了的情况下用二是把求解器换成 libmambaconda install -n base conda-libmamba-solver conda config --set solver libmamba换完之后求解速度通常快好几倍实测在依赖复杂的深度学习环境上提升非常明显。另一个选择是直接用 mamba 这个兼容工具命令基本一致把conda换成mamba就行它底层就是 libmamba 求解器。如果报的是PackagesNotFoundError说明当前 channel 里没有这个包或者包名拼错了。先conda search 包名看看有没有没有就换 channel比如加-c conda-forge很多小众包只在这里。搜不到再考虑 pip 装。7.3 DLL 初始化失败与 CUDA 相关报错这条报错很多人见过OSError: [WinError 1114] 动态链接库(DLL)初始化例程失败。 Error loading ...\torch\lib\c10.dll or one of its dependencies.torch 的c10.dll加载不了绝大多数不是 torch 本身的问题而是它依赖的底层运行库缺失或版本不匹配。按这个顺序排查装最新的 Microsoft Visual C 运行库VC_redist这是最常见的原因尤其是新装的系统检查 Python 版本和 torch 版本是否匹配Python 3.12 早期的 torch 版本不支持装上去就是这种报错检查是不是同时在环境里用 conda 装了一遍 torch、又用 pip 装了一遍两份文件混在一起删掉其中一个显卡驱动太旧CUDA 运行库初始化失败这种情况一般是cudnn相关报错升级驱动即可。关于 CUDAconda 装带 CUDA 的 torch 时pytorch-cuda11.7这种参数要写对版本而且要配一个 cudnn 版本匹配的 channel。我一般的处理是明确按官方给的组合来conda install pytorch torchvision torchaudio pytorch-cuda11.7 -c pytorch -c nvidiapytorch-cuda后面的版本要和你机器上驱动支持的 CUDA 版本对得上驱动支持的 CUDA 版本可以用nvidia-smi右上角看到。驱动版本低于包要求时装完就是各种 DLL 和初始化失败。7.4 网络类报错CondaHTTPError、SSLError、ConnectionError这一类基本都出在网络层。先确认是不是没配网或者镜像源挂了换回默认源试一次如果默认源能通说明是镜像的问题。SSLError有可能是系统证书过期更新系统证书或者装certifi通常能解决。另一个高频场景是机器走了统一代理但 conda 不知道需要在.condarc里配proxy_servers: http: http://your-proxy:port https: https://your-proxy:port或者设HTTP_PROXY、HTTPS_PROXY环境变量。这里要强调如果你在公司网络里访问不了公共源正确的做法是找运维要内部私有源地址而不是自己乱试公开的第三方源。7.5 排查速查表报错关键字大概率原因处理动作conda 不是内部或外部命令PATH 没配加安装目录和 Scripts 目录重开终端run conda init before conda activateshell 未初始化执行 conda init重开终端或 sourceSolving environment 卡死求解器算不动换 libmamba 求解器PackagesNotFoundErrorchannel 里没有加 -c conda-forge 或搜索确认包名WinError 1114 c10.dll运行库缺失装 VC_redist查版本匹配EnvironmentLocationNotFound路径或登记错乱检查 envs_dirs 和 envs.txt删环境报文件占用环境还被激活或进程在跑deactivate 后重试或手动删目录环境激活后 python 命令找不到环境损坏用 conda list -n 从外部排查重建8. 和编辑器打通以及几个容易被忽略的配置8.1 PyCharm 里怎么选到 conda 环境PyCharm 新建项目时选Previously configured interpreter然后 Add Interpreter → Conda Environment → 选Use existing environment下拉框里会列出你所有的 conda 环境。如果没列出来在 Conda executable 那一栏手动指到 conda 的路径Windows 是miniconda3\Scripts\conda.exeLinux/macOS 是~/miniconda3/bin/conda。指对了之后环境列表会自动刷新。这里有个关键点解释器的路径要指向环境内部的 python 可执行文件不是环境目录本身。Windows 上是envs\myenv\python.exeLinux/macOS 上是envs/myenv/bin/python。手动选错成目录PyCharm 会一直提示解释器无效。另外 PyCharm 的终端默认会继承项目解释器对应的环境如果发现终端里conda activate出来的环境不对检查 Settings → Tools → Terminal 里的 shell path 配置。8.2 VSCode 里切换解释器VSCode 靠 Python 扩展识别环境。按CtrlShiftP输入Python: Select Interpreter列表里会显示所有 conda 环境名字后面带(conda)标记。选完新开终端python就会指向那个环境。如果列表里没有你的环境多半是 Python 扩展没找到 conda 路径可以在设置里搜python.condaPath手动填上。有一点要注意VSCode 的集成终端是否自动激活环境取决于设置项python.terminal.activateEnvironment。默认是开启的但如果你用的是自定义 shell 或者远程连接可能失效这时候在终端里手动conda activate一次即可。远程 WSL 场景下conda 要在 WSL 里装一份VSCode 的远程扩展会检测 WSL 内部的环境别在 Windows 侧配了却没装到 WSL 里那个是找不到的。8.3 导入别人的配置与版本回退别人给你一个environment.yml直接conda env create -f environment.yml想自定义名字加-n 新名字。如果文件里写死了prefix绝对路径跨机器会失效把那个字段删掉再导入。conda 自身版本想回退比如新版引入了你不想要的兼容问题conda install -n base conda23.1.0降级 base 里的 conda 需要一点耐心中途不要打断。回退前先把其他终端全关掉防止正在用 conda 的进程锁住文件。9. 几条用血泪换来的经验先说我个人最看重的一条建环境的时候就把 Python 版本钉死别用默认最新。我吃过一次亏某次建环境没写版本conda 给了个当时最新的 3.12结果几个依赖 numpy 1.x 的科研库全装不上来回折腾了两小时后来老老实实写python3.10一次就过。Python 小版本的生态兼容性差异比想象中大得多尤其在深度学习圈3.10 和 3.11 是目前最稳的两个选择。第二条是关于 pip 和 conda 混用。原则是能用 conda 装的优先用 condaconda 里没有的再用 pip而且一个包只用一种方式装。很多人都遇到过pip 装完 conda 又装一遍导致的文件冲突表现是 import 时报一堆奇怪的符号错误。想知道某个包是谁装的conda list最后一列写着pypi的就是 pip 装的其他就是 conda 装的。第三条.condarc里把pkgs_dirs指到大盘并且定期conda clean -t能省下非常可观的磁盘。我有台机器光包缓存就堆了 60 G清完那一刻感觉换了个新硬盘。最后分享一个小习惯每建一个新项目第一件事是建环境第二件事是在项目根目录放一个environment.yml并把当前环境导出进去。等半年后你回头看这个项目靠这一份文件就能一键重建比重装一遍省下的时间不是一点半点。环境这东西管得好是隐形资产管不好就是持续的隐性成本。