服务简介#

OpenBox 的设计原则是把BBO作为服务提供给用户。

../_images/sys_framework.svg
OpenBox的体系结构。

OpenBox 系统的体系结构包含以下五个组成构件:

  • Service Master 负责节点管理,负载均衡以及容错。

  • Task Database 保存所有任务的历史信息和历史状态。

  • Suggestion Server 给每个任务生成新的配置。

  • REST API 使用RESTful APIs来连接Workers和Suggestion Service。

  • Evaluation workers 由用户拥有和定义任务。

并行基础设施#

OpenBox可以同时为大量任务生成配置。仅仅使用单台机器不足以处理工作负载。 因此,我们的建议将服务部署在多台机器上,每个机器是一个Suggestion Server。 每个Suggestion Server并行对多个任务生成建议。 这为我们提供了一个可大规模扩展的建议基础设施。 另一个主要组件是Service Master,它负责管理Suggestion Server,并平衡工作负载。 它作为统一的端点,接受工人的请求; 这样,每个工人就不需要知道调度细节。 工作者从Suggestion Server请求新配置,Suggestion Server根据自动算法选择模块确定的算法生成这些配置。 具体来说,在这个过程中,Suggestion Server利用基于局部惩罚的并行化机制和迁移学习框架来提高采样效率。

一个主要的设计考虑是维护一个容许误差的生产系统,因为机器崩溃是不可避免的。 在OpenBox中,Service Master监视每个服务器的状态,并保留一个活动服务器表。 当新任务到来时,Service Master会将其分配给活动服务器并记录此绑定信息。 如果一台服务器关闭,它的任务将被主服务器调度到一个新的服务器,以及存储在Task Database中的相关优化历史记录。 负载平衡是进行此类任务分配的最重要准则之一。 另外,Service Master的快照存储在远程数据库服务中;如果主机关闭,我们可以通过重新启动节点并从数据库中获取快照来恢复它。

服务接口#

任务描述语言#

为了便于使用,我们设计了一个任务描述语言(TDL)来定义优化任务。 TDL的核心部分是定义搜索空间,包括每个参数的类型、取值范围以及它们之间的关系。 OpenBox支持FLOAT、INTEGER、ORDINAL和CATEGORICAL等参数类型。 此外,用户还可以对参数添加条件,进一步限制搜索空间。用户还可以在TDL中指定时间预算、任务类型、工作结点数量、并行策略和使用历史。

task_config = {
    "parameter": {
        "x1": {"type": "float", "default": 0,
            "bound": [-5, 10]} ,
        "x2": {"type": "int", "bound": [0, 15]} ,
        "x3": {"type": "cat", "default": "a1",
            "choice": ["a1", "a2", "a3"]} ,
        "x4": {"type": "ord", "default": 1,
            "choice": [1, 2, 3]}} ,
    "condition": {
        "cdn1": {"type": "equal", "parent": "x3",
            "child": "x1", "value": "a3"}} ,
    "number_of_trials": 200 ,
    "time_budget": 10800 ,
    "task_type": "soc",
    "parallel_strategy": "async",
    "worker_num": 10,
    "use_history": True
    }

这里有一个TDL的例子。 它定义了四个不同类型的参数x1-4和一个条件cdn1,表示只有当*x3 = “a3”*时,x1才处于激活状态。 时间预算为3小时,并行策略为异步,并启用了迁移学习。

基本工作流#

给定任务的TDL,OpenBox的基本工作流实现如下:

# Register the worker with a task .
global_task_id = worker.CreateTask(task_tdl)
worker.BindTask(global_task_id)
while not worker.TaskFinished():
    # Obtain a configuration to evaluate.
    config = worker.GetSuggestions()
    # Evaluate the objective function.
    result = Evaluate(config)
    # Report the evaluated results to the server.
    worker.UpdateObservations(config, result)

这里Evaluate是用户提供的目标函数的评估过程。 通过调用CreateTask,worker获得一个全局唯一标识符global_task_id。 所有注册了相同global_task_id的工作人员都保证链接到同一个任务,从而支持并行评估。 当任务未完成时,工作者继续调用GetSuggestionsUpdateObservations从建议服务中提取建议并更新其相应的观察结果。

接口#

用户可以通过如下接口和 OpenBox 进行交互:

  • Register: 它接受global_task_id作为输入,该id是在从workers调用CreateTask时创建的,并将当前worker与相应的任务绑定。 这允许在多个worker之间共享优化过程的历史记录。

  • Suggest: 根据对当前任务的历史观察,它提出了下一步要评估的配置。

  • Update: 这种方法用从worker那里获得的观察更新优化历史。观察结果包括三个部分:目标值、约束结果和评价信息。

  • StopEarly: 它返回一个布尔值,指示是否应提前停止当前计算。

  • Extrapolate: 它用延拓的方法,并以交互方式向用户提供资源感知建议。