Gestion des noyaux Jupyter

Les serveurs de notebooks Jupyter s’exécutent via des noyaux (kernels), qui définissent l’environnement d’exécution (version de Python, C++, bibliothèques et dépendances requises, accès GPU, …).

Sur cette plateforme, deux types de noyaux sont disponibles :

  • des noyaux fournis par défaut ;

  • des noyaux personnalisés, que vous pouvez créer selon vos besoins.

Si vous débutez ou n’avez pas de besoin spécifique, utilisez les noyaux fournis.

Noyaux fournis

Les noyaux fournis peuvent être choisis directement à la connexion sur l’interface, par le biais du menu déroulant [CC_Provided_kernels]. Ils permettent d’exécuter différents types d’environnements spécifiques, sans se soucier de la mise en place de ce dernier : il suffit de cocher l’environnement souhaité pour que celui soit disponible dans son serveur de notebooks.

Ces environnements peuvent être utilisés pour réaliser de l’exploration rapide dans une configuration validée, mais toutefois figée (et pas nécessairement reproductible). Ils sont maintenus de manière contrôlée et leurs versions évoluent peu afin de garantir leur stabilité.

Trois types d’environnements sont proposés :

Usage

Description

Modules disponibles

scientific

Calcul scientifique et Machine Learning

numpy, pandas et outils de visualisation (matplotlib, bokeh, …)

quantum-computing

Informatique quantique basé sur Qiskit (IBM)

Framework qiskit complet

RAG/LLM

Chatbot / LLM

transformers, sentence_transformers et chromadb

Exemples de Notebooks

Une collection d’exemples prêts à l’emploi catégorisés par thématique d’utilisation

https://gitlab.in2p3.fr/ccin2p3-support/utilities-examples/examples/notebooks
  • Deux environnements Python sont fournis par défaut (cases à cocher grisées). Les autres noyaux doivent être sélectionnés afin d’être ajoutés à sa session.

  • La liste et les versions des principaux modules disponibles dans l’environnement considéré sont disponibles en survolant avec la souris l’icône d’information à côté du nom d’un noyau.

  • La compatibilité GPU (selon le modèle) est également disponible dans le tableau (menu déroulant). Se référer à la bulle d’information pour connaître la version de CUDA le cas échéant, et les frameworks GPU disponibles.

Ajouter un noyau personnalisé

Créer un noyau personnalisé est recommandé dans les cas suivants :

  • utilisation de bibliothèques spécifiques ;

  • besoin de reproductibilité (et de portabilité) ;

  • utilisation de GPU ou de frameworks spécialisés (tels que JAX ou PyTorch) ou de versions spécifiques.

Deux (principales) approches sont possibles :

Environnement Python simple

basé sur venv, pour un usage rapide (environnement simple)

Environnement Python géré

basé sur uv, conda ou pixi, pour des projets robustes et reproductibles (environnement plus complexe, qui requiert des logiciels autres que Python)

Cette méthode est particulièrement adaptée si vous possédez déjà un environnement fonctionnel. Elle s’appuie sur la construction d’un environnement Python avec l’aide de venv. Il s’agit d’une procédure simple, mais peu robuste, et non reproductible. La procédure complète est la suivante :

Créez un environnement virtuel
% python -m venv <monenv>
Activez-le
% source <mon env>/bin/activate
Installez les dépendances nécessaires
% pip install ipykernel pyzmq

Une fois les modules requis installés dans l’environnement, on peut enregistrer le nouvel environnement en tant que noyau Jupyter comme suit :

% python -m ipykernel install --user --name <mon env> --display-name "Python (<mon env>)"

Le display_name est le nom que vous souhaitez donner à votre noyau personnalisé et sera utilisé pour l’identifier dans l’interface JupyterLab.

