JupyterHub for AI/ML: GPU quotas and MLflow integration

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1All 1566 services
JupyterHub for AI/ML: GPU quotas and MLflow integration
Medium
~2-3 days
Frequently Asked Questions

AI Development Areas

AI Solution Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1319
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1226
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    927
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1161
  • image_logo-advance_0.webp
    B2B Advance company logo design
    622
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    897

JupyterHub for AI/ML: GPU quotas, MLflow integration, and team environments

Working on ML projects in a team often hits the wall of "it works on my machine but not on the server". Different library versions, no GPU access, unsynchronized datasets — chaos that kills productivity. JupyterHub with Kubernetes solves this at the infrastructure level. We have configured dozens of such environments for teams from 3 to 50 people and know all the pitfalls. One client — a company developing NLP models: 12 engineers used to spend up to 4 hours per week syncing environments. After implementing JupyterHub, that time dropped to zero. Turnkey — from image selection to MLflow integration — in 5 business days. We will assess your project for free, contact us.

Problems we solve

  • Environment incompatibility. Each developer uses their own package versions. JupyterHub provides a unified Docker image with fixed dependencies. This eliminates "works on my machine" scenarios.
  • GPU shortage. Without quotas, one user can hog all resources, leaving colleagues without compute. ResourceQuota and PriorityClass distribute GPUs fairly, and PriorityClass ensures production tasks are not preempted by research ones.
  • Data duplication. Datasets are copied to each machine, wasting space and time on sync. A shared PVC in read-only mode solves this: the latest dataset version is available to all users at /data/shared.

Why JupyterHub over separate servers?

Criterion JupyterHub (Kubernetes) Separate Servers
Reproducibility Same image for all Manual dependency installation
GPU management Quotas, priorities, monitoring No centralized control
Security Isolation via Kubernetes Namespaces Shared file access
Scaling Autoscaling pods Manual machine addition

How we set up GPU quotas

For fair GPU distribution, we use ResourceQuota on namespaces and PriorityClass for task prioritization. Example configuration:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: jhub-quota
spec:
  hard:
    requests.nvidia.com/gpu: "8"    # Max 8 GPUs at once
    limits.memory: "512Gi"
    requests.cpu: "64"

PriorityClass for GPU: research tasks have low priority, production inference has high priority. This prevents critical processes from being blocked.

How to integrate JupyterHub with MLflow?

Stack: Kubernetes (EKS/GKE), Helm, Docker, PyTorch 2.2, MLflow 2.11, DVC, Great Expectations.

# Add Helm repository
helm repo add jupyterhub https://hub.jupyter.org/helm-chart/
helm repo update

# config.yaml
cat > config.yaml << 'EOF'
hub:
  config:
    Authenticator:
      admin_users:
        - admin
    GitHubOAuthenticator:
      client_id: "your-github-client-id"
      client_secret: "your-github-client-secret"
      oauth_callback_url: "https://jupyter.company.com/hub/oauth_callback"
      allowed_organizations:
        - your-github-org

singleuser:
  image:
    name: jupyter/datascience-notebook
    tag: "python-3.11"
  profileList:
    - display_name: "CPU Standard (4 CPU, 16GB RAM)"
      description: "For EDA and light training"
      default: true
    - display_name: "GPU Instance (1x A100 40GB)"
      description: "For model training"
      kubespawner_override:
        extra_resource_limits:
          nvidia.com/gpu: "1"
    - display_name: "GPU Large (2x A100 80GB)"
      kubespawner_override:
        extra_resource_limits:
          nvidia.com/gpu: "2"
  storage:
    capacity: 50Gi
    homeMountPath: /home/jovyan

# Shared storage for datasets (read-only for users)
singleuser:
  extraVolumes:
    - name: shared-datasets
      persistentVolumeClaim:
        claimName: shared-datasets-pvc
        readOnly: true
  extraVolumeMounts:
    - name: shared-datasets
      mountPath: /data/shared
      readOnly: true
EOF

helm install jupyterhub jupyterhub/jupyterhub \
  --namespace jhub --create-namespace \
  --values config.yaml

For more details on configuration, see the official Zero to JupyterHub documentation.

Resource profiles detailed in the table:

Profile CPU RAM GPU Storage
CPU Standard 4 vCPU 16 GB 50 GB
GPU Instance 4 vCPU 32 GB 1× A100 40GB 100 GB
GPU Large 8 vCPU 64 GB 2× A100 80GB 200 GB

Custom Docker images for ML

FROM jupyter/datascience-notebook:python-3.11

USER root
RUN apt-get update && apt-get install -y \
    libgomp1 \
    && rm -rf /var/lib/apt/lists/*

USER ${NB_UID}

# ML dependencies
RUN pip install --no-cache-dir \
    torch==2.2.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 \
    transformers==4.38.0 \
    datasets \
    accelerate \
    peft \
    mlflow==2.11.0 \
    dvc[s3] \
    great_expectations \
    lightgbm xgboost catboost \
    optuna \
    shap \
    wandb

# MLflow tracking server URL
ENV MLFLOW_TRACKING_URI=http://mlflow.internal:5000

# DVC remote config
COPY dvc_config /home/jovyan/.dvc/config

MLflow is automatically available from all notebooks via the environment variable. DVC is configured with corporate remote storage. The shared dataset folder with the latest dataset versions is mounted read-only. Git pre-commit hooks are installed globally for code standardization.

Typical result: An ML team of 10+ people works in a unified environment without "works on my machine" issues, with shared access to GPU resources and centralized experiment tracking. This significantly reduces compute costs through GPU utilization.

Process

  1. Analysis — study current infrastructure, GPU requirements, data volume.
  2. Design — develop architecture: namespaces, images, quotas.
  3. Implementation — deploy JupyterHub via Helm, configure authentication.
  4. Integration — connect MLflow, DVC, shared storage.
  5. Testing — verify scenarios: training launch, logging, data access.
  6. Team training — conduct a workshop, hand over documentation.

What's included

Deliverable Description
Infrastructure documentation Architecture, deployment diagram, upgrade instructions
Configured cluster JupyterHub with authentication, profiles, GPU quotas
Docker images Ready-to-use images with PyTorch, MLflow, DVC
Integrations MLflow, DVC, shared storage, pre-commit hooks
Training 2-hour session for the team + recording
Support 2 weeks after handover — bug fixes, answering questions
How we maintain reproducibility?

We pin library versions in the Dockerfile, use lock files (pip freeze), and set up pre-commit hooks. The final environment is reproducible with a single helm install command. We guarantee stability for 2 weeks after deployment.

Guarantees and experience

Over 5 years of experience in MLOps, 20+ deployments for teams from 3 to 50 people. We guarantee 99.9% SLA availability and environment reproducibility. Order JupyterHub setup for your project — we will provide demo access to a working environment within 2 days. Get a consultation by contacting us.