# 服务简介 **OpenBox** 的设计原则是把BBO作为服务提供给用户。
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**的基本工作流实现如下: ```python # 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**的工作人员都保证链接到同一个任务,从而支持并行评估。 当任务未完成时,工作者继续调用**GetSuggestions**和**UpdateObservations**从建议服务中提取建议并更新其相应的观察结果。 ### 接口 用户可以通过如下接口和 **OpenBox** 进行交互: + **Register**: 它接受global_task_id作为输入,该id是在从workers调用CreateTask时创建的,并将当前worker与相应的任务绑定。 这允许在多个worker之间共享优化过程的历史记录。 + **Suggest**: 根据对当前任务的历史观察,它提出了下一步要评估的配置。 + **Update**: 这种方法用从worker那里获得的观察更新优化历史。观察结果包括三个部分:目标值、约束结果和评价信息。 + **StopEarly**: 它返回一个布尔值,指示是否应提前停止当前计算。 + **Extrapolate**: 它用延拓的方法,并以交互方式向用户提供资源感知建议。