Skip to content

Commit ff50351

Browse files
authored
chore: bump version to 0.6.0 in pyproject.toml and Cargo.toml files (#22)
* feat: add config file support to CLI for hyperparameter loading - Introduced `--config` argument to load configuration files (JSON/TOML/YAML) in the CLI. - Enhanced `_describe_parameters` to handle loaded configurations and prioritize them over defined parameters. - Implemented recursive merging of configurations and added interpolation support. - Added tests for CLI configuration loading and precedence of overrides. - Refactored loader functions to support multiple file loading and validation against schemas. * feat: enhance README and add benchmark scripts for performance evaluation - Updated README to include detailed performance comparisons between Hyperparameter and Hydra, highlighting speed advantages. - Added new benchmark scripts to evaluate parameter access performance across different methods. - Introduced a new `run_benchmark.py` script to automate benchmark execution and output results. - Included additional benchmark configurations and tests for various access patterns. - Updated .gitignore to exclude benchmark output files. * feat: add guides and cookbook documentation for Hyperparameter - Introduced new navigation section in mkdocs.yml for Guides and Cookbook. - Added comprehensive architecture overview in architecture.md and architecture.zh.md. - Created a Cookbook with common recipes for configuration management in cookbook.md and cookbook.zh.md. - Included a migration guide from Hydra to Hyperparameter in migration_from_hydra.md and migration_from_hydra.zh.md. - Enhanced documentation accessibility with both English and Chinese versions for key documents. * feat: add hyperparameter logo to README and Chinese README - Introduced a new SVG logo for Hyperparameter in the project. - Updated both English and Chinese README files to include the new logo, enhancing visual appeal and branding. * refactor: update parameter management syntax and enhance documentation - Replaced `param_scope` with `scope` and `auto_param` with `param` across all documentation and examples for consistency. - Updated README, API reference, and various example files to reflect the new syntax. - Enhanced the clarity of the quick start guide and migration documentation to facilitate user transition to the new syntax. - Ensured all tests are aligned with the updated parameter management methods. * chore: update README files with new logo and enhanced formatting - Added a centered logo to both English and Chinese README files for improved branding. - Changed the header from an H3 to an H1 for better visibility and consistency. - Reformatted the description to be centered and bold, enhancing the overall presentation of the project. * refactor: update hyperparameter management syntax across benchmark and example files - Replaced `param_scope` with `hp.scope` and `auto_param` with `hp.param` in benchmark scripts and examples for consistency. - Updated CLI examples to utilize `hp.launch()` instead of `run_cli()`. - Enhanced documentation to reflect the new syntax and improve clarity in usage. * chore: bump version to 0.6.0 in pyproject.toml and Cargo.toml files - Updated version number from 0.5.14 to 0.6.0 across all relevant Cargo.toml files for core, macros, and Python packages. - Ensured consistency in versioning across the project.
1 parent 2ec3338 commit ff50351

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+4112
-1155
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,4 @@ examples/sparse_lr/mlruns/
147147
Cargo.lock
148148
.trunk/
149149
proptest-regressions/
150+
benchmark/outputs/

README.md

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
# Hyperparameter
1+
<p align="center">
2+
<img src="hyperparameter.svg" alt="Hyperparameter Logo" width="180" height="180">
3+
</p>
24

3-
<h3 align="center">
4-
<p style="text-align: center;">
5-
<a href="README.md" target="_blank">ENGLISH</a> | <a href="README.zh.md">中文文档</a>
6-
</p>
7-
</h3>
5+
<h1 align="center">Hyperparameter</h1>
86

97
<p align="center">
8+
<a href="README.md" target="_blank">ENGLISH</a> | <a href="README.zh.md">中文文档</a>
9+
</p>
1010

11-
**Hyperparameter, Make configurable AI applications. Build for Python/Rust hackers.**
12-
11+
<p align="center">
12+
<strong>Make configurable AI applications. Build for Python/Rust hackers.</strong>
1313
</p>
1414

1515
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.
@@ -22,33 +22,64 @@ pip install hyperparameter
2222
# Run a ready-to-use demo
2323
python -m hyperparameter.examples.quickstart
2424

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

2828
# Inspect params and defaults
2929
python -m hyperparameter.examples.quickstart -lps
30-
python -m hyperparameter.examples.quickstart -ep greet.name
31-
32-
# Running from source? Use module mode or install editable
33-
# python -m hyperparameter.examples.quickstart
34-
# or: pip install -e .
35-
```
36-
37-
What it shows:
38-
- default values vs scoped overrides (`param_scope`)
39-
- `@auto_param` + `launch` exposing a CLI with `-D/--define` for quick overrides
40-
41-
## Key Features
30+
python -m hyperparameter.examples.quickstart -ep greet.name
31+
32+
# Running from source? Use module mode or install editable
33+
# python -m hyperparameter.examples.quickstart
34+
# or: pip install -e .
35+
```
36+
37+
## Why Hyperparameter?
38+
39+
### 🚀 Unmatched Performance (vs Hydra)
40+
41+
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.
42+
43+
| Method | Time (1M iters) | Speedup (vs Hydra) |
44+
| :--- | :--- | :--- |
45+
| **HP: Injected (Native Speed)** | **0.0184s** | **856.73x** 🚀 |
46+
| **HP: Dynamic (Optimized)** | **2.4255s** | **6.50x** ⚡️ |
47+
| **Hydra (Baseline)** | 15.7638s | 1.00x |
48+
49+
> Benchmark scenario: Accessing a nested parameter `model.layers.0.size` 1,000,000 times in a loop.
50+
> See `benchmark/` folder for reproduction scripts.
51+
52+
### ✨ Zero-Dependency Schema Validation
53+
54+
Hyperparameter supports structural validation using standard Python type hints without introducing heavy dependencies (like Pydantic or OmegaConf).
55+
56+
```python
57+
from dataclasses import dataclass
58+
import hyperparameter as hp
59+
60+
@dataclass
61+
class AppConfig:
62+
host: str
63+
port: int
64+
debug: bool = False
65+
66+
# Validates types and converts automatically: "8080" -> 8080 (int)
67+
cfg = hp.config("config.toml", schema=AppConfig)
68+
```
69+
70+
## Key Features
4271

4372
### For Python Users
4473

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

47-
- **Intuitive Scoping:** Control parameter scope through `with` statement;
48-
49-
- **Configuration File:** Easy to load parameters from config files;
50-
51-
### For Rust and C++ Users
76+
- **Intuitive Scoping:** Control parameter scope through `with` statement;
77+
78+
- **Configuration File:** Easy to load parameters from config files (JSON/TOML/YAML) with composition and interpolation support;
79+
80+
- **Zero-Overhead Validation:** Optional schema validation using standard Python type hints;
81+
82+
### For Rust and C++ Users
5283

5384
- **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.
5485

@@ -67,15 +98,15 @@ pip install hyperparameter
6798
### Python
6899
69100
```python
70-
from hyperparameter import auto_param, param_scope
101+
import hyperparameter as hp
71102
72-
@auto_param("foo")
103+
@hp.param("foo")
73104
def foo(x=1, y="a"):
74105
return f"x={x}, y={y}"
75106
76107
foo() # x=1, y='a'
77108
78-
with param_scope(**{"foo.x": 2}):
109+
with hp.scope(**{"foo.x": 2}):
79110
foo() # x=2, y='a'
80111
```
81112
@@ -124,7 +155,7 @@ ASSERT(1 == GET_PARAM(a.b, 1), "get undefined param");
124155
#### Python
125156
126157
```python
127-
x = param_scope.foo.x | "default value"
158+
x = hp.scope.foo.x | "default value"
128159
```
129160
130161
#### Rust
@@ -138,9 +169,9 @@ x = param_scope.foo.x | "default value"
138169
#### Python
139170
140171
```python
141-
with param_scope() as ps: # 1st scope start
172+
with hp.scope() as ps: # 1st scope start
142173
ps.foo.x=1
143-
with param_scope() as ps2: # 2nd scope start
174+
with hp.scope() as ps2: # 2nd scope start
144175
ps.foo.y=2
145176
# 2nd scope end
146177
# 1st scope end
@@ -165,11 +196,11 @@ with_params!{ // 1st scope start
165196
#### Python
166197
167198
```python
168-
@auto_param("foo")
199+
@hp.param("foo")
169200
def foo(x=1): # Print hyperparameter foo.x
170201
print(f"foo.x={x}")
171202
172-
with param_scope() as ps:
203+
with hp.scope() as ps:
173204
ps.foo.x=2 # Modify foo.x in the current thread
174205
175206
foo() # foo.x=2
@@ -205,9 +236,9 @@ In command line applications, it's common to define hyperparameters using comman
205236
206237
```python
207238
# example.py
208-
from hyperparameter import param_scope, auto_param
239+
import hyperparameter as hp
209240
210-
@auto_param("example")
241+
@hp.param("example")
211242
def main(a=0, b=1):
212243
print(f"example.a={a}, example.b={b}")
213244
@@ -218,7 +249,7 @@ if __name__ == "__main__":
218249
parser.add_argument("-D", "--define", nargs="*", default=[], action="extend")
219250
args = parser.parse_args()
220251
221-
with param_scope(*args.define):
252+
with hp.scope(*args.define):
222253
main()
223254
```
224255

README.zh.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
# Hyperparameter
1+
<p align="center">
2+
<img src="hyperparameter.svg" alt="Hyperparameter Logo" width="180" height="180">
3+
</p>
24

3-
<h3 align="center">
4-
<p style="text-align: center;">
5-
<a href="README.md" target="_blank">ENGLISH</a> | <a href="README.zh.md">中文文档</a>
6-
</p>
7-
</h3>
5+
<h1 align="center">Hyperparameter</h1>
86

97
<p align="center">
8+
<a href="README.md" target="_blank">ENGLISH</a> | <a href="README.zh.md">中文文档</a>
9+
</p>
1010

11-
**Hyperparameter, Make configurable AI applications. Build for Python/Rust hackers.**
12-
11+
<p align="center">
12+
<strong>Make configurable AI applications. Build for Python/Rust hackers.</strong>
1313
</p>
1414

1515
`Hyperparameter` 是一个多功能超参数管理库,旨在简化机器学习算法和系统开发中超参数的管理和控制。专为机器学习系统(MLSYS)开发者设计,超参数提供了一个统一的解决方案,侧重于在Python中易于使用、在Rust和C++中高性能访问,并提供了一组宏,以实现无缝超参数管理。
@@ -20,11 +20,13 @@
2020

2121
- **Pythonic语法:** 使用keyword参数语法定义超参数;
2222

23-
- **直观的作用域:** 通过`with`语句控制参数的作用域;
24-
25-
- **配置文件:** 从配置文件轻松加载参数;
26-
27-
### 针对Rust和C++用户
23+
- **直观的作用域:** 通过`with`语句控制参数的作用域;
24+
25+
- **强大的配置加载:** 支持 JSON/TOML/YAML 多文件组合加载 (Composition) 与变量插值 (Interpolation);
26+
27+
- **零开销校验:** 支持可选的基于 Python Type Hints 的 Schema 校验;
28+
29+
### 针对Rust和C++用户
2830

2931
- **高性能后端:** 超参数在Rust中实现,提供了强大且高性能的超参数管理后端。在Rust和C++中以最小开销访问超参数,非常适合注重性能的ML和系统开发者。
3032

@@ -43,15 +45,15 @@ pip install hyperparameter
4345
### Python
4446

4547
```python
46-
from hyperparameter import auto_param, param_scope
48+
import hyperparameter as hp
4749

48-
@auto_param("foo")
50+
@hp.param("foo")
4951
def foo(x=1, y="a"):
5052
return f"x={x}, y={y}"
5153

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

54-
with param_scope(**{"foo.x": 2}):
56+
with hp.scope(**{"foo.x": 2}):
5557
foo() # x=2, y='a'
5658
```
5759

@@ -100,7 +102,7 @@ ASSERT(1 == GET_PARAM(a.b, 1), "get undefined param");
100102
#### Python
101103
102104
```python
103-
x = param_scope.foo.x | "default value"
105+
x = hp.scope.foo.x | "default value"
104106
```
105107

106108
#### Rust
@@ -114,9 +116,9 @@ x = param_scope.foo.x | "default value"
114116
#### Python
115117

116118
```python
117-
with param_scope() as ps: # 第1个作用域开始
119+
with hp.scope() as ps: # 第1个作用域开始
118120
ps.foo.x=1
119-
with param_scope() as ps2: # 第2个作用域开始
121+
with hp.scope() as ps2: # 第2个作用域开始
120122
ps.foo.y=2
121123
# 第2个作用域结束
122124
# 第1个作用域结束
@@ -141,14 +143,12 @@ with_params!{ // 第1个作用域开始
141143
#### Python
142144

143145
```python
144-
@auto_param("foo")
146+
@hp.param("foo")
145147
def foo(x=1): # 打印超参数 foo.x
146148
print(f"foo.x={x}")
147149

148-
with param_scope() as ps:
149-
ps.foo.x=2 # 在当前线程设置foo.x
150-
151-
中修改 foo.x
150+
with hp.scope() as ps:
151+
ps.foo.x=2 # 在当前线程中修改 foo.x
152152

153153
foo() # foo.x=2
154154
threading.Thread(target=foo).start() # foo.x=1,新线程的超参数值不受主线程的影响
@@ -183,9 +183,9 @@ fn main() {
183183

184184
```python
185185
# example.py
186-
from hyperparameter import param_scope, auto_param
186+
import hyperparameter as hp
187187

188-
@auto_param("example")
188+
@hp.param("example")
189189
def main(a=0, b=1):
190190
print(f"example.a={a}, example.b={b}")
191191

@@ -196,7 +196,7 @@ if __name__ == "__main__":
196196
parser.add_argument("-D", "--define", nargs="*", default=[], action="extend")
197197
args = parser.parse_args()
198198

199-
with param_scope(*args.define):
199+
with hp.scope(*args.define):
200200
main()
201201
```
202202

benchmark/bench_hp.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import time
2+
import hyperparameter as hp
3+
4+
@hp.param
5+
def main():
6+
start = time.time()
7+
acc = 0
8+
9+
# We use hp.scope directly, which is the idiomatic way
10+
# to access parameters anywhere in the code.
11+
with hp.scope() as ps:
12+
for _ in range(1_000_000):
13+
acc += ps.model.layers._0.size | 10
14+
15+
duration = time.time() - start
16+
print(f"Hyperparameter Time: {duration:.4f} seconds (acc={acc})")
17+
return duration
18+
19+
if __name__ == "__main__":
20+
# Pre-populate scope to simulate loaded config
21+
with hp.scope(**{"model.layers._0.size": 10}):
22+
main()
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import time
2+
import hyperparameter as hp
3+
4+
@hp.param
5+
def main():
6+
start = time.time()
7+
acc = 0
8+
9+
for _ in range(1_000_000):
10+
acc += hp.scope.model.layers._0.size | 10
11+
12+
duration = time.time() - start
13+
print(f"Hyperparameter Time: {duration:.4f} seconds (acc={acc})")
14+
return duration
15+
16+
if __name__ == "__main__":
17+
hp.launch()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import time
2+
import hyperparameter as hp
3+
4+
@hp.param
5+
def main():
6+
start = time.time()
7+
acc = 0
8+
9+
for _ in range(1_000_000):
10+
with hp.scope() as ps:
11+
acc += ps.model.layers._0.size | 10
12+
13+
duration = time.time() - start
14+
print(f"Hyperparameter Time: {duration:.4f} seconds (acc={acc})")
15+
return duration
16+
17+
if __name__ == "__main__":
18+
# Pre-populate scope to simulate loaded config
19+
with hp.scope(**{"model.layers._0.size": 10}):
20+
main()

benchmark/bench_hp_injected.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import time
2+
import hyperparameter as hp
3+
4+
@hp.param
5+
def main(layer_size: int = 10):
6+
start = time.time()
7+
acc = 0
8+
9+
for _ in range(1_000_000):
10+
acc += layer_size
11+
12+
duration = time.time() - start
13+
print(f"Hyperparameter Time: {duration:.4f} seconds (acc={acc})")
14+
return duration
15+
16+
if __name__ == "__main__":
17+
hp.launch()

0 commit comments

Comments
 (0)