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.6.0.tar.gz (19.7 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.6.0-py3-none-any.whl (13.7 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for nucl-0.6.0.tar.gz
Algorithm Hash digest
SHA256 0f7597aa2d9fc61a9e88c06f59ba58d0074d016249d3a2d8e36efdb430a92d9f
MD5 f9e0842e8ed33099160b0ecfd8c64b88
BLAKE2b-256 4357a021bb91e6a04fd4ac0eec8f5fbdfb3b001f5a99e79d87c8fce996072178

See more details on using hashes here.

Provenance

The following attestation bundles were made for nucl-0.6.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.6.0-py3-none-any.whl.

File metadata

  • Download URL: nucl-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 13.7 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.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6611af75ba5b674157809b8563ea6d0b39d4f17364c93dd350599db31df51001
MD5 f563300d0b4fc8c97892c2f6527db20c
BLAKE2b-256 78fdecc025fe72863914de1a30f6748f81fa49bbebc5af0f91cc063ca66442f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for nucl-0.6.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