GPU Compute

Badgr Compute API

One API, two primitives: badgr serve for persistent endpoints, badgr run for one-off jobs. Fine-tuning, transcription, image generation, embeddings — these are all job types, not separate products. You don't configure compute providers. You run commands.

1. Install and log in

npm install -g badgr-cli

Requires Node.js 18+. Installs the badgr command.

badgr login

Prompts for your API key and saves it to ~/.badgr/config.json.

2. Two primitives, many job types

badgr serve <model>Start a persistent OpenAI-compatible endpoint. Stays running until you run badgr down.
badgr run <command>Run a one-off GPU job. Streams logs, exits when done. Billing stops automatically.
badgr down <id>Terminate any deployment. Stops billing immediately.
badgr logs <id>Fetch log output from a running or completed deployment.
badgr receiptsCost, route, and retry record for every action.

3. API shapes

badgr serve and badgr run expose different API shapes — don't mix them up.

badgr serve — OpenAI-compatible /v1 endpoint

After badgr serve starts, export BADGR_ENDPOINT and point any OpenAI SDK client at it:

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ["BADGR_API_KEY"],
    base_url=os.environ["BADGR_ENDPOINT"],
)

# Chat completions  (badgr serve <model>)
resp = client.chat.completions.create(
    model="qwen/Qwen2.5-7B-Instruct",
    messages=[{"role": "user", "content": "Hello"}],
)

# Embeddings        (badgr serve <model> --task embed)
resp = client.embeddings.create(
    model="BAAI/bge-large-en-v1.5",
    input=["hello world"],
)

# Transcription     (badgr serve <model> --task transcribe)
with open("audio.mp3", "rb") as f:
    transcript = client.audio.transcriptions.create(
        model="large-v3", file=f, response_format="text",
    )

# Image generation  (badgr serve <model> --task image)
resp = client.images.generate(
    model="black-forest-labs/FLUX.1-schnell",
    prompt="A futuristic city at sunset",
    n=1, size="1024x1024",
)

Phase 1 endpoint coverage

POST /v1/chat/completionsChat — badgr serve <model>
POST /v1/embeddingsEmbeddings — badgr serve <model> --task embed
POST /v1/audio/transcriptionsTranscription — badgr serve <model> --task transcribe
POST /v1/images/generationsImage gen — badgr serve <model> --task image

Not promised in Phase 1

Responses API · Assistants · Realtime · Files · Vector stores · Fine-tuning API · Moderation · Batch API · Video generation · Tool calls / function calling (unless your runtime supports it)

badgr run — Badgr Compute job shape

Not OpenAI-compatible. This is the Badgr job API — for training, batch scripts, ComfyUI, and any workload that should start, run, and exit:

curl -X POST "$BADGR_API_BASE/v1/jobs" \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "custom.run",
    "code_uri": "badgr-upload://abc123",
    "cmd": "python train.py",
    "max_cost": 5
  }'

4. Job types and recipes

badgr serve— persistent endpoints

Serve an open-source model

LLaMA, Mistral, Qwen, and any Hugging Face model via vLLM

Deploy a vLLM endpoint

Custom vLLM config, version pinning, extended context

Embeddings endpoint

Run TEI or a vLLM embedding model as a persistent API

Image generation

Serve a Diffusers or ComfyUI container as an endpoint

Transcription endpoint

Persistent Whisper endpoint for audio-to-text workloads

badgr run— jobs that start, run, and exit

One-off GPU job

Run any Python script or container command on a GPU

Batch inference

Offline scoring, embedding generation, large-scale eval

Fine-tuning / LoRA

Adapter training with Axolotl, TRL, or custom scripts

Image and video batch jobs

Diffusers, ComfyUI, or video synthesis pipelines

Audio and transcription jobs

Whisper batch jobs, audio processing pipelines

Integrations

GitHub Actions

badgr-run and badgr-serve composite actions for CI/CD pipelines

MCP (agent compute)

badgr-mcp exposes GPU tools to Claude, Cursor, and other coding agents

5. How it runs your code

Badgr does not require you to build or push a Docker image. Point it at a folder, a GitHub repo, or a custom image — it handles the rest.

Flow 1 — local project folder (primary)

badgr run . --cmd "python score_leads.py" --max-cost 1

