Skip to main content

A hyper-parameter library for researchers, data scientists and machine learning engineers.

Project description

Hyperparameter Logo

Hyperparameter

ENGLISH | 中文文档

Make configurable AI applications. Build for Python/Rust hackers.

Hyperparameter is a versatile library designed to streamline the management and control of hyperparameters in machine learning algorithms and system development. Tailored for AI researchers and Machine Learning Systems (MLSYS) developers, Hyperparameter offers a unified solution with a focus on ease of use in Python, high-performance access in Rust and C++, and a set of macros for seamless hyperparameter management.

5-Minute Try

pip install hyperparameter

# Run a ready-to-use demo
python -m hyperparameter.examples.quickstart

# Try the @hp.param CLI: override defaults from the command line
python -m hyperparameter.examples.quickstart --define greet.name=Alice --enthusiasm=3

# Inspect params and defaults
python -m hyperparameter.examples.quickstart -lps
    python -m hyperparameter.examples.quickstart -ep greet.name
    
    # Running from source? Use module mode or install editable
    # python -m hyperparameter.examples.quickstart
    # or: pip install -e .
    ```
    
    ## Why Hyperparameter?
    
    ### 🚀 Unmatched Performance (vs Hydra)
    
    Hyperparameter is built on a high-performance Rust backend, making it significantly faster than pure Python alternatives like Hydra, especially in inner-loop parameter access.
    
    | Method | Time (1M iters) | Speedup (vs Hydra) |
    | :--- | :--- | :--- |
    | **HP: Injected (Native Speed)** | **0.0184s** | **856.73x** 🚀 |
    | **HP: Dynamic (Optimized)** | **2.4255s** | **6.50x** ⚡️ |
    | **Hydra (Baseline)** | 15.7638s | 1.00x |
    
    > Benchmark scenario: Accessing a nested parameter `model.layers.0.size` 1,000,000 times in a loop.
    > See `benchmark/` folder for reproduction scripts.
    
    ### ✨ Zero-Dependency Schema Validation
    
    Hyperparameter supports structural validation using standard Python type hints without introducing heavy dependencies (like Pydantic or OmegaConf).
    
    ```python
    from dataclasses import dataclass
    import hyperparameter as hp
    
    @dataclass
    class AppConfig:
        host: str
        port: int
        debug: bool = False
    
    # Validates types and converts automatically: "8080" -> 8080 (int)
    cfg = hp.config("config.toml", schema=AppConfig)
    ```
    
    ## Key Features

### For Python Users

- **Pythonic Syntax:** Define hyperparameters using keyword argument syntax;

    - **Intuitive Scoping:** Control parameter scope through `with` statement;
    
    - **Configuration File:** Easy to load parameters from config files (JSON/TOML/YAML) with composition and interpolation support;
    
    - **Zero-Overhead Validation:** Optional schema validation using standard Python type hints;
    
    ### For Rust and C++ Users

- **High-Performance Backend:** Hyperparameter is implemented in Rust, providing a robust and high-performance backend for hyperparameter management. Access hyperparameters in Rust and C++ with minimal overhead, making it ideal for ML and system developers who prioritize performance.

- **Macro-Based Parameter Management:** Hyperparameter provides a set of macros for both Rust and C++ users. These macros mimic Python's `with` statements and adhere to language-specific scoping rules.

- **Compile-Time Hashing:** Both Rust and C++ interfaces utilize compile-time hashing of hyperparameter names, reducing runtime hash computation overhead.

## Quick Start

### Installation

```bash
pip install hyperparameter

Python

import hyperparameter as hp

@hp.param("foo")
def foo(x=1, y="a"):
    return f"x={x}, y={y}"

foo()  # x=1, y='a'

with hp.scope(**{"foo.x": 2}):
    foo()  # x=2, y='a'

Rust

fn foo() -> i32 {
    with_params! {
        @get x = foo.x or 1i32; // Read hyperparameter with default value

        println!("x={}", x);
    }
}

fn main() {
    foo(); // x=1

    with_params! {
        @set foo.x = 2i32; // Set hyperparameter

        foo(); // x=2
    }

    foo(); // x=1
}

C++

ASSERT(1 == GET_PARAM(a.b, 1), "get undefined param");
{
  auto guard = WITH_PARAMS(a, 1,        //
                            a.b, 2.0,    //
                            a.b.c, true, //
                            a.b.c.d, "str");
  ASSERT(1 == GET_PARAM(a, 0), "get int value");
  ASSERT(1 == GET_PARAM(a, 0), "get int value");
}

Detailed Usage Examples

Support for Default Values

Python

x = hp.scope.foo.x | "default value"

Rust

@get x = foo.x or "default value";

Scope Control of Parameter Values

Python

with hp.scope() as ps: # 1st scope start
    ps.foo.x=1
    with hp.scope() as ps2: # 2nd scope start
        ps.foo.y=2
    # 2nd scope end
# 1st scope end

Rust

with_params!{ // 1st scope start
    @set foo.x=1;

    with_params!{ //2nd scope start
        @set foo.y=2

        ...
    } // 2nd scope end
} // 1st scope end

Thread Isolation/Thread Safety

Python

@hp.param("foo")
def foo(x=1): # Print hyperparameter foo.x
    print(f"foo.x={x}")

