Skip to main content

Minimal ML experiment platform wrapping Azure ML, Vertex AI, and Vercel Sandbox

Project description

NUCL

Minimal ML experiment platform. 2,000 lines of code.

NUCL wraps Azure ML, Vertex AI, and Vercel Sandbox behind a unified CLI and web dashboard. No servers to manage, no databases to maintain, no collectors to deploy. Every feature delegates to a managed service.

nucl run --name "vision/resnet-50-v2" --script train.py --gpu-type t4
nucl ps vision/
nucl log vision/resnet-50-v2 -f
nucl pull vision/resnet-50-v2

Architecture

graph LR
    subgraph Clients
        CLI["CLI (Python)"]
        Web["Web Dashboard"]
    end

    subgraph Vercel
        API["Next.js API Routes"]
        Auth["Clerk (auth + API keys)"]
    end

    subgraph Sandbox["Vercel Sandbox (Python 3.13)"]
        AzureSDK["azure-ai-ml SDK"]
        VertexSDK["vertex AI SDK"]
    end

    subgraph Platforms
        AzureML["Azure ML"]
        VertexAI["Vertex AI"]
        SandboxRun["Sandbox (CPU)"]
    end

    CLI -- HTTP --> API
    Web -- HTTP --> API
    API --> Auth
    API -- "job submission" --> Sandbox
    API -. "read ops (list, logs, cancel)" .-> Platforms
    AzureSDK --> AzureML
    VertexSDK --> VertexAI
    Sandbox --> SandboxRun

Job submission spins up a short-lived Vercel Sandbox with Python 3.13 and uses the official cloud SDKs to upload code and create training jobs. Read operations (list, logs, cancel) use direct REST API calls.

Three platforms:

Platform GPU Use case
Azure ML Yes Production training on Azure
Vertex AI Yes Production training on GCP
Sandbox No (CPU) Quick tests, no cloud account needed

Setup

Web (Vercel)

cd web
bun install
cp .env.example .env.local  # fill in values
bun dev

Required environment variables:

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
ENCRYPTION_KEY=<openssl rand -hex 32>
VERCEL_TOKEN=...

CLI

cd cli
uv sync
uv run nucl --help

Or install globally:

uv tool install .
nucl --help

CLI Commands

Auth

nucl auth login                    # Browser-based sign-in
nucl auth logout
nucl auth status

Teams (Clerk Organizations)

nucl team show                     # Current team info
nucl team set <org-id>             # Switch team
nucl team config azure             # Set Azure credentials for team
nucl team config vertex            # Set Vertex credentials for team

Jobs

nucl run --name "project/experiment" --script train.py --gpu-type t4
nucl ps                            # List all experiments
nucl ps project/                   # Filter by folder
nucl log <job-id> -f               # Stream logs
nucl stop <job-id>
nucl pull <job-id> ./outputs       # Download results

Models

nucl model ls
nucl model pull <name>

HPO

nucl hpo run config.yaml

Experiment Organization

Experiments use path-based naming with / as the folder separator:

lung-cancer/detection/yolov9-baseline
lung-cancer/detection/yolov9-augmented
lung-cancer/segmentation/unet-v1
breast-cancer/screening/resnet-50

Filter by prefix with nucl ps lung-cancer/detection/. The web dashboard renders folder paths with a muted prefix and bold experiment name.

Cloud Credentials

Credentials are stored per-team using Clerk Organization privateMetadata, encrypted with AES-256-GCM. They never touch the CLI or browser -- only the server-side API routes decrypt them to submit jobs.

An org admin configures credentials once via the Team Settings page or nucl team config. All team members use them.

In-Job Logging

NUCL does not ship a custom SDK. Use MLflow directly in your training scripts:

import mlflow

mlflow.log_param("learning_rate", 0.001)
mlflow.log_metric("accuracy", 0.95)
mlflow.log_artifact("model.pth")

Both Azure ML and Vertex AI natively support MLflow.

Tech Stack

Layer Technology
CLI Python 3.11+, Click, httpx
Web Next.js 16, React 19, TypeScript 6
UI shadcn, Tailwind CSS 4, TanStack Table
Data fetching TanStack Query 5
Auth Clerk 7 (Organizations, API keys)
Job submission Vercel Sandbox (Python 3.13)
Encryption AES-256-GCM
Package management uv (Python), Bun (JS)

Tests

# Web (158 tests)
cd web && bunx vitest run

# CLI (94 tests)
cd cli && uv run pytest -v

What NUCL Does Not Do

NUCL delegates everything it can. It does not:

  • Provision VMs (cloud platforms do this)
  • Collect logs (cloud platforms do this)
  • Manage GPU quotas (cloud platforms do this)
  • Handle preemption (cloud platforms do this)
  • Build Docker images (use platform environments)
  • Provide an in-job SDK (use MLflow)
  • Run a backend server (Vercel handles this)
  • Manage a database (Clerk handles credentials, no DB needed)

License

Internal use only.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nucl-0.7.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nucl-0.7.0-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file nucl-0.7.0.tar.gz.

File metadata

  • Download URL: nucl-0.7.0.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nucl-0.7.0.tar.gz
Algorithm Hash digest
SHA256 61f4cad1eaa3dd17edf1c24bb56312d5d0a52d4635b5022bd7e8f991c68d40ea
MD5 3ba503c0cb2a3c205f13a4dcef9c5a13
BLAKE2b-256 f427e7a919323cc946c8288cac496495de44d6ea77e9e1cc6dc9979857929d66

See more details on using hashes here.

Provenance

The following attestation bundles were made for nucl-0.7.0.tar.gz:

Publisher: publish-cli.yml on lunit-io/nucl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nucl-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: nucl-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nucl-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a72b1fe623eb0690ec9f30ee159646dd00a948319cc4d03a35ecd51776a0454e
MD5 93370d8ecf4cbde9fc5b57dc3cfc875c
BLAKE2b-256 79ca8eb61ec924fc7f6874a5d724628da18dd8e859397e633b9e27582675e830

See more details on using hashes here.

Provenance

The following attestation bundles were made for nucl-0.7.0-py3-none-any.whl:

Publisher: publish-cli.yml on lunit-io/nucl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page