Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4 from PyTorchLightning/renaming
Browse files Browse the repository at this point in the history
Renaming
  • Loading branch information
krshrimali authored Jun 13, 2022
2 parents dd60444 + 3190c33 commit 19a6292
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 89 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:

- name: Tests
run: |
coverage run --source lightning_hp_engine -m py.test lightning_hp_engine tests -v --junitxml=junit/test-results-${{ runner.os }}-${{ matrix.python-version }}.xml
coverage run --source hp_space_generator -m py.test hp_space_generator tests -v --junitxml=junit/test-results-${{ runner.os }}-${{ matrix.python-version }}.xml
- name: Statistics
if: success()
Expand Down
27 changes: 13 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div align="center">
<img src="https://pl-bolts-doc-images.s3.us-east-2.amazonaws.com/lai.png" width="200px">

A lightning component to run a Hyper-Parameter engine on a given config for RandomSearch and GridSearch strategies.
A lightning component to generate Hyper Parameter Space on a given config for Random Search and Grid Search strategies.

______________________________________________________________________

Expand All @@ -12,8 +12,8 @@ ______________________________________________________________________
Use these instructions to install:

```bash
git clone https://github.com/PyTorchLightning/lightning-hp-engine.git
cd lightning-hp-engine
git clone https://github.com/PyTorchLightning/LAI-Hyper-Parameter-Space-Generator.git
cd LAI-Hyper-Parameter-Space-Generator
pip install -r requirements.txt
pip install -e .
```
Expand All @@ -40,8 +40,8 @@ from lightning.frontend import StreamlitFrontend
from lightning.utilities.state import AppState


from lightning_hp_engine import LightningHPEngine
from lightning_hp_engine import RandomSearchStrategy, GridSearchStrategy
from hp_space_generator import HPSpaceGenerator
from hp_space_generator import RandomSearchStrategy, GridSearchStrategy


class DoSomethingExtra(LightningWork):
Expand Down Expand Up @@ -80,10 +80,10 @@ class Visualizer(LightningFlow):
return StreamlitFrontend(render_fn=_render_fn)


