Skip to content

Commit 926b8b1

Browse files
justinvyumatthewdeng
authored andcommitted
[train] New persistence mode: Migrate 🐙 Tune tests and examples (medium) (ray-project#39081)
Signed-off-by: Justin Yu <justinvyu@anyscale.com>
1 parent f4443ad commit 926b8b1

File tree

7 files changed

+57
-192
lines changed

7 files changed

+57
-192
lines changed

.buildkite/pipeline.ml.yml

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,7 @@
293293
- TUNE_TESTING=1 DATA_PROCESSING_TESTING=1 ./ci/env/install-dependencies.sh
294294
- ./ci/env/env_info.sh
295295
- bazel test --config=ci $(./ci/run/bazel_export_options) --build_tests_only
296-
--test_tag_filters=medium_instance,-soft_imports,-gpu_only,-rllib,-multinode,-new_storage
297-
--test_env=RAY_AIR_NEW_PERSISTENCE_MODE=0
296+
--test_tag_filters=medium_instance,-soft_imports,-gpu_only,-rllib,-multinode
298297
python/ray/tune/...
299298

300299
- label: ":octopus: :spiral_note_pad: New output: Tune tests and examples (small)"
@@ -320,9 +319,8 @@
320319
- TUNE_TESTING=1 DATA_PROCESSING_TESTING=1 ./ci/env/install-dependencies.sh
321320
- ./ci/env/env_info.sh
322321
- bazel test --config=ci $(./ci/run/bazel_export_options) --build_tests_only
323-
--test_tag_filters=medium_instance,-soft_imports,-gpu_only,-rllib,-multinode,-new_storage
322+
--test_tag_filters=medium_instance,-soft_imports,-gpu_only,-rllib,-multinode
324323
--test_env=AIR_VERBOSITY=1
325-
--test_env=RAY_AIR_NEW_PERSISTENCE_MODE=0
326324
python/ray/tune/...
327325

328326

@@ -369,18 +367,6 @@
369367
--test_env=RAY_AIR_NEW_PERSISTENCE_MODE=1
370368
python/ray/tune/...
371369

372-
- label: ":octopus: :floppy_disk: New persistence mode: Tune tests and examples (medium)"
373-
conditions: ["NO_WHEELS_REQUIRED", "RAY_CI_TUNE_AFFECTED"]
374-
instance_size: medium
375-
commands:
376-
- cleanup() { if [ "${BUILDKITE_PULL_REQUEST}" = "false" ]; then ./ci/build/upload_build_info.sh; fi }; trap cleanup EXIT
377-
- TUNE_TESTING=1 DATA_PROCESSING_TESTING=1 ./ci/env/install-dependencies.sh
378-
- ./ci/env/env_info.sh
379-
- bazel test --config=ci $(./ci/run/bazel_export_options) --build_tests_only
380-
--test_tag_filters=medium_instance,-soft_imports,-gpu_only,-rllib,-multinode,-no_new_storage
381-
--test_env=RAY_AIR_NEW_PERSISTENCE_MODE=1
382-
python/ray/tune/...
383-
384370

385371
###### END STORAGE REFACTOR
386372

python/ray/tune/BUILD

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ py_test(
238238
size = "large",
239239
srcs = ["tests/test_sample.py"],
240240
deps = [":tune_lib"],
241-
tags = ["team:ml", "exclusive", "medium_instance", "no_new_storage"],
241+
tags = ["team:ml", "exclusive", "medium_instance"],
242242
)
243243

244244
py_test(
@@ -254,7 +254,7 @@ py_test(
254254
size = "large",
255255
srcs = ["tests/test_searchers.py"],
256256
deps = [":tune_lib"],
257-
tags = ["team:ml", "exclusive", "medium_instance", "no_new_storage"],
257+
tags = ["team:ml", "exclusive", "medium_instance"],
258258
)
259259

260260
py_test(
@@ -334,15 +334,15 @@ py_test(
334334
size = "large",
335335
srcs = ["tests/test_trial_scheduler.py"],
336336
deps = [":tune_lib"],
337-
tags = ["team:ml", "exclusive", "medium_instance", "new_storage"],
337+
tags = ["team:ml", "exclusive", "medium_instance"],
338338
)
339339

340340
py_test(
341341
name = "test_trial_scheduler_pbt",
342342
size = "large",
343343
srcs = ["tests/test_trial_scheduler_pbt.py"],
344344
deps = [":tune_lib"],
345-
tags = ["team:ml", "exclusive", "medium_instance", "new_storage"],
345+
tags = ["team:ml", "exclusive", "medium_instance"],
346346
)
347347

348348
py_test(
@@ -390,7 +390,7 @@ py_test(
390390
size = "large",
391391
srcs = ["tests/test_tuner.py"],
392392
deps = [":tune_lib"],
393-
tags = ["team:ml", "exclusive", "medium_instance", "no_new_storage"],
393+
tags = ["team:ml", "exclusive", "medium_instance"],
394394
)
395395

396396
py_test(

python/ray/tune/search/searcher.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,22 @@ def add_evaluated_trials(
229229
# lazy imports to avoid circular dependencies
230230
from ray.tune.experiment import Trial
231231
from ray.tune.analysis import ExperimentAnalysis
232+
from ray.tune.analysis.experiment_analysis import NewExperimentAnalysis
232233
from ray.tune.result import DONE
233234

234-
if isinstance(trials_or_analysis, Trial):
235-
trials_or_analysis = [trials_or_analysis]
236-
elif isinstance(trials_or_analysis, ExperimentAnalysis):
237-
trials_or_analysis = trials_or_analysis.trials
235+
if isinstance(trials_or_analysis, (list, tuple)):
236+
trials = trials_or_analysis
237+
elif isinstance(trials_or_analysis, Trial):
238+
trials = [trials_or_analysis]
239+
elif isinstance(
240+
trials_or_analysis, (ExperimentAnalysis, NewExperimentAnalysis)
241+
):
242+
trials = trials_or_analysis.trials
243+
else:
244+
raise NotImplementedError(
245+
"Expected input to be a `Trial`, a list of `Trial`s, or "
246+
f"`ExperimentAnalysis`, got: {trials_or_analysis}"
247+
)
238248

239249
any_trial_had_metric = False
240250

@@ -261,7 +271,7 @@ def trial_to_points(trial: Trial) -> Dict[str, Any]:
261271
intermediate_values=None, # we do not save those
262272
)
263273

264-
for trial in trials_or_analysis:
274+
for trial in trials:
265275
kwargs = trial_to_points(trial)
266276
if kwargs:
267277
self.add_evaluated_point(**kwargs)

python/ray/tune/tests/test_sample.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212

1313
import ray
1414
import ray.tune.search.sample
15-
from ray import tune
15+
from ray import train, tune
1616
from ray.tune import Experiment
1717
from ray.tune.search.util import logger
1818
from ray.tune.search.variant_generator import generate_variants
1919

2020

2121
def _mock_objective(config):
22-
tune.report(**config)
22+
train.report(config)
2323

2424

2525
def assertDictAlmostEqual(a, b):

python/ray/tune/tests/test_searchers.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
from copy import deepcopy
33
import numpy as np
44
import os
5+
from packaging.version import Version
6+
import pandas
7+
import pytest
58
import shutil
69
import tempfile
710
import unittest
811
from unittest.mock import patch
912

1013
import ray
11-
from ray import tune
14+
from ray import train, tune
1215
from ray.air.constants import TRAINING_ITERATION
1316
from ray.tune.search import ConcurrencyLimiter
1417

@@ -18,21 +21,21 @@ def _invalid_objective(config):
1821
metric = "point" if "point" in config else "report"
1922

2023
if config[metric] > 4:
21-
tune.report(float("inf"))
24+
train.report({"_metric": float("inf")})
2225
elif config[metric] > 3:
23-
tune.report(float("-inf"))
26+
train.report({"_metric": float("-inf")})
2427
elif config[metric] > 2:
25-
tune.report(np.nan)
28+
train.report({"_metric": np.nan})
2629
else:
27-
tune.report(float(config[metric]) or 0.1)
30+
train.report({"_metric": float(config[metric]) or 0.1})
2831

2932

3033
def _multi_objective(config):
31-
tune.report(a=config["a"] * 100, b=config["b"] * -100, c=config["c"])
34+
train.report(dict(a=config["a"] * 100, b=config["b"] * -100, c=config["c"]))
3235

3336

3437
def _dummy_objective(config):
35-
tune.report(metric=config["report"])
38+
train.report(dict(metric=config["report"]))
3639

3740

3841
class InvalidValuesTest(unittest.TestCase):
@@ -224,6 +227,9 @@ def testDragonfly(self):
224227
self.assertCorrectExperimentOutput(out)
225228

226229
def testHEBO(self):
230+
if Version(pandas.__version__) >= Version("2.0.0"):
231+
pytest.skip("HEBO does not support pandas>=2.0.0")
232+
227233
from ray.tune.search.hebo import HEBOSearch
228234

229235
with self.check_searcher_checkpoint_errors_scope():
@@ -507,6 +513,9 @@ def dbr_space(trial):
507513
dbr_searcher.add_evaluated_point(point, 1.0)
508514

509515
def testHEBO(self):
516+
if Version(pandas.__version__) >= Version("2.0.0"):
517+
pytest.skip("HEBO does not support pandas>=2.0.0")
518+
510519
from ray.tune.search.hebo import HEBOSearch
511520

512521
searcher = HEBOSearch(
@@ -684,6 +693,9 @@ def testDragonfly(self):
684693
self._restore(searcher)
685694

686695
def testHEBO(self):
696+
if Version(pandas.__version__) >= Version("2.0.0"):
697+
pytest.skip("HEBO does not support pandas>=2.0.0")
698+
687699
from ray.tune.search.hebo import HEBOSearch
688700

689701
searcher = HEBOSearch(
@@ -816,7 +828,6 @@ def testOptuna(self):
816828

817829

818830
if __name__ == "__main__":
819-
import pytest
820831
import sys
821832

822833
sys.exit(pytest.main(["-v", __file__]))

python/ray/tune/tests/test_tuner.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from unittest.mock import patch
44

55
import pytest
6-
import shutil
76
import unittest
87
from typing import Optional
98

@@ -23,7 +22,6 @@
2322
from ray.train.trainer import BaseTrainer
2423
from ray.train.xgboost import XGBoostTrainer
2524
from ray.tune import Callback, CLIReporter
26-
from ray.tune.result import DEFAULT_RESULTS_DIR
2725
from ray.tune.tune_config import TuneConfig
2826
from ray.tune.tuner import Tuner
2927

@@ -106,6 +104,12 @@ def gen_dataset_func_eager():
106104
class TunerTest(unittest.TestCase):
107105
"""The e2e test for hparam tuning using Tuner API."""
108106

107+
@pytest.fixture(autouse=True)
108+
def local_dir(self, tmp_path, monkeypatch):
109+
monkeypatch.setenv("RAY_AIR_LOCAL_CACHE_DIR", str(tmp_path / "ray_results"))
110+
self.local_dir = str(tmp_path / "ray_results")
111+
yield self.local_dir
112+
109113
def setUp(self):
110114
ray.init()
111115

@@ -114,9 +118,6 @@ def tearDown(self):
114118

115119
def test_tuner_with_xgboost_trainer(self):
116120
"""Test a successful run."""
117-
shutil.rmtree(
118-
os.path.join(DEFAULT_RESULTS_DIR, "test_tuner"), ignore_errors=True
119-
)
120121
trainer = XGBoostTrainer(
121122
label_column="target",
122123
params={},
@@ -156,10 +157,6 @@ def test_tuner_with_xgboost_trainer(self):
156157
def test_tuner_with_xgboost_trainer_driver_fail_and_resume(self):
157158
# So that we have some global checkpointing happening.
158159
os.environ["TUNE_GLOBAL_CHECKPOINT_S"] = "1"
159-
shutil.rmtree(
160-
os.path.join(DEFAULT_RESULTS_DIR, "test_tuner_driver_fail"),
161-
ignore_errors=True,
162-
)
163160
trainer = XGBoostTrainer(
164161
label_column="target",
165162
params={},
@@ -211,18 +208,16 @@ def on_step_end(self, iteration, trials, **kwargs):
211208
tuner.fit()
212209

213210
# Test resume
214-
restore_path = os.path.join(DEFAULT_RESULTS_DIR, "test_tuner_driver_fail")
215-
tuner = Tuner.restore(restore_path, trainable=trainer)
211+
restore_path = os.path.join(self.local_dir, "test_tuner_driver_fail")
212+
tuner = Tuner.restore(restore_path, trainable=trainer, param_space=param_space)
216213
# A hack before we figure out RunConfig semantics across resumes.
217214
tuner._local_tuner._run_config.callbacks = None
218215
results = tuner.fit()
219216
assert len(results) == 4
217+
assert not results.errors
220218

221219
def test_tuner_with_torch_trainer(self):
222220
"""Test a successful run using torch trainer."""
223-
shutil.rmtree(
224-
os.path.join(DEFAULT_RESULTS_DIR, "test_tuner_torch"), ignore_errors=True
225-
)
226221
# The following two should be tunable.
227222
config = {"lr": 1e-2, "hidden_size": 1, "batch_size": 4, "epochs": 10}
228223
scaling_config = ScalingConfig(num_workers=1, use_gpu=False)
@@ -387,6 +382,8 @@ def test_nonserializable_trainable():
387382
Tuner(lambda config: print(lock))
388383

389384

385+
# TODO(justinvyu): [chdir_to_trial_dir]
386+
@pytest.mark.skip("chdir_to_trial_dir is not implemented yet.")
390387
@pytest.mark.parametrize("runtime_env", [{}, {"working_dir": "."}])
391388
def test_tuner_no_chdir_to_trial_dir(shutdown_only, chdir_tmpdir, runtime_env):
392389
"""Tests that setting `chdir_to_trial_dir=False` in `TuneConfig` allows for

0 commit comments

Comments
 (0)