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)"]
        DB["Drizzle + Neon"]
    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 --> DB
    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
DATABASE_URL=postgresql://...
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)
Database Neon (serverless Postgres), Drizzle ORM
Job submission Vercel Sandbox (Python 3.13)
Encryption AES-256-GCM
Package management uv (Python), Bun (JS)

Tests

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

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

# Coverage
cd web && bunx vitest run --coverage    # 100% statements, 97.7% branches
cd cli && uv run pytest --cov=nucl      # 100% lines

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 server (Neon handles this)

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.1.0.tar.gz (14.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.1.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nucl-0.1.0.tar.gz
  • Upload date:
  • Size: 14.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.1.0.tar.gz
Algorithm Hash digest
SHA256 9dd5d0c695aba01a435baaef1a8fe0efab0d3cf361eab7f3675696ec16f41aca
MD5 e1f7a40a06283ad491baf88d1bf34fff
BLAKE2b-256 a4a395875e963ed1a1fd6e1027338b298a28cc0ab8e2f0178c9acc42b1e20356

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: nucl-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 db1d8cf583b5a0b6730f81e9d810ad71ca2d3344c56b6ae02b5349d794e6e844
MD5 9f410623e15589db873cbaa42dd8b29e
BLAKE2b-256 0946efc381dbb4aaabbc5218fe0fc0686c205dfb3d8192a6aa9b956bb20d4693

See more details on using hashes here.

Provenance

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