使用 IJava 的 Google Colab 笔记本在安装 + 刷新后卡在“正在连接”

2023-11-24

在初始 IJava 安装和浏览器页面刷新后,我的所有笔记本都停止连接。

以前做什么工作

  1. 执行第一个单元格
!wget https://github.com/SpencerPark/IJava/releases/download/v1.3.0/ijava-1.3.0.zip 
!unzip ijava-1.3.0.zip 
!python install.py --sys-prefix
  1. 等待Installed java kernel message

  2. 刷新浏览器页面。

  3. 使用 Java 代码执行任何单元。

现在发生的是

我可以执行第一个单元格并得到Installed java kernel消息,看到笔记本状态为“已连接”。

但刷新页面后,笔记本的状态永远停留在“正在连接”,

因此没有单元格可以被执行。

--

我免费使用 Google Colab,但由于初始安装仍然有效,并且刷新页面之前笔记本状态为“已连接”,因此这应该不是问题。

知道发生了什么变化,以及如何让我的 Java 笔记本再次连接吗?

--

UPDATE 1

页面重新加载后,当我尝试运行包含 Java 代码的单元格时,这是我在一段时间后收到的错误消息:

await connected: disconnected
@https://ssl.gstatic.com/colaboratory-static/common/5f9fa09db4e185842380071022f6c9a6/external_polymer_binary_l10n__en_gb.js:6249:377
promiseReactionJob@[native code]

另外,笔记本设置是

运行时类型:java

硬件加速器:None

这些单元包含非常简单的 Java 代码,没有外部库,没有 CPU 或 GPU 密集型内容。

出于调试目的,我尝试运行其他单元(例如安装 Java 或 Python 代码的单元),但当然,它们在没有连接的情况下也不会执行。

--

UPDATE 2

安装 IJava 后和页面重新加载之前,我注意到 Java 内核的路径与“预安装”ir 和 python3 内核的路径不同:

!jupyter kernelspec list

 Available kernels:
  ir         /usr/local/share/jupyter/kernels/ir
  python3    /usr/local/share/jupyter/kernels/python3
  java       /usr/share/jupyter/kernels/java

这可能是问题所在吗?

(我以前从未检查过这一点,所以我不知道最近默认路径是否已更改。)

这是 ipynb 文件的元数据内容:

{
    "nbformat": 4,
    "nbformat_minor": 0,
    "metadata": {
        "colab": {
            "provenance": [{
                "file_id": "...",
                "timestamp": 1670411565504
            }, {
                "file_id": "...",
                "timestamp": 1670311531999
            }, {
                "file_id": "...",
                "timestamp": 1605675807586
            }],
            "authorship_tag": "..."
        },
        "kernelspec": {
            "name": "java",
            "display_name": "java"
        }
    },
    "cells": [{
       ...
    ]}
}

在某些时候,colab 将默认传输更改为ipc(从默认的tcp) IJava 不支持。

/usr/bin/python3 /usr/local/bin/jupyter-notebook --ip=... --transport=ipc --port=...

内核启动但从未正确连接,并且不发送 jupyter 正在等待的初始内核信息消息。

