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.3.0.tar.gz (19.5 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.3.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for nucl-0.3.0.tar.gz
Algorithm Hash digest
SHA256 9167520577982245090c9a69a2292dfa38fcbe0d646c742f07835f4e42704f7d
MD5 efbf1e1fa7aea4f33d6abe4a472e46c4
BLAKE2b-256 a069c0ef3cbca1ae83b8917adb2504710e3a32e471a25a2971bc668089c75ba1

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: nucl-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 13.5 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 82f4cb7c53dc531ee9e29683f0743c366992b81eff3395069d368fe4af232bbd
MD5 05badd26f5f5a3a7649a1cf489309ece
BLAKE2b-256 0a0183331ff6a56dc751da4f48e30937032c80e22eb5385876b27cf6009ba9a0

See more details on using hashes here.

Provenance

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