class HPEComponent(LightningFlow):
class HPComponent(LightningFlow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.hpe = LightningHPEngine()
self.space_generator = HPSpaceGenerator()
self.work_random_search = DoSomethingExtra()
self.work_grid_search = DoSomethingExtra()
self.visualize = Visualizer()
Expand All @@ -93,27 +93,26 @@ class HPEComponent(LightningFlow):
# If you want, you can write your own preprocess functions, and pass should_preprocess=False
# in the class instantiation.

hpe_config = {
hp_config = {
"backbone": ["prajjwal1/bert-tiny", "pra1/bert-medium"],
"learning_rate": [0.000001, 0.1],
}

# work_cls allows you to use the hyper-paramaters from the given num_runs
# basically .run() method is called with the hpes from the HP Engine component after this

self.hpe.run(hpe_dict=hpe_config, num_runs=5,
self.space_generator.run(hp_dict=hp_config, num_runs=5,
work=self.work_random_search, strategy=RandomSearchStrategy(should_preprocess=True))

# self.hpe.run(hpe_dict=hpe_config, num_runs=5,
# self.space_generator.run(hp_dict=hp_config, num_runs=5,
# strategy=GridSearchStrategy(should_preprocess=False), work=self.work_grid_search)

if self.work_random_search.has_succeeded:
self.visualize.run(self.hpe.results)
self.visualize.run(self.space_generator.results)

def configure_layout(self):
return {"name": "hpe Output", "content": self.visualize}
return {"name": "generated Hyper Parameter Space", "content": self.visualize}


# To launch the hpe Component
app = LightningApp(HPEComponent(), debug=True)
app = LightningApp(HPComponent(), debug=True)
```
6 changes: 6 additions & 0 deletions hp_space_generator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from hp_space_generator.component import HPSpaceGenerator
from hp_space_generator.search_strategy import SearchStrategy
from hp_space_generator.random_search_strategy import RandomSearchStrategy
from hp_space_generator.grid_search_strategy import GridSearchStrategy

__all__ = ["HPSpaceGenerator", "SearchStrategy", "RandomSearchStrategy", "GridSearchStrategy"]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from lightning import LightningFlow


class LightningHPEngine(LightningFlow):
class HPSpaceGenerator(LightningFlow):
"""
The HP Engine Component is used to suggest a list of configurations (hyper-parameters) to run with some config
from the user for any task.
Expand All @@ -12,22 +12,22 @@ class LightningHPEngine(LightningFlow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.hpe_dict = {}
self.hp_dict = {}
self.num_runs = 0
self.results = None

# Having strategy as a class allows the users to define their own strategy class
def run(self, hpe_dict: dict, num_runs: int=1, strategy=None, work=None, work_kwargs={},
def run(self, hp_dict: dict, num_runs: int=1, strategy=None, work=None, work_kwargs={},
*args, **kwargs):
if self.results is None:
self.hpe_dict = hpe_dict
self.hp_dict = hp_dict
self.num_runs = num_runs

# Thought: maybe we should receive an object, and not the class...?
# Let them instantiate it with the args they want to store?
# Yep^^ done! :)
for run_id in range(num_runs):
strategy.run(run_id=run_id, hpe_config_dict=hpe_dict, *args, **kwargs)
strategy.run(run_id=run_id, hp_config_dict=hp_dict, *args, **kwargs)

# Now pass the runs to the given work_cls
assert len(strategy.runs) > 0, "The strategy class did not generate any runs! Probably something went wrong..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ class GridSearchStrategy(SearchStrategy):
def __init__(self, should_preprocess=False, *args, **kwargs):
super().__init__(should_preprocess=should_preprocess, *args, **kwargs)

def run(self, hpe_config_dict: Dict[str, Any], run_id=-1):
def run(self, hp_config_dict: Dict[str, Any], run_id=-1):
if self.should_preprocess:
hpe_config_dict = self.preprocess(hpe_config_dict)
hp_config_dict = self.preprocess(hp_config_dict)

self.runs.extend(self.generate_runs(run_id, hpe_config_dict))
self.runs.extend(self.generate_runs(run_id, hp_config_dict))

def preprocess(self, hpe_dict):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,43 @@

from ray import tune

from lightning_hp_engine import SearchStrategy
from hp_space_generator import SearchStrategy


class RandomSearchStrategy(SearchStrategy):
def run(self, run_id: int, hpe_config_dict: Dict[str, Any], *args, **kwargs):
def run(self, run_id: int, hp_config_dict: Dict[str, Any], *args, **kwargs):
# To ensure that we don't preprocessing again, we need to pass the pre-processed dict in the run method maybe?
# Currently for each run in the given num_runs, pre-processing will happen each time!
# Maybe do this in __init__()?
if self.should_preprocess:
hpe_config_dict = self.preprocess(hpe_config_dict)
self.runs.extend(self.generate_runs(run_id, hpe_config_dict))
hp_config_dict = self.preprocess(hp_config_dict)
self.runs.extend(self.generate_runs(run_id, hp_config_dict))

def preprocess(self, hpe_dict):
# Pre-process incoming hpe_dict into a dict with values which can be supported by _generate_runs
def preprocess(self, hp_dict):
# Pre-process incoming hp_dict into a dict with values which can be supported by _generate_runs
# This currently assumes you are using a Random Strategy, feel free to override it with something else

preprocessed_hpe_dict = {}
for key, val in hpe_dict.items():
preprocessed_hp_dict = {}
for key, val in hp_dict.items():
if key == "backbone":
if isinstance(val, str):
preprocessed_hpe_dict[key] = val
preprocessed_hp_dict[key] = val
elif isinstance(val, list):
preprocessed_hpe_dict[key] = tune.choice(val)
preprocessed_hp_dict[key] = tune.choice(val)
else:
raise TypeError(f"Expected either List or a string for backbone but got {type(val)}")
elif key == "learning_rate":
if not isinstance(val, list) or len(val) != 2:
raise ValueError(f"Expected a list of two numbers (float/int) but got {val}")
preprocessed_hpe_dict[key] = tune.uniform(val[0], val[1])
preprocessed_hp_dict[key] = tune.uniform(val[0], val[1])
else:
preprocessed_hpe_dict[key] = val
return preprocessed_hpe_dict
preprocessed_hp_dict[key] = val
return preprocessed_hp_dict

def generate_runs(self, run_id: int, hpe_dict: Dict[str, Any]):
def generate_runs(self, run_id: int, hp_dict: Dict[str, Any]):
runs = []
model_config = {}
for key, domain in hpe_dict.items():
for key, domain in hp_dict.items():
if hasattr(domain, "sample"):
model_config[key] = domain.sample()
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ def __init__(self, should_preprocess=True, *args, **kwargs):
self.should_preprocess = should_preprocess
self.runs = []

def run(self, hpe_config_dict: Dict[str, Any], num_runs=1, *args, **kwargs):
def run(self, hp_config_dict: Dict[str, Any], num_runs=1, *args, **kwargs):
raise NotImplementedError("You need to implement the run method")

def preprocess(hpe_config_dict, *args, **kwargs):
raise NotImplementedError("You need to implement preprocess(hpe_config_dict) method")
def preprocess(hp_config_dict, *args, **kwargs):
raise NotImplementedError("You need to implement preprocess(hp_config_dict) method")

def generate_runs(num_runs: int, hpe_config_dict: Dict[str, Any], *args, **kwargs):
raise NotImplementedError("You need to implement generate_runs(num_runs, hpe_config_dict) method")
def generate_runs(num_runs: int, hp_config_dict: Dict[str, Any], *args, **kwargs):
raise NotImplementedError("You need to implement generate_runs(num_runs, hp_config_dict) method")
File renamed without changes.
6 changes: 0 additions & 6 deletions lightning_hp_engine/__init__.py

This file was deleted.

8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
_PATH_ROOT = os.path.dirname(__file__)


def _load_py_module(fname, pkg="lightning_hp_engine"):
def _load_py_module(fname, pkg="hp_space_generator"):
spec = spec_from_file_location(
os.path.join(pkg, fname), os.path.join(_PATH_ROOT, pkg, fname)
)
Expand All @@ -22,12 +22,12 @@ def _load_py_module(fname, pkg="lightning_hp_engine"):
REQUIREMENTS = [req.strip() for req in open("requirements.txt").readlines()]

setup(
name="lightning_hp_engine",
name="hp_space_generator",
version="0.0.1",
description="Run Hyper Parameter Engine around the given choices of hyper-parameters with Grid Search and Random Search strategies",
description="Generator Hyper Parameter space around the given choices of hyper-parameters with Grid Search and Random Search strategies",
author="Kushashwa Ravi Shrimali, Ethan Harris",
author_email="[email protected]",
url="https://github.com/PyTorchLightning/LAI-hyper-parameter-engine",
url="https://github.com/PyTorchLightning/LAI-Hyper-Parameter-Space-Generator",
packages=find_packages(exclude=["tests", "tests.*"]),
install_requires=setup_tools._load_requirements(_PATH_ROOT),
)
36 changes: 36 additions & 0 deletions tests/test_hp_space_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from hp_space_generator import HPSpaceGenerator, RandomSearchStrategy, GridSearchStrategy

from lightning import LightningWork

class DoSomethingExtra(LightningWork):
def __init__(self):
super().__init__(run_once=True)
self.hp_list = []

def run(self, hp_list):
self.hp_list.extend(hp_list)


def test_hp_space_generator_random():
# Test the HP Component for text classification
hp_config = {
"backbone": ["prajjwal1/bert-tiny", "pra1/bert-medium"],
"learning_rate": [0.00001, 0.01],
}

space_generator = HPSpaceGenerator()
work_obj = DoSomethingExtra()
space_generator.run(hp_config, num_runs=2, work=work_obj, strategy=RandomSearchStrategy())
assert len(work_obj.hp_list) != 0, "Didn't generate results..."

def test_hp_space_generator_grid():
# Test the HP Space Generator Component for text classification
hp_config = {
"backbone": ["prajjwal1/bert-tiny", "pra1/bert-medium"],
"learning_rate": [0.00001, 0.01],
}

space_generator = HPSpaceGenerator()
work_obj = DoSomethingExtra()
space_generator.run(hp_config, num_runs=2, work=work_obj, strategy=GridSearchStrategy(should_preprocess=False))
assert len(work_obj.hp_list) != 0, "Didn't generate results..."
36 changes: 0 additions & 36 deletions tests/test_hpe.py

This file was deleted.

0 comments on commit 19a6292

Please sign in to comment.