From f12ab167ea22071588348aba216134313a2522c3 Mon Sep 17 00:00:00 2001 From: Tyrin Todd Date: Tue, 10 Feb 2026 11:37:23 -0800 Subject: [PATCH] (no commit message) --- README.md | 67 +++++++++++++++++++--------------------------- config.json | 4 --- probe.json | 1 + probe.safetensors | Bin 0 -> 20636 bytes program.json | 2 +- 5 files changed, 29 insertions(+), 45 deletions(-) create mode 100644 probe.json create mode 100644 probe.safetensors diff --git a/README.md b/README.md index 22dc50c..77c405b 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,13 @@ Modaic internal SDK for benchmarking judges and training confidence probes. ## Installation ```bash +cd cli uv sync ``` ## CLI Commands -All commands can be run via `uv run bench ` or using the shorthand `uv run `. +All commands are run from the `cli` directory via `uv run mo `. ### `create` @@ -25,15 +26,12 @@ Create benchmark datasets for training confidence probes. This command runs a ju ```bash # Interactive mode (recommended) - prompts for configuration -uv run create ppe -uv run create judge_bench +uv run mo create ppe +uv run mo create judge_bench # With config file -uv run create ppe --config config.yaml -uv run create judge_bench --config config.yaml - -# Full command form -uv run bench create ppe --config config.yaml +uv run mo create ppe --config config.yaml +uv run mo create judge_bench --config config.yaml ``` **Options:** @@ -70,16 +68,13 @@ Train a confidence probe on an embeddings dataset created with `create`. ```bash # Interactive mode (recommended) - prompts for all configuration -uv run train +uv run mo train # With config file -uv run train --config config.yaml +uv run mo train --config config.yaml # With CLI arguments -uv run train --dataset tytodd/my-embeddings --epochs 10 --lr 0.0001 - -# Full command form -uv run bench train --config config.yaml +uv run mo train --dataset tytodd/my-embeddings --epochs 10 --lr 0.0001 ``` **Options:** @@ -131,16 +126,13 @@ Evaluate a trained confidence probe on a dataset. Computes calibration and discr ```bash # Interactive mode (recommended) - prompts for probe and dataset -uv run eval +uv run mo eval # With CLI arguments -uv run eval --probe tytodd/my-probe --dataset tytodd/my-embeddings +uv run mo eval --probe tytodd/my-probe --dataset tytodd/my-embeddings # Evaluate on train split instead of test -uv run eval --probe tytodd/my-probe --dataset tytodd/my-embeddings --split train - -# Full command form -uv run bench eval --probe tytodd/my-probe --dataset tytodd/my-embeddings +uv run mo eval --probe tytodd/my-probe --dataset tytodd/my-embeddings --split train ``` **Options:** @@ -188,15 +180,12 @@ Compile (optimize) a judge using GEPA over a dataset. GEPA iteratively improves ```bash # Interactive mode -uv run compile -uv run compile ppe +uv run mo compile +uv run mo compile ppe # With config file -uv run compile --config config.yaml -uv run compile ppe --config config.yaml - -# Full command form -uv run bench compile --config config.yaml +uv run mo compile --config config.yaml +uv run mo compile ppe --config config.yaml ``` **Options:** @@ -235,7 +224,7 @@ seed: 42 --- -### `reembed` +### `embed` Regenerate embeddings for an existing dataset using a different model or layer. Useful for experimenting with different embedding configurations without re-running the judge. @@ -243,13 +232,10 @@ Regenerate embeddings for an existing dataset using a different model or layer. ```bash # Interactive mode -uv run reembed +uv run mo embed # With CLI arguments -uv run reembed --dataset tytodd/my-dataset --hf-model Qwen/Qwen3-VL-32B-Instruct --layer -1 - -# Full command form -uv run bench reembed --dataset tytodd/my-dataset +uv run mo embed --dataset tytodd/my-dataset --hf-model Qwen/Qwen3-VL-32B-Instruct --layer -1 ``` **Options:** @@ -272,7 +258,7 @@ uv run bench reembed --dataset tytodd/my-dataset ```bash # Original dataset was created with layer 32 # Now try middle layer instead -uv run reembed \ +uv run mo embed \ --dataset tytodd/my-embeddings \ --hf-model Qwen/Qwen3-VL-32B-Instruct \ --layer -1 @@ -298,19 +284,19 @@ Use `-1` for the middle layer if experimenting with an unlisted model. ```bash # 1. Create a probe dataset from a benchmark -uv run create ppe +uv run mo create ppe # 2. Train a confidence probe -uv run train --dataset tytodd/ppe-qwen3-embeddings +uv run mo train --dataset tytodd/ppe-qwen3-embeddings # 3. Evaluate the probe on a test set -uv run eval --probe tytodd/my-probe --dataset tytodd/ppe-qwen3-embeddings +uv run mo eval --probe tytodd/my-probe --dataset tytodd/ppe-qwen3-embeddings # 4. (Optional) Compile/optimize a judge with GEPA -uv run compile ppe +uv run mo compile ppe # 5. (Optional) Re-embed with different layer -uv run reembed --dataset tytodd/my-dataset --layer 32 +uv run mo embed --dataset tytodd/my-dataset --layer 32 ``` ## Environment Variables @@ -321,5 +307,6 @@ Create a `.env` file with: OPENAI_API_KEY=... WANDB_API_KEY=... HF_TOKEN=... -MODAIC_API_KEY=... +MODAIC_TOKEN=... +TOGETHER_API_KEY=... ``` diff --git a/config.json b/config.json index 63fe6fc..0e72b46 100644 --- a/config.json +++ b/config.json @@ -34,10 +34,6 @@ "label": { "__dspy_field_type": "output", "desc": "Which response is better: 'A>B' or 'B>A'", - "enum": [ - "A>B", - "B>A" - ], "prefix": "Label:", "title": "Label", "type": "string" diff --git a/probe.json b/probe.json new file mode 100644 index 0000000..6de82a1 --- /dev/null +++ b/probe.json @@ -0,0 +1 @@ +{"probe_version":"v1","embedding_dim":5120,"model_path":"Qwen/Qwen3-VL-32B-Instruct","dropout":0.0,"layer_index":16,"num_layers":65,"probe_type":"linear"} \ No newline at end of file diff --git a/probe.safetensors b/probe.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..2044c37c0933b13afd61dd3f2b32558ba173b97e GIT binary patch literal 20636 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