tune 设计

设计目标

自动调优通过测量候选来选择配置(块大小、内核变体、布局)。若做得天真,它会过拟合:所谓“胜者”往往只是在恰好被测量的形状上、噪声恰好有利的那个候选。tune 提供防止这种情况的策略组件——稳健分数、实际意义上的持平、确认和留出集——同时把候选的构建和运行留给应用,在那里它们可以像其他任何基准测试一样被验证和测量。

数学背景

分数

一个被测量 nn 次的候选 cc 具有样本 t1,…,tnt_1, \dots, t_n。基于 stats 设计中推导的稳健性理由,它的分数是可用样本(有限、非负)的中位数。次要指标 scs_c(工作区字节数、代码大小)用于决出持平。

赢家诅咒

设 p^c=pc+εc\hat p_c = p_c + \varepsilon_c 为候选 cc 的测量分数,其真实代价为 pcp_c,噪声均值为零。选取测量值的最小值是向下有偏的:

E[min⁡cp^c]≤min⁡cE[p^c]=min⁡cpc,\mathbb E\bigl[\min_c \hat p_c\bigr] \le \min_c \mathbb E[\hat p_c] = \min_c p_c ,

因为对真正最好的 c∗c^* 有 min⁡cp^c≤p^c∗\min_c \hat p_c \le \hat p_{c^*},取期望得到 E[min⁡cp^c]≤pc∗\mathbb E[\min_c \hat p_c] \le p_{c^*}。当有许多代价相近的候选时,被选中的那个更可能是运气好而不是真的好。由此得到两种补救措施,TuningBudget 为两者都命了名:用新的 confirmation_samples 重新测量 finalists(新的噪声与选择无关,因此确认后的分数是无偏的),以及在胜者未参与选择的 holdout 上评估它。

实际意义上的持平

阈值为 tt 的 select_best 构成持平集

F={ c:pc−pmin⁡pmin⁡⋅100≤t },F = \Bigl\{\, c : \frac{p_c - p_{\min}}{p_{\min}} \cdot 100 \le t \,\Bigr\},

并返回 FF 中次要值最好的元素,再按最小 id 决出。该规则与顺序无关:FF 只由值定义,而第二步是 FF 上一个全序(先次要值、再 id)的最小值,当 id 唯一时它是唯一的。因此对输入进行置换不会改变结果。

Pareto 支配

在两个指标都取最小化时,若 po≤pcp_o \le p_c、so≤scs_o \le s_c 且 (po,so)≠(pc,sc)(p_o, s_o) \ne (p_c, s_c),则 oo 支配 cc(o≺co \prec c)。前沿为 {c:∄ o≺c}\{c : \nexists\, o \prec c\}。按主要代价排序时,前沿上的次要代价严格递减:若 pa<pbp_a < p_b 且 sa≤sbs_a \le s_b,则 a≺ba \prec b,矛盾,因此 sa>sbs_a > s_b。前沿上主要代价相等的点,其次要代价也必须相等。前沿之外的每个点都被前沿上的某个点支配(支配是有限集上的严格偏序,因此每条链都终止于一个极小元)。

大空间的随机子集

seeded_order 按候选 id 的带种子 64 位 FNV-1a 哈希对候选排序,其作用相当于一个伪随机置换。取它的前 BB 个候选。如果 id 与质量无关,每个候选落入该前缀的可能性都相同,前缀中至少包含一个来自空间中最好的 qq 比例的候选的概率为

1−(1−q)B.1 - (1 - q)^{B} .

B=60B = 60 时,对前 5 % 就已经有 1−0.9560≈0.9541 - 0.95^{60} \approx 0.954。这是支持随机搜索优于网格搜索的经典论证。11 J. Bergstra 和 Y. Bengio,“Random search for hyper-parameter optimization”,JMLR 13,2012。

设计决策

策略在此,副作用在应用中

问题。 构建候选可能意味着编译一个内核;运行它则必须在某个协议下经过验证和计时。选择。 tune 以分数作为输入,从不运行任何东西;BuiltCandidate 携带一个 runner.Implementation。理由。 这样调优测量就与其他所有基准测试一样经过相同的验证、校准和事件流,而调优策略可以用编造的数字来测试。

中位数分数

score_samples 取可用样本的中位数,并把没有可用样本的候选标记为无效,因此候选不会因为某次出错的测量返回 0 或 NaN 而胜出。

在有界前缀上穷举搜索

exhaustive_scores 为枚举中的前 budget 个候选打分,并为每个候选(包括被拒绝的)记录一个 BuildEvent。与 seeded_order 结合时,前缀就是一个可复现的随机子集;采用自然顺序和较大的预算时,它就是完整的网格搜索。策略字符串 global:<id> 指明单一的全局胜者;更精细的策略(按形状、Pareto)用 select_best、pareto_frontier 和 @model.DeploymentPolicy 构建。

自适应确认

confirmation_count 在相对不确定度越过 5 % 和 20 % 时,把基础确认次数乘以 1、2 或 3,并截断到预算之内。噪声大的决赛候选获得更多样本,安静的候选则不浪费时间。

正确性与不变量

  • select_best 恰好在没有可用分数时返回 None;否则其结果是可用的、在最快者的阈值范围内,并且与输入顺序无关(推导见上文)。
  • pareto_frontier 只返回可用且非支配的分数,按主要值、次要值、id 排序。
  • exhaustive_scores 最多检查 budget 个候选,并且只对有效候选调用打分回调。
  • seeded_order 是其输入的一个置换,只取决于 id 和种子。
  • confirmation_count 位于 [0,budget][0, \text{budget}] 中。

被否决的方案

  • 贝叶斯优化或进化搜索。 有效,但需要对空间建模,并使结果更难复现;钩子(neighbors、seeded_order)允许用户自行编写搜索。
  • 均值分数。 一次被抢占的运行就会左右结果。
  • 选取原始最小值。 会受到赢家诅咒的影响。

边界

  • 这里不构建、运行或验证任何候选。
  • TuningBudget、TuningObjective 和 HoldoutPlan 是数据;没有函数强制执行它们。
  • 本包中没有任何函数使用 CandidateSpace.neighbors。
  • exhaustive_scores 本身不使用 seeded_order;如果你想要随机子集,请先对空间重新排序。

Footnotes

  1. J. Bergstra 和 Y. Bengio,“Random search for hyper-parameter optimization”,JMLR 13,2012。 ↩