[HyperOpt] rec_eval node is GarbageCollected

Hello, I’m attempting to use the points_to_evaluate parameter with HyperOptSearch, however, I encounter an error in reference to the node/expression evaluated being GarbageCollected. I’m guessing this is probably an error with HyperOpt, not Tune but I’m not certain.

Here is the error:

Traceback (most recent call last):
  File "hyperopt/pyll/base.py", line 869, in rec_eval
    int(switch_i)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'type'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tune_hype2.py", line 136, in <module>
    main()
  File "tune_hype2.py", line 109, in main
    run("PPO",
  File "ray/tune/tune.py", line 588, in run
    runner.step()
  File "ray/tune/trial_runner.py", line 583, in step
    next_trial = self._get_next_trial()  # blocking
  File "ray/tune/trial_runner.py", line 727, in _get_next_trial
    self._update_trial_queue(blocking=wait_for_trial)
  File "ray/tune/trial_runner.py", line 1190, in _update_trial_queue
    trial = self._search_alg.next_trial()
  File "ray/tune/suggest/search_generator.py", line 89, in next_trial
    return self.create_trial_if_possible(self._experiment.spec,
  File "ray/tune/suggest/search_generator.py", line 97, in create_trial_if_possible
    suggested_config = self.searcher.suggest(trial_id)
  File "ray/tune/suggest/suggestion.py", line 395, in suggest
    suggestion = self.searcher.suggest(trial_id)
  File "ray/tune/suggest/hyperopt.py", line 297, in suggest
    suggested_config = hpo.pyll.rec_eval(
  File "hyperopt/pyll/base.py", line 871, in rec_eval
    raise TypeError("switch argument was", switch_i)
TypeError: ('switch argument was', <class 'hyperopt.pyll.base.GarbageCollected'>)

Here is the code I’m attempting to use:

import ray
from ray.tune import run

from ray.rllib.agents.ppo import DEFAULT_CONFIG
from ray.rllib.models.tf.fcnet import FullyConnectedNetwork

from ray.tune.schedulers import ASHAScheduler
from ray.tune.suggest.hyperopt import HyperOptSearch
from ray.tune.suggest import ConcurrencyLimiter

from hyperopt import hp
from hyperopt.pyll import scope

from . import Env

from copy import deepcopy


def main():
    metric = "episode_reward_mean"
    mode = "max"
    hc = [[4, 4], [8, 8], [16, 16], [32, 32], [64, 64], [128, 128], [256, 256],
          [512, 512], [1024, 1024], [2048, 2048], [5012, 5012]]
    lc = [4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 5012]
    space = {
        # Exp Collection
        "train_batch_size": scope.int(hp.quniform("train_batch_size",
                                                  32, 10000, 1)),
        "sgd_minibatch_size": scope.int(hp.quniform("sgd_minibatch_size",
                                                    4, 8192, 1)),
        "num_sgd_iter": scope.int(hp.quniform("num_sgd_iter",
                                              3, 30, 1)),
        # Policy Updating
        "clip_param": hp.choice("clip_param", [0.1, 0.2, 0.3]),
        "kl_target": hp.quniform("kl_target", 3e-3, 3e-2, 1e-3),
        "kl_coeff": hp.quniform("kl_coeff", 0.3, 1.0, 0.1),
        "gamma": hp.quniform("gamma", 0.8, 0.9997, 1e-4),
        "lambda": hp.quniform("lambda", 0.9, 1.0, 0.1),
        # Loss
        "vf_loss_coeff": hp.quniform("vf_loss_coeff", 0.5, 1.0, 0.1),
        "entropy_coeff": hp.quniform("entropy_coeff", 0, 0.01, 1e-2),
        "lr": hp.quniform("lr", 5e-6, 3e-3, 1e-6),
        "model": {
            "fcnet_hiddens": hp.choice("fcnet_hiddens", hc),
            "use_lstm": hp.choice("use_lstm", [True, False]),
            "lstm_cell_size": hp.choice("lstm_cell_size", lc),
        }
    }

    best_configs = []
    base_cfg = DEFAULT_CONFIG
    base_cfg["model"] = {"use_lstm": False}
    remove = []
    for key in base_cfg:
        if key not in space:
            remove.append(key)
    [base_cfg.pop(key) for key in remove]
    best_configs.append(deepcopy(base_cfg))

    algo = HyperOptSearch(space, points_to_evaluate=best_configs,
                          metric=metric, mode=mode)
    algo = ConcurrencyLimiter(algo, 8)
    sched = ASHAScheduler(metric=metric, mode=mode)

    ray.init(include_dashboard=False, num_gpus=0)
    run("PPO",
        search_alg=algo,
        scheduler=sched,
        num_samples=-1,
        config={
            "env": Env,
            "num_workers": 1,
            "model": {
                "custom_model": FullyConnectedNetwork,
            },
        },
        )


if __name__ == "__main__":
    main()

Hm, the problem comes up in the model part of the config - if this is commented out, it works.

We recently fixed a similar bug with nested lists here: [tune] Fix hyperopt points to evaluate for nested lists by krfricke · Pull Request #18113 · ray-project/ray · GitHub

Maybe this is similar.

I’ll open an issue to track this: [Bug][tune] HyperOpt nested dict throws TypeError (switch argument was GarbageCollected) · Issue #19507 · ray-project/ray · GitHub

1 Like

Thank you for the quick response.