badgr-cli 1.0.43 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +180 -230
- package/package.json +1 -1
- package/src/badgr.js +12 -0
- package/src/catalog.js +46 -0
- package/src/commands/comfyui.js +70 -56
- package/src/commands/detect.js +58 -0
- package/src/commands/receipts.js +39 -2
- package/src/commands/run.js +150 -68
- package/src/commands/serve.js +278 -115
- package/src/commands/train.js +22 -27
- package/src/detect.js +362 -0
- package/src/progress.js +202 -0
- package/src/store.js +11 -0
- package/tests/detect.test.js +191 -0
- package/tests/job-progress-poll.test.js +136 -0
- package/tests/productized-runners.test.js +7 -0
- package/tests/run-lifecycle.test.js +111 -1
- package/tests/serve-apps.test.js +189 -0
- package/tests/serve-lifecycle.test.js +116 -2
- package/tests/store.test.js +22 -1
- package/tests/template.test.js +4 -4
- package/tests/workload-templates.test.js +22 -0
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Badgr supports many GPU workloads through two commands: `serve` for persistent endpoints, `run` for jobs.
|
|
4
4
|
|
|
5
|
+
> **Safety promise:** every run has `--max-cost`, live logs, automatic teardown, and a receipt. Run `badgr down <id>` any time to stop billing immediately.
|
|
6
|
+
|
|
5
7
|
```bash
|
|
6
8
|
npm install -g badgr-cli
|
|
7
9
|
```
|
|
@@ -23,56 +25,75 @@ badgr run . --cmd "python train.py" --max-cost 5
|
|
|
23
25
|
# 4. Serve an OpenAI-compatible inference endpoint
|
|
24
26
|
badgr serve meta-llama/Llama-3.1-8B-Instruct --max-cost 10
|
|
25
27
|
|
|
26
|
-
# 5.
|
|
27
|
-
|
|
28
|
-
# client = OpenAI(api_key=os.environ["BADGR_API_KEY"], base_url=os.environ["BADGR_ENDPOINT"])
|
|
28
|
+
# 5. Stop billing
|
|
29
|
+
badgr down <deployment-id>
|
|
29
30
|
|
|
30
|
-
#
|
|
31
|
+
# 6. View cost, route, and retry receipts
|
|
31
32
|
badgr receipts
|
|
33
|
+
```
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
`badgr serve` prints a URL you can point any OpenAI SDK client at — see [OpenAI compatibility](#openai-compatibility).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Also try: image generation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
badgr comfyui batch --workflow sdxl-basic --prompt "a cat on a beach" --max-cost 5
|
|
35
43
|
```
|
|
36
44
|
|
|
45
|
+
Runs a blessed ComfyUI workflow, no setup, and prints image URLs when done. No manual teardown needed — it stops itself. Details in [`badgr comfyui batch` options](#badgr-comfyui-batch-options).
|
|
46
|
+
|
|
37
47
|
---
|
|
38
48
|
|
|
39
49
|
## Commands
|
|
40
50
|
|
|
51
|
+
```text
|
|
52
|
+
login
|
|
53
|
+
run
|
|
54
|
+
serve
|
|
55
|
+
status
|
|
56
|
+
logs
|
|
57
|
+
down
|
|
58
|
+
receipts
|
|
59
|
+
test
|
|
60
|
+
```
|
|
61
|
+
|
|
41
62
|
| Command | What it does |
|
|
42
63
|
|---------|-------------|
|
|
43
64
|
| `badgr login` | Save API key to `~/.badgr/config.json` |
|
|
44
|
-
| `badgr serve <model>` | Start a persistent OpenAI-compatible endpoint |
|
|
45
65
|
| `badgr run <command>` | Run a one-off GPU job (any container command) |
|
|
66
|
+
| `badgr serve <model>` | Start a persistent OpenAI-compatible endpoint |
|
|
46
67
|
| `badgr status` | Show what's running and what's billing |
|
|
47
|
-
| `badgr down <id>` | Terminate a deployment — stops billing immediately |
|
|
48
68
|
| `badgr logs <id>` | Fetch log output from a deployment |
|
|
69
|
+
| `badgr down <id>` | Terminate a deployment — stops billing immediately |
|
|
49
70
|
| `badgr receipts [n]` | Cost, route, and retry receipts (default 10) |
|
|
50
|
-
| `badgr capacity` | Check available GPU capacity right now |
|
|
51
|
-
| `badgr billing` | Show balance and add funds |
|
|
52
71
|
| `badgr test` | Run an end-to-end test (provision → run → teardown) |
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
| `badgr workload info <name>` | Show stats, route history, and recent jobs for a workload |
|
|
56
|
-
| `badgr workload delete <name>` | Delete a saved workload |
|
|
57
|
-
| `badgr workspace list` | List workspace trackers (job history + cost per context) |
|
|
58
|
-
| `badgr workspace create <name>` | Create a workspace tracker, optionally linked to a storage path |
|
|
59
|
-
| `badgr workspace info <name>` | Show jobs, cost, and files for a workspace |
|
|
60
|
-
| `badgr workspace delete <name>` | Archive a workspace tracker |
|
|
72
|
+
|
|
73
|
+
More commands below, under [Advanced](#advanced): `comfyui`, `train`, `transcribe`, `embed`, `workload`, `workspace`, `capacity`, `billing`.
|
|
61
74
|
|
|
62
75
|
`badgr serve` — for anything that needs a persistent endpoint: LLM serving, embeddings, image generation APIs, transcription APIs.
|
|
63
76
|
|
|
64
77
|
`badgr run` — for anything that starts, runs, and exits: batch inference, fine-tuning, evals, image/video batch jobs, audio processing.
|
|
65
78
|
|
|
66
|
-
|
|
79
|
+
---
|
|
67
80
|
|
|
68
|
-
|
|
69
|
-
| `badgr comfyui batch --workflow ...` | Productized batch image generation — no ComfyUI setup, blessed workflow only |
|
|
70
|
-
| `badgr train <config.yaml>` | LoRA / fine-tuning job, stream logs |
|
|
71
|
-
| `badgr train lora --base-model ...` | Productized LoRA training — preset + dataset, no config file needed |
|
|
72
|
-
| `badgr transcribe <audio>` | Whisper transcription, print transcript |
|
|
73
|
-
| `badgr embed <model> <input>` | Text embeddings, output JSONL |
|
|
81
|
+
## Common flags
|
|
74
82
|
|
|
75
|
-
|
|
83
|
+
These appear on most commands (`run`, `serve`, `comfyui`, `train`, `transcribe`, `embed`) — documented once here instead of repeated in every table below.
|
|
84
|
+
|
|
85
|
+
| Flag | Default | Description |
|
|
86
|
+
|------|---------|-------------|
|
|
87
|
+
| `--gpu <type>` | auto | GPU type override — see [GPU options](#gpu-options) |
|
|
88
|
+
| `--tier 1\|2` | 1 | `1` = reliable managed routing (default); `2` = lower-cost marketplace routing |
|
|
89
|
+
| `--region US\|EU\|AU` | — | Region preference. If omitted, Badgr chooses best available capacity |
|
|
90
|
+
| `--max-price <$/hr>` | — | Hard spend cap per GPU-hour |
|
|
91
|
+
| `--count <n>` | 1 | Number of GPUs |
|
|
92
|
+
| `--env KEY=VALUE` | — | Environment variable (repeatable) |
|
|
93
|
+
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount — **required** for `run`, `comfyui run`, `comfyui batch`, `train lora` |
|
|
94
|
+
| `--detach` | off | Launch and return immediately, don't stream logs (`serve` uses `--no-wait` instead — see below) |
|
|
95
|
+
|
|
96
|
+
Each command section below lists only its own extra flags.
|
|
76
97
|
|
|
77
98
|
---
|
|
78
99
|
|
|
@@ -84,21 +105,26 @@ badgr serve meta-llama/Llama-3.1-8B-Instruct --gpu L40S --region EU
|
|
|
84
105
|
|
|
85
106
|
| Flag | Default | Description |
|
|
86
107
|
|------|---------|-------------|
|
|
87
|
-
| `--gpu <type>` | auto | GPU type override — Badgr Auto selects based on model size if omitted |
|
|
88
108
|
| `--image <img>` | — | Serve a custom container instead of a HuggingFace model |
|
|
89
109
|
| `--task <task>` | — | vLLM task override, e.g. `embed` for embedding models |
|
|
90
|
-
| `--env KEY=VALUE` | — | Environment variable (repeatable) |
|
|
91
|
-
| `--tier 1\|2` | 1 | `1` = reliable execution (default); `2` = lower-cost burst capacity |
|
|
92
|
-
| `--count <n>` | 1 | Number of GPUs (1–8) |
|
|
93
|
-
| `--region US\|EU\|AU` | — | Optional region preference. If omitted, Badgr chooses best available capacity. |
|
|
94
|
-
| `--max-price <$/hr>` | — | Hard spend cap per GPU-hour |
|
|
95
|
-
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount |
|
|
96
110
|
| `--health-path <path>` | auto | Readiness path to poll (auto-detected for ComfyUI → `/system_stats`) |
|
|
97
|
-
| `--no-wait` |
|
|
111
|
+
| `--no-wait` | off | Skip endpoint health check and return immediately |
|
|
98
112
|
| `--list-aliases` | — | List blessed vLLM model aliases (`qwen-7b`, `llama-8b`, `qwen-coder-7b`) and exit — no provisioning, no API key required |
|
|
99
113
|
|
|
100
114
|
Blessed aliases expand to a full model ID + preset GPU, e.g. `badgr serve qwen-7b` → `Qwen/Qwen2.5-7B-Instruct` on an RTX 4090. Run `badgr serve --list-aliases` to see the current list.
|
|
101
115
|
|
|
116
|
+
### Model support levels
|
|
117
|
+
|
|
118
|
+
`badgr serve qwen-7b` is the happy path — a tested route with no extra setup. `badgr serve` also accepts any other model ID or a custom container:
|
|
119
|
+
|
|
120
|
+
| Level | What it means |
|
|
121
|
+
|-------|---------------|
|
|
122
|
+
| **Tested route** (`badgr serve qwen-7b`) | One of the aliases above — tested and officially supported. |
|
|
123
|
+
| **Best-effort Hugging Face model** (`badgr serve <org>/<model>`) | Any other Hugging Face model ID. Badgr will try a compatible route — not a guarantee every model works. |
|
|
124
|
+
| **Custom container** (`badgr serve --image ...`) | You own the server behavior; Badgr manages runtime, logs, spend caps, teardown, and the receipt. |
|
|
125
|
+
|
|
126
|
+
Gated Hugging Face models (e.g. Llama, Gemma) may need `--env HF_TOKEN=$HF_TOKEN`. Badgr only prints that hint if the deployment actually fails to start.
|
|
127
|
+
|
|
102
128
|
---
|
|
103
129
|
|
|
104
130
|
## `badgr run` options
|
|
@@ -121,18 +147,26 @@ Badgr zips and uploads the folder (Flow 1) or clones the repo (Flow 2), picks a
|
|
|
121
147
|
| Flag | Default | Description |
|
|
122
148
|
|------|---------|-------------|
|
|
123
149
|
| `--cmd <command>` | — | Command to run inside the uploaded project or cloned repo (required for folder/GitHub flows) |
|
|
124
|
-
| `--gpu <type>` | auto | GPU type override — Badgr Auto selects if omitted |
|
|
125
150
|
| `--min-vram <GB>` | — | Minimum VRAM in GB — optional constraint for Auto routing |
|
|
126
|
-
| `--image <img>` | — | Custom Docker image — bypasses the runner
|
|
127
|
-
| `--env KEY=VALUE` | — | Environment variable (repeatable) |
|
|
128
|
-
| `--tier 1\|2` | 1 | `1` = reliable execution (default); `2` = lower-cost burst capacity |
|
|
129
|
-
| `--count <n>` | 1 | Number of GPUs |
|
|
130
|
-
| `--region US\|EU\|AU` | — | Optional region preference. If omitted, Badgr chooses best available capacity. |
|
|
131
|
-
| `--max-price <$/hr>` | — | Hard spend cap per GPU-hour |
|
|
151
|
+
| `--image <img>` | — | Custom Docker image — bypasses the runner |
|
|
132
152
|
| `--max-runtime <min>` | — | Auto-stop after N minutes |
|
|
133
|
-
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount (required) |
|
|
134
|
-
| `--detach` | — | Launch and return immediately, don't stream logs |
|
|
135
153
|
| `--save <name>` | — | Save this job as a named workload after it completes |
|
|
154
|
+
| `--workspace <name-or-id>` | — | Link this run to a workspace (name or `ws_` ID) |
|
|
155
|
+
| `--output <path>` | — | See "Crash recovery" below |
|
|
156
|
+
| `--checkpoint <path>` | — | See "Crash recovery" below |
|
|
157
|
+
| `--retry-safe` | off | See "Crash recovery" below |
|
|
158
|
+
| `--resume-cmd "<cmd>"` | — | See "Crash recovery" below |
|
|
159
|
+
|
|
160
|
+
**Crash recovery is a convention, not a feature Badgr runs for you.** Badgr just passes these through into the container as environment variables — *your* script has to read them and actually write the files:
|
|
161
|
+
|
|
162
|
+
| Flag | Container sees | Your script needs to |
|
|
163
|
+
|------|-----------------|-----------------------|
|
|
164
|
+
| `--output <path>` | `BADGR_OUTPUT_DIR=<path>` | Write outputs it wants preserved to that path |
|
|
165
|
+
| `--checkpoint <path>` | `BADGR_CHECKPOINT_DIR=<path>` | Write/read resumable checkpoints at that path |
|
|
166
|
+
| `--retry-safe` | `BADGR_RETRY_SAFE=1` | Confirm it's safe to re-run from scratch (e.g. it checkpoints/dedupes internally) |
|
|
167
|
+
| `--resume-cmd "<cmd>"` | *(not passed to the container)* | Nothing — Badgr just prints this command back to you on failure, so you have it without digging through shell history |
|
|
168
|
+
|
|
169
|
+
On failure, `badgr run` / `badgr serve` / `badgr comfyui run` all print a `Class:`/`Next:` pair identifying what went wrong (e.g. `out_of_memory`, `image_pull_failed`, `cuda_unavailable`) and a suggested next step.
|
|
136
170
|
|
|
137
171
|
---
|
|
138
172
|
|
|
@@ -147,16 +181,10 @@ Requires either `--max-cost` or `--persistent` to prevent runaway billing.
|
|
|
147
181
|
|
|
148
182
|
| Flag | Default | Description |
|
|
149
183
|
|------|---------|-------------|
|
|
150
|
-
| `--gpu <type>` | auto (16+ GB VRAM) | GPU type override |
|
|
151
|
-
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount |
|
|
152
|
-
| `--max-price <$/hr>` | — | Hard spend cap per GPU-hour |
|
|
153
|
-
| `--tier 1\|2` | 1 | Provider tier |
|
|
154
|
-
| `--region US\|EU\|AU` | — | Region preference |
|
|
155
184
|
| `--check-nodes <n1,n2>` | — | Verify custom nodes are installed after startup |
|
|
156
|
-
| `--no-wait` |
|
|
157
|
-
| `--persistent` |
|
|
158
|
-
| `--
|
|
159
|
-
| `--yes` / `-y` | — | Skip duplicate-deployment warning |
|
|
185
|
+
| `--no-wait` | off | Skip health check, return immediately |
|
|
186
|
+
| `--persistent` | off | Run until manually stopped (no spending cap) |
|
|
187
|
+
| `--yes` / `-y` | off | Skip duplicate-deployment warning |
|
|
160
188
|
|
|
161
189
|
---
|
|
162
190
|
|
|
@@ -176,253 +204,175 @@ Blessed workflows: `sdxl-basic` (SDXL text-to-image, default sampler settings).
|
|
|
176
204
|
| `--workflow <name>` | — | Blessed workflow ID (required) — currently `sdxl-basic` |
|
|
177
205
|
| `--prompts <file>` | — | Text file, one prompt per line |
|
|
178
206
|
| `--prompt <text>` | — | Inline prompt (repeatable) — combine with `--prompts` if needed |
|
|
179
|
-
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount (required unless `--dry-run`) |
|
|
180
207
|
| `--max-runtime <min>` | 60 | Auto-stop after N minutes |
|
|
181
208
|
| `--gpu-type <type>` | workflow default | GPU type override |
|
|
182
|
-
| `--tier 1\|2` | 1 | Provider tier |
|
|
183
209
|
| `--dry-run` | — | Preview the batch (workflow, GPU, prompt count, cost) without provisioning |
|
|
184
210
|
|
|
185
211
|
Polls until complete and prints image URLs, or detaches with `badgr status` guidance if it outlives `--max-runtime`.
|
|
186
212
|
|
|
187
213
|
---
|
|
188
214
|
|
|
189
|
-
##
|
|
190
|
-
|
|
191
|
-
```bash
|
|
192
|
-
badgr train config.yaml --gpu A100 --max-runtime 240 --env HF_TOKEN=$HF_TOKEN
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
Detects framework (axolotl, unsloth, trl) from config content, but **only Axolotl configs run today** — the container command for `unsloth`/`trl`/unrecognized configs isn't wired up yet, so `badgr train` blocks before provisioning rather than billing a GPU that's guaranteed to fail. Use `--framework axolotl` to force it, or use `badgr train lora` for a config-free productized path. Default max-runtime is 120 min.
|
|
196
|
-
|
|
197
|
-
| Flag | Default | Description |
|
|
198
|
-
|------|---------|-------------|
|
|
199
|
-
| `--gpu <type>` | auto (40+ GB VRAM preferred) | GPU type override |
|
|
200
|
-
| `--max-runtime <min>` | 120 | Auto-stop after N minutes |
|
|
201
|
-
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount |
|
|
202
|
-
| `--max-price <$/hr>` | — | Hard spend cap per GPU-hour |
|
|
203
|
-
| `--tier 1\|2` | 1 | Provider tier |
|
|
204
|
-
| `--region US\|EU\|AU` | — | Region preference |
|
|
205
|
-
| `--framework <name>` | auto-detect | Force framework: `axolotl`, `unsloth`, `trl` (only `axolotl` currently runs) |
|
|
206
|
-
| `--env KEY=VALUE` | — | Environment variable (repeatable) |
|
|
207
|
-
| `--detach` | — | Launch and return immediately, don't stream logs |
|
|
208
|
-
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
## `badgr train lora` options
|
|
215
|
+
## Receipts
|
|
212
216
|
|
|
213
|
-
|
|
217
|
+
Every `badgr serve` and `badgr run` action generates a receipt:
|
|
214
218
|
|
|
215
219
|
```bash
|
|
216
|
-
badgr
|
|
217
|
-
badgr
|
|
220
|
+
badgr receipts # last 10
|
|
221
|
+
badgr receipts 50 # last 50
|
|
218
222
|
```
|
|
219
223
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
| Flag | Default | Description |
|
|
223
|
-
|------|---------|-------------|
|
|
224
|
-
| `--base-model <id>` | — | HuggingFace model ID (required) — validated to exist before provisioning |
|
|
225
|
-
| `--dataset <path\|url>` | — | Local file, direct URL, or `s3://` URI |
|
|
226
|
-
| `--file-id <id>` | — | Badgr upload ID instead of `--dataset` |
|
|
227
|
-
| `--preset small\|medium` | `small` | Training profile — see below |
|
|
228
|
-
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount (required unless `--dry-run`) |
|
|
229
|
-
| `--max-runtime <min>` | 240 | Auto-stop after N minutes |
|
|
230
|
-
| `--gpu-type <type>` | preset default | GPU type override |
|
|
231
|
-
| `--tier 1\|2` | 1 | Provider tier |
|
|
232
|
-
| `--dry-run` | — | Preview the job (preset, GPU, rank, epochs, cost) without provisioning |
|
|
233
|
-
|
|
234
|
-
**Presets:**
|
|
224
|
+
Each receipt includes runtime, estimated/settled cost, status, retries, teardown/billing result, and job/deployment ID.
|
|
235
225
|
|
|
236
|
-
|
|
237
|
-
|--------|-----|-----------|--------|----------|
|
|
238
|
-
| `small` (default) | RTX 4090 | 16 | 3 | Fast, low-cost — good default for most datasets |
|
|
239
|
-
| `medium` | A100 | 32 | 5 | Larger rank/more epochs — bigger datasets or higher quality |
|
|
226
|
+
---
|
|
240
227
|
|
|
241
|
-
|
|
228
|
+
## OpenAI compatibility
|
|
242
229
|
|
|
243
|
-
|
|
230
|
+
`badgr serve` provisions a vLLM endpoint that is fully OpenAI-compatible:
|
|
244
231
|
|
|
245
|
-
|
|
232
|
+
```python
|
|
233
|
+
import os
|
|
234
|
+
from openai import OpenAI
|
|
246
235
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
236
|
+
# Export BADGR_ENDPOINT from the URL printed by `badgr serve`
|
|
237
|
+
client = OpenAI(
|
|
238
|
+
api_key=os.environ["BADGR_API_KEY"],
|
|
239
|
+
base_url=os.environ["BADGR_ENDPOINT"],
|
|
240
|
+
)
|
|
241
|
+
resp = client.chat.completions.create(
|
|
242
|
+
model="meta-llama/Llama-3.1-8B-Instruct",
|
|
243
|
+
messages=[{"role": "user", "content": "Hello"}],
|
|
244
|
+
)
|
|
250
245
|
```
|
|
251
246
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
| `--output <format>` | — | Output format: `txt`, `srt`, `vtt` |
|
|
260
|
-
| `--max-runtime <min>` | 30 | Auto-stop after N minutes |
|
|
261
|
-
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount |
|
|
262
|
-
| `--max-price <$/hr>` | — | Hard spend cap per GPU-hour |
|
|
263
|
-
| `--tier 1\|2` | 1 | Provider tier |
|
|
264
|
-
| `--region US\|EU\|AU` | — | Region preference |
|
|
265
|
-
| `--env KEY=VALUE` | — | Environment variable (repeatable) |
|
|
266
|
-
| `--detach` | — | Launch and return immediately, don't stream logs |
|
|
247
|
+
```js
|
|
248
|
+
import OpenAI from "openai";
|
|
249
|
+
const client = new OpenAI({
|
|
250
|
+
apiKey: process.env.BADGR_API_KEY,
|
|
251
|
+
baseURL: process.env.BADGR_ENDPOINT, // URL printed by `badgr serve`
|
|
252
|
+
});
|
|
253
|
+
```
|
|
267
254
|
|
|
268
255
|
---
|
|
269
256
|
|
|
270
|
-
##
|
|
257
|
+
## GPU options
|
|
271
258
|
|
|
272
|
-
|
|
273
|
-
badgr embed BAAI/bge-large-en-v1.5 documents.txt --max-cost 2
|
|
274
|
-
badgr embed BAAI/bge-large-en-v1.5 s3://bucket/corpus.jsonl
|
|
275
|
-
badgr embed documents.txt # uses default model
|
|
276
|
-
```
|
|
259
|
+
Badgr Auto selects the best eligible GPU for your workload. Add `--gpu <type>` or `--min-vram <GB>` only when you need more control.
|
|
277
260
|
|
|
278
|
-
|
|
261
|
+
| Flag value | GPU | VRAM | Best for |
|
|
262
|
+
|-----------|-----|------|---------|
|
|
263
|
+
| RTX_3090 | NVIDIA RTX 3090 | 24 GB | Dev, inference |
|
|
264
|
+
| RTX_4090 | NVIDIA RTX 4090 | 24 GB | Inference, training, dev |
|
|
265
|
+
| L40S | NVIDIA L40S | 48 GB | Inference, vLLM, embeddings |
|
|
266
|
+
| A100 | NVIDIA A100 | 40–80 GB | Training, inference |
|
|
267
|
+
| H100 | NVIDIA H100 | 80 GB | Large model training |
|
|
279
268
|
|
|
280
|
-
|
|
281
|
-
|------|---------|-------------|
|
|
282
|
-
| `--gpu <type>` | auto (8+ GB VRAM) | GPU type override |
|
|
283
|
-
| `--batch-size <n>` | — | Embedding batch size |
|
|
284
|
-
| `--max-runtime <min>` | 30 | Auto-stop after N minutes |
|
|
285
|
-
| `--max-cost <$>` | — | Auto-stop when total spend reaches this amount |
|
|
286
|
-
| `--max-price <$/hr>` | — | Hard spend cap per GPU-hour |
|
|
287
|
-
| `--tier 1\|2` | 1 | Provider tier |
|
|
288
|
-
| `--region US\|EU\|AU` | — | Region preference |
|
|
289
|
-
| `--env KEY=VALUE` | — | Environment variable (repeatable) |
|
|
290
|
-
| `--detach` | — | Launch and return immediately, don't stream logs |
|
|
269
|
+
Additional GPU types may be routable depending on current capacity — check with `badgr capacity`. Pricing is confirmed before provisioning; use `--dry-run` to see it first. Full GPU support details: see [NOTES.md](../../NOTES.md#gpu-support) in the repo root.
|
|
291
270
|
|
|
292
271
|
---
|
|
293
272
|
|
|
294
|
-
##
|
|
273
|
+
## Routing
|
|
295
274
|
|
|
296
|
-
|
|
275
|
+
`--tier 1` (default) uses managed provider routing — reliable, consistent performance. `--tier 2` uses marketplace routing for lower-cost options. Most users should stick with the default.
|
|
297
276
|
|
|
298
|
-
|
|
277
|
+
Preview any command before provisioning with `--dry-run`, e.g.:
|
|
299
278
|
|
|
300
279
|
```bash
|
|
301
|
-
badgr
|
|
280
|
+
badgr serve meta-llama/Llama-3.1-8B-Instruct --dry-run
|
|
302
281
|
```
|
|
303
282
|
|
|
304
|
-
|
|
283
|
+
---
|
|
305
284
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
badgr workload run my-training-job --set HF_TOKEN=newval # override an env var
|
|
310
|
-
```
|
|
285
|
+
## Advanced
|
|
286
|
+
|
|
287
|
+
Less common commands — training, transcription, embeddings, and the workload/workspace trackers. Same flags as `run`/`serve` unless noted (see [Common flags](#common-flags)).
|
|
311
288
|
|
|
312
|
-
|
|
289
|
+
### `badgr train` / `badgr train lora`
|
|
313
290
|
|
|
314
291
|
```bash
|
|
315
|
-
badgr
|
|
316
|
-
badgr workload info my-training-job # stats, route history, recent jobs
|
|
317
|
-
badgr workload delete my-training-job
|
|
292
|
+
badgr train config.yaml --gpu A100 --max-runtime 240 --env HF_TOKEN=$HF_TOKEN
|
|
318
293
|
```
|
|
319
294
|
|
|
320
|
-
|
|
321
|
-
|---|---|
|
|
322
|
-
| `--max-cost <$>` | Override the saved spend cap for this run |
|
|
323
|
-
| `--max-runtime <min>` | Override the saved runtime limit for this run |
|
|
324
|
-
| `--set KEY=VALUE` | Override a saved config value for this run (repeatable) |
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Workspaces
|
|
329
|
-
|
|
330
|
-
Workspaces are an advanced infrastructure concept — most users never need to manage them directly. When you run `badgr run .`, Badgr handles code upload, dependency caching, and artifact storage automatically. Workspaces are only needed when you want to group jobs under a named context for cost tracking, or link jobs to persistent S3/GCS storage.
|
|
295
|
+
Detects framework (axolotl, unsloth, trl) from the config file, but **only Axolotl configs run today** — `unsloth`/`trl`/unrecognized configs are blocked before provisioning rather than billing a GPU that's guaranteed to fail. Default max-runtime is 120 min.
|
|
331
296
|
|
|
332
297
|
```bash
|
|
333
|
-
badgr
|
|
334
|
-
badgr run . --cmd "python eval.py" --workspace my-project --max-cost 5
|
|
335
|
-
badgr workspace info my-project # jobs, total cost, files
|
|
336
|
-
badgr workspace list
|
|
337
|
-
badgr workspace delete my-project
|
|
298
|
+
badgr train lora --base-model mistralai/Mistral-7B-v0.1 --dataset ./train.jsonl --preset small --max-cost 20
|
|
338
299
|
```
|
|
339
300
|
|
|
340
|
-
|
|
341
|
-
|---|---|
|
|
342
|
-
| `--storage <path>` | S3/GCS path to associate with this workspace |
|
|
343
|
-
| `--desc <text>` | Optional description |
|
|
344
|
-
|
|
345
|
-
---
|
|
346
|
-
|
|
347
|
-
## Routing
|
|
348
|
-
|
|
349
|
-
Badgr Auto selects the best eligible route based on GPU type, VRAM, availability, region, workload requirements, and reliability. Advanced users can optionally choose an execution tier or hardware constraint.
|
|
350
|
-
|
|
351
|
-
Most users should use the default Badgr Auto route. Tiers are an optional advanced control.
|
|
301
|
+
Productized LoRA training — pass a base model and dataset, no Axolotl config file needed. Badgr generates the config from a preset and returns a downloadable adapter.
|
|
352
302
|
|
|
353
|
-
|
|
303
|
+
| Flag | Default | Description |
|
|
304
|
+
|------|---------|-------------|
|
|
305
|
+
| `--framework <name>` | auto-detect | Force framework: `axolotl`, `unsloth`, `trl` (only `axolotl` currently runs) |
|
|
306
|
+
| `--base-model <id>` | — | HuggingFace model ID (required for `train lora`) — validated to exist before provisioning |
|
|
307
|
+
| `--dataset <path\|url>` | — | Local file, direct URL, or `s3://` URI |
|
|
308
|
+
| `--file-id <id>` | — | Badgr upload ID instead of `--dataset` |
|
|
309
|
+
| `--preset small\|medium` | `small` | `small` = RTX 4090, rank 16, 3 epochs. `medium` = A100, rank 32, 5 epochs |
|
|
310
|
+
| `--gpu-type <type>` | preset default | GPU type override for `train lora` |
|
|
311
|
+
| `--dry-run` | — | Preview the job without provisioning |
|
|
354
312
|
|
|
355
|
-
|
|
313
|
+
On completion, `train lora` prints an `adapter_url` — download with `GET /v1/jobs/{job_id}/adapter`, or via `badgr workload info` if saved.
|
|
356
314
|
|
|
357
|
-
|
|
315
|
+
### `badgr transcribe`
|
|
358
316
|
|
|
359
317
|
```bash
|
|
360
|
-
badgr
|
|
318
|
+
badgr transcribe recording.mp3 --max-cost 2
|
|
361
319
|
```
|
|
362
320
|
|
|
363
|
-
|
|
321
|
+
Whisper transcription. Accepts a public URL, S3/GCS URI, or a local file under 50 MB. Default max-runtime is 30 min.
|
|
364
322
|
|
|
365
|
-
|
|
323
|
+
| Flag | Default | Description |
|
|
324
|
+
|------|---------|-------------|
|
|
325
|
+
| `--model <name>` | `large-v3` | Whisper model |
|
|
326
|
+
| `--language <code>` | — | Language hint (e.g. `en`, `fr`) |
|
|
327
|
+
| `--output <format>` | — | Output format: `txt`, `srt`, `vtt` |
|
|
366
328
|
|
|
367
|
-
|
|
329
|
+
### `badgr embed`
|
|
368
330
|
|
|
369
331
|
```bash
|
|
370
|
-
badgr
|
|
371
|
-
badgr receipts 50 # last 50
|
|
332
|
+
badgr embed BAAI/bge-large-en-v1.5 documents.txt --max-cost 2
|
|
372
333
|
```
|
|
373
334
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
---
|
|
377
|
-
|
|
378
|
-
## OpenAI compatibility
|
|
335
|
+
Text embeddings via vLLM. Accepts a public URL, S3/GCS URI, or a local text file under 10 MB. Outputs JSONL (`{"text": ..., "embedding": [...]}`). Default max-runtime is 30 min.
|
|
379
336
|
|
|
380
|
-
|
|
337
|
+
| Flag | Default | Description |
|
|
338
|
+
|------|---------|-------------|
|
|
339
|
+
| `--batch-size <n>` | — | Embedding batch size |
|
|
381
340
|
|
|
382
|
-
|
|
383
|
-
import os
|
|
384
|
-
from openai import OpenAI
|
|
341
|
+
### Workloads
|
|
385
342
|
|
|
386
|
-
|
|
387
|
-
client = OpenAI(
|
|
388
|
-
api_key=os.environ["BADGR_API_KEY"],
|
|
389
|
-
base_url=os.environ["BADGR_ENDPOINT"],
|
|
390
|
-
)
|
|
391
|
-
resp = client.chat.completions.create(
|
|
392
|
-
model="meta-llama/Llama-3.1-8B-Instruct",
|
|
393
|
-
messages=[{"role": "user", "content": "Hello"}],
|
|
394
|
-
)
|
|
395
|
-
```
|
|
343
|
+
A workload is a saved job configuration, created with `--save <name>` on `badgr run`. Rerun by name instead of retyping all the flags; Badgr tracks success rate, average cost, and the last known-good route.
|
|
396
344
|
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
345
|
+
```bash
|
|
346
|
+
badgr run . --cmd "python train.py" --max-cost 10 --save my-training-job
|
|
347
|
+
badgr workload run my-training-job
|
|
348
|
+
badgr workload list
|
|
349
|
+
badgr workload info my-training-job
|
|
350
|
+
badgr workload delete my-training-job
|
|
403
351
|
```
|
|
404
352
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
353
|
+
| Subcommand | Description |
|
|
354
|
+
|------------|-------------|
|
|
355
|
+
| `list [n]` | List saved workloads |
|
|
356
|
+
| `info <name>` | Stats, route history, recent jobs |
|
|
357
|
+
| `run <name>` | Submit a new job using the workload's saved config (`--max-cost`, `--max-runtime`, `--set KEY=VALUE` to override) |
|
|
358
|
+
| `delete <name>` | Delete the workload record |
|
|
408
359
|
|
|
409
|
-
|
|
360
|
+
### Workspaces
|
|
410
361
|
|
|
411
|
-
|
|
362
|
+
Most users never need this — `badgr run .` handles upload, caching, and artifact storage automatically. Workspaces are for grouping jobs under a named cost/context bucket, optionally linked to S3/GCS storage.
|
|
412
363
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
Additional GPU types may be routable depending on current capacity — check with `badgr capacity`.
|
|
364
|
+
```bash
|
|
365
|
+
badgr workspace create my-project --storage s3://my-bucket/runs --desc "nightly evals"
|
|
366
|
+
badgr run . --cmd "python eval.py" --workspace my-project --max-cost 5
|
|
367
|
+
badgr workspace info my-project
|
|
368
|
+
badgr workspace list
|
|
369
|
+
badgr workspace delete my-project
|
|
370
|
+
```
|
|
422
371
|
|
|
423
|
-
|
|
372
|
+
### Other commands
|
|
424
373
|
|
|
425
|
-
|
|
374
|
+
- `badgr capacity [--gpu <type>]` — check available GPU capacity right now
|
|
375
|
+
- `badgr billing status` / `badgr billing add <amount>` — check balance / add funds
|
|
426
376
|
|
|
427
377
|
---
|
|
428
378
|
|
package/package.json
CHANGED
package/src/badgr.js
CHANGED
|
@@ -20,14 +20,17 @@ import { embedCommand } from './commands/embed.js';
|
|
|
20
20
|
import { templateCommand } from './commands/template.js';
|
|
21
21
|
import { workloadCommand } from './commands/workload.js';
|
|
22
22
|
import { workspaceCommand } from './commands/workspace.js';
|
|
23
|
+
import { detectCommand } from './commands/detect.js';
|
|
23
24
|
|
|
24
25
|
const HELP = `
|
|
25
26
|
${chalk.bold('badgr')} — run or serve GPU workloads from one command
|
|
26
27
|
|
|
27
28
|
${chalk.bold('COMMANDS')}
|
|
28
29
|
${chalk.cyan('badgr login')} Authenticate with your API key
|
|
30
|
+
${chalk.cyan('badgr detect <path>')} Inspect a project and report the GPU job Badgr would run
|
|
29
31
|
${chalk.cyan('badgr run <command>')} Run a one-off GPU job
|
|
30
32
|
${chalk.cyan('badgr serve <model>')} Serve a model with an OpenAI-compatible endpoint
|
|
33
|
+
${chalk.cyan('badgr serve openwebui')} Serve Open WebUI — chat UI, connects to a model endpoint
|
|
31
34
|
${chalk.cyan('badgr status')} Show what's running and what's billing
|
|
32
35
|
${chalk.cyan('badgr logs <id>')} Stream logs for a running job or endpoint
|
|
33
36
|
${chalk.cyan('badgr down <id>')} Stop a deployment and end billing
|
|
@@ -53,12 +56,20 @@ ${chalk.bold('SHORTCUTS')} ${chalk.dim('(wrappers around run / serve for common
|
|
|
53
56
|
${chalk.cyan('badgr serve --list-aliases')} List blessed vLLM model shortcuts (qwen-7b, llama-8b, …)
|
|
54
57
|
|
|
55
58
|
${chalk.bold('EXAMPLES')}
|
|
59
|
+
${chalk.dim('# Point Badgr at any project and see what it detects:')}
|
|
60
|
+
badgr detect .
|
|
61
|
+
badgr run . --max-cost 5 --save my-job
|
|
62
|
+
badgr workload run my-job
|
|
63
|
+
|
|
56
64
|
${chalk.dim('# Verify the stack works end-to-end:')}
|
|
57
65
|
badgr test
|
|
58
66
|
|
|
59
67
|
${chalk.dim('# Serve a model (OpenAI-compatible):')}
|
|
60
68
|
badgr serve meta-llama/Llama-3.1-8B-Instruct --max-cost 10
|
|
61
69
|
|
|
70
|
+
${chalk.dim('# Serve Open WebUI, connected to a model endpoint:')}
|
|
71
|
+
badgr serve openwebui --model qwen-7b --max-cost 10
|
|
72
|
+
|
|
62
73
|
${chalk.dim('# Serve a Hugging Face GGUF file via llama.cpp:')}
|
|
63
74
|
badgr serve --runtime llama.cpp \\
|
|
64
75
|
--hf-repo org/model-repo \\
|
|
@@ -141,6 +152,7 @@ async function main() {
|
|
|
141
152
|
|
|
142
153
|
switch (cmd) {
|
|
143
154
|
case 'login': return loginCommand(chalk, saveConfig);
|
|
155
|
+
case 'detect': return detectCommand(config, rest, chalk);
|
|
144
156
|
case 'run': return runCommand(config, rest, chalk);
|
|
145
157
|
case 'serve': return serveCommand(config, rest, chalk);
|
|
146
158
|
case 'status': return statusCommand(config, rest, chalk);
|