Badgr zips your current directory, uploads it, picks a generic runner, installs deps from requirements.txt or package.json, runs the command, stores outputs for 48 hours, and tears down the GPU. No Docker required.

Flow 2 — public GitHub repo

badgr run https://github.com/user/repo --cmd "python score_leads.py" --max-cost 1

No upload step — the runner clones the repo directly. Good for open-source projects and CI pipelines.

Flow 3 — custom Docker image (advanced)

badgr run . --image myco/lead-env:latest --cmd "python score_leads.py" --max-cost 1

Bring your own container when dependencies are too custom or heavy. Mutually exclusive with automatic runtime detection.

Generic runners (Badgr picks automatically)

badgr-python-runnerPython 3.11 + CUDA. Auto-selected when requirements.txt or pyproject.toml is present.
badgr-node-runnerNode.js 20 + CUDA. Auto-selected when package.json is present.
badgr-vllm-runnervLLM pre-installed. Used by badgr serve and model.serve jobs.
badgr-train-runnerAxolotl + TRL + Unsloth. Used by badgr train.
badgr-comfyui-runnerComfyUI pre-installed. Used by badgr comfyui run.

6. Quick examples

Run a local project on a GPU

badgr run . --cmd "python train.py" --gpu A100 --max-cost 10

Serve a model

badgr serve Qwen/Qwen2.5-7B-Instruct --max-cost 10

Stop billing

badgr down <deployment-id>

7. How jobs work

Every badgr run or badgr serve call submits a job through the Badgr Jobs API. You can also drive this API directly if you want to integrate GPU workloads into your own systems.

Job lifecycle

queuedJob accepted; waiting for a GPU to become available
provisioningGPU is being allocated from the provider pool
runningContainer is executing; logs are streaming
completedJob exited cleanly; billing has stopped
failedJob exited with an error or the GPU was lost
canceledStopped via badgr down or POST /v1/jobs/{id}/cancel

REST API

POST /v1/jobsSubmit a compute job (run, serve, fine-tune, image gen)
GET /v1/jobs/{id}Poll status, logs, and results for a job
POST /v1/jobs/{id}/cancelStop a running job and settle billing

Job types

custom.runRun any Python script or container command. Exits when the command exits.
model.servePersistent OpenAI-compatible vLLM endpoint. Pass a full HuggingFace model ID or a blessed alias (qwen-7b, llama-8b, qwen-coder-7b). Stays up until canceled.
train.loraFine-tune with Axolotl. Pass config_preset: 'small' or 'medium' for zero-config training. Accepts dataset_url, dataset_file_id, or github_dataset_url. Completes when training finishes; adapter available at GET /v1/jobs/{id}/adapter.
comfy.batchRun a batch of prompts through ComfyUI. Pass workflow_id: 'sdxl-basic' and a prompts list (up to 20). Returns image_urls pointing to stored images at GET /v1/jobs/{id}/images/{index}.
image.generateGenerate images via Lemonfox (provider-managed, fast, cheap).

8. Workload examples

Submit a batch script (custom.run)

# Upload your project zip to get a code_uri (multipart POST)
zip -r project.zip . -x "*.git*" "node_modules/*" "__pycache__/*"
curl -X POST https://aibadgr.com/v1/uploads \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -F "file=@project.zip" > upload.json
# upload.json → { "code_uri": "https://aibadgr.com/v1/uploads/.../download?token=..." }

# Submit the job
curl https://aibadgr.com/v1/jobs \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "custom.run",
    "input": {
      "gpu": "A100",
      "code_uri": "<code_uri from upload>",
      "cmd": "python train.py --epochs 10",
      "env": { "HF_TOKEN": "hf_..." }
    },
    "policy": { "max_cost": 5 }
  }'

Start a persistent model endpoint (model.serve)

curl https://aibadgr.com/v1/jobs \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "model.serve",
    "model": "Qwen/Qwen2.5-7B-Instruct",
    "gpu": "RTX_4090"
  }'

Returns a deployment_url once the model is healthy. Use it as your baseURL with any OpenAI-compatible client.

Poll until complete

curl https://aibadgr.com/v1/jobs/$JOB_ID \
  -H "Authorization: Bearer $BADGR_API_KEY"

# Response fields:
# status: queued | provisioning | running | completed | failed | canceled
# logs:   recent stdout/stderr lines
# result: output data when status=completed

