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=50 succeeds
  • Invalid: training_epochs=0 raises HPCallError: 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 min and max in hp.int(), hp.float(), hp.multi_int(), and hp.multi_float() to define inclusive numeric ranges.
  • Automatic validation: The HP class in src/hypster/hp.py automatically dispatches bounds to validators in src/hypster/hp_calls.py when parameters are processed.
  • Error handling: Violations raise HPCallError with 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_bounds automatically 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →