kernel

Connecting a solveit kernel to a Modal sandbox
flowchart TD
    A[Start a remote IPython kernel] --> B[Register the remote IPython kernel]
    B --> C[Swap SolveIt's IPython kernel with the remote one]
from solveit_modal.sandbox import *

We’ll first spin up a sandbox.

app = mk_app('solveit-sandbox')
img = mk_img(pips=['ipykernel', 'torch'], apts=['openssh-server'])
vol = mk_vol('solveit-volume')
sb = mk_sandbox(app, img, vol, timeout=600, gpu='T4', secrets={})
host,port = get_tunnel(sb)
inject_pubkey(sb, get_pubkey()); start_ssh(sb)
ssh = mk_ssh(host, port)
verify_ssh(ssh)
INFO - ∞ creating sandbox; this may take 5-10 minutes if you are creating this sandbox for the first time... | 2026-06-17 06:27:28,629
INFO - ✔ sandbox ready | 2026-06-17 06:28:25,941
INFO - ✔ gotten tunnel: r451.modal.host:34457 | 2026-06-17 06:28:41,496
INFO - ✔ public key injected | 2026-06-17 06:28:42,020
INFO - ✔ started ssh service | 2026-06-17 06:28:42,656
System: Linux
Hostname: modal
User: root
Kernel: 4.4.0
Architecture: x86_64
OS Type: GNU/Linux
GPU: Tesla T4

Next up is starting a remote IPython kernel.


start_remote_kernel


def start_remote_kernel(
    ssh:Callable, # SSH caller from mk_ssh
    kernel_path:str='/root/.local/share/jupyter/runtime/kernel-ipyf.json', # kernel JSON path
):

Start remote kernel and wait until ready.

start_remote_kernel(ssh)
INFO - ∞ starting kernel | 2026-06-17 06:28:45,403
INFO - ✔ remote kernel ready: /root/.local/share/jupyter/runtime/kernel-ipyf.json | 2026-06-17 06:28:49,862

We’ll also need to fetch which Python is being used.


get_remote_python


def get_remote_python(
    ssh:Callable, # SSH caller from mk_ssh
)->str: # path to remote python

Return the path of Python on the remote machine.

p = get_remote_python(ssh); p
'/usr/local/bin/python3'

Now that the an IPython kernel is up and running on the Modal sandbox, it’s time to register that kernel to SolveIt, and then swap it.

We’ll be doing that with Dr. Scott Hawley’s awesome ipyfernel library.

I’d do _all_ = ipyfernel.core.__all__, but nbdev would through an error.

register_remote_kernel(remote_python=p)
connect_existing_kernel(f'{host}:{port}')
ipyf_remote_kernel is already a registered kernel
/app/data/.ssh/config file updated.
Successfully created connection file and forwarded ports!
Success: connected to remote kernel via r451.modal.host:34457

And we’re done! Use the %remote line magic or %%remote cell magic to run code on Modal’s sandbox.

#%%remote <-- cell magic (remove # when actually using)
import platform
platform.uname()
uname_result(system='Linux', node='modal', release='4.4.0', version='#1 SMP Sun Jan 10 15:06:54 PST 2016', machine='x86_64')
#%%remote <-- cell magic (remove # when actually using)
!nvidia-smi
Wed Jun 17 06:28:53 2026       
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.95.05              Driver Version: 580.95.05      CUDA Version: 13.0     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  Tesla T4                       On  |   00000000:E7:00.0 Off |                    0 |
| N/A   30C    P8              9W /   70W |       0MiB /  15360MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+

Alternatively, ipyfernel also has a sticky mode allowing us to run code remotely by default.

set_sticky()
Code cells will now execute remotely.
import torch
/usr/local/lib/python3.12/site-packages/torch/_subclasses/functional_tensor.py:362: UserWarning: Failed to initialize NumPy: No module named 'numpy' (Triggered internally at /pytorch/torch/csrc/utils/tensor_numpy.cpp:84.)
  cpu = _conversion_method_template(device=torch.device("cpu"))
torch.cuda.is_available()
True

%%local to run code locally.

#%%local <-- cell magic (remove # when actually using)
unset_sticky()
Code cells will now run locally.
stop_remote()
Code cells will now run locally.
Shutting down remote kernel
sb.terminate()