Connecting Visual Studio Code with Jupyter Notebooks on a remote GPU server instance

Leverage the power of all three without compromise

Chong-U Lim
6 min readFeb 1, 2024
Leverage the power of all three great tools to up your machine learning development workflow!

In the field of machine learning, the use of Jupyter Notebooks is ubiquitous for both experimenting and sharing findings. The standard way of working with Jupyter Notebooks is Jupyter Lab, which is a powerful and versatile interatice development environment (IDE) in itself.

Visual Studio Code vs. Jupyter Lab

However, it is increasingly common for developers to use Visual Studio Code as their IDE, as opposed to Jupyter Lab. There are many reasons why, including the following (non-exhaustive) list.

  1. Having one IDE for both regular python .py and notebooks .ipynb .
  2. Having access to VS Code’s wide variety of extensions for things like type checking (Pylance), formatting (Prettier) and linting (Ruff).
  3. Being able to make use of things like GitHub Copilot for code-completion and hints.

If any of the both resonates with you as a developer, but you haven’t had the chance (or been able to) leverage VS Code with Jupyter Notebooks, this article might be just for you.

Connecting VS Code to remote Jupyter kernels

One of the (coolest) things that VS Code enables is connecting to remote Jupyter kernels. What this means is that you are not constrained to whatever is on your local machine; instead you can connect to a Jupyter kernel that is on a shared network or even hosted elsewhere on the internet.

This is extremely powerful and versatile as it means you can leverage a kernel that is hosted on more powerful hardware (with an GPU, for example) and not have to worry about whether you have the same set of dependencies between your local and remote Jupyter instances.

Prerequisites

  1. Visual Studio Code — Python Extension
  2. Visual Studio Code — Jupyter Extension
  3. Visual Studio Code — Remote — SSH

Walkthrough

  1. Click the “Access remote kernel” button on the left

2. Copy the URL in the “Connect to the remote Jupyter kernel” dialog

3. In VSCode, create a new Jupyter Notebook .ipynb file and click on kernel in the top right hand corner
Alternatively, you can open the command palette with Ctrl+Shift+P (Cmd+Shift+P on a Mac) and choose “Notebook: Select Notebook Kernel”

4. Simply paste the URL you copied from step 2 into the input.

Now, whatever you run in VS Code will be run against the remote kernel. All dependencies and packages that were installed on the kernel are available — so there is no need to do any reinstallation.

How do I run my existing notebooks vs. a blank new notebook?

Because you are simply connected to the remote kernel (and note the remote file system), you will need to rely on having a local copy of your source files on your local machine.

The way you can envision this is:

  1. You have a common GitHub repository with all your notebooks.
  2. You clone the GitHub repository on your local machine (so that you have access to the files)
  3. You open up whichever notebook you want
  4. You select the remote kernel as per the instructions above.

But wait, Pylance isn’t running and I can’t view class/method definitions anymore!

Unfortunately, yes — this is a known limitation of remote kernels on VS Code. Due to the fact that you are only connected to the kernel and not the code server, VS Code won’t have the ability for Pylance to perform type and import checking nor viewing class/method definitions, such as by ctrl+clicking (or cmd+clicking) on variables and methods.

It is the same reason why you need a local copy of your notebook files — there is no access to the remote filesystem.

However, do not fear! As there is actually a way to get to our desired end state: where VS Code has access to not just the kernel, but the file system and also the ability for Pylance and other extensions to work! Let’s walk through how…

Connecting VS Code to remote server instances

The key idea here is that rather than just connecting to the Jupyter kernel, we instead connect to the server instance entirely! You get the benefits of connecting to a remote kernel, but in addition:

  1. You don’t need a local copy of your files to run
  2. You have full access to the file system of the remote server
  3. You have full access to VS Code and its extensions including Pylance for type checking and jumping to definitions.

Rather than using Paperspace Gradient you will need to use Paperspace Core.

Before starting, you will need to have SSH keys set up on your local machine and have imported the public keys into your Paperspace account. You can find a quick overview on the Paperspace documentation.
If you’d like a step by step guide for doing this, let me know in the comments!

  1. Switch from Paperspace Gradient to Paperspace Core by clicking the top left hand corner of your console.
  2. Click “Create a Machine”
  3. Choose a template. I used “ML-in-a-Box”.
  4. Scroll down and expand “Advanced Settings” and select “Static” for your public IP.

You can customise the other fields as you wish. Once you are done — create your machine.

Once your machine is created — click on the Connect button which will show you how to ssh into your instance.

Copy the whole string (including the ssh) and launch Visual Studio Code.

In the bottom left hand corner, click the blue button indicating the remote you are connected to.

Alternatively, open the command palette (Ctrl+Shift+P) or (Cmd+Shift+P for Mac) and choose “Connect to Host…”

In the prompt, paste the string from the earlier step into the input. You should see the prompt for selecting the platform of your remote host: (Linux, Windows or macOS) — so choose Linux.

I’m being prompted for a password?

If you get prompted for a password, this would mean your SSH keys are not set up correctly. You can fix this by adding the following entries to your .ssh/config

Host paperspace-core-box 
HostName <ip address of your core instance>
User paperspace
IdentityFile <path to your private key e.g., ~/.ssh/id_ed25519 or ~/.ssh/id_rsa>

You can replace paperspace-core-box with whatever name you wish.

Try to “Connect to Host…” again, and select the entry with the name you chose above. You should be able to connect without needing to enter a password.

What success looks like

Voila! If you end up with a screen similar to below, you are now connected *fully* to your remote instance. You can open a terminal and perform commands right within VS Code, and it will all run directly on the instance.

Next steps

You can now clone your repository containing your notebooks, , install your VS Code extensions (along with any others you rely on) and work with the remote server instance directly within VS Code itself!

  1. git clone your repository
  2. open your repository folder in VS Code
  3. open the terminal in VS Code
  4. install python, pip, venv (using your favourite way of doing so e.g., anaconda, pyenv)
  5. pip install jupyterlab ipykernel
  6. Create your virtual environment python -m venv my_env
  7. activate your virtual environmentsource my_env/bin/activate
  8. install your projects dependencies e.g., pip install -r requirements.txt
  9. add the venv to jupyter lab python -m ipykernel install --name=my_env
  10. Switch the kernel in VSCode to the one you just added and you’re good to go!

Questions?

Did this guide help you? Did I miss anything or were there any questions? Let me know in the comments!

--

--

Chong-U Lim

Follower of Jesus. More than a decade working in gamedev (ex-Electronic Arts, ex-Improbable). AI/machine machine research (PhD from MIT).