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

资讯详情

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

Jupyter Notebook 运行无反应?从 Kernel 到 DLL 的完整排查指南

Jupyter Notebook 运行无反应?从 Kernel 到 DLL 的完整排查指南 Jupyter Notebook 里把文件命名为error.ipynb然后点运行单元格光标一直在转In [*]卡住不动输出区一片空白连个报错都不给——这个场景我见过的次数一只手数不过来。而且非常诡异的是很多人在网上搜Jupyter error 运行没反应第一反应都会归咎于是不是文件名里带了 error 这个单词程序以为自己是错误文件所以拒绝执行。今天想说句公道话Jupyter Notebook 从来没有文件名包含 error 就静默拒绝运行这种设定。文件叫error.ipynb、test_error.ipynb、错误.ipynb都能正常执行。那为什么你的笔记本确实没反应因为真正的问题藏在更深的地方——Kernel 没连上、依赖库 DLL 加载失败、浏览器端 JS 报错、环境变量混乱这些都会造成运行无反应而文件名里的 error 只是压垮心理防线的最后一根稻草。这篇文章会从现象复现开始逐层拆解命名 error 且运行没反应背后真正的技术链路把每个排查步骤、日志位置、解决命令都写清楚所有过程都是我实际排查中用过的路径适合卡壳半天找不到头绪的 Jupyter 使用者直接照抄。1. 先复现一次这个error现象到底长什么样我先把最容易被误解的地方拎出来你在 Jupyter 文件列表里看到的error标记和文件名完全是两回事。1.1 文件列表里的红色 error 标记说的是文件健康状态新建一个 notebook默认名字是Untitled.ipynb注意看左侧文件列表——如果这个文件曾经运行到一半 Kernel 崩了或者代码抛了异常但你没关闭输出文件列表里它前面会出现一个红底白字的 error 图标。这是 Jupyter 在告诉你这个 notebook 最后一次执行状态不正常或者它是一个从崩溃中恢复的副本。很多人看到这个红色 error 再低头看文件名里也有 error就觉得完了文件被标记为错误了。其实你把文件名改成test.ipynb只要 Kernel 上次是异常退出的它照样显示红色 error 图标。这个标记来自 notebook 的元数据execution_state和kernel连接状态跟名字里的字符串没有半毛钱关系。真正决定运行有没有反应的是当前 Kernel 进程是否存活、是否建立了连接。1.2 运行没反应的具体表现比想象中更迷惑我总结了一下运行没反应最常见的几种表现你可以对号入座表现状态特征最容易误判的方向In [*]一直不变单元格左边一直显示星号不变成数字以为是代码死循环实际 Kernel 没收到任务输出区完全空白执行后既没有报错红字也没有正常输出以为是 print 写错了实际执行根本没启动光标闪烁但无反应点运行按钮后按钮变灰页面像卡住以为是浏览器卡了实际是 WebSocket 连接断了控制台没有任何输出终端里 Jupyter 日志也没动静以为是静默错误实际 Kernel 早就退出了注意第一行的In [*]——这是 Jupyter 最诚实的信号。它代表内核已接收代码但未返回结果。如果连这行都不出现说明内核压根没收到你的执行请求。如果In [*]出现后长时间不变化十有八九是内核进程还活着但执行被某个阻塞操作拖住了或者内核已经死掉但前端不知道。我当时在被这个问题折磨的时候第一件事就是把文件名 error这个因素彻底忘掉直接去查三层链路Kernel 状态、后端日志、浏览器控制台。接下来按这个顺序讲。2. error命名的两个隐藏风险不是运行元凶但强烈建议改掉虽然文件名不是运行没反应的原因但我在实际项目协作中发现error这个名字确实会带来两类副作用不致命但足够烦人。2.1 风险一误导协作者和三天后的你自己数据科学项目里 notebook 经常要分享给同事。你给文件起名error.ipynb同事打开项目目录看到的是一堆error.ipynb、error_final.ipynb、error_final2.ipynb他根本不知道这个文件是干嘛的。更常见的是如果你把 notebook 输出为 HTML 或 PDF 报告标题栏也会原样带着 error客户收到一个叫error.html的交付文件第一印象就很糟糕。我自己的习惯是notebook 命名用日期_用途_状态格式比如20250115_数据清洗_v2.ipynb。如果这个文件确实在排查某个错误我会用debug_xxx而不是error避免和 Jupyter 的 error 状态标记在视觉上混淆。2.2 风险二版本管理和自动化工具容易误伤不少团队用 git 管理 notebook很多 CI 配置里会写一些文件过滤规则。比如.gitignore里忽略了error.log、error_report.html之类的产物如果你偏偏建了一个error_notebook.ipynb某些自动化脚本在扫描文件名时也可能产生误判轻则报警重则把文件当成日志清理掉。虽然这些都属于工具规则设计问题但没必要让自己踩这种莫名其妙的坑。2.3 如果你想改名先停手用 Jupyter 的内部重命名这里有个很多新手踩过的坑直接去 Windows 资源管理器里把error.ipynb改名成normal.ipynb然后双击打开发现 notebook 内容变成了一堆乱码甚至 Jupyter 根本打不开。原因很简单.ipynb本质是 JSON 文件文件名的name字段和磁盘上的实际文件名是一一对应的。你用外部工具改名后notebook 内部的metadata.name还是旧值Jupyter 打开时发现不一致轻则弹警告重则触发 JSON 解析异常表现为打开后运行没反应。正确做法是在 Jupyter 首页勾选文件点 Rename或者打开 notebook 后用 File - Save Notebook As 另存为新名字让 Jupyter 同时更新内部元数据和磁盘文件名。改完名之后保险起见重启一下 Kernel 再跑避免旧内核和新元数据产生状态错位。3. 第一层真凶排查Kernel 状态与运行日志排除了文件名这个干扰项后开始查真凶。运行没反应90% 的情况出在前端和内核之间的连接上。这一层没查清楚后面全都是白忙。3.1 右上角那个圆点信息量很大Jupyter Notebook 界面右上角有个实心圆点旁边写着 Kernel 状态一般有四种情况状态含义能否执行 cellNo Kernel没有选择任何内核不能Connecting / Reconnecting前端正在尝试连接内核进程不能等一会可能好Starting内核进程正在启动中可能可以但很慢Idle内核空闲等待执行可以Busy内核正在执行代码可以排队但看起来像没反应我遇到最多的运行没反应其实是 Connecting 和 Starting 卡死。你点运行前端把代码通过 WebSocket 发给内核但连接根本没建立起来代码就挂在半空中表现就是In [*]永远不变。这种时候点十次运行都没用得先解决连接问题。解决方案按顺序试菜单栏Kernel - Restart Kernel等状态变成 Idle 再执行。如果 Restart 后还是 Connecting点击Kernel - Change Kernel重新选择Python 3 (ipykernel)。如果列表里没有可选内核说明你的 Jupyter 不知道自己该用哪个 Python 环境后面会专门讲。3.2 启动 Jupyter 的那个终端窗口才是真正的案发现场很多人习惯从 Anaconda Navigator 或快捷方式启动 Jupyter然后启动窗口就最小化不管了。这是最大的错误——那个窗口会打印所有内核启动日志。运行没反应时切到那个窗口拉到底部你大概率能看到类似这样的信息[I 20250115 10:23:45 notebookapp] Kernel started: 123abc [E 20250115 10:23:46 kernelmanager] Error in kernel startup: Traceback (most recent call last): File C:\...\base\lib\site-packages\jupyter_client\manager.py, line 234, in start_kernel raise RuntimeError(Kernel didnt respond in 60 seconds) RuntimeError: Kernel didnt respond in 60 secondsKernel didnt respond是内核进程本身启动失败。下面通常跟着更明确的报错。如果启动窗口里没有任何输出那问题可能出在浏览器端跳到第 5 部分看。3.3 用新笔记本测试法快速定位当你不确定是当前文件坏了还是整个 Kernl 坏了最快的办法是新开一个空白笔记本执行print(11)。操作路径File - New - Notebook然后输入 11 执行。如果新笔记本正常输出2说明 Kernel 没问题问题在当前这个error.ipynb文件本身可能 JSON 元数据损坏后面有修复方法。如果新笔记本也没反应问题在全局环境继续往下看。这一招能帮你把排查范围立刻缩小一半比我见过很多人一遍遍重启电脑高效得多。4. 第二层真凶排查DLL 加载失败这类环境级错误新笔记本也没反应、启动日志里出现Importerror或DLL load failed——恭喜你找到了真正的案发现场。这类问题在 Windows 上非常常见也是最近搜索热词里大家集中踩坑的重灾区。4.1 典型症状import 阶段直接 DLL load failed举个例子热词里反复出现的这条报错运行jupyter notebook出现importerror: dll load failed while importing rpds:rpds-py是一个 Python 依赖库被jsonschema等包间接依赖。Windows 下出现DLL load failed while importing rpds通常不是你的代码写错了而是rpds这个二进制包和你当前 Python 版本、Visual C 运行库不匹配。你的 notebook 第一行可能就是import something触发了这个错误但由于它发生在内核初始化阶段前端的表现经常是运行没反应而不是红字报错。我见过最典型的一个案例用户在 Anaconda base 环境Python 3.11能跑后来新装了一个 Python 3.12 环境再用 Jupyter 选到新环境一执行就In [*]卡住切到终端看到的就是 rpdsDLL load failed。原因是 Python 3.12 对应的rpds-py新版还没适配或者安装的是旧版二进制动态库加载不了。4.2 为什么 DLL 加载失败经常表现为没反应这里要先理解 Jupyter 的执行链路。你点运行后前端把代码发给内核内核在执行代码前要先初始化自己的 Python 环境——导入 IPython 本身的依赖库。这些依赖库里只要有一个 DLL 加载失败内核进程就会在初始化阶段崩溃。但内核崩溃后前端拿到的可能是一条 WebSocket 断开消息而不是 Python 的错误输出。所以你的屏幕表现就是点击运行 - 转圈 - 没反应 - Kernel 状态变回 No Kernel 或 Connecting。4.3 一套可落地的修复方案遇到这类问题别在 notebook 里反复重试直接在终端cmd 或 Anaconda Prompt里操作# 1. 确认当前内核用的是哪个 Python jupyter kernelspec list # 2. 进入内核对应的 Python 环境重新安装对应库 conda activate your_env_name pip install --upgrade rpds-py # 3. 验证库能否单独加载 python -c import rpds; print(ok)如果第 3 步直接报DLL load failed说明问题出在 VC 运行库。下载安装最新版 Visual C Redistributablex64 版本重启电脑再验证一次。绝大多数DLL load failed while importing的库都能通过重装库装运行库解决。注意安装后要重启 Jupyter不是只重启 Kernel——因为 DLL 的加载发生在进程第一次启动时。如果是ipykernel本身出了问题可以执行conda install ipykernel --force-reinstall我遇到过一个很刁钻的情况ipykernel版本太旧不兼容当前 Python 3.12导致内核启动就崩表现同样是运行没反应。强制重装到最新版后解决。4.4 容易被误判的partially initialized module提示还有一种报错出现在终端里提示ImportError: cannot import name xxx from partially initialized module yyy新手的常见反应是去翻yyy包的源码看那个函数是不是改名了。但实际上这个报错绝大多数是yyy包依赖的某个底层 DLL 加载失败导致模块初始化不完整。解决方案和上面一样重装对应的依赖包或者干脆把环境里的包用 conda 统一重装一遍。不要一上来就怀疑函数名。5. 第三层真凶排查浏览器端被忽略的报错如果后端日志干干净净Kernel 也能启动新笔记本也能跑但你回到那个命名 error的文件还是没反应——那问题很可能不在 Python不在后端而在你的浏览器。这一层很多人一辈子没想过但它真实的坑很多。5.1 按 F12看 Console 里的红色报错在没反应的 Jupyter 页面按 F12 打开开发者工具切到 Console控制台标签看有没有红色报错。最常见的有两类报错内容含义处理方式WebSocket connection to ws://... failed前端和后端的 WebSocket 连接断开刷新页面试一次还不行重启 JupyterFailed to load resource: 404某些 JS 文件找不到一般是 Jupyter 静态资源没装全重装 jupyter notebookERR_CONNECTION_REFUSED浏览器访问不了本地端口重启 Jupyter 或换端口启动很多情况下刷新页面就能解决——因为 WebSocket 连接可能因为休眠而断开了但 Jupyter 没自动重连。刷新后如果 Kernel 状态变成 Idle立刻试运行。刷新都解决不了的重启jupyter notebook服务。5.2 浏览器插件Jupyter 静默失败的隐形杀手这是我最想吐槽的一类问题。有段时间我装了某个翻译插件和一个广告拦截插件之后每次在 Jupyter 里连续执行多个单元格第二个单元格必卡死页面看起来像死机但终端日志完全正常。折腾了一整天最后在无痕窗口里打开同样的 URL一切正常才定位到是插件在搞鬼。遇到运行没反应且后端日志正常时强烈建议做一个插件排除测试复制 Jupyter 的 URL形如http://localhost:8888/notebooks/xxx.ipynb。打开无痕/隐私窗口粘贴 URL 访问。无痕窗口里执行相同代码。如果正常说明是你日常浏览器的某个插件在拦截 WebSocket 请求或干扰页面脚本。Jupyter 的前端依赖 WebSocket 与内核通信而部分插件会拦截本地 WebSocket导致代码发不出去表现就是按钮点了没反应。这个问题在 GitHub 上有一堆 issue但 Jupyter 官方没有能力修复浏览器插件冲突只能自己排查。5.3 一个被忽略的选项尝试换个浏览器如果你用的浏览器是某个赖在旧内核版本上的魔改版或者打开了太多标签导致内存紧张换个浏览器是最快的验证方式。我一般备用的组合是主力 Chrome 日常写代码出问题直接用 Edge 或 Firefox 开同样的 URL。换浏览器能立刻把浏览器问题和后端问题切成两半。6. 从现象倒推一套可照抄的排查顺序前面把三层真凶都拆开了现在把它们串成一条时间线。以后你再遇到Jupyter 运行没反应建议死死按这个顺序走不要跳步不要一上来就重装 Anaconda。下面这张表是我每次排查的实际顺序你直接抄。6.1 五分钟排查清单步骤操作定位的问题类型1看右上角 Kernel 状态连接状态类2切到启动 Jupyter 的终端窗口拉日志内核启动崩溃、依赖缺失3新开空白 notebook执行11当前文件损坏 vs 全局环境故障4按 F12 查看浏览器 ConsoleWebSocket 断开、插件拦截5无痕窗口访问同一 URL浏览器插件冲突6终端执行jupyter kernelspec list内核环境混乱7重启 Jupyter 服务页面状态假死/连接泄漏这里提个醒很多教程一上来就让你pip install --upgrade notebook或者重装 Anaconda我强烈反对。如果是插件冲突或 Kernel 状态问题重装完了问题还在白白浪费一个小时。按表格从上到下走每一步只需要几十秒走到哪一步发现真实报错就顺着修下去。6.2 一个完整的排错记录从error 命名到真相为了让这套流程更直观我分享一个近期帮人排查的实际案例字段做了脱敏但过程完全真实。一位同事的 notebook 文件叫error_demo.ipynb里面第一行是import pandas as pd执行后一直In [*]完全没输出。他最开始怀疑是文件名带了 error改名为demo.ipynb后依然如故。我接手后按上面的清单走右上角 Kernel 状态显示Starting但不是 Idle。切到 Anaconda Prompt 启动窗口看到最后几行[E ...] ModuleNotFoundError: No module named pandas问题立刻清楚了他通过 Anaconda Navigator 启动 Jupyter默认使用的是 base 环境但 pandas 装在另一个叫data_env环境里。base 环境里根本没有 pandas内核启动时因为 Python 文件开头有 import pandas 无法初始化于是在 GUI 里表现为运行没反应。解决方案不是改文件名而是Kernel - Change Kernel - data_env把内核切到正确的环境。切换后重新执行立刻输出正常。这个案例很典型文件名里的 error 完全是巧合真正的坑是Jupyter 用的环境和你的包所在环境不一致。Anaconda Navigator 默认以 base 环境启动 Jupyter如果你平时把包都装在自定义环境里新建的 notebook 虽然界面右上角显示 Python 3实际却可能永远找不到你需要的库。所以排查时问自己一句我确定 Jupyter 当前内核是我装包的那个环境吗6.3 notbook 文件本身损坏时的自救还有一种情况内核没问题、环境没问题、浏览器没问题但只有那个文件运行没反应而且打开文件时旁边有红色 error。十有八九是.ipynb文件本身被改坏了。常见原因是外部工具打开过文件并保存为非标准 JSON或者在文件保存时机器断电。自救步骤复制一份.ipynb备份。用文本编辑器打开确认最外层是合法的 JSON。如果metadata字段里kernel的name写了一个不存在的内核名如python3x把它改成python3。保存后刷新浏览器重新打开。另一个更稳的办法在终端里用 jq 或 Python 脚本校验 JSONjupyter nbconvert --to script error.ipynb如果这条命令能成功生成.py文件说明 notebook 的代码内容至少是完整的只是元数据有问题如果报错说明 JSON 损坏可能需要从autosave备份或.ipynb_checkpoints目录恢复。7. 这几条预防习惯比事后排查更重要排查经验再多也不如提前避开。这些年用过 Jupyter 之后我慢慢形成了一套近乎固执的防守习惯。这里没什么高深理论但每一条都是从运行没反应的血泪里换来的。7.1 用环境隔离 内核绑定兜底永远不要裸装一堆包到 base 环境。我的固定做法是每一个项目建一个环境项目根目录放一个environment.yml。创建环境后第一次启动 Jupyter 前先把这个环境注册成内核conda activate project_env pip install ipykernel python -m ipykernel install --user --name project_env --display-name Python (project_env)以后打开 Jupyter 时在Kernel - Change Kernel里就能直接看到带环境名的选项。这样即使 base 环境缺包也绝不会影响项目环境内的 notebook 执行。7.2 每换一次环境或升级大版本先跑一个最小矩阵换 Python 大版本比如 3.11 跳到 3.12或重装 Anaconda 后不要直接打开几十个旧 notebook。先新建一个空白 notebook一次性执行这些验证import sys print(sys.version) import pandas as pd import numpy as np # 其他项目依赖一次性 import 进来如果这一套能跑通再开旧文件。别小看这一步它能帮你把DLL load failed这类环境级问题拦截在正式工作之前。如果环境有问题这一条报错就会完整报到现在而不是让某个旧 notebook 静默无响应。7.3 命名规范日期开头 用途 版本我现在建文件永远用20250115_数据清洗_v3.ipynb这样的格式不用error、test、aaa这类词。好处有几个第一文件列表按文件名排序后同一天的 notebook 会聚在一起第二不会和 Jupyter 的 error 状态标记在视觉上混淆第三git 提交历史里别人能一眼看懂这个文件的用途。文件名尽量只包含字母、数字、下划线避免中文和空格带来的环境兼容问题——某些库对含中文路径的文件解析不够友好Windows 下路径带中文偶尔会触发奇怪的问题。养成这三个习惯之后你再遇到 Jupyter 无响应基本可以确定是环境或依赖的硬件问题而不是自己那点命名习惯惹的祸。排查范围能缩小到最近改了什么而不是哪个玄学地方出了问题。最后分享一个我个人的小经验。Jupyter 的运行没反应绝大多数不是玄学而是前端-Kernel-后端-浏览器这条链路在某一环断了。只要你记住链路的存在把看日志当成第一反应而不是百度报错文案很多问题几分钟就能定位。与其在网上反复搜error 命名运行没反应不如直接把启动 Jupyter 的那个终端窗口保持可见它藏着的真相永远比标题多。
返回列表