How to Define and Validate Parameter Bounds (min/max) in Hypster
Use the min and max arguments in hp.int(), hp.float(), hp.multi_int(), or hp.multi_float() to restrict numeric ranges, and Hypster automatically validates inputs against these bounds through the ParameterValidator class in src/hypster/hp_calls.py.
Hypster, the open-source configuration library from gilad-rubin/hypster, provides built-in bounds validation for numeric hyperparameters. By specifying min and max constraints when defining parameters in your configuration functions, you enforce operational limits without writing manual validation logic, ensuring that integer, float, and multi-value numeric parameters remain within acceptable ranges.
How Parameter Bounds Work in Hypster
Core Validation Architecture
The bounds validation system operates through a dispatcher-validator pattern across two primary modules. The HP class in src/hypster/hp.py acts as the dispatcher, while validator classes in src/hypster/hp_calls.py perform the actual numeric comparisons.
When you call a numeric parameter method like hp.int() or hp.float(), the system packages your min and max arguments into specification objects (SingleValueSpec or MultiValueSpec). These specifications travel through the execution chain until they reach the validation layer.
The Validation Flow
In src/hypster/hp.py (lines 47–50), the _handle_single_value method detects whether bounds were provided and forwards them to the validator:
if (min is not None or max is not None) and hasattr(validator, "validate_bounds"):
validator.validate_bounds(validated_value, min, max, full_path)
The ParameterValidator.validate_bounds method in src/hypster/hp_calls.py (lines 26–50) performs the actual comparison and raises a descriptive HPCallError when violations occur:
if min_val is not None and value < min_val:
raise HPCallError(...)
if max_val is not None and value > max_val:
raise HPCallError(...)
For multi-value parameters, the MultiValidator.validate_bounds method (lines 55–62) iterates over each element and delegates to the element validator, providing index-specific error reporting:
for i, value in enumerate(values):
self.element_validator.validate_bounds(value, min_val, max_val, f"{param_path}[{i}]")
Defining Min/Max Constraints in Practice
Single Numeric Parameters
The HP._int and HP._float methods accept optional min and max arguments that define inclusive bounds. These parameters work with the strict argument to simultaneously enforce type safety and numeric ranges.
def config(hp):
# Integer between 1 and 5 (inclusive)
batch = hp.int(3, name="batch_size", min=1, max=5)
# Float between 0.0 and 1.0 with strict type checking
lr = hp.float(0.01, name="learning_rate", min=0.0, max=1.0, strict=True)
return {"batch_size": batch, "lr": lr}
Multi-Value Numeric Lists
For list-based parameters, hp.multi_int() and hp.multi_float() apply bounds validation to every element individually. If any list item violates the constraints, Hypster raises an error indicating the specific index that failed validation.
def config(hp):
# Each layer size must be between 10 and 100
layers = hp.multi_int([20, 30], name="layer_sizes", min=10, max=100)
return {"layers": layers}
Passing [5, 20] triggers:
Parameter 'layer_sizes': invalid item at index 0: value 5 is below minimum bound 10
Default Value Validation
Bounds apply equally to user-provided values and default values. If you define a parameter with hp.int(50, name="epochs", min=10, max=200) and the user does not override it, Hypster validates that the default 50 satisfies the constraints before returning the configuration.
Code Examples
Basic Integer Bounds
Define a parameter restricted to a specific operational range:
def config(hp):
epochs = hp.int(10, name="training_epochs", min=1, max=100)
return {"epochs": epochs}
- Valid:
training_epochs=50succeeds - Invalid:
training_epochs=0raisesHPCallError: Parameter 'training_epochs': value 0 is below minimum bound 1
Float Constraints with Precision
Control continuous hyperparameters like learning rates with tight bounds:
def config(hp):
dropout = hp.float(0.2, name="dropout_rate", min=0.0, max=0.9)
return {"dropout": dropout}
The bounds are inclusive, so values 0.0 and 0.9 are accepted, while 0.95 triggers a maximum bound violation.
Multi-Parameter Validation
Validate entire arrays of numeric values, such as neural network layer dimensions:
def config(hp):
hidden_units = hp.multi_int([64, 128, 256], name="hidden_units", min=32, max=512)
return {"units": hidden_units}
Each element in [64, 128, 256] is checked individually against the min=32 and max=512 constraints.
Combining Bounds with Strict Typing
Prevent implicit type coercion while maintaining numeric ranges:
def config(hp):
temperature = hp.float(1.0, name="temp", min=0.1, max=2.0, strict=True)
return {"temp": temperature}
With strict=True, passing temp=1 (integer) fails type validation before bounds checking occurs, ensuring type safety alongside range constraints.
Summary
- Bounds arguments: Use
minandmaxinhp.int(),hp.float(),hp.multi_int(), andhp.multi_float()to define inclusive numeric ranges. - Automatic validation: The
HPclass insrc/hypster/hp.pyautomatically dispatches bounds to validators insrc/hypster/hp_calls.pywhen parameters are processed. - Error handling: Violations raise
HPCallErrorwith descriptive messages indicating whether the failure occurred on a single value or a specific index in a multi-value list. - Default protection: Bounds apply to default values, ensuring that unspecified parameters still satisfy operational constraints.
- Extensibility: Any custom validator implementing
validate_boundsautomatically gains min/max support through Hypster's dispatcher logic.
Frequently Asked Questions
What types of parameters support min and max bounds in Hypster?
Integer, float, and their multi-value variants support bounds validation. Specifically, use hp.int(), hp.float(), hp.multi_int(), or hp.multi_float() with the min and max arguments. Non-numeric types like booleans or strings do not support these constraints, as the validation logic resides in numeric-specific validators within src/hypster/hp_calls.py.
Are the min and max bounds inclusive or exclusive?
The bounds are inclusive. According to the validation logic in src/hypster/hp_calls.py, a value equal to min or max passes validation; only values strictly less than min or strictly greater than max trigger an HPCallError. The code explicitly checks value < min_val and value > max_val to determine violations.
What error does Hypster raise when bounds are violated?
Hypster raises an HPCallError with a descriptive message indicating the parameter name, the offending value, and the bound that was breached. For multi-value parameters, the error includes the specific index where the violation occurred (e.g., invalid item at index 0: value 5 is below minimum bound 10).
Do min/max constraints apply to default parameter values?
Yes, bounds are enforced against default values. If you define hp.int(50, name="epochs", min=10, max=200) and do not provide a value for epochs in your input dictionary, Hypster validates that the default 50 satisfies the min=10 and max=200 constraints before returning the final configuration object.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →