想象你被派去一家拥有十万道菜的自助餐厅,任务是找到全场最好吃的那道菜。如果每道菜都从头吃到尾,你恐怕要花一整年。聪明的评论家会怎么做?夹起一小块,嚼两下,味道平平就立刻放下盘子,转战下一道——这就是“提前终止”;再看一眼食材清单,把明显不合口味的菜系直接划掉——这就是“配置剪枝”。AI编译器里的自动调优,正像这位评论家:在成千上万个算子配置里,找出让深度学习模型跑得最快的那一个。TVM、Ansor、MetaSchedule 这些工具之所以能在几小时内完成调优,靠的正是这两招“省时间”的绝活。这篇内容将带你理解,如何借“尝一口就放下”和“划掉不合适的菜”的智慧,让调优又快又准。

岗位关联

掌握提前终止与剪枝,是 AI 编译器性能工程师大幅压缩调优时间、在有限算力预算下更快交付高性能算子的核心技能,也是理解 TVM/Ansor 自动调度体系的关键一环。

目录
  1. 可视化演示
  2. 调优全流程
  3. 提前终止
  4. 终止判据
  5. 配置剪枝
  6. 剪枝算法
  7. 工程实践
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

本节配有交互动效(进入视口后自动加载,约 3KB)。

调优循环:搜索\u2192编译\u2192测量\u2192更新 \u7422\u9885: \u6d4b\u91cf\u592a\u61621000\u4e2a\u914d\u7f6e\u00d710\u6b21\u91cd\u590d\u6bcf\u6b21~3s \u2192 \u603b\u8ba18.3h= 10000...

调优全流程

评论家进店后,不会满场乱跑,而是先建立一套“探险系统”:按菜系分区、先看菜单再试吃、边吃边记录口味偏好。自动调优也一样,它有一个清晰的循环节奏,每一步都在回答“下一道菜试什么、怎么打分、如何更新判断”。

在 TVM 这类 AI 编译器中,自动调优(AutoTVM / Ansor / MetaSchedule)的核心是一个 Tuning 循环:先生成一批算子配置(比如循环分块大小、向量宽度),再把它们放到目标硬件上实测延迟,用测量结果训练成本模型,最后让模型指导下一次生成更可能快的配置。如此循环往复,直到找到满意的实现。

这个循环里有三个关键角色:搜索策略负责“怎么生成新配置”,测量评估负责“怎么打分”,成本模型负责“怎么预测没测过的配置”。搜索空间 Ω 是所有可能参数组合的集合,循环的目标就是在其中找到执行时间最小的配置:

整套“探险系统”就是先在脑海里生成待试吃清单,挨个试吃、记录分数,再用试吃得出的偏好指导下一轮点菜。调优循环的本质,就是这个“试吃—记分—再点菜”的回路,而提前终止和剪枝正是让这个回路跑得更快的关键加速器。

x∗=arg⁡min⁡x∈Ωt(x)\displaystyle x^{*} = \arg\min_{x \in \Omega} t(x)
通俗说明:我们要在所有的候选配置 x 中,找出一个让执行时间 t(x) 达到最小的“最优配置 x\*”。
  1. 最优配置 x\*这是我们要找的“全场最美味的一道菜”。在数学上,它是让目标函数达到最小值的那个参数组合。
    x∗\displaystyle x^{*}
  2. 候选配置 x调优中每次生成的一个具体参数组合,比如“tile 尺寸 = 64,向量宽度 = 8”。
    x\displaystyle x
  3. 搜索空间 Ω所有可能配置的集合,就像自助餐厅里的全部菜品。
    Ω\displaystyle \Omega
  4. 执行时间 t(x)把配置 x 编译出的代码在目标硬件上实际跑一遍所需的时间,也就是我们的“美味评分”。
    t(x)\displaystyle t(x)

提前终止

评论家尝一口就放下盘子的动作,在调优里叫提前终止(early termination)。它回答一个问题:当一个配置的真实性能还很模糊时,能不能根据已经观测到的一点点迹象,果断说“不”?