Cancel and stop billing

curl -X POST https://aibadgr.com/v1/jobs/$JOB_ID/cancel \
  -H "Authorization: Bearer $BADGR_API_KEY"

9. Productized runner flows

Three zero-config GPU flows. No Docker image selection, no Axolotl YAML, no ComfyUI setup — just a job type and parameters.

model.serve — blessed aliases

Pass a short alias and Badgr resolves the full model ID, GPU type, and vLLM image automatically. Aliases: qwen-7b, llama-8b, qwen-coder-7b.

curl https://aibadgr.com/v1/jobs \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "model.serve",
    "input": { "model": "qwen-7b" }
  }'

# Response includes endpoint_url and the resolved model_id:
# {
#   "output": {
#     "endpoint_url": "https://...",
#     "model": "Qwen/Qwen2.5-7B-Instruct",
#     "alias": "qwen-7b"
#   }
# }

Or pass a full HuggingFace model ID: "model": "mistralai/Mistral-7B-Instruct-v0.3". Cancel with POST /v1/jobs/{id}/cancel when done.

train.lora — presets + real Axolotl

Use config_preset for zero-config LoRA fine-tuning. Presets: small (RTX 4090, rank 16, 3 epochs) or medium (A100, rank 32, 5 epochs). Dataset from a URL, a Badgr upload ID, or a GitHub URL.

# Option A: dataset from URL
curl https://aibadgr.com/v1/jobs \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "train.lora",
    "input": {
      "base_model": "Qwen/Qwen2.5-7B-Instruct",
      "config_preset": "small",
      "dataset_url": "https://huggingface.co/datasets/tatsu-lab/alpaca/resolve/main/data/train-00000-of-00001.parquet"
    }
  }'

# Option B: dataset from a GitHub repo file
# "github_dataset_url": "https://github.com/user/repo/blob/main/data/train.jsonl"

# Option C: dataset from a Badgr file upload
# "dataset_file_id": "<id from POST /v1/uploads>"

# After completion, download the LoRA adapter:
curl https://aibadgr.com/v1/jobs/$JOB_ID/adapter \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -o lora-adapter.tar.gz

comfy.batch — batch image generation

Queue up to 20 prompts through ComfyUI in a single job. Images are downloaded and stored; retrieve them at GET /v1/jobs/{id}/images/{index}. Currently supports workflow_id: "sdxl-basic" (SDXL 1.0, 1024×1024).

curl https://aibadgr.com/v1/jobs \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "comfy.batch",
    "input": {
      "workflow_id": "sdxl-basic",
      "prompts": [
        "a red fox in a snowy forest, photorealistic",
        "a futuristic city at sunset, digital art",
        "an astronaut riding a horse on the moon"
      ]
    }
  }'

# After completion, job output contains:
# { "image_urls": ["https://aibadgr.com/v1/jobs/.../images/0", ...] }

# Download each image:
curl https://aibadgr.com/v1/jobs/$JOB_ID/images/0 \
  -H "Authorization: Bearer $BADGR_API_KEY" \
  -o image_0.png

GPU options

Badgr Auto selects the best eligible GPU for your workload. Use --gpu or --min-vram only when you need more control.

Flag valueGPUVRAM
RTX_3090NVIDIA RTX 309024 GB
RTX_4090NVIDIA RTX 409024 GB
L40SNVIDIA L40S48 GB
A100NVIDIA A10040–80 GB
H100NVIDIA H10080 GB

Available GPU types may vary by region and current capacity. Run badgr capacity or use --dry-run to confirm availability and pricing before provisioning.

GPU Capacity

Check available GPUs before launching

Browse updated capacity, pricing, and availability on the Badgr Capacity page. Check what GPUs are ready right now and their hourly rates.

Browse GPU capacity →

Coming soon

Real-time log streaming (currently polls every 4 s — functional, not true streaming)
Multi-node training jobs (distributed across multiple GPU machines)
Spot/preemptible GPU instances for non-critical batch workloads

Not supported

AMD Radeon GPUs
Intel Arc GPUs
Apple Silicon (M-series)
NVIDIA T4 / V100 (retired from pool)
Consumer GPUs below RTX 3080 (insufficient VRAM for most workloads)