Reactor allows YAML files for configuration. The configuration schema is completely up to you: you
define whatever parameters your model needs. Reactor loads the YAML, merges any CLI overrides, and
passes the result to your model’s constructor as a DictConfig object.
Quick Start
# Run with config from @model decorator
reactor run
# Run with a specific config file
reactor run -c configs/my_config.yaml
# Override a single value from CLI
reactor run --model.fps=60
# Combine: load config file + override specific values
reactor run -c configs/base.yaml --model.num_steps=10 --model.use_cache=false
Throughout this page, we omit the --runtime argument for brevity. In practice, you will
typically run reactor run --runtime http ... for local development. See Model
Instancing for details on running your model.
How Configuration Flows to Your Model
Configuration passes through several stages before reaching your model:
- The CLI reads the
config field from the @model decorator (or uses the -c flag if provided)
- The YAML file is loaded
- Any
--model.* CLI overrides are merged on top
- The final
DictConfig is passed to your model’s __init__
EDITOR: Add diagram showing configuration flow from @model decorator and CLI flags through
OmegaConf merge to the model constructor.
Configuration Files (YAML)
Configuration files are standard YAML files. They can contain any structure your model expects:
# configs/default.yaml
# Basic parameters
fps: 30
height: 480
width: 832
seed: 1
# Nested configuration
model_kwargs:
local_attn_size: 12
timestep_shift: 5.0
sink_size: 3
# Lists
denoising_step_list:
- 1000
- 750
- 500
- 250
# Paths (relative to working directory)
generator_ckpt: models/longlive_base.pt
lora_ckpt: models/lora.pt
The YAML file is parsed by OmegaConf, which supports advanced
features like:
- Variable interpolation:
output_path: ${model_name}/outputs
- Environment variables:
api_key: ${oc.env:API_KEY}
Specifying a Config File
In the @model Decorator
Set a default config file in your decorator:
@model(name="my-model", config="configs/default.yaml")
class MyVideoModel(VideoModel):
...
When you run reactor run without the -c flag, the runtime loads this file. If no config field
is specified in the decorator, the model receives an empty configuration.
With the -c Flag
Use -c or --config to specify a config file explicitly:
reactor run -c configs/high_quality.yaml
reactor run --config configs/experimental.yaml
When you specify -c, it takes precedence over the config field in the @model decorator. This
lets you switch between configurations without modifying your code:
# Use the fast config for development
reactor run -c configs/fast.yaml
# Use the high-quality config for production
reactor run -c configs/high_quality.yaml
CLI Overrides with --model.*
You can override any configuration value from the command line using the --model. prefix:
reactor run --model.fps=60 --model.seed=42
For nested values, use dot notation:
reactor run --model.model_kwargs.timestep_shift=3.0
Overrides are merged on top of the configuration file, so you can load a base config and tweak
specific values:
reactor run -c configs/base.yaml --model.num_steps=20 --model.use_cache=true
Type Handling
OmegaConf automatically infers types from the values you provide:
| CLI Value | Interpreted Type |
|---|
--model.fps=30 | int |
--model.scale=1.5 | float |
--model.enabled=true | bool |
--model.enabled=false | bool |
--model.name=my-model | str |
--model.path=/tmp/out | str |
For strings that look like numbers or booleans, quote them:
reactor run --model.version="1.0" # string, not float
Configuration Priority
When multiple sources provide configuration, they are merged in this order (later sources override
earlier ones):
@model decorator config field: Base configuration from the file specified in the decorator
-c flag: Replaces the decorator config entirely if provided
--model.* overrides: Applied on top of whichever config file was loaded
Example Scenarios
Scenario 1: Decorator config only
reactor run
# Loads: @model(config="configs/default.yaml") -> configs/default.yaml
Scenario 2: -c flag overrides decorator
reactor run -c configs/fast.yaml
# Loads: configs/fast.yaml (ignores decorator's config field)
Scenario 3: CLI overrides on top of file
reactor run -c configs/base.yaml --model.fps=60
# Loads: configs/base.yaml, then overrides fps=60
Scenario 4: CLI overrides with no config file
reactor run --model.fps=60 --model.seed=42
# Creates config from CLI overrides only: {fps: 60, seed: 42}
This last scenario is useful for simple models that only need a few parameters.
Accessing Configuration in Your Model
Your model’s __init__ method receives the merged configuration as a DictConfig. There are two
approaches: typed parsing (recommended) or direct access.
Recommended: Typed Configuration with Dataclass
Define a dataclass that describes your expected configuration schema. This gives you autocompletion,
type checking, and validation in one place:
from dataclasses import dataclass, field
from typing import Optional, List
from omegaconf import DictConfig, OmegaConf
from reactor_runtime import VideoModel
@dataclass
class ModelConfig:
"""Configuration schema for MyVideoModel."""
fps: int = 30
height: int = 480
width: int = 832
seed: Optional[int] = None
num_steps: int = 5
use_cache: bool = True
denoising_steps: List[int] = field(default_factory=lambda: [1000, 750, 500, 250])
class MyVideoModel(VideoModel):
def __init__(self, config: DictConfig):
# Parse DictConfig into typed dataclass
self.cfg: ModelConfig = OmegaConf.structured(ModelConfig)
self.cfg = OmegaConf.merge(self.cfg, config)
# Now you have full type safety and IDE autocompletion
self._fps = self.cfg.fps # int, guaranteed
self._height = self.cfg.height # int, guaranteed
self._seed = self.cfg.seed # Optional[int]
You can also use Pydantic for more advanced validation:
from pydantic import BaseModel, Field
from omegaconf import DictConfig, OmegaConf
class ModelConfig(BaseModel):
"""Configuration schema with Pydantic validation."""
fps: int = Field(default=30, ge=1, le=120, description="Frames per second")
height: int = Field(default=480, ge=64, description="Output height in pixels")
width: int = Field(default=832, ge=64, description="Output width in pixels")
num_steps: int = Field(default=5, ge=1, le=100, description="Denoising steps")
cfg_scale: float = Field(default=7.5, ge=1.0, le=20.0, description="Guidance scale")
class MyVideoModel(VideoModel):
def __init__(self, config: DictConfig):
# Convert DictConfig to dict, then validate with Pydantic
raw_dict = OmegaConf.to_container(config, resolve=True)
self.cfg = ModelConfig(**raw_dict)
# Full validation happens automatically
self._fps = self.cfg.fps
self._num_steps = self.cfg.num_steps
Alternative: Direct Access with .get()
For simpler models or rapid prototyping, you can access values directly:
class MyVideoModel(VideoModel):
def __init__(self, config: DictConfig):
# Safe access with defaults using .get()
self._fps = config.get("fps", 30)
self._seed = config.get("seed", None)
# Dot-access (raises ConfigAttributeError if missing)
self._height = config.height
self._width = config.width
# Access nested values
self._timestep_shift = config.model_kwargs.timestep_shift
# Check if a key exists
if "lora_ckpt" in config:
self._load_lora(config.lora_ckpt)
DictConfig Tips
The DictConfig object from OmegaConf behaves like a dictionary but also supports:
# Dot-access (attribute style)
config.fps # Same as config["fps"]
# Safe access with defaults
config.get("missing_key", "default_value")
# Check existence
"fps" in config # True/False
# Convert to plain dict if needed
plain_dict = OmegaConf.to_container(config, resolve=True)
# Convert to YAML string (for logging)
from omegaconf import OmegaConf
print(OmegaConf.to_yaml(config))
Use the typed dataclass or Pydantic approach for any model you plan to maintain long-term. It
provides IDE autocompletion, catches typos at startup, documents your configuration schema in
code, and makes refactoring safer. The direct .get() approach is fine for quick experiments but
becomes error-prone as your config grows.
Inspecting Available Configuration Options
Use --config-help to see all available parameters in a config file and their current values:
reactor run -c configs/default.yaml --config-help
Output:
Model configuration options from: configs/default.yaml
============================================================
Available parameters (override with --model.<key>=<value>):
--model.fps=30
Type: int, Default: 30
--model.height=480
Type: int, Default: 480
--model.model_kwargs.timestep_shift=5.0
Type: float, Default: 5.0
...
============================================================
This helps you discover what options are available and how to override them.
Best Practices
Use a Base Config in the @model Decorator
Always specify a default configuration in your decorator so reactor run works out of the box:
@model(name="my-model", config="configs/default.yaml")
class MyVideoModel(VideoModel):
...
Create Multiple Config Variants
Keep different configurations for different use cases:
configs/
├── default.yaml # Balanced defaults
├── fast.yaml # Lower quality, faster inference
├── high_quality.yaml # Higher quality, slower inference
└── debug.yaml # Verbose logging, small batches
Use CLI Overrides for Experiments
Do not create a new config file for every experiment. Use CLI overrides:
# Quick iteration on a parameter
reactor run -c configs/base.yaml --model.num_steps=5
reactor run -c configs/base.yaml --model.num_steps=10
reactor run -c configs/base.yaml --model.num_steps=20
Document Your YAML Files
Add comments to your YAML files for users who edit them directly:
# Number of denoising steps. Higher = better quality, slower.
# Recommended: 4-8 for real-time, 20+ for offline rendering.
num_steps: 5
# Classifier-free guidance scale. Higher = more prompt adherence.
# Range: 1.0 (no guidance) to 15.0 (strong guidance)
cfg_scale: 7.5
Fail Fast with Clear Errors
If not using Pydantic validation, check required fields and constraints early:
def __init__(self, config: DictConfig):
if "model_path" not in config:
raise ValueError(
"Config missing required 'model_path'. "
"Add it to your config file or pass --model.model_path=<path>"
)
self._num_steps = config.get("num_steps", 5)
if self._num_steps < 1:
raise ValueError(f"num_steps must be >= 1, got {self._num_steps}")
With Pydantic, this validation happens automatically when you instantiate the config model.
Common Issues
Config File Not Found
Error loading config file 'configs/default.yaml': [Errno 2] No such file or directory
Solution: Paths in the @model decorator are relative to the model file’s directory. Make sure
the config file exists at the specified path.
Unknown Configuration Key
If your model crashes because of an unexpected key, it means the YAML file contains parameters the
model does not use. Either:
- Remove unused keys from the YAML file
- Use
config.get() with defaults instead of direct access
Type Mismatch
ValueError: expected int, got str
Solution: YAML infers types automatically. If a value like version: 1.0 is being read as float
when you need a string, quote it: version: "1.0"
CLI Reference
| Argument | Description |
|---|
-c, --config | Path to YAML config file. Overrides the @model decorator’s config field |
--config-help | Show all config options from the specified config file and exit |
--model.<key>=<value> | Override a specific config value. Can be repeated |
Environment Variables in Config
OmegaConf supports environment variable interpolation:
# configs/production.yaml
api_key: ${oc.env:MY_API_KEY}
output_dir: ${oc.env:OUTPUT_DIR,/tmp/output} # with default