Cette commande crée un fichier kernel.json qui sera placé dans le HOME de l’utilisateur, dans l’arborescence suivante : $HOME/.local/share/jupyter/kernels/python3. Notez que le dernier répertoire ici nommé python3 est le nom utilisé par défaut, tout autre nom peut convenir tant que ce répertoire contient le fichier kernel.json. C’est ce fichier que Jupyter va chercher pour créer la liste des noyaux disponibles, et accessibles directement dans Jupyter.

Dépendances

Afin que le noyau puisse s’instancier et communiquer avec l’interface Jupyter, les deux modules suivants (et leurs dépendances) sont indispensables :

ipykernel
pyzmq

Important

Ces deux modules doivent être disponibles dans votre environnement, sans quoi la communication entre le noyau et Jupyter ne pourra se faire (le noyau sera alors dans l’état Unkown).

Afin de permettre l’interactivité lors de la visualisation (pour matplotlib en particulier), on aura besoin des modules suivants :

ipywidgets
ipympl
plotly

Note

ipywidgets et ipympl sont deux modules qui fournissent divers widgets permettant ainsi d’interagir avec des graphes créés par matplotlib. plotly est une couche JavaScript plus générique, elle peut donc fournir des widgets pour des langages autres que Python, tel que Julia.

Qualité de code (optionnel) :

black
isort
yapf

Création du fichier kernel.json

Le fichier kernel.json, brique indispensable à l’instanciation d’un noyau, et placé dans $HOME/.local/share/jupyter/kernels/python3 (par défaut) ressemble à ça :

{
"argv": [
     "/pbs/software/redhat-9-x86_64/jnp/venvs/py3.13.11/bin/python",
     "-m",
     "ipykernel_launcher",
     "-f",
     "{connection_file}"
],
"display_name": "Python (<mon env>)",
"language": "python"
}

Afin d’éviter les conflits et rendre cet environnement plus robuste il est possible de forcer la variable PYTHONPATH comme suit (cela empêchera Python de chercher des modules dans d’autres emplacements) :

{
"argv": [
     "/pbs/software/redhat-9-x86_64/jnp/venvs/py3.13.11/bin/python",
     "-m",
     "ipykernel_launcher",
     "-f",
     "{connection_file}"
],
"display_name": "Python 3.13.11 - Scientific",
"language": "python",
"env": {
     "PYTHONPATH": "/pbs/software/redhat-9-x86_64/jnp/venvs/py3.13.11/lib/python3.13/site-packages"
}
}

Note

Dans ce champ env il est également possible de redéfinir toute variable d’environnement.

Attention

Une mauvaise configuration de PYTHONPATH (ou de toute autre variable d’environnement) peut entraîner des problèmes divers lors de l’exécution du noyau, tels que des problèmes de compatibilité (mauvaise version d’un module Python, ou module non trouvé).

Note

Il est tout-à-fait possible de créer un nouveau répertoire dans $HOME/.local/share/jupyter/kernels/, disons python3.9, et d’y placer un fichier kernel.json qui respecte le format des exemples ci-dessus. Le respect de la syntaxe json est primordial afin que Jupyter puisse correctement lire la configuration du noyau correspondant.

Utilisation du script jupyter-helper.sh

Afin d’utiliser un script helper jupyter-helper.sh, on modifiera le fichier kernel.json pour y intercaler le script :

{
  "display_name": "conda3",
  "language": "python",
  "argv": [
      "<CHEMIN DU SCRIPT>/jupyter-helper.sh",
      "-f",
      "{connection_file}"
  ]
}

Ce script jupyter-helper.sh fournira les détails pour configurer l’environnement du nouveau noyau. Ce script ressemblera à ça :

#!/bin/bash
source /usr/share/Modules/init/bash

# Use of Environment Module to set up conda and activate the correct env
module load Programming_Languages/anaconda/3.9
conda activate <your_env>

# Handle the environment variables as required
unset PYTHONPATH
export PYTHONPATH=/path/to/your_env:$PYTHONPATH

# Instanciate the kernel within the set up environment
exec python -m ipykernel_launcher "$@"

La première partie configure l’environnement requis (ici, nous mettons en place un environnement Anaconda), et la dernière ligne indique à Jupyter comment démarrer ce nouveau noyau. Pour que le noyau puisse s’initialiser il faut que le script ait les permissions d’exécution :

% chmod +x jupyter-helper.sh

Ce mécanisme est particulièrement utile lorsque la configuration de l’environnement est complexe :

  • l’environnement dépend d’autres applicatifs ou de modules système (appelés via module load) ;

  • plusieurs variables d’environnement doivent être configurées.

Note

Pour certains logiciels, tels que ROOT/C++, le CC-IN2P3 fournit des noyaux prêts à l’emploi. Ils sont placés dans la zone logicielle suivante : /pbs/software/redhat-9-x86_64/jupyter_kernels.

Si vous avez besoin d’aide à écrire les fichiers jupyter-helper.sh et kernel.json pour mettre en place vos noyaux personnalisés, veuillez contacter le support utilisateurs.

Noyaux GPU

Un environnement GPU aura certaines spécificités :

  • la version de la bibliothèque CUDA utilisable dépend du modèle du GPU (et des pilotes installés) ;

  • la compatibilité entre la version de CUDA et le framework GPU souhaité est requise.

Le CC-IN2P3 maintient les pilotes CUDA à jour, et ne fournit que des versions compatibles avec l’ensemble des GPUs fournis. Il conviendra cependant de vérifier la bonne compatibilité entre ces pilotes et les bibliothèques CUDA d’une part et la version du framework à installer avec ces bibliothèques d’autre part.

Il existe deux principaux frameworks GPUs : PyTorch et JAX. Ces frameworks sont fournis par certains noyaux par défaut.

Il conviendra donc d’installer la bonne version du framework en fonction des bibliothèques CUDA disponibles, et compatibles avec les pilotes installés (maintenus par le CC-IN2P3). Pour ce faire, on recommande d’utiliser pip tel qu’il est stipulé dans les instructions d’installation des documentations officielles respectives.

Voici des exemples d’installations de JAX pour GPU Nvidia et de PyTorch pour GPU Nvidia. Notez que dans les deux cas la version des bibliothèques CUDA requise est précisée, ce qui permettra également de télécharger cette version si nécessaire, et assure qu’on a la compatibilité entre le framework et les bibliothèques CUDA.

Exemple avec PyTorch :
% pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
Exemple avec JAX :
% pip install --upgrade pip

# NVIDIA CUDA 13 installation
# Note: wheels only available on linux.
% pip install -U "jax[cuda13]"

Afin de s’assurer de la compatibilité avec les pilotes, et donc de pouvoir correctement utiliser le GPU, il est nécessaire de réaliser un calcul quelconque. Voici un exemple de multiplication de deux matrices avec JAX, qui permettra de valider que le GPU est bien vu, que la compilation XLA est effective (jit) et que le calcul est bien réalisé sur le GPU.

import jax
import jax.numpy as jnp

# Print available devices
print("Devices:", jax.devices())

# Create test matrices
key = jax.random.PRNGKey(0)
A = jax.random.normal(key, (2000, 2000))
B = jax.random.normal(key, (2000, 2000))

# JIT-compiled matrix multiplication
@jax.jit
def matmul(a, b):
    return a @ b

# Run once (triggers compilation)
C = matmul(A, B)

# Force computation
C.block_until_ready()

print("Done.")

Dépannage

Le noyau ne démarre pas

Vérifiez que les modules ipykernel et pyzmq sont bien installés dans l’environnement actif.

Modules introuvables

Vérifiez l’environnement actif, typiquement les modules sont installés sous l’arborescence suivante <PATH/TO/PYTHON/ENV>/lib/python3.11/site-packages/ (python3.11 correspondant explicitement à la version de Python installée et accessible dans cet environnement).

Problèmes avec le GPU

  • À partir d’un terminal dans Jupyter, vérifiez que vous avez bien accès à un GPU avec la commande nvidia-smi.

  • Vérifiez la compatibilité entre pilotes GPU, bibliothèques CUDA et le framework installé.