在 TVM 的测量阶段,一个配置被送去目标硬件后,并非一次性拿到最终延迟。实际测量往往分多个时间片采样,或者通过任务调度器对同一配置多次运行取平均。如果前几次采样的结果已经明显差于当前最优配置,那么继续测下去大概率也是浪费算力。提前终止,就是在“结果还没完全出来”时,用已有的部分证据做止损决策。

设当前已知最优配置耗时为 t_best,正在测量的配置已观测到的部分性能为 τ(x)。如果 τ(x) 和 t_best 的差距大到一定程度,就可以终止测量,判定这个配置“不值得”:

尝一口就放下,不是鲁莽,而是聪明地把精力留给真正值得的菜。提前终止省下来的每一毫秒,最终都会变成探索更多配置的筹码,让调优在同样的时间内走得更远。

若 τ(x)tbest>θ,则终止对配置 x 的测量\displaystyle \text{若 } \frac{\tau(x)}{t_{best}} > \theta \text{,则终止对配置 } x \text{ 的测量}
通俗说明:如果这个配置测出来已经比当前冠军慢了好几倍(超过阈值 θ),就别再浪费时间了,直接换下一个。
  1. 已观测部分性能 τ(x)测量过程中已经拿到的那部分时间数据,相当于评论家已经咽下的那一口菜,是判断要不要继续的依据。
    τ(x)\displaystyle \tau(x)
  2. 当前最优 t_best到目前为止看到的最快配置的耗时,是衡量“值不值得继续”的基准线。
    tbest\displaystyle t_{best}
  3. 终止阈值 θ一个大于 1 的数,比如 3 表示“如果比最优慢 3 倍以上就放弃”。调得太小容易误杀,调得太大省不下时间。
    θ\displaystyle \theta

终止判据

光有“放下盘子”的直觉还不够,评论家需要清晰规则:什么情况下算“不行了”?是口味太差,还是已经吃饱了?终止判据就是这套规则,它决定了“何时踩刹车”。

在自动调优中,常见的触发方式有三类。相对最优判据:当前配置的部分性能比最优差超过阈值 θ 就立即终止,这是最常用的“单个配置止损”。收敛判据:若连续 N 轮调优最优性能几乎不再提升,就停止整个调优过程,这是“整体收工”。预算判据:达到预设的时间或测试次数上限就结束,这是“最后底线”。

收敛判据可以用一个公式表达。设第 k 轮的最优延迟为 t_best^(k),如果过去 N 轮的最优性能相对变化小于 ε,说明搜索已经进入高原区,再跑也难有突破:

规则越清晰,判断越稳定。终止判据就是调优循环里的“红绿灯”:单配置的灯用相对差距控制,整体流程的灯用收敛和预算控制,让算力始终花在最有可能产生突破的地方。

∣ tbest(k)−tbest(k−N) ∣tbest(k−N)<ε⇒终止调优\displaystyle \frac{|\,t_{best}^{(k)} - t_{best}^{(k-N)}\,|}{t_{best}^{(k-N)}} < \varepsilon \quad \Rightarrow \quad \text{终止调优}
通俗说明:如果最近 N 轮里,最优成绩几乎没进步(相对变化小于 ε),就像跑步成绩迟迟不提高,教练会喊停,把时间留给别的事。
  1. 第 k 轮最优 t_best^(k)当前这一轮结束时已知的最快配置耗时,代表“现在的最好成绩”。
    tbest(k)\displaystyle t_{best}^{(k)}
  2. N 轮前最优 t_best^(k-N)N 轮之前记录的最优耗时,用来做“是否进步了”的对比参照。
    tbest(k−N)\displaystyle t_{best}^{(k-N)}
  3. 相对提升量分子是两次最优耗时的绝对差值,分母是 N 轮前的值,整体表示“最近的进步幅度占原来的比例”。
    ∣ tbest(k)−tbest(k−N) ∣tbest(k−N)\displaystyle \frac{|\,t_{best}^{(k)} - t_{best}^{(k-N)}\,|}{t_{best}^{(k-N)}}
  4. 收敛阈值 ε比如 0.01,表示进步不到 1% 就认为收敛了,可以放心收工。
    ε\displaystyle \varepsilon

配置剪枝

评论家翻开菜单,看到“香菜芥末冰淇淋”,不用试也知道不行——这就是配置剪枝:在动手试之前,先根据已知信息和约束把明显不合理的候选划掉,从源头减少试吃的数量。

在 TVM 的自动调度中,配置剪枝发生在搜索空间层面。常见的剪枝依据有三类:硬件约束——比如分块尺寸超过缓存容量、向量宽度不满足芯片对齐要求,这类配置编译出来根本跑不快甚至无法运行;规则约束——某些循环变换组合在理论上就互相冲突,可以直接排除;相似去重——两个配置在参数空间里离得很近,已知一个性能差,另一个大概率也差,可以只保留一个。

怎么判断两个配置“离得近”?可以把每个配置看成 K 维空间里的一个点,用欧氏距离度量相似度。设两个配置为 x_i、x_j,距离小于阈值 δ 就认为它们是“邻桌重复菜”:

划掉菜单上“注定难吃”的菜,评论家把宝贵的试吃名额留给真正的潜力股。配置剪枝看似缩小了搜索范围,实际上提高了搜索的“命中率”——每一口都更有价值。

d(xi,xj)=∑n=1K(xi,n−xj,n)2<δ\displaystyle d(x_i, x_j) = \sqrt{\sum_{n=1}^{K} (x_{i,n} - x_{j,n})^2} < \delta
通俗说明:两个配置如果在所有参数上的差距都不大(距离小于 δ),在剪枝时就被当作重复项处理,只测其中一个即可。
  1. 两个配置 x_i, x_j搜索空间中的两个候选点,比如 x_i = (tile=64, vec=8)、x_j = (tile=96, vec=8)。
    xi,xj\displaystyle x_i, \quad x_j
  2. 第 n 维参数 x_{i,n}配置向量在某个维度上的取值,代表一个可调参数,如分块大小、展开因子等。
    xi,n\displaystyle x_{i,n}
  3. 求和与开方对所有 K 个维度上差值的平方求和再开方,得到两点间的欧氏距离,衡量“这两道菜有多雷同”。
    ∑n=1K(xi,n−xj,n)2\displaystyle \sqrt{\sum_{n=1}^{K} (x_{i,n} - x_{j,n})^2}
  4. 相似度阈值 δ距离小于 δ 判定为相似,用于剪掉其中一个,避免重复测量浪费预算。
    δ\displaystyle \delta

剪枝算法

光有“划掉”的意识不够,具体怎么划才聪明?评论家会结合历史点评数据、菜品品类规律,动态决定哪些菜该踢出名单——这正是调优中剪枝算法的任务,它是剪枝策略在真实系统中的落地方式。

在 Ansor / MetaSchedule 中,剪枝不是一次性做完,而是贯穿多轮迭代。进化搜索时,每一轮都用成本模型给候选配置打分,分数低的直接淘汰;从历史测量记录中提取特征,用“已测过的慢配置”去推测没测过的相似配置;一些明显超出硬件能力的配置,在生成阶段就被规则引擎拦截,根本不会进入测量队列。

量化剪枝好处的常用指标是加速比。设不剪枝时需要完整测量 N_full 个配置、每个平均耗时 t_full;剪枝后只需测 N_pruned 个、每个平均 t_pruned。总加速比是两者总耗时之比:

好的剪枝算法,就像一位经验丰富的评论家:不用看完整个菜单就能预判哪些菜品值得试。多轮迭代中持续积累的测量数据,让“划菜单”的手越来越准。

S=TfullTpruned=Nfull×tfullNpruned×tpruned\displaystyle S = \frac{T_{full}}{T_{pruned}} = \frac{N_{full} \times t_{full}}{N_{pruned} \times t_{pruned}}
通俗说明:加速比说的是“用了剪枝省下的时间”相当于原来的几倍。如果测试数量砍了一半、单个耗时也少一半,加速比就是 4 倍。
  1. 完整调优总耗时 T_full不剪枝时从头到尾测完所有候选的总时间,代表“最笨但最全”的基线。
    Tfull\displaystyle T_{full}
  2. 剪枝后总耗时 T_pruned剪掉低效配置后,剩下测量工作的总时间。
    Tpruned\displaystyle T_{pruned}
  3. 测量数量 N_full 与 N_pruned剪枝前后需要实测的配置个数,是加速比的主要贡献来源。
    Nfull,Npruned\displaystyle N_{full}, \quad N_{pruned}
  4. 平均测量时间 t_full 与 t_pruned因为提前终止让差配置“测得更短”,剪枝后的平均测量时间往往也更低,两项一起压缩总耗时。
    tfull,tpruned\displaystyle t_{full}, \quad t_{pruned}

工程实践

把整套方法搬到真正的厨房(生产环境),就变成了工程问题:阈值设多少?剪枝多激进?评论家要在“尝得够不够多”和“时间够不够用”之间找到平衡点,这就是调优工程实践的核心。

实践中最常调的三组参数:提前终止倍率 θ(TVM 场景通常设 1.5~10,取决于硬件测量噪声,噪声大就往大调);收敛轮数 N 与 ε(控制整体何时收工,Ansor 的 early_stopping 就是这类机制);剪枝阈值 δ 与候选保留比例(常用成本模型做 top-k 过滤,保留最有希望的少量配置)。另外,测量本身有波动,工业级调优常对一个配置重复测量多次取中位数,再决定是否提前终止。

调优总预算可以写成下面的公式,方便我们在动手前就估算成本:

最终,评论家开出的“美食榜单”质量,取决于他在“尝得多”和“尝得快”之间找到的平衡。工程实践就是把这种平衡变成可配置、可度量、可复现的参数——调优不再是碰运气的玄学,而是有策略、有预算、有回报的系统工程。

Ttotal=Nmeasured×tavg+Tcost\displaystyle T_{total} = N_{measured} \times t_{avg} + T_{cost}
通俗说明:总时间 = 实际测的配置数 × 每个平均耗时 + 模型训练开销。剪枝和早停都能降低第一项,但代价是需要花时间训练和维护成本模型。
  1. 实测配置数 N_measured经过剪枝过滤和提前终止后,真正完成“完整测量”的配置数量。
    Nmeasured\displaystyle N_{measured}
  2. 平均测量时间 t_avg因为差配置被提前终止,平均值会被拉低,这是早停带来的第二重收益。
    tavg\displaystyle t_{avg}
  3. 模型开销 T_cost成本模型的训练、更新和推理时间,在搜索空间很大时不可忽视,也是剪枝“付出的成本”。
    Tcost\displaystyle T_{cost}

AI 应用场景

TVM/Ansor 算子自动调优加速

阶段:AI 编译与算子优化阶段(调优测量环节)

解决的问题:深度学习模型部署时,卷积、矩阵乘等算子需要为特定硬件挑选最优的循环分块与向量化参数。传统做法是从头全量测试所有配置,一组算子常常要跑十几个小时甚至几天;资源有限时只能草草收工,性能不达标。利用提前终止和配置剪枝后,Ansor 的进化搜索每轮先用成本模型淘汰低分候选,仅对少数高分候选实测;实测中发现远逊于当前最优配置立即停止,调优时间可缩短至原来的 1/5~1/3。

具体案例:为 ResNet-50 的卷积算子调优,原本在 GPU 上需要约 10 小时的 Ansor 全量扫描;开启 early_stopping 与成本模型剪枝后约 2.5 小时完成,端到端推理延迟从 3.2ms 降到 2.8ms。

端侧 NPU 算子库开发

阶段:算子库开发与硬件适配阶段

解决的问题:为某款端侧 NPU 开发矩阵乘算子库时,搜索空间包含大量违反硬件约束的配置(如 tile 超过片上 SRAM 大小、对齐方式不合法)。直接全量搜索会浪费大量算力,且容易在调优过程中频繁触发编译失败。将硬件约束写成剪枝规则后,超限配置在生成阶段就被拦截;相似 tile 组合去重后仅保留代表性配置,搜索空间从 4 万降到 3 千。

具体案例:工程师把“tile 总字节数超过缓存容量则过滤”写入调优脚本,叠加相似配置去重,调优时间从 8 小时降到 40 分钟,最终算子性能达到手写汇编的 95%。

MLPerf 推理基准冲刺

阶段:推理性能基准测试与调优阶段

解决的问题:MLPerf 推理赛前时间预算固定(比如 12 小时),必须在截止前把模型调到最优。如果每轮配置都完整测量,轮数会被测量时间死死卡住;用提前终止配合剪枝,可以在同样的预算内跑更多轮次,显著提高找到好配置的概率。

具体案例:调优脚本中设置 early_stopping = 20 轮,并用“预估延迟超过最优 3 倍即终止当前测量”的规则拦截低效配置,12 小时内完成的调优轮数从 30 轮提升到 80 轮,模型在公开基准上的成绩因此提升了 8%。

Python 演示

python88 行
"""模拟TVM算子自动调优中的提前终止与配置剪枝"""import randomimport time  class Config:    """一个算子配置:tile尺寸与向量宽度"""    def __init__(self, tile, vec, latency):        self.tile = tile        self.vec = vec        self.latency = latency  # 真实延迟,单位us  PRUNE_K = 5   # 超过当前最优5倍的配置被剪枝EARLY_K = 3   # 测量中发现比最优慢3倍则提前终止  def measure(cfg, best_latency, use_early):    """模拟硬件测量,支持提前终止     真实硬件测量分多个采样点;这里用一次随机"早期样本"模拟    """    sample = cfg.latency * random.uniform(0.8, 1.3)    if use_early and sample > best_latency * EARLY_K:        time.sleep(0.0005)  # 提前终止:只付出少量测量开销        return None    time.sleep(0.002)       # 完整测量开销    return cfg.latency  def build_space():    """构造60个候选配置:6种tile x 5种向量宽度 x 2个变体"""    space = []    for tile in range(1, 7):        for vec in [1, 2, 4, 8, 16]:            for _ in range(2):                space.append(Config(tile, vec, random.uniform(15, 350)))    return space  def run_tuning(space, use_prune, use_early, rounds=50):    """调优循环:剪枝 -> 采样 -> 测量 -> 更新最优"""    best_cfg = None    best_latency = float("inf")    measured = 0    stopped = 0    pruned_hit = 0     for _ in range(rounds):        # 配置剪枝:只保留有希望的候选;最优解尚未出现时不剪        if use_prune and best_cfg is not None:            candidates = [c for c in space                          if c.latency <= best_latency * PRUNE_K]        else:            candidates = space        pruned_hit += len(space) - len(candidates)        if not candidates:            break         cfg = random.choice(candidates)        lat = measure(cfg, best_latency, use_early)        if lat is None:            stopped += 1            continue         measured += 1        if lat < best_latency:            best_cfg = cfg            best_latency = lat     return best_latency, measured, stopped, pruned_hit  def main():    random.seed(42)    space = build_space()     print("== 方案1:无剪枝、无提前终止 ==")    lat1, m1, _, _ = run_tuning(space, use_prune=False, use_early=False)    print(f"最优延迟 {lat1:6.1f} us  完整测量 {m1:3d} 次")     print("== 方案2:剪枝 + 提前终止 ==")    lat2, m2, s2, p2 = run_tuning(space, use_prune=True, use_early=True)    print(f"最优延迟 {lat2:6.1f} us  完整测量 {m2:3d} 次  早停 {s2} 次  剪枝过滤 {p2} 次")  if __name__ == "__main__":    main()
目的:用一个可运行的简化模型,直观对比“无策略”与“剪枝+提前终止”两种调优方式在测量次数和最终结果上的差异。
  1. class Config:定义一个算子配置的数据结构,包含 tile 尺寸、向量宽度和真实延迟。
  2. PRUNE_K = 5配置剪枝的倍率阈值,比当前最优慢 5 倍的候选直接被过滤。
  3. sample = cfg.latency * random.uniform(0.8, 1.3)模拟硬件测量早期采样到的部分性能,带随机噪声。
  4. if use_early and sample > best_latency * EARLY_K:提前终止的核心判断:早期样本比最优慢 3 倍就放弃。
  5. time.sleep(0.0005)提前终止时只付出少量测量开销,显著节约时间。
  6. candidates = [c for c in space if c.latency <= best_latency * PRUNE_K]配置剪枝:过滤掉明显低效的候选。
  7. lat = measure(cfg, best_latency, use_early)分阶段测量,返回 None 表示测量的配置被提前终止。
  8. if lat < best_latency:只有完整测量的数据才能更新最优记录,被终止的配置不计入。

常见误区

误区配置剪枝嘛,应该就是编译时把没用的代码删掉、减小二进制体积吧?就像编译器里的死代码消除那样。

正解这里的配置剪枝和编译器的死代码删除完全是两回事。它发生在“搜索空间”层面——在调优前或调优过程中,把不合适的算子参数组合从候选列表里移除,减少需要实测的配置数量。好比评论家根据菜单划掉不喜欢的菜系,而不是把厨房里没用的厨具扔掉。两者都叫“剪枝”,但对象和时机完全不同。

为何常见:“剪枝”在编译原理里本就是删除无用代码的术语,同一个词被沿用到调度搜索的语境中,初学者很容易把两个场景混为一谈。

误区提前终止就是给每个配置设一个超时上限,比如超过 5 秒就杀掉,防止某个配置卡死拖慢整体进度。

正解超时是“绝对时间红线”,防止单次测量无限卡住;提前终止是“相对比较判据”——根据当前配置已测得的性能与已知最优的差距,判断值不值得继续测。评论家放下盘子,不是因为“吃这道菜超过了 3 分钟”,而是因为“这味道明显比刚才那盘差太多”。前者保底不崩溃,后者真正省预算,两者互补但不可互相替代。

为何常见:两者最终都表现为“提早停止”,初学者容易用“超时”这个已有的操作系统概念去套新东西,忽略了“相对最优”这个关键差异。

误区把提前终止阈值从 3 倍调到 1.2 倍,剪枝阈值也调小,这样大部分配置都被早早淘汰,调优肯定又快又好。

正解阈值过小会误杀“前采样慢但整体不错”的配置。真实测量有噪声——温度波动、CPU 频率抖动、cache 状态都会让早期样本失真。评论家要是尝第一口觉得“不够惊艳”就把菜倒掉,很可能错过一盘需要慢慢品味的佳肴。工业实践中通常把提前终止阈值设在 1.5~10 倍,并配合多次采样取中位数来降低噪声影响。

为何常见:人们默认“测量是精确的”,忽略了硬件测量的随机波动,于是把“激进的早停”直接等同于“高效”,而没有考虑误杀风险。

误区配置剪枝既然能预测哪些配置差,那它砍掉的一定都是差的,真正的最优配置肯定会留在候选里。

正解剪枝本质上是一种“预测性过滤”,无论基于规则、相似度还是成本模型,都存在误删风险。成本模型预测准确率只有 80% 时,被删掉的那 20% 里就可能藏着最优配置。工程上的应对是“渐进式剪枝”:多轮迭代中逐步缩小范围,保留一部分不确定区域继续探索,而不是一次把候选砍死。

为何常见:看到“剪枝”这个词,容易联想到修剪花木那样精确的操作;实际上它是基于统计和预测的概率性取舍,误差是内生的。

面试题

Q1. 在自动调优中,“提前终止”的核心目的是什么?

单选题 · easy

  • A.减少单配置测量时间← 正确答案
  • B.减小编译器体积
  • C.扩大搜索空间范围
  • D.提高模型推理精度

答案:A。提前终止在测量过程中发现配置明显差于最优就停止,直接减少了差配置消耗的测量时间,省出的预算可以探索更多配置。B、C、D 都与提前终止的语义无关。

Q2. “配置剪枝”指的是以下哪项操作?

单选题 · easy

  • A.删除编译期无用代码
  • B.排除搜索空间低效候选← 正确答案
  • C.压缩配置文件的体积
  • D.减少神经网络的层数

答案:B。配置剪枝发生在搜索空间层面,目标是把明显低效的算子参数组合从候选列表中移除,减少实测次数。A 是编译原理里的死代码删除,C 是文件压缩,D 是模型结构压缩,都不是调度层面的剪枝。

Q3. 在调优循环中,成本模型的主要作用是什么?

单选题 · easy

  • A.预测性能以减少实测← 正确答案
  • B.直接生成部署代码
  • C.完全替代硬件测量
  • D.托管显存的分配任务

答案:A。成本模型根据历史测量数据学习打分,用来预测没测过的配置的性能,辅助剪枝和候选筛选,从而减少昂贵的真实测量。它不生成代码、不测硬件、也不管显存,只是“估分”。

Q4. 下列哪些属于提前终止的合理触发条件?

多选题 · mid

  • A.早采样本比最优慢四倍← 正确答案
  • B.成本模型给出极低分数← 正确答案
  • C.配置与最优完全相同
  • D.编译器输出告警信息

答案:AB。A 是测量阶段的相对比较判据,B 是模型层的预判式淘汰,二者都合理。C 虽然可以跳过,但它属于“重复配置去重”而非提前终止;D 编译器告警与配置性能优劣没有直接因果关系,不能作为终止依据。

Q5. 当前最优延迟为 50us,提前终止阈值 θ=3,某配置早期采样为 200us,应如何处理?

单选题 · mid

  • A.继续完整测量
  • B.立即终止此配置← 正确答案
  • C.调整阈值至 4 倍
  • D.重复采样三次再看

答案:B。200 / 50 = 4 > 3,已经超过终止阈值,继续测下去大概率还是浪费时间,立即终止是正确的止损动作。选 A 忽略了超出阈值的事实;C 是修改规则而非执行规则;D 在阈值已超时不必要。

Q6. 下列对提前终止与超时的关系描述正确的是?

单选题 · mid

  • A.超时相对,早停绝对
  • B.早停相对,超时绝对← 正确答案
  • C.两者都做相对比较
  • D.两者都用绝对上限

答案:B。提前终止是把当前配置的部分性能与“当前最优”做相对比较,超时则是一个固定的绝对时间上限。评论家放下盘子是因为“不如之前的好”,而不是“吃了 3 分钟到点”;防卡死靠超时,省预算靠早停。

Q7. 下列哪些做法能够有效减少自动调优总耗时?

多选题 · mid

  • A.成本模型过滤低分配置← 正确答案
  • B.测量差时立即终止← 正确答案
  • C.全量测量所有配置
  • D.相似配置去重再测← 正确答案

答案:ABD。A 是模型级剪枝,B 是测量级早停,D 是配置去重,三者都能减少实际完整测量的次数或时间。C 恰恰相反,全量测量会让总耗时更多,与调优加速的目标背道而驰。

Q8. 搜索空间有 256 个配置,剪枝率 50%,每个配置完整测量耗时 10ms,成本模型训练耗时 500ms,总调优耗时是多少?

单选题 · hard

  • A.2560ms
  • B.1780ms← 正确答案
  • C.1280ms
  • D.880ms

答案:B。剪枝后只需测量 256 × 50% = 128 个配置,测量耗时 128 × 10 = 1280ms,加上成本模型训练 500ms,总耗时 1280 + 500 = 1780ms。选 A 是没算剪枝,选 C 是漏加模型开销,选 D 把模型开销错算成测量时间。

Q9. 关于 Ansor/MetaSchedule 的进化搜索与剪枝,正确的说法包括?

多选题 · hard

  • A.成本模型淘汰低分候选← 正确答案
  • B.保留性能靠前的记录← 正确答案
  • C.完全随机且不加过滤
  • D.历史记录辅助剪枝← 正确答案

答案:ABD。Ansor 的进化搜索利用成本模型打分来淘汰低分候选,并在每轮迭代中保留表现靠前的配置作为下一轮进化的基础,同时综合历史测量记录做剪枝决策。C 描述的“完全随机”与进化搜索利用模型指导的本质相矛盾,因此错误。

Q10. 关于剪枝策略的评价,哪句表述最准确?

单选题 · extreme

  • A.全量测量一定比剪枝更可靠
  • B.大胆剪枝总能获得更快速度
  • C.剪枝是带误差的取舍需平衡← 正确答案
  • D.成本模型可做到百分百准确

答案:C。剪枝本质是基于预测的取舍,预测必然带有误差,因此需要在“减少测量”和“保留潜在最优”之间做平衡。A 绝对化,忽略了时间预算约束;B 忽略了误杀风险;D 不现实,成本模型只能逼近真实性能,无法做到百分百准确。