尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Jupyter Notebook多环境配置与内核切换完全指南:告别环境地狱

Jupyter Notebook多环境配置与内核切换完全指南:告别环境地狱 做数据科学和机器学习的人谁没在 Jupyter Notebook 里折腾过环境我见过太多情况一个项目要 TensorFlow 1.x另一个要 PyTorch还有一个要纯 Python 3.6 环境跑老代码。老老实实在 conda 里创建了分环境打开 Jupyter Notebook 却死活看不到这些新环境的名字只能在 base 环境里硬撑。又或者你明明在新环境里装好了包Notebook 里 import 却报 ModuleNotFoundError查半天发现内核用的还是另一个环境的 Python。这一期就把 Jupyter Notebook 多环境配置和内核切换这件事彻底讲清楚包含两种主流方法、内核管理机制、以及十个实操中用得上的排查技巧。不管你是刚入门还是已经踩过几次坑照着做基本都能一次搞定。1. 为什么要多环境以及 Jupyter「内核」到底是个什么东西1.1 多环境解决的是包依赖冲突Python 环境的混乱是很多人的噩梦。你装了某个库它依赖 numpy 1.x另一个项目却要求 numpy 2.x硬装的话其中一个项目就会跑不起来。conda 这类虚拟环境工具就是为了解决这个问题每个环境是一套独立的 Python 解释器和独立的 site-packages 目录在一个环境里装包完全不影响另一个环境。我在实际项目中通常这样划分环境环境名Python 版本主要用途py3103.10日常数据分析、pandas/sklearn 建模py383.8兼容旧模型代码、TensorFlow 1.15 遗留项目py3113.11JupyterLab 本身 常规开发作为主入口场景也很典型你有一个 2020 年写的模型文件用的是 Python 3.8 和 TF 1.15升级 Python 3.11 后各种报错。与其花时间改代码不如保留一个 py38 的旧环境需要跑它的时候切换过去效率高得多。1.2 内核不是 Jupyter 本体而是「一个后端 Python 进程的入口」很多新手会误以为 Jupyter Notebook 启动后所有代码都在同一个 Jupyter 进程里执行。实际完全不是这样。Jupyter Notebook 是一个 Web 界面你点一个单元格运行代码浏览器把代码发给 Jupyter ServerJupyter Server 再启动一个独立的「内核进程」来执行代码。这个内核本质上就是某个特定 Python 环境里的解释器进程。Jupyter 本体只是一个外壳代码真正跑在哪个解释器里取决于你选择的是哪个「内核」。每个内核对应一个 kernel.json 文件里面记录了这个内核要调用的 Python 解释器路径、环境变量、启动参数等。你打开 Jupyter 界面时右上角或菜单里看到的内核名字列表就是 Jupyter 去扫描固定目录下所有 kernel.json 后生成的。所以要让新 conda 环境出现在内核列表里核心工作就是给那个环境生成一份 kernel.json让 Jupyter 能发现它。理解了这一点你就明白为什么很多人「在 Jupyter 里找不到新环境」——他们只创建了 conda 环境但没有注册内核Jupyter 根本不知道那个环境存在。2. 环境准备安装 Conda 并创建目标环境2.1 安装 Anaconda 或 Miniconda要管理多环境conda 是目前最主流的方式。Miniconda 更轻量只包含 conda 和 Python 基础包Anaconda 自带的包多适合不想一个个装的人。我平时用 Miniconda因为环境都是自己按需装的Anaconda 里很多包用不上还占空间。Windows 和 macOS 的用户直接下载官方安装包Linux 用户用命令安装。装的时候有几个容易忽略的点注意安装过程中Windows 上千万不要勾选「Add Anaconda to my PATH environment variable」正确做法是安装完成后使用 Anaconda Prompt 或 PowerShell 里的 conda init 功能避免污染系统 PATH。很多人装完出现 conda 不是内部命令就是因为初始化出了问题。安装完成后在终端里执行conda --version看到版本号就说明基础环境没问题。如果没有往后走几步conda init bash然后重启终端。Windows 用户则是在开始菜单里的 Anaconda Prompt 中操作。2.2 用 conda 创建两个目标环境为了演示我建两个环境一个叫 env_dataPython 3.10一个叫 env_legacyPython 3.8conda create -n env_data python3.10 -y conda create -n env_legacy python3.8 -y基本对应文章开头表格里的 py310 和 py38 两个场景。建完后分别激活环境装几个常用包conda activate env_data pip install numpy pandas scikit-learn matplotlib conda activate env_legacy pip install numpy1.19.5 pandas1.2.4 matplotlib这里故意在 env_legacy 里装旧版 numpy是想模拟出一个真实场景当你切到 env_legacy 这个内核时能感觉到 numpy 版本确实变了验证内核切换是真实生效而不是表面现象。3. 方法一用 ipykernel 手动注册内核最通用也最稳定3.1 安装 ipykernel 并理解「在哪个环境装」的区别这是最老牌也最可靠的方案它适合所有场景包括 conda 环境、venv 环境以及某些需要手动指定解释器的奇葩需求。关键点在于ipykernel 必须装在你希望「作为内核运行」的那个环境里。比如我想让 env_data 出现在 Jupyter 的内核列表中就必须在 env_data 环境下安装 ipykernelconda activate env_data pip install ipykernel执行完这条命令后已经安装的 ipykernel 也不能直接注册还需要一步操作执行 python -m ipykernel install告诉 Jupyter「这个环境可以注册为一个内核」。3.2 模块安装与内核注册的原理当你在 env_data 环境下执行 python -m ipykernel install 时它做的事情很明确找到这个环境对应的 python.exeWindows或 pythonLinux/macOS的绝对路径然后把这串路径写进一个 kernel.json 文件再把文件放到 Jupyter 的 kernels 目录。以后 Jupyter 看到这个文件就知道「这里有一个内核它的 Python 解释器是 xxx」。实际操作# 在 env_data 环境下 python -m ipykernel install --user --name env_data --display-name Python (env_data)参数拆解--user把 kernel.json 安装到当前用户的 kernels 目录而不是全局系统目录。普通情况用 --user 就够也避免权限问题。--name内核的唯一标识名一般和 env 名保持一致方便识别和管理。这个 name 不能有空格和特殊符号。--display-name在 Jupyter Notebook 界面上显示的名字可以随便起比如「Python (env_data)」中文也支持。同理给 env_legacy 注册conda activate env_legacy pip install ipykernel python -m ipykernel install --user --name env_legacy --display-name Python (env_legacy)完成后再看一眼 kernels 目录下生成的 kernel.json 内容Windows 一般在 C:\Users\你的用户名\AppData\Roaming\jupyter\kernels\env_data\kernel.jsonLinux/macOS 在 ~/.local/share/jupyter/kernels/env_data/kernel.json{ argv: [ C:/Users/你的用户名/miniconda3/envs/env_data/python.exe, -m, ipykernel_launcher, -f, {connection_file} ], display_name: Python (env_data), language: python }看到 argv 里第一项是 env_data 环境的 python 路径就说明注册成功了。Jupyter 启动内核的时候就是用这个路径去启动一个解释器进程。3.3 启动 Jupyter 并切换内核接下来启动 Notebookjupyter notebook浏览器打开首页后你会发现新建 Notebook 时下拉列表里多了两个选项Python (env_data) 和 Python (env_legacy)。如果是已经打开的 Notebook可以通过菜单栏 Kernel - Change Kernel 来切换或者点击右上角的内核名称直接切换。切到 env_legacy 后我习惯先跑一段验证代码import sys import numpy as np print(sys.executable) print(np.__version__)如果一切正常sys.executable 会指向 env_legacy 环境下的 python.exenumpy 版本显示 1.19.5。这就证明代码确实跑在那个旧环境里了。4. 方法二用 nb_conda_kernels 自动发现环境懒人福音4.1 自动发现所有 conda 环境手动注册每次新建环境都要重复一遍「装 ipykernel install」的操作虽然不麻烦但总归是手动动作。如果你有大量的 conda 环境比较省心的方案是 nb_conda_kernels。这个包的工作原理和手动注册完全不同它是装在 Jupyter Server 所在环境通常是 base 环境里的一个扩展。它启动后会扫描你系统里所有的 conda envs发现哪个环境装了 ipykernel就自动生成对应的内核不需要你手动指定 name 和 display-name。安装方式conda activate base conda install nb_conda_kernels -y然后启动 Jupyterjupyter notebook这个时候再新建 Notebook你会发现所有安装了 ipykernel 的 conda 环境都自动出现在了内核列表里。注意这里的条件至少两个环境都要安装 ipykernelnb_conda_kernels 才能识别并生成内核。4.2 两种方法怎么选手动注册方法一和自动发现方法二各有利弊我分享一下实际使用的取舍。对比维度ipykernel 手动注册nb_conda_kernels 自动发现适用环境conda、venv、自编译 Python 都能用仅 conda 环境效果最理想配置步骤每个环境都要手动执行命令只在 base 环境装一次后续环境自动识别可控性内核的名字、显示名完全自己定义内核名是 conda env 名自动显示为 Python [conda env:xxx]也想手动改但麻烦出错概率低手动路径明确偶尔需要保证各环境 ipykernel 版本支持管理批量环境环境多了嫌麻烦不心动吗新建环境后无需手动注册我个人的习惯是日常使用 nb_conda_kernels 做主力因为建新环境后省去手动注册步骤。但遇到那种非 conda 的虚拟环境或者希望内核名非常直观的场景还是会用 ipykernel 手动注册。两种方法并不冲突可以同时装内核列表里会同时出现两种方式注册的内核只是要留意避免重复注册同名内核。5. 内核管理的进阶玩法查看、删除、重命名与多解释器支持5.1 列出所有内核不管用哪种方式最终都是向 Jupyter 的 kernels 目录写 kernel.json。想查看当前 Jupyter 到底发现了哪些内核执行jupyter kernelspec list输出示例Available kernels: env_data C:/Users/你的用户名/AppData/Roaming/jupyter/kernels/env_data env_legacy C:/Users/你的用户名/AppData/Roaming/jupyter/kernels/env_legacy python3 C:/Users/你的用户名/miniconda3/share/jupyter/kernels/python3python3 是 conda 自带的默认内核对应 base 环境。如果执行完没看到刚注册的环境名说明 kernel.json 写的位置 Jupyter 没有扫描到或者注册命令执行时报错了回头检查那两条命令是否在正确的环境下执行。5.2 删除和重命名内核删除一个内核很简单直接删对应的 kernel.json 目录或者用命令jupyter kernelspec uninstall env_data这个场景很实用。比如你删除了某个 conda 环境但它对应的内核还残留在列表里选中的话会报错。清理方式就是上面的命令。重命名则不建议用命令直接改 kernel.json 里的 display_name 字段就行。比如我想让 env_legacy 在界面上显示为「Legacy TF1.15」用编辑器打开它的 kernel.json把 display_name 改成 Legacy TF1.15保存后重启 Jupyter界面显示名就变了。注意 --name 对应的目录名不能随便改因为它是内核的唯一 ID改名等于注册了一个新内核。5.3 不只有 PythonR、Julia 和虚拟环境也能注册这个方案理论上可以给任何 Jupyter 支持的语言注册内核。比如装 R 内核conda activate env_r conda install r-irkernel -y R -e IRkernel::installspec(name env_r, displayname R (env_r))Julia 装 IJulia 后会自动注册venv 创建的环境也能用 ipykernel 注册方式和 conda env 几乎一样只是路径不同。防火墙、权限、网络问题暂不展开这里要强调的是只要解释器能被操作系统直接调用、能被 ipykernel 找到你就能把它注册成 Jupyter 内核这是这套机制最大的灵活性。6. 常见问题与排查技巧实录6.1 我在 conda 里建了环境但 Jupyter 找不到这是被问得最多的一个问题。原因几乎都是同一个没有注册内核或者 Jupyter Server 运行的环境和创建的环境不是同一个。检查顺序执行conda activate 你的环境名确认你在目标环境中。执行which pythonLinux/macOS或where pythonWindows确认路径包含你的环境名。执行pip show ipykernel确认 ipykernel 已安装。没装就pip install ipykernel。执行python -m ipykernel install --user --name 你的环境名 --display-name Python (你的环境名)观察输出没有报错。执行jupyter kernelspec list确认新增。重启 Jupyter Server。6.2 在 Notebook 里 import 已安装的包报 ModuleNotFoundError典型表现你在 env_data 里pip install pandas打开 Notebook 却发现 pandas 不存在。原因很直接Notebook 当前使用的内核不是 env_data 环境。比如你在 base 环境启动了 Jupyter新建 Notebook 默认用的是 python3 内核也就是 base 环境自然看不到 env_data 里装的包。解决方式就是切换内核通过菜单 Kernel - Change Kernel选择 Python (env_data)。也可以在新建 Notebook 的时候直接选对内核。很难排查的话先跑一下 sys.executable 打印路径立刻能定位用的哪个解释器。技巧当你同时开多个环境时最好创建一个「标准验证单元格」内容就是 sys.executable 和关键包的版本号切换内核后先跑一遍确认环境正确再进行后续操作。6.3 启动 Jupyter 后浏览器不弹出来Jupyter 本质是在本地开了一个 HTTP 服务浏览器只是个客户端。不弹浏览器有几种情况一是电脑默认浏览器设置问题。Jupyter 偶尔会尝试调用系统默认浏览器失败尤其是第一次使用或系统默认浏览器被修改过。解决方式是直接复制 Jupyter Server 启动后终端输出的那个 URL一般是 http://localhost:8888/tree手动粘贴到浏览器地址栏访问。这招最实在。二是端口被占用。默认端口 8888如果之前有残留的 Jupyter 进程会出现端口占用或跳转到 8889。奇怪但常见。可以执行jupyter notebook --port9999指定端口顺便看是不是有多个 Jupyter 实例在跑。三是防火墙拦截了 localhost 回环连接。这个比较少但企业电脑或某些安全软件可能出问题。6.4 Notebook 单元格执行代码没有任何反应这个热搜的关键词很有代表性遇到「点了运行没反应」绝大多数不是代码问题而是前端连接不到内核。可能的情况内核已经死了界面右上角圆圈一直转或显示断线。你手动切换了 conda 环境然后停掉了原来的 Jupyter Server 进程。内存达到上限Python 进程被系统杀掉。安装了某个前端扩展干扰了 JupyterLab 的交互。浏览器插件比如广告拦截类拦截了 websocket 连接。处理方案先健康检查在终端看 Jupyter Server 日志有没有 kernel has died 之类。换一个全新的干净内核测试用最简单的一句话 print(test)排除代码本身的问题。关闭所有浏览器插件后刷新页面。直接重启 JupyterCtrlC 关闭服务重新启动。换一个浏览器试试Chrome 和 Edge 出问题的概率相对低老版本 Safari 有时抽风。右键检查浏览器控制台报错能定位是 websocket 断开还是 JS 报错。6.5 同一个环境命令行里能 importNotebook 里却不行这种情况通常发生在「启动 Jupyter 的位置」环境混乱的时候。比如说你从 base 环境启动的 Notebook然后新建 Notebook 时手动选了某个环境的内核。内核创建是独立进程它的解释器路径是 kernel.json 里写的那个跟你终端的当前环境没有任何关系。还有一种是在某个环境里启动了 jupyter notebook但登录页面默认内核是 python3显示 base 环境。你以为在项目环境里实际上一直在 base 跑的导致越跑越乱。最好的习惯启动 Jupyter 之前先 conda activate 目标环境再确认 kernelspec list 里期望的内核都在最后启动。这套流程能避免绝大多数环境错乱。6.6 Jupyter Notebook 网页版登录入口与密码问题如果 Jupyter 不是你本机启动的而是跑在远端服务器访问时要填 token 或密码。启动时终端会显示类似http://localhost:8888/tree?tokenxxxxxx的一串地址。直接复制访问就不需要单独输入 token。如果记不住可以在配置目录里配置固定密码jupyter notebook password输入两次密码会写入配置文件之后再登录输入这个密码即可。这个方法在团队协作服务器上比较常用。6.7 新环境里安装好内核还是反复出现 Configuration file 报错有些用户会遇到 Jupyter 提示 The configuration file could not be loaded、或者注册内核时提示路径不对。多数情况是 Jupyter 的配置目录权限或环境变量出了问题。Windows 上常见的是 JUPYTER_CONFIG_DIR 或用户目录没配好。可以尝试执行jupyter --paths查看 Jupyter 到底在哪些位置找配置和 kernels确认检查目标是否指向你预期的地方。6.8 内核列表里出现重复的相同名字如果你先手动注册了一个 env_data 的内核后面又装了 nb_conda_kernels列表里可能会出现两个指向同一环境的条目只是名字不同。这种问题虽然不影响使用但比较碍眼。建议制定一套规则要么全部走 nb_conda_kernels 自动发现要么全部手动注册。要切换方式时先把另一个方式产生的内容清理掉再启用另一种。避免混用导致内核列表越来越冗长。6.9 环境里装了 jupyter 或 jupyterlab但外层的 Jupyter 找不到它这也解释了为什么我建议把所有环境都装 jupyter 的话不在环境里装——你只需要在 base 环境装一份 JupyterLab/Notebook 作为入口其余环境只需要装 ipykernel 或让 nb_conda_kernels 自动感知。如果每个环境都装一份 jupyter notebook不仅磁盘占用大还会产生各种混乱的端口进程。我的推荐布局是base 环境只装 jupyterlab、nb_conda_kernels可选。业务环境按项目需求装 pip/conda 包加上 ipykernel通过 Jupyter 内核方式使用。6.10 使用虚拟环境 venv 时怎么注册不一定只能用 conda。如果你用的是 Python 自带的 venvpython -m venv /path/to/myenv source /path/to/myenv/bin/activate # Linux/macOS /path/to/myenv/Scripts/activate.bat # Windows pip install ipykernel python -m ipykernel install --user --name myvenv --display-name Python (myvenv)原理一模一样只要路径和激活方式不同。有时候环境里 pip 安装 ipykernel 会提示环境配置问题但路径对得上基本都能注册成功。7. 实操心得总结写到这里我认为值得强调的一件事情是Jupyter Notebook 多环境配置的核心就是理解「内核 解释器进程」这个等式。不管是手动注册还是 nb_conda_kernels 自动发现最终都是让 Jupyter 知道「你要用哪个 Python 来跑这段代码」。这条路走通了后面不管多少个环境都是重复几个固定步骤。最后分享几个我保持在日常使用中的习惯每次新建环境先装 ipykernel再顺手jupyter kernelspec list确认注册成功。这样永远不会出现「环境建了一堆Jupyter 里全看不见」的尴尬。给内核起显示名时带上 Python 版本或项目名比如 Python 3.10 (nlp)界面上一眼能识别。当遇到 import 报错第一步永远先打印 sys.executable 确认解释器路径而不是急着 pip install。周期性执行jupyter kernelspec list把长期不用的旧内核清掉环境干净能省很多无谓的心智负担。希望这篇文章能让你从「环境地狱」里解脱出来。有问题欢迎在评论区说出具体现象和日志我看到会尽量回复。
返回列表