with hp.scope() as ps:
    ps.foo.x=2 # Modify foo.x in the current thread
    
    foo() # foo.x=2
    threading.Thread(target=foo).start() # foo.x=1, new thread's hyperparameter value is not affected by the main thread

Rust

fn foo() { // Print hyperparameter foo.x
    with_params!{
        @get x = foo.x or 1;

        println!("foo.x={}", x);
    }
}

fn main() {
    with_params!{
        @set foo.x = 2; // Modify foo.x in the current thread
        
        foo(); // foo.x=2
        thread::spawn(foo); // foo.x=1, new thread's hyperparameter value is not affected by the main thread
    }
}

Command Line Application

In command line applications, it's common to define hyperparameters using command line arguments (e.g., -D, --define) and control hyperparameters on the command line. Here's an example in Python and Rust:

Python

# example.py
import hyperparameter as hp

@hp.param("example")
def main(a=0, b=1):
    print(f"example.a={a}, example.b={b}")

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()

    parser.add_argument("-D", "--define", nargs="*", default=[], action="extend")
    args = parser.parse_args()

    with hp.scope(*args.define):
        main()

Rust

// example.rs
use hyperparameter::*;
use hyperparameter_derive::Parser;

fn main() {
    #[derive(Parser, Debug)]
    struct DeriveArgs {
        #[arg(short = 'D', long)]
        define: Vec<String>,
    }

    let args = DeriveArgs::parse();

    with_params! {
        params ParamScope::from(&args.define);

        foo()
    }
}

fn foo() {
    with_params! {
        @get a = example.a or 0;
        @get b = example.b or 1;
        
        println!("example.a={}, example.b={}",a ,b);
    }
}

More Examples

parameter tunning for researchers

This example demonstrates how to use hyperparameter in research projects, and make experiments reproducible.

experiment tracing for data scientists

This example showcases experiment management with hyperparameter and result tracing with mlflow.tracing.

Behavior Guarantees (Semantic Contract)

  • Keys & hashing: keys use . for nesting, case is preserved, and hashing uses the same UTF-8 input and seed across Python/Rust/C++; invalid characters are an error.
  • Read precedence: current thread’s innermost scope > parent scopes outward > frozen global snapshot > user default. Writes only affect the current scope and rollback on exit.
  • Defaults vs. missing: only missing keys fall back to defaults; explicit None/False/0 are treated as existing values. Type conversion rules (bool/int/float/str) are consistent across languages; invalid values use a best-effort conversion and otherwise fall back to the provided default (no silent random values).
  • Threads & frozen(): each thread starts from the frozen global snapshot; mutations stay in-thread unless frozen() is called, which atomically updates the global snapshot. Global mutations are lock-protected in the Python backend, matching Rust semantics.
  • Error model: reading an undefined key without a default raises a key error; backend load failure falls back to the Python backend without noisy tracebacks; no silent failure on type errors.
  • Multiprocess notice: cross-process consistency requires a shared backend (e.g., Rust backend or user-provided storage adapter); the built-in Python backend only guards threads, not processes.

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

hyperparameter-0.6.0.tar.gz (72.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

hyperparameter-0.6.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (437.1 kB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ x86-64

hyperparameter-0.6.0-cp37-abi3-macosx_11_0_arm64.whl (370.9 kB view details)

Uploaded CPython 3.7+macOS 11.0+ ARM64

hyperparameter-0.6.0-cp37-abi3-macosx_10_7_x86_64.whl (384.3 kB view details)

Uploaded CPython 3.7+macOS 10.7+ x86-64

File details

Details for the file hyperparameter-0.6.0.tar.gz.

File metadata

  • Download URL: hyperparameter-0.6.0.tar.gz
  • Upload date:
  • Size: 72.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for hyperparameter-0.6.0.tar.gz
Algorithm Hash digest
SHA256 065e3ea223b6f3774de8cc4cb7c31e21a7939663785941fedfe64ce93707a1a8
MD5 b57a98551f1345dd96b1d4480fe2d69e
BLAKE2b-256 5adc0a1729fb6c498b6578ac301605517b01bc30f21b56b54e493913c661b1fc

See more details on using hashes here.

File details

Details for the file hyperparameter-0.6.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for hyperparameter-0.6.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 96caedaca1160ae742859bc2e9b94352b1b01fa041936467db5e96e84e9ed578
MD5 5bcbd395884b9876c0641a6bb7a84f49
BLAKE2b-256 a11226a3aa69814f5138b9a36afd741645ead4d0d3b9b23efa094bed7428bdd9

See more details on using hashes here.

File details

Details for the file hyperparameter-0.6.0-cp37-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hyperparameter-0.6.0-cp37-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ba8a4155ef34ae45e3bc64c6b27efdc8779a9c82621b265286b917038f6e544b
MD5 ed42cb435cfcdad524fc7f37c9603e8c
BLAKE2b-256 40d6282f94276b7e49491e76a7bd6a1b768e4ca5f7ca5a6dbda2fc379abe6506

See more details on using hashes here.

File details

Details for the file hyperparameter-0.6.0-cp37-abi3-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for hyperparameter-0.6.0-cp37-abi3-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 86316d438d490afa74b6d3f968aceb4fb0854b19bf9378944b4e66710c281d54
MD5 ac44e61f0058402c2d428a01935d704e
BLAKE2b-256 4e98b589281e6a0f65b1b3e80e5d5db80ad877fa39f1db99797e71939d64ebd5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page