pip install "ray[tune]"★Tune + its deps (core Ray ispip install ray).from ray import tune★The one import you need for everything here.ray.init()Optional —fit()auto-inits; call to set CPUs/GPUs/address.ray.init(num_cpus=8, num_gpus=2)Cap local resources for the trial pool.ray.init(address="auto")Attach to an existing cluster.ray.shutdown()Tear the runtime down.
space = {"lr": tune.uniform(0, 1)}★1 · define the search space (a dict).def objective(config): … tune.report({…})★2 · the trainable — readconfig, report metrics.tuner = tune.Tuner(objective, param_space=space, …)★3 · assemble the run.results = tuner.fit()★4 · launch all trials, block till done.results.get_best_result().config★5 · the winning hyperparameters.
tune.uniform(0, 1)★Continuous float in a range.tune.loguniform(1e-4, 1e-1)★Log scale — for learning rates & the like.tune.randint(1, 100)★Integer in[lower, upper).tune.choice(["a", "b", "c"])★Pick one from a list.tune.quniform(0, 10, 0.5) · tune.qrandint(…)Quantized (stepped) float / int.tune.randn(0, 1) · tune.lograndint(…)Gaussian · log-scaled integer.tune.grid_search([16, 32, 64])Try every value — multiplies trial count.
tune.sample_from(lambda c: c.config.a * 2)Derive one param from another / arbitrary Python."b": tune.sample_from(lambda c: np.random.randint(c.config.a))Conditional ranges that depend on a sibling."net": {"lr": tune.uniform(…), "units": tune.choice(…)}Nest dicts — Tune recurses into the space.tune.qloguniform(1e-4, 1e-1, 5e-5)Quantized log range.
def objective(config): …★One arg: the sampledconfigdict.config["lr"]Read your hyperparameters off it.for step in range(epochs): tune.report({…})★Report each iteration so schedulers can act.tune.report({"score": final})A single report also works for one-shot objectives.from ray.train import reportdeprecatedInside a Tune function usetune.report, nottrain.report.
tune.report({"loss": l, "acc": a})Report several metrics at once.# training_iteration is added automaticallyUse it as atime_attr/ stop key for free.tune.report(m, checkpoint=ckpt)Attach a checkpoint to this step (see card 08).tune.get_context().get_trial_id()Trial id / dir from inside the trainable.
class MyTrainable(tune.Trainable):For fine control over checkpoint/restore & PBT.def setup(self, config): …Build model/optimizer once.def step(self): return {"score": …}One iteration; the dict is auto-reported.def save_checkpoint / load_checkpoint(self, dir)Persist & restore trial state.
ckpt = tune.Checkpoint.from_directory(d)Wrap a local dir of saved files.tune.report(metrics, checkpoint=ckpt)★Report + checkpoint together, per step.ckpt = tune.get_checkpoint()★At trial start — resume from here if notNone.with ckpt.as_directory() as d: …Materialize the checkpoint to read files back.
tune.Tuner(trainable, param_space=space)★Minimal Tuner — random search, 1 sample.tune.Tuner(…, tune_config=…, run_config=…)Full form — the two config objects steer everything.results = tuner.fit()Run all trials → returns aResultGrid.tune.Tuner.restore(path, trainable)Reload an interrupted experiment, then.fit().
metric="score", mode="max"★Which metric, and which direction is better.num_samples=20★How many configs to sample (×grid, if any).search_alg=OptunaSearch()Smart search instead of random.scheduler=ASHAScheduler()★Early-stop weak trials.max_concurrent_trials=4Cap trials running at once.time_budget_s=3600Wall-clock budget for the whole search.
name="my_exp"Experiment folder name.storage_path="s3://bucket/runs"★Where checkpoints + results land (local/NFS/S3/GCS).stop={"training_iteration": 100}Global stop condition per trial.checkpoint_config=tune.CheckpointConfig(…)Keep-N, checkpoint scoring & frequency.callbacks=[…], verbose=1Loggers/hooks + console verbosity.failure_config=tune.FailureConfig(max_failures=3)Auto-retry flaky trials.
BasicVariantGenerator()★Default — random / grid search.from ray.tune.search.optuna import OptunaSearch★TPE / Optuna backend — great general default.from ray.tune.search.hyperopt import HyperOptSearchTree-Parzen via HyperOpt.from ray.tune.search.bayesopt import BayesOptSearchGaussian-process Bayesian search.AxSearch · TuneBOHB · HEBOSearch · NevergradSearchMore backends — each apip installextra.
ConcurrencyLimiter(searcher, max_concurrent=4)★Sequential searchers need this to parallelize sanely.Repeater(searcher, repeat=3)Average noisy objectives over repeats.search_alg.save("algo.pkl") · restore(…)Persist searcher state across restarts.
ASHAScheduler()★Async successive halving — the usual first choice.PopulationBasedTraining(…)★PBT — evolve hyperparameters mid-training.HyperBandScheduler() · HyperBandForBOHB()HyperBand · pair BOHB search with it.MedianStoppingRule()Stop trials below the running median.FIFOScheduler()Default — no early stopping at all.
time_attr="training_iteration"★What "budget" means (iterations, ortime_total_s).max_t=100Max budget a trial can reach.grace_period=10Never stop before this many units — give trials a chance.reduction_factor=4Keep top 1/4 at each rung.
tune.with_resources(obj, {"cpu": 2, "gpu": 1})★Reserve per trial; controls how many run in parallel.{"gpu": 0.5}Fractional GPUs — pack 2 trials per card.tune.with_resources(obj, PlacementGroupFactory([…]))Multi-node / multi-worker trials (e.g. distributed training).lambda cfg: {"gpu": cfg["n_gpu"]}Resources that depend on the sampled config.
tune.with_parameters(obj, data=big_df)★Put large data in the object store, not a closure.def objective(config, data): …Extra args arrive afterconfig.ref = ray.put(model); ray.get(ref)Manual object-store handle when you need it.
best = results.get_best_result()★Best trial (needs metric+mode if not in TuneConfig).best.config · best.metricsIts hyperparameters · last reported metrics.results.get_dataframe()★All trials as a pandas DataFrame.best.get_best_checkpoint(metric, mode)Best checkpoint of the best trial.results.errors · results.num_errorsWhat failed, and how many.
stop={"score": 0.98, "training_iteration": 50}★Stop a trial when any threshold is hit.class Stop(tune.Stopper): def __call__(…)Custom logic — e.g. plateau / whole-experiment stop.tune.Tuner.restore(path, trainable, resume_errored=True)★Resume after a crash; retry the errored trials.time_budget_s=1800Or just cap the whole search by wall-clock.
storage_path="s3://…"★Shared storage is required for multi-node runs.$ ray up cluster.yaml · $ ray submit …Same script scales from laptop to cluster unchanged.from ray.air.integrations.wandb import WandbLoggerCallbackLog every trial to W&B (also MLflow, Comet).$ tensorboard --logdir ~/ray_resultsTensorBoard reads Tune's logs out of the box.TuneReportCheckpointCallbackBridge Keras/Lightning/XGBoost training into Tune.