当/如果到了某个时刻我们可以要求开始tcp相反,运输会更好(参见https://github.com/googlecolab/colabtools/issues/3267)但目前我们可以解决这个问题。

解决方法是在 java 内核前面放置一个小的本地代理,该代理连接所有 ipc 通道并将它们转发到另一组连接到 java 内核的 tcp 通道。

第一个单元仍然是通常的安装/设置,但也包括代理的安装:

%%sh
# Install java kernel
wget -q https://github.com/SpencerPark/IJava/releases/download/v1.3.0/ijava-1.3.0.zip 
unzip -q ijava-1.3.0.zip 
python install.py

# Install proxy for the java kernel
wget -qO- https://gist.github.com/SpencerPark/e2732061ad19c1afa4a33a58cb8f18a9/archive/b6cff2bf09b6832344e576ea1e4731f0fb3df10c.tar.gz | tar xvz --strip-components=1
python install_ipc_proxy_kernel.py --kernel=java --implementation=ipc_proxy_kernel.py

运行该单元格。你可能有Unrecognized runtime "java"; defaulting to "python3"没关系。单元运行后输出类似于:

Installed java kernel into "/usr/local/share/jupyter/kernels/java"
e2732061ad19c1afa4a33a58cb8f18a9-b6cff2bf09b6832344e576ea1e4731f0fb3df10c/install_ipc_proxy_kernel.py
e2732061ad19c1afa4a33a58cb8f18a9-b6cff2bf09b6832344e576ea1e4731f0fb3df10c/ipc_proxy_kernel.py
Moving java kernel from /usr/local/share/jupyter/kernels/java...
Wrote modified kernel.json for java_tcp in /usr/local/share/jupyter/kernels/java_tcp/kernel.json
Installing the proxy kernel in place of java in /usr/local/share/jupyter/kernels/java
Installed proxy kernelspec: {"argv": ["/usr/bin/python3", "/usr/local/share/jupyter/kernels/java/ipc_proxy_kernel.py", "{connection_file}", "--kernel=java_tcp"], "env": {}, "display_name": "Java", "language": "java", "interrupt_mode": "message", "metadata": {}}
Proxy kernel installed. Go to 'Runtime > Change runtime type' and select 'java'
install.py:164: DeprecationWarning: replace is ignored. Installing a kernelspec always replaces an existing installation
  install_dest = KernelSpecManager().install_kernel_spec(

按照打印的说明进行操作:Go to 'Runtime > Change runtime type' and select 'java'。运行时现在应该显示“Connected to java...”并且您应该能够编写和执行 java 代码。

Try https://colab.research.google.com/gist/SpencerPark/447de114fcd3e6a272dc140809462e30例如基础笔记本。


该设置单元应该是您运行所需的一切,但这里对代理内核中的内容进行了一些解释。它作为要点发布(https://gist.github.com/SpencerPark/e2732061ad19c1afa4a33a58cb8f18a9)。总体思路是:

  1. 将真正的内核重命名为_tcp后缀 (java_tcp)并使用预期名称将代理安装在其位置(java).

  2. 启动代理内核并绑定所有内容,就像代理本身就是内核一样。

    shell_socket = create_and_bind_socket(shell_port, zmq.ROUTER)
    stdin_socket = create_and_bind_socket(stdin_port, zmq.ROUTER)
    control_socket = create_and_bind_socket(control_port, zmq.ROUTER)
    iopub_socket = create_and_bind_socket(iopub_port, zmq.PUB)
    hb_socket = create_and_bind_socket(hb_port, zmq.REP)
    
  3. 使用支持的参数启动真正的内核(传输"tcp")和相同的会话信息。这很重要,因此我们可以将消息直接转发到真正的内核,而无需在中间对它们进行解码。

    kernel_manager = KernelManager()
    kernel_manager.kernel_name = args.kernel
    kernel_manager.transport = "tcp"
    kernel_manager.client_factory = ProxyKernelClient
    kernel_manager.autorestart = False
    
    kernel_manager.session.signature_scheme = signature_scheme
    kernel_manager.session.key = key
    
    kernel_manager.start_kernel()
    
  4. 为每对通道启动一个 zmq 代理(这都是ProxyKernelClient does).

    Thread(target=zmq.proxy, args=(proxy_server_socket, self.kernel_client_socket)).start()
    
  5. 然后我们就完成了!只需等待托管内核进程退出,然后我们自己也退出。

    exit_code = kernel_manager.kernel.wait()
    kernel_client.stop_channels()
    zmq_context.destroy(0)
    exit(exit_code)
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 IJava 的 Google Colab 笔记本在安装 + 刷新后卡在“正在连接” 的相关文章

随机推荐