PRISM - Parameter Research & Investigation Sweep Manager
Project description
๐ฌ PRISM - Parameter Research & Investigation Sweep Manager
PRISM is a simple tool to run parameter sweeps for ML experiments. Give it a base config and a sweep definition, and it will generate, validate, and execute all experiment variations.
What is PRISM?
PRISM takes your base experiment configuration and creates multiple variations by changing specific parameters. It then:
- Validates each configuration using your custom Python validator
- Runs your training script with each validated config
- Tracks progress and captures metrics
- Provides an interactive TUI to monitor experiments
Installation
From PyPI (Recommended)
pip install prism-sweep
From Source
git clone https://github.com/FrancescoCorrenti/prism-sweep.git
cd prism-sweep
pip install -e .
After installation, you can use prism_tui or prism commands from anywhere.
Quick Start Guide
Using the Interactive TUI (Recommended)
The easiest way to use PRISM is through the interactive terminal interface:
prism_tui
First Time Setup:
- Navigate to your project directory in the TUI
- Follow the guided setup to create
prism.project.yaml- Give it a name
- Select sweep definition(s)
- Give it a name
- Run experiments: Study Menu โ Execute Study โ Run All
- Select base config YAML
- Select sweep definition(s)
- Give it a name
- Monitor progress: Watch real-time logs and metrics
- Retry failures: Study Menu โ Retry Failed
- Run experiments: Study Menu โ Execute Study โ Run All
- Monitor progress: Watch real-time logs and metrics
- Retry failures: Study Menu โ Retry Failed
Using the Command Line
For automation and scripting, use the CLI:
# Create a study from base config and sweep definition
prism create --base configs/base.yaml \
--prism configs/prism/lr_sweep.prism.yaml \
--name lr_experiment
# Run all experiments in the study
prism run lr_experiment --all
# Run specific experiments
prism run lr_experiment lr_low lr_mid
# Check study status
prism status lr_experiment
# List all studies
prism list
# Retry failed experiments
prism retry lr_experiment
What Files Do I Need?
PRISM needs 3-4 files in your project:
1. prism.project.yaml (Project Configuration)
This tells PRISM where everything is. The TUI can create this for you, or create it manually:
project:
name: my-ml-project
version: "1.0"
paths:
train_script: scripts/train.py # Your training script
configs_dir: configs # Where configs live
prism_configs_dir: configs/prism # Where sweep definitions live
output_dir: outputs # Where results go
validator:
module: configs/validator.py # Optional: custom validator
metrics:
output_mode: stdout_json # How to capture metrics
2. Base Config (e.g., configs/base.yaml)
Your experiment's default configuration:
learning_rate: 0.001
batch_size: 32
epochs: 100
model: resnet18
data:
path: /data/train
augmentation: true
3. Sweep Definition (e.g., configs/prism/lr_sweep.yaml)
Defines which parameters to vary:
# Nominal parameters (creates named experiments)
learning_rate:
lr_low: 0.0001
lr_mid: 0.001
lr_high: 0.01
4. Custom Validator (Optional: configs/validator.py)
Validates configs before training:
from typing import Dict, Any
from dataclasses import dataclass
@dataclass
class ExperimentConfig:
learning_rate: float
batch_size: int
epochs: int
def validate(self):
if self.learning_rate <= 0:
raise ValueError("Learning rate must be > 0")
if self.batch_size < 1:
raise ValueError("Batch size must be >= 1")
def validate(config_dict: Dict[str, Any]) -> ExperimentConfig:
"""Called by PRISM to validate each config."""
config = ExperimentConfig(
learning_rate=config_dict.get('learning_rate', 0.001),
batch_size=config_dict.get('batch_size', 32),
epochs=config_dict.get('epochs', 100)
)
config.validate()
return config
- Cross-field validation
- Set default values
- Convert enums, paths, etc.
### Your Training Script
Make sure it accepts a `--config` argument:
```python
# scripts/train.py
import argparse
import yaml
import json
parser = argparse.ArgumentParser()
parser.add_argument('--config', required=True)
args = parser.parse_args()
with open(args.config) as f:
config = yaml.safe_load(f)
# Train your model...
learning_rate = config['learning_rate']
# ...
# Print metrics for PRISM
print(json.dumps({"loss": 0.123, "accuracy": 0.95}))
File Structure
After running PRISM, your project will look like:
your-project/
โโโ prism.project.yaml # Project config
โโโ configs/
โ โโโ validator.py # Optional: custom validator
โ โโโ base.yaml # Base configuration
โ โโโ prism/
โ โโโ lr_sweep.yaml # Sweep definition
โโโ scripts/
โ โโโ train.py # Your training script
โโโ outputs/ # Generated by PRISM
โโโ lr_experiment.prism # Study state (created by PRISM)
โโโ lr_experiment/ # Experiment outputs (created by PRISM)
โโโ lr_low/
โ โโโ config.yaml # Validated config for this experiment
โ โโโ ... # Your training outputs
โโโ lr_mid/
Sweep Definition Syntax
Named Parameters (Nominal)
# Creates experiments with custom names
model:
size:
small_model: small
large_model: large
layers:
small_model: 12
large_model: 24
Creates experiments: small_model, large_model
Positional Parameters (Lists - Zipped Together)
# Creates experiments run_0, run_1, run_2
batch_size: [16, 32, 64]
learning_rate: [0.01, 0.001, 0.0001]
run_0: batch_size=16, lr=0.01run_1: batch_size=32, lr=0.001run_2: batch_size=64, lr=0.0001
Sweep Definitions (Advanced)
# Choice sweep
optimizer:
lr:
_type: choice
_values: [0.001, 0.01, 0.1]
# Range sweep
epochs:
_type: range
_min: 10
_max: 100
_step: 10
# Linspace sweep
momentum:
_type: linspace
_min: 0.0
_max: 0.99
_num: 5
Multiple Files (Cartesian Product)
prism create --base base.yaml \
--prism models.yaml \
--prism optimizers.yaml \
--name model_opt_sweep
If models.yaml has 3 variations and optimizers.yaml has 2, you get 3ร2=6 experiments.
Complete Example
Base config (configs/base.yaml):
optimizer:
type: adam
lr: 0.001
weight_decay: 0.0001
model:
backbone: resnet50
hidden_dim: 512
Sweep config (configs/prism/lr_sweep.prism.yaml):
optimizer:
lr:
lr_low: 0.0001
lr_mid: 0.001
lr_high: 0.01
This creates 3 experiments:
lr_low: with optimizer.lr = 0.0001lr_mid: with optimizer.lr = 0.001lr_high: with optimizer.lr = 0.01
All other parameters stay the same from base config.
Metrics Capture
PRISM can capture metrics in three ways:
1. JSON stdout (default)
Your training script prints JSON:
import json
print(json.dumps({"loss": 0.5, "accuracy": 0.92}))
2. File output
# In prism.project.yaml
metrics:
output_mode: file
output_file: metrics.json
Your script writes metrics.json in the output directory.
3. Exit code only
metrics:
output_mode: exit_code
PRISM only checks if the script succeeded (exit code 0).
Advanced Features
Custom Train Arguments
You can customize how PRISM calls your training script:
# In prism.project.yaml
paths:
train_script: scripts/train.py
train_args:
- --config
- "{config_path}"
- --gpu
- "0"
Resume Failed Experiments
prism retry study_name
Or in TUI: Study Menu โ Retry Failed
Tips
- Start small: Test with 2-3 experiments before scaling up
- Use the TUI: It's much easier than CLI for exploration
- Validate early: Run one experiment manually before creating a big sweep
- Check metrics: Make sure your training script prints/writes them correctly
Troubleshooting
"No train_script defined"
โ Add paths.train_script: scripts/train.py to prism.project.yaml
"Validator module not found"
โ Check the path in validator.module is correct relative to project root
"Config validation failed"
โ Check your validate() function - it's rejecting the config
Experiments hang at "Testing data loading"
โ Fixed! Make sure you have latest version with PYTHONUNBUFFERED=1
โ Fixed! Latest version forces colors with FORCE_COLOR=1
- Python 3.8+
pyyamlrich(for TUI) That's it! No other dependencies.
- Organized: Never lose track of which experiment used which parameters
- Validated: Catch config errors before training starts
- Interactive: TUI makes it easy to monitor and manage experiments
Ready to start? Run prism_tui and follow the prompts!
parameters:
training.learning_rate: 0.001
- name: lr_high parameters: training.learning_rate: 0.01
### 3. Create and Run Study
## Sweep Configuration
## Custom Python Validator
PRISM supports custom Python validators for config validation. This is useful when you have:
- Complex type conversions (e.g., YAML โ Python dataclasses)
- Cross-field validation logic
- Enum types with custom behavior
- Integration with existing config systems
### Setup
In `prism.project.yaml`:
```yaml
project:
name: my-project
version: "1.0"
paths:
train_script: scripts/train.py
output_dir: outputs
# Custom Python validator
validator:
module: configs/validator.py
Validator Module Interface
Your validator module must expose a validate(config_dict) function:
# configs/validator.py
from typing import Dict, Any
from dataclasses import dataclass
from enum import Enum
class ModelType(str, Enum):
RESNET = "resnet"
VIT = "vit"
@dataclass
class ModelConfig:
type: ModelType
hidden_size: int = 768
@dataclass
class ExperimentConfig:
model: ModelConfig
learning_rate: float
epochs: int
def validate(self):
"""Custom validation logic."""
if self.model.type == ModelType.VIT and self.epochs < 100:
raise ValueError("ViT requires at least 100 epochs")
def validate(config_dict: Dict[str, Any]) -> ExperimentConfig:
"""
Validate and convert raw config dict to typed dataclass.
This function is called by PRISM before passing the config
to your training script.
Args:
config_dict: Raw YAML config as dictionary
Returns:
Validated ExperimentConfig (dataclass will be serialized back to YAML)
Raises:
ValueError: If validation fails
"""
# Convert dict to dataclass
model = ModelConfig(
type=ModelType(config_dict.get('model', {}).get('type', 'resnet')),
hidden_size=config_dict.get('model', {}).get('hidden_size', 768)
)
config = ExperimentConfig(
model=model,
learning_rate=config_dict.get('learning_rate', 0.001),
epochs=config_dict.get('epochs', 100)
)
# Run validation
config.validate()
return config
How It Works
- PRISM loads your base config YAML
- PRISM expands it with sweep parameters
- PRISM calls your
validate(config_dict)function - If validation passes, the result is serialized back to YAML
- The validated YAML is passed to your training script
This means your training script can simply reload the YAML - it's already validated!
# scripts/train.py
import yaml
with open(args.config) as f:
config = yaml.safe_load(f)
# ... use config['model']['type'], config['learning_rate'], etc.
Directory Structure
my_project/
โโโ prism.project.yaml # Project configuration
โโโ configs/ # Base configurations
โ โโโ base.yaml
โ โโโ validator.py # Optional: custom validator
โ โโโ prism/ # Sweep definitions
โ โโโ lr_sweep.prism.yaml
โ โโโ model_sweep.prism.yaml
โโโ scripts/
โ โโโ train.py # Your training script
โโโ outputs/ # Results and state
โโโ my_study.prism # Study state file
โโโ my_study/ # Experiment outputs
Commands Reference
CLI Commands
# Project management
prism init # Initialize new project
prism list # List all studies
# Study management
prism create --name NAME --config BASE --prism SWEEP # Create new study
prism status NAME # Show study status
prism delete NAME --force # Delete a study
prism reset NAME # Reset study to pending
# Experiment execution
prism run --study NAME --all # Run all pending experiments
prism run --study NAME --next # Run next pending
prism run --study NAME --key KEY # Run specific experiment
prism retry NAME # Retry failed experiments
# Inspection
prism show-config NAME KEY # Show experiment config
prism diff NAME KEY1 KEY2 # Compare two configs
prism mark NAME KEY done/failed # Mark experiment status
# Interactive
prism tui # Launch TUI
TUI Interface
prism_tui # Launch interactive TUI
The TUI provides:
- ๐ Recent projects quick-access
- ๐ Study overview with experiment status
- ๐ One-click experiment execution
- ๐ Real-time metrics display
- โ๏ธ Configuration browser
State Management
Each study has a .prism state file that tracks:
- Experiment configurations
- Execution status (PENDING, RUNNING, DONE, FAILED)
- Timestamps and metrics
- Original config paths for reset
Requirements
- Python 3.8+
- PyYAML
- Rich (for TUI)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Setup
# Clone the repository
git clone https://github.com/FrancescoCorrenti/prism-sweep.git
cd prism-sweep
# Install in development mode
pip install -e ".[dev]"
License
MIT License - see LICENSE file for details.
Author
Francesco Correnti
Links
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file prism_sweep-0.1.0.tar.gz.
File metadata
- Download URL: prism_sweep-0.1.0.tar.gz
- Upload date:
- Size: 49.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e56b33d9a377e3dda1d0e8495d7958220d14a5c33d3100cd0bdf13d1b7fd456d
|
|
| MD5 |
3c66776ed83b549b7f084165b8f40df1
|
|
| BLAKE2b-256 |
6f22b6b873a2e6fe853d019c82addb07a7f679a4f95f3b5741ba377969255b47
|
File details
Details for the file prism_sweep-0.1.0-py3-none-any.whl.
File metadata
- Download URL: prism_sweep-0.1.0-py3-none-any.whl
- Upload date:
- Size: 47.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc9bc0a24ceb67797e710ea08830e749ce0d57b295c0be36ea65e549c2fb3fe6
|
|
| MD5 |
f0277b21a235d5dff97c8c3c31bd0206
|
|
| BLAKE2b-256 |
c2fb96af1790b06d1dab8f85c63f265250fb8671a16d3339bbbc8899efca9e02
|