ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Ray Tune 与 AxSearch 集成指南:基于 Ax 贝叶斯优化的超参数调优实战

Ray Tune 与 AxSearch 集成指南:基于 Ax 贝叶斯优化的超参数调优实战 Ray Tune 与 AxSearch 集成指南基于 Ax 贝叶斯优化的超参数调优实战【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray本篇指南围绕 Ray Tune 官方示例 ax_example.py由 ax_example.rst 以literalinclude方式嵌入文档展开系统讲解如何在 Ray Tune 中接入基于 AxAdaptive Experimentation由 Meta 开源、底层基于 BoTorch/PyTorch 的贝叶斯优化平台的搜索算法AxSearch包括参数约束、结果约束、并发限制以及与调度器协同使用。读完本文你将能独立在 Ray Tune 中搭建一套带约束的贝叶斯超参数调优流程并理解其底层实现机制。一、AxSearch 在 Ray Tune 中的定位Ray Tune 内置了多种超参数优化HPO框架的集成包括 Ax、HyperOpt、Optuna、Nevergrad、BOHB、BayesOpt 等。在 doc/source/tune/examples/index.rst 中这些示例被归类在 Hyperparameter optimization frameworks 一节在 doc/source/tune/api/suggestion.rst 中AxSearch与BasicVariantGenerator随机/网格搜索等并列作为可选的search_alg。AxSearch的价值在于使用 Ax 提供的高效贝叶斯优化策略底层由 BoTorch 驱动基于高斯过程建模原生支持参数约束如x1 x2 2.0与结果约束如l2norm 1.25这是多数内置搜索算法不具备的能力可与 Ray Tune 的调度器如AsyncHyperBandScheduler叠加使用实现在提前停止的同时进行智能采样自动把 Ray Tune 的搜索空间语法转换为 Ax 的搜索空间格式。从源码看AxSearch继承自Searcher基类位于 python/ray/tune/search/ax/ax_search.py对外统一由 python/ray/tune/search/ax/init.py 导出。二、环境准备AxSearch依赖独立的ax-platform库。安装命令pip install ax-platform示例源码的 docstring 明确标注了该依赖见 python/ray/tune/examples/ax_example.py 第 1-6 行。ax-search模块通过惰性导入方式加载 Axtry: import ax ... except ImportError若未安装实例化AxSearch时会直接抛出断言错误并提示安装命令assert ax is not None, Ax must be installed! You can install AxSearch with the command: pip install ax-platform.同时源码兼容新旧两代 Ax API新版使用ax.service.ax_client.ObjectiveProperties定义目标旧版使用objective_name/minimize参数_setup_experiment()中通过try/except TypeError自动降级适配。三、完整示例逐段剖析以下完整代码即文档所引用的示例 python/ray/tune/examples/ax_example.py它同时验证了AxSearch可以独立调度器AsyncHyperBandScheduler配合使用。3.1 基准函数Hartmann6import time import numpy as np from ray import tune from ray.tune.schedulers import AsyncHyperBandScheduler from ray.tune.search.ax import AxSearch def hartmann6(x): alpha np.array([1.0, 1.2, 3.0, 3.2]) A np.array( [ [10, 3, 17, 3.5, 1.7, 8], [0.05, 10, 17, 0.1, 8, 14], [3, 3.5, 1.7, 10, 17, 8], [17, 8, 0.05, 10, 0.1, 14], ] ) P 10 ** (-4) * np.array( [ [1312, 1696, 5569, 124, 8283, 5886], [2329, 4135, 8307, 3736, 1004, 9991], [2348, 1451, 3522, 2883, 3047, 6650], [4047, 8828, 8732, 5743, 1091, 381], ] ) y 0.0 for j, alpha_j in enumerate(alpha): t 0 for k in range(6): t A[j, k] * ((x[k] - P[j, k]) ** 2) y - alpha_j * np.exp(-t) return yHartmann6 是超参数调优领域经典的 6 维测试函数定义域通常为[0, 1]^6具有多个局部极值常用于验证优化算法对多峰函数的最小化能力。示例中它作为被优化的目标函数其全局最小值约为-3.322。3.2 训练函数easy_objectivedef easy_objective(config): for i in range(config[iterations]): x np.array([config.get(x{}.format(i 1)) for i in range(6)]) tune.report( { timesteps_total: i, hartmann6: hartmann6(x), l2norm: np.sqrt((x**2).sum()), } ) time.sleep(0.02)easy_objective接收 Tune 注入的config字典把搜索空间中的x1~x6组装成向量每个迭代步通过tune.report(...)上报三类指标timesteps_total当前迭代步用于调度器判断进度与提前停止hartmann6优化目标metricmodemin表示求最小l2norm配置向量的 L2 范数仅作为结果约束的判定指标不参与主目标优化。time.sleep(0.02)用于模拟真实训练中每个 step 的开销使调度器的提前停止机制更具实际意义。3.3 配置搜索算法与约束if __name__ __main__: import argparse parser argparse.ArgumentParser() parser.add_argument( --smoke-test, actionstore_true, helpFinish quickly for testing ) args, _ parser.parse_known_args() algo AxSearch( parameter_constraints[x1 x2 2.0], # Optional. outcome_constraints[l2norm 1.25], # Optional. ) # Limit to 4 concurrent trials algo tune.search.ConcurrencyLimiter(algo, max_concurrent4) scheduler AsyncHyperBandScheduler()这一小段是示例的核心演示点parameter_constraints参数约束声明搜索空间内参数之间的线性关系约束这里x1 x2 2.0。由于x1、x2本身取值范围是[0, 1]该约束在本例中并不收紧可行域主要用于演示语法Ax 支持诸如x3 x4、x3 x4 2这类表达式。outcome_constraints结果约束对上报指标施加约束l2norm 1.25表示只接受 L2 范数不超过 1.25 的候选点。Ax 的贝叶斯优化会在采样的同时考虑满足结果约束的概率即约束贝叶斯优化这一点在 ax_search.py 的_process_result中也有体现——完成一个 trial 时除了目标指标所有outcome_constraints涉及的指标也会一并喂给 Axmetrics_to_include。ConcurrencyLimiter并发限制Ax 的默认生成策略通常是串行优化的示例源码在检测到_enforce_sequential_optimization时会提示Be sure to use a ConcurrencyLimiter通过tune.search.ConcurrencyLimiter(algo, max_concurrent4)包装后最多同时运行 4 个 trial避免因并行采样过多而降低贝叶斯模型质量同时仍能充分利用多核/多机资源。AsyncHyperBandScheduler异步超带调度器根据timesteps_total的进度提前终止表现不佳的 trial与搜索算法正交组合示例专门验证了带独立调度器场景的可用性。3.4 Tuner 组装与运行tuner tune.Tuner( easy_objective, run_configtune.RunConfig( nameax, stop{timesteps_total: 100}, ), tune_configtune.TuneConfig( metrichartmann6, # provided in the easy_objective function modemin, search_algalgo, schedulerscheduler, num_samples10 if args.smoke_test else 50, ), param_space{ iterations: 100, x1: tune.uniform(0.0, 1.0), x2: tune.uniform(0.0, 1.0), x3: tune.uniform(0.0, 1.0), x4: tune.uniform(0.0, 1.0), x5: tune.uniform(0.0, 1.0), x6: tune.uniform(0.0, 1.0), }, ) results tuner.fit() print(Best hyperparameters found were: , results.get_best_result().config)关键点metrichartmann6必须与easy_objective中tune.report的键一致modemin明确优化方向AxSearch构造时未显式传metric/mode说明二者可以通过TuneConfig注入内部由set_search_properties完成。param_space中x1~x6均为tune.uniform(0.0, 1.0)连续量iterations100是固定超参不参与搜索。AxSearch会自动将 Tune 语法转换为 Ax 的 range 参数。num_samples控制总 trial 数正常跑 50 个--smoke-test时仅 10 个用于快速验证。结果通过results.get_best_result().config直接打印最优超参数配置。运行方式# 完整运行 50 个 trial python python/ray/tune/examples/ax_example.py # 冒烟测试仅 10 个 trial快速验证流程 python python/ray/tune/examples/ax_example.py --smoke-test四、AxSearch 核心 API 与参数详解根据 ax_search.py 的类文档与构造实现AxSearch的完整签名如下AxSearch( spaceNone, # 手动指定的 Ax 搜索空间字典或列表形式 metricNone, # 优化指标名须与 tune.report 中的键一致 modeNone, # min 或 max points_to_evaluateNone, # 初始建议点列表[dict] parameter_constraintsNone,# 参数约束如 x3 x4 outcome_constraintsNone, # 结果约束如 m1 3 ax_clientNone, # 已初始化的 AxClient 实例 **ax_kwargs, # 传递给 AxClient 的其他参数如 random_seed )各参数说明参数类型含义与说明spacedict/list[dict]Ax 格式搜索空间。若为 Tune 格式字典会被自动转换若不传则必须通过Tuner(param_space...)或已有ax_client提供metricstr目标指标名必须出现在tune.report的结果字典中若为None但指定了mode默认使用ray.tune.result.DEFAULT_METRICmodemin/max优化方向默认max。注意示例中显式设为minpoints_to_evaluatelist[dict]已有先验好配置按顺序最先运行帮助算法预热parameter_constraintslist[str]线性参数约束表达式如x3 x4、x3 x4 2outcome_constraintslist[str]形如metric_name bound的结果约束如m1 3ax_clientAxClient复用一个已创建好实验的AxClient此时不得再传space、metric、parameter_constraints、outcome_constraints源码会显式抛ValueError校验**ax_kwargs-透传给内部AxClient(**kwargs)例如random_seed当显式传入ax_client时被忽略4.1 方式一自动转换 Tune 搜索空间推荐from ray import tune from ray.tune.search.ax import AxSearch config { x1: tune.uniform(0.0, 1.0), x2: tune.uniform(0.0, 1.0), } def easy_objective(config): for i in range(100): intermediate_result config[x1] config[x2] * i tune.report({score: intermediate_result}) ax_search AxSearch() tuner tune.Tuner( easy_objective, tune_configtune.TuneConfig( search_algax_search, metricscore, modemax, ), param_spaceconfig, ) tuner.fit()AxSearch会调用静态方法convert_search_space将 Tune 采样器转换为 Ax 参数定义。转换规则见 ax_search.py 的convert_search_spaceTune 采样器Ax 参数类型说明tune.uniform(a, b)Float{type: range, bounds: [a, b], value_type: float, log_scale: False}连续均匀tune.loguniform(a, b)Float{type: range, bounds: [a, b], value_type: float, log_scale: True}对数均匀tune.uniform(a, b)Integer{type: range, bounds: [a, b-1], value_type: int, ...}整型均匀注意上界减 1tune.loguniform(a, b)Integer同上log_scale: True整型对数均匀tune.choice([...])Categorical{type: choice, values: categories}类别型嵌套 dict / list 中的固定值{type: fixed, value: val}固定参数需要注意的限制不支持grid_search转换时若检测到grid_vars会直接抛ValueError(Grid search parameters cannot be automatically converted to an Ax search space.)不支持量化采样器tune.quniform等带Quantized包装的采样器会打印警告并丢弃量化AxSearch does not support quantization. Dropped quantization.嵌套 dict/list 的参数名以/连接例如a/b/0。4.2 方式二手动传递 Ax 格式搜索空间from ray import tune from ray.tune.search.ax import AxSearch parameters [ {name: x1, type: range, bounds: [0.0, 1.0]}, {name: x2, type: range, bounds: [0.0, 1.0]}, ] def easy_objective(config): for i in range(100): intermediate_result config[x1] config[x2] * i tune.report({score: intermediate_result}) ax_search AxSearch(spaceparameters, metricscore, modemax) tuner tune.Tuner( easy_objective, tune_configtune.TuneConfig(search_algax_search), ) tuner.fit()Ax 参数字典必含字段name参数名、typerange/fixed/choice、range 类型需bounds下界在前choice 类型需valuesfixed 类型需单个value。该方式便于复用已有的 Ax 实验定义或精确控制log_scale等细节。4.3 方式三复用已有 AxClient高级当需要复用AxClient例如跨实验共享随机种子、或接入已有 Ax 实验时from ax.service.ax_client import AxClient, ObjectiveProperties from ray.tune.search.ax import AxSearch client AxClient(random_seed4321) client.create_experiment( parametersconverted_config, objectives{_metric: ObjectiveProperties(minimizeFalse)}, ) searcher AxSearch(ax_clientclient)这正是 python/ray/tune/tests/test_searchers.py 中testAxManualSetup的用法。此时AxSearch不再自行创建实验而是直接向已有实验追加 trial且构造参数中不允许再携带任何实验定义信息源码中的冲突校验逻辑见_setup_experiment。五、约束机制详解约束是AxSearch区别于多数内置搜索算法的杀手锏示例中同时演示了两种5.1 参数约束parameter_constraints对搜索空间内参数施加线性不等式例如AxSearch(parameter_constraints[x1 x2 2.0])Ax 支持任意参数的线性组合表达式包括x3 x4、x3 x4 2等形式。贝叶斯优化在推荐下一组参数时会把该约束纳入采样过程避免无效探索。5.2 结果约束outcome_constraints对训练过程中上报的指标施加边界AxSearch(outcome_constraints[l2norm 1.25])其形式为指标名 比较符 边界如m1 3。从 ax_search.py 的_process_result可以看到trial 完成时 Ax 需要同时收到目标指标与所有结果约束指标的值metrics_to_include [self._metric] [ oc.metric.name for oc in self._ax.experiment.optimization_config.outcome_constraints ]即 Ax 会用带约束的高斯过程模型同时建模目标与约束的可行性推荐大概率满足约束且目标优秀的候选点。六、源码级运行原理6.1 一次 trial 的生命周期AxSearch实现Searcher接口的两个核心方法suggest(trial_id)若无points_to_evaluate剩余则调用self._ax.get_next_trial()获取 Ax 推荐的新参数并将 Tune 的trial_id映射到 Ax 的trial_index保存在_live_trial_mapping。若 Ax 因并行上限MaxParallelismReachedException或数据不足DataRequiredError无法给出新点则返回None让 Tune 暂停生成。有初始建议点时则从points_to_evaluate中弹出并通过attach_trial(config)直接附加。on_trial_complete(trial_id, result, error)将结果交给_process_result其中若发现metric为 NaN/Inf会调用ax.abandon_trial()放弃该 trial 而不是上报非法值合法结果则通过ax.complete_trial(trial_index, raw_datametric_dict)回填驱动贝叶斯模型更新。返回值还需经过unflatten_list_dict还原为嵌套配置当搜索空间含固定值与可调参数混排的列表如[1, tune.uniform(2, 3), 4]时会先对键排序再反扁平化避免键序错乱。6.2 检查点与恢复AxSearch通过save(checkpoint_path)/restore(checkpoint_path)用cloudpickle序列化整个实例状态实现 Tune 的断点续训与故障恢复。test_searchers.py中的check_searcher_checkpoint_errors_scope专门校验搜索算法检查点化后不出现序列化错误。6.3 与调度器的协同示例使用AsyncHyperBandScheduler验证了搜索算法与调度器可叠加调度器负责何时提前终止表现差的 trial搜索算法负责下一个 trial 采哪里。Ray Tune 的ConcurrencyLimiter则进一步协调两者——控制同时在跑的 trial 数确保 Ax 的串行生成策略不被并发打乱。test_convergence.py与test_tune_restore_warm_start.py中同样覆盖了AxSearch与ConcurrencyLimiter组合如ConcurrencyLimiter(AxSearch(...), max_concurrent10)及 warm-start 场景。七、验证与测试仓库为AxSearch提供了多维度测试可作为集成正确性的参考python/ray/tune/tests/test_searchers.pytestAx自动转换搜索空间 ConcurrencyLimiter 16 个样本确保 Ax 真正拟合了代理模型、testAxManualSetup手动AxClient创建实验并覆盖混合列表参数python/ray/tune/tests/test_convergence.py收敛性验证当前ax warm start用例被标记为跳过说明 warm-start 依赖的 Ax 版本升级后曾出现问题集成时建议以当前 Ax 版本实测为准python/ray/tune/tests/test_tune_restore_warm_start.py利用AxSearch.convert_search_space构造空间、组装AxClient并指定 Ax 生成策略GenerationStrategy的恢复/热启动测试代码中同时兼容 Ax 1.0ax.adapter.registry.Generators与 Ax 0.xax.modelbridge.registry.Models两代 API。八、实践要点与注意事项务必安装ax-platform否则AxSearch构造即失败metric/mode二选一设置可在AxSearch(...)传入也可在TuneConfig传入set_search_properties会回填若构造时只给mode不给metric会退回DEFAULT_METRIC不要对 AxSearch 使用grid_search会自动转换失败量化采样器会被静默降级为普通均匀采样并行度要用ConcurrencyLimiter控制Ax 的串行优化策略在未限制并发时可能打印告警推荐max_concurrent取 4~10 量级NaN/Inf 指标会被自动放弃abandon_trial无需在训练函数中额外处理约束语法是字符串表达式参数约束面向参数名结果约束面向tune.report中出现的指标名写错名称会在 Ax 建实验时报错版本兼容ax_search.py对 Ax 新旧 APIObjectivePropertiesvsobjective_name、GeneratorsvsModels做了双轨适配集成时尽量使用较新的ax-platform以获得完整功能。九、小结本文以 Ray Tune 官方 Ax 示例为骨架完整还原了AxSearch的配置、约束、并发控制、调度器组合与运行方式并结合 python/ray/tune/search/ax/ax_search.py 的实现剖析了搜索空间转换、trial 生命周期、NaN 处理与检查点机制。相比普通随机/网格搜索AxSearch的贝叶斯优化能在更少的 trial 数内逼近全局最优尤其适合评估代价高昂的深度学习训练场景其参数约束与结果约束能力则为工程上常见的资源/质量双约束调优提供了开箱即用的方案。读者可将示例中的hartmann6替换为真实模型训练目标直接落地到自己的调优流水线中。【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表