想象你是一家新餐厅的老板,请来一位天才主厨。主厨要研发招牌菜“矩阵红烧肉”,可他发现做这道菜的门道多得吓人:肉要切多大块?一次炒一份还是四份一起炒?备菜环节是一次备出十份的量还是边炒边备?厨房里两个灶台怎么分工?每一种选择都有好几种甚至几十种变化,把所有可能性组合起来,能排出几亿份不同的菜谱。如果让主厨把每份菜谱都试做一遍,他从天亮忙到天黑也试不完,餐厅早就倒闭了。 但聪明的玩法不是“全都试”,而是“聪明地试”。主厨先设计一份实验菜单——只把看起来合理的做法放进去,比如肉块大小限定在几种常见尺寸、灶台分工限定为两种主流模式;再把明显没道理的组合(比如肉块切得像米粒那么小)直接划掉。这份实验菜单,就是自动调优里的“调优空间”(Tuning Space):它划定了自动调优搜索最优调度时可探索的全部范围。空间设计得好不好,直接决定最终菜品的口感和找到好配方要花的时间——这正是自动调优成败的基石。

岗位关联

理解调优空间的设计与剪枝,是驾驭 TVM 自动调优的基石。它能帮你少走调优弯路、快速逼近硬件性能上限,是 AI 编译器与推理优化工程师必备的核心直觉。

目录
  1. 可视化演示
  2. 空间定义:主厨的实验菜单
  3. 核心构成:菜谱卡上的四个栏目
  4. 设计原则:菜单的取舍之道
  5. 剪枝策略:划掉不靠谱的做法
  6. 搜索效率:试菜快慢的隐形推手
  7. 工程实践:真实厨房里的菜单落地
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态展示调优空间笛卡尔积定义、核心参数维度(分块/展开/线程/共享内存)、静态规则剪枝提升搜索效率、以及覆盖率/冗余度/搜索成本三维评估四个核心视角。

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

空间定义:主厨的实验菜单

老板把一张空白菜单递给主厨,说:“把你认为值得尝试的做法都写下来,咱们照着菜单一道一道试。”主厨拿起笔,在“切肉尺寸”一栏写下 4、8、16 三档,在“一锅几份”一栏写下 1、2、4。这些栏目的所有取值组合排在一起,就是一张实验菜单。在自动调优的世界里,这张菜单有一个正式的名字——调优空间。

在 TVM 编译框架中,一个算子(比如卷积、矩阵乘法)的底层实现叫调度(Schedule)。调度回答了数据如何分块、循环如何变换、计算如何并行的全部细节。调优空间,就是所有可能调度方案的集合:自动调优器要做的,正是在成千上万份“菜谱卡”中,找到性能最好的那一张。

形式上,TVM 用模板(Template)描述算子的调度骨架,把分块大小、向量化宽度、展开因子、线程绑定等留作“旋钮”。每个旋钮的取值范围构成一个取值域,所有取值域的组合就构成调优空间:

这张实验菜单自带一句潜台词:“最优做法一定在这里面,我们要做的只是把它找出来。”如果菜单太小,好菜谱可能根本没被写进去;如果菜单太大,后面的试菜就会变成一场漫长的苦役。主厨在下笔的那一刻,就决定了整场调优的命运。

T={(x1,x2,…,xn)∣xi∈Di,  i=1,2,…,n}\displaystyle T = \{(x_1, x_2, \dots, x_n) \mid x_i \in D_i, \; i = 1, 2, \dots, n\}
这个式子把“实验菜单”精确化了:每一行是一份菜谱卡,n 个栏目各取一个合法值,组合起来就是一个候选调度。
  1. 配置元组$(x_1, x_2, \dots, x_n)$ 是一份完整的菜谱卡,记录 n 个调度旋钮的取值,例如“分块 16、向量化 4、展开 2、线程 4”。
    (x1,x2,…,xn)(x_1, x_2, \dots, x_n)
  2. 数值取值域$D_i$ 是第 i 个旋钮允许的取值范围,对应菜单某一栏里写下的候选清单,如 [1, 4, 8, 16]。
    xi∈Dix_i \in D_i
  3. 遍历全部组合空间 $T$ 由所有满足条件的元组构成,把每一栏的候选两两组合,得到的就是全部可选调度。

核心构成:菜谱卡上的四个栏目

实验菜单上有四栏,每一栏对应厨房里的一种决策。第一栏“肉块尺寸”决定一盘肉怎么切,对应调度中的分块系数(tile);第二栏“一锅几份”决定锅铲一次能翻动几块肉,对应向量化因子(vectorize);第三栏“备菜量”决定一次备好几份菜的原料,对应展开因子(unroll);第四栏“灶台分工”决定几位厨师怎么分活,对应线程绑定(bind)。

这四类参数,是 TVM 调度中最常见也最影响性能的旋钮。它们本质上是向硬件打招呼的方式:分块向缓存问好,向量化向 SIMD 单元(一条指令同时处理多份数据的硬件模块)问好,展开向指令流水线问好,线程绑定向多核处理器问好。调优空间的大小,由四栏候选数量共同决定。

若一个算子有 n 个旋钮,第 i 个旋钮有 $|D_i|$ 种取值,那么空间总大小就是所有候选数的连乘:

四个栏目像四把调节旋钮,拧动任意一个,都会成片地改变菜单的规模。主厨必须清楚每把旋钮的脾气:哪把最影响口感,哪把稍微一动就让试菜量翻倍——这正是后面设计原则与剪枝策略要解决的问题。

∣T∣=∣D1∣×∣D2∣×⋯×∣Dn∣=∏i=1n∣Di∣\displaystyle |T| = |D_1| \times |D_2| \times \cdots \times |D_n| = \prod_{i=1}^{n} |D_i|
空间大小是“连乘”出来的:每个旋钮哪怕只多两档,总体也可能膨胀好几倍——这就是自动调优里最著名的“组合爆炸”。
  1. 单维候选数$|D_i|$ 表示第 i 个旋钮的候选取值个数,比如分块系数有 [1, 4, 8, 16, 32] 共 5 档。
    ∣Di∣|D_i|
  2. 连乘运算$\prod_{i=1}^{n}$ 把所有维度乘起来。4 个旋钮各有 5 档,空间就是 $5 \times 5 \times 5 \times 5 = 625$。
    ∏i=1n∣Di∣\prod_{i=1}^{n} |D_i|
  3. 组合爆炸旋钮数 n 每增加一个,空间就乘以一个新维度的大小,空间增长速度远超我们的直觉。

设计原则:菜单的取舍之道

主厨重新审视实验菜单,发现它还有改进空间:有些栏目档位太细,每档之间做出来的菜几乎没差别;有些栏目又漏了关键档位。好菜单有个朴素的道理——“该有的都有,不该有的别放”,落到工程上就是四条设计原则。

一是覆盖充分:最优配置必须落在空间内,否则搜索算法再强也找不到它;二是空间可控:空间数量级要控制在调优预算允许的范围内;三是粒度平衡:旋钮的步长不能太粗(漏掉好点)也不能太细(膨胀空间);四是任务适配:计算密集型和访存密集型算子需要不同的空间侧重。

这四条原则其实是同一个权衡的不同侧面:空间越满,性能上限越高;空间越大,搜索成本越高。可以把“空间效用”写成:

设计原则不是死板的教条,而是主厨权衡的艺术。菜单做厚,上限更高但要花更多时间试菜;做薄,省时间却可能永远够不到最高水平。聪明的做法,是把这份权衡留给“剪枝”和“搜索”接力完成。

max⁡T  U(T)=Pmax⁡(T)−λ⋅log⁡2∣T∣\displaystyle \max_{T} \; U(T) = P_{\max}(T) - \lambda \cdot \log_2 |T|
式子左边说“性能越好,空间加分越多”;右边说“空间越大,成本惩罚越重”。λ 是权衡系数:调优时间预算越紧张,λ 就要调得越大。
  1. 最优性能$P_{\max}(T)$ 表示在这个空间里能搜索到的最好性能,覆盖越充分,这个值越接近全局最优。
    Pmax⁡(T)P_{\max}(T)
  2. 空间惩罚$\log_2 |T|$ 把空间大小映射到搜索成本——空间每翻一倍,待探索的配置就多一倍,取对数让惩罚与“数量级”挂钩。
    log⁡2∣T∣\log_2 |T|
  3. 权衡系数$\lambda$ 体现调优时间预算的松紧,预算越紧 λ 越大,工程上通常通过小规模实验标定。
    λ\lambda

剪枝策略:划掉不靠谱的做法

主厨终于提笔修改菜单。他划掉了“肉块切成米粒大小”——夹都夹不起来;又划掉“一个灶台同时炒四十份”——锅根本盛不下。这些被划掉的做法,就是调优空间里被剪掉的配置。剪枝(Pruning)的核心思想,是把“必不可能好”的配置提前排除。

剪枝与空间设计是配套动作:设计决定“写哪些栏目”,剪枝决定“划掉哪些行”。工程上有四种主流手段。约束过滤:硬性合法性检查,如分块大小必须能被向量化宽度整除;启发式规则:基于经验的软规则,如小分块配大展开通常没有收益;结构性剪枝:在模板层级排除整类无意义的变换顺序;层级限制:控制变换嵌套的深度。

形式化地,剪枝后的空间可以写成:

剪枝不是碰运气丢骰子,而是有依据的定向排除。划掉米粒肉块不会损失任何好菜,因为好菜谱从来不需要米粒肉块。剪得好,菜单变薄了,招牌菜反而更容易被找到。

T′={c∣c∈T,  Φ(c)=true}\displaystyle T' = \{c \mid c \in T, \; \Phi(c) = \mathrm{true}\}
$\Phi$ 是一组“保留条件”。同时满足所有硬约束和启发式规则的配置 c,才能留在精简后的空间里,进入真正的搜索阶段。
  1. 剪枝后空间$T'$ 是经过剪枝的实际搜索空间,通常比原始空间小一个数量级以上。
    T′T'
  2. 保留条件$\Phi(c) = \mathrm{true}$ 表示配置 c 通过合法性检查与启发式规则,例如整除约束、线程上限、经验阈值。
    Φ(c)=true\Phi(c) = \mathrm{true}
  3. 逐行筛选$\{c \mid c \in T, \dots\}$ 表示从原始空间 T 中逐个取出配置,只保留满足条件的行,构成新的子集。
    {c∣c∈T,… }\{c \mid c \in T, \dots\}

搜索效率:试菜快慢的隐形推手

菜单定稿后,试菜工作正式开始。助理每天上午按菜单试做几道、下午记录味道,主厨再根据结果调整后续试菜顺序。他们很快发现:菜单越薄,找到最佳菜谱越快;菜单越厚,试了半天还在第一页打转。这正是调优空间对搜索效率最直接的影响。

空间大小决定了采样密度和收敛速度:空间小,搜索器能在有限试验次数里把每个区域都摸一遍,快速锁定最优区域;空间大,采样点如大海捞针,收敛曲线迟迟走平。除空间规模外,TVM 还会用代价模型(用预测代替真实测量的性能预估器)来减少实际试菜次数。

搜索总时间由试验次数与单次评估耗时共同决定。设精简后需要试验 $N_{\mathrm{trial}}$ 次,每次评估耗时 $t_{\mathrm{eval}}$,则:

调优空间像一个漏斗的入口:入口太宽,沙子全漏下去要等很久;入口适度收紧,沙子才能集中且快速地流到目标位置。搜索算法再聪明,也绕不开空间设计这道前置关卡。

ttotal=Ntrial×teval\displaystyle t_{\mathrm{total}} = N_{\mathrm{trial}} \times t_{\mathrm{eval}}
剪枝直接缩小 $N_{\mathrm{trial}}$,代价模型压缩 $t_{\mathrm{eval}}$,双管齐下,搜索效率就能大幅提升。
  1. 试验次数$N_{\mathrm{trial}}$ 是搜索器实际评估的配置数量,空间越大,需要试验的次数通常越多。
    NtrialN_{\mathrm{trial}}
  2. 单次评估耗时$t_{\mathrm{eval}}$ 是编译并运行一个配置平均花的时间,包含编译开销与运行开销,代价模型能显著压低它。
    tevalt_{\mathrm{eval}}
  3. 总时间$t_{\mathrm{total}}$ 是两者的乘积。空间设计得越小、预估越准,总数就越低;这也是“调优时间预算”的数学来源。
    ttotal=Ntrial×tevalt_{\mathrm{total}} = N_{\mathrm{trial}} \times t_{\mathrm{eval}}

工程实践:真实厨房里的菜单落地

回到真实厨房。餐厅的招牌菜是“三乘三爆炒卷积”和“矩阵红烧肉”(对应 3×3 卷积与矩阵乘法 GEMM),厨房里没有魔法,只有一套套落地的实验菜单。在 TVM 实践中,调优空间通过模板代码定义。

以卷积算子为例,模板在空间维度(H/W)与通道维度(C)分别定义分块旋钮,再叠加向量化、展开、线程绑定等选项;矩阵乘法则在 M、N、K 三个轴各设分块旋钮。模板里用类似 cfg.define_knob("tile_x", [1, 4, 8, 16]) 的语句声明每个旋钮的取值范围,范围和步长就是设计决策本身。

空间设计完成后,效果靠两个指标评估:调优耗时(找到最优配置的时间),以及性能加速比。加速比定义为基线实现耗时与调优后最优实现耗时的比值:

从空白菜单到量产菜品,调优空间贯穿自动调优的始终。设计得好,主厨和团队能少熬夜;设计得差,再强的搜索算法也救不回来——这正是“调优空间决定调优上限”在真实工程里的含义。

Speedup=tbaselinetbest\displaystyle \text{Speedup} = \frac{t_{\mathrm{baseline}}}{t_{\mathrm{best}}}
例如基线 CUDA 实现耗时 2 ms,调优后最优调度耗时 0.8 ms,加速比就是 2.5 倍。工程上常用加速比曲线观察“调了多久、值不值得”。
  1. 基线耗时$t_{\mathrm{baseline}}$ 是没做自动调优时的参考实现耗时,常见基线是朴素实现或厂商库默认配置。
    tbaselinet_{\mathrm{baseline}}
  2. 最优调度耗时$t_{\mathrm{best}}$ 是自动调优搜索到的最佳配置的实测耗时,空间覆盖越充分,它越接近理论下限。
    tbestt_{\mathrm{best}}
  3. 加速比含义$\text{Speedup}$ 大于 1 说明调优有效,工程上以真实硬件测量为准,避免只用代价模型估计。
    Speedup=tbaselinetbest\text{Speedup} = \frac{t_{\mathrm{baseline}}}{t_{\mathrm{best}}}

AI 应用场景

云端推理服务上线前的算子加速

阶段:模型部署与推理优化

解决的问题:传统做法依赖工程师手工编写 CUDA kernel 或调用厂商算子库,一旦更换 GPU 型号或输入尺寸,性能又回落到基线水平。AutoTVM 通过设计贴合硬件与算子的调优空间,自动搜索高性能调度,把硬件潜力榨出来。

具体案例:某视频分析团队将 YOLOv5 部署到 A100 集群前,对 Conv2d、GEMM 等 20 余个算子分别设计调优空间,设置每个算子的调优预算为 30 分钟。经过 6 小时批量调优,整体推理延迟降低 42%,且后续换卡只需重新跑一遍调优流水线。

移动端跨芯片平台的快速适配

阶段:端侧模型迁移与编译

解决的问题:同一模型在骁龙 CPU、Mali GPU 与自研 NPU 上,最优调度完全不同,手写优化无法覆盖每种芯片。为每类硬件设计针对性调优空间,成为端侧部署的标准动作。

具体案例:手机端人脸检测模型在更换 SoC 后,工程师沿用模板,但把分块与向量化取值域按新芯片的缓存行大小重新界定,剪枝规则加入新硬件的线程上限。15 分钟即完成搜索,推理时延从 38 ms 降到 21 ms。

数据中心批量算子库建设

阶段:AI Infra 算子库建设

解决的问题:业务团队维护数百个算子,逐个手工优化不现实。以模板自动生成每个算子的调优空间,配合代价模型离线批量调优,是规模化算子库的成熟路径。

具体案例:某云厂商在自研推理引擎中,为 300 多个算子自动生成调优空间,剪枝后平均每个算子空间缩减到原始的 15%,离线批量调优后 90% 的算子达到或超过厂商库性能。

Python 演示

python48 行
# -*- coding: utf-8 -*-"""用纯 Python 模拟 TVM 调优空间的构建与剪枝流程。"""import itertools  def build_full_space():    """每个调度参数的可选值做笛卡尔积, 构成完整调优空间。"""    tile_options   = [1, 4, 8, 16, 32]    vector_options = [1, 2, 4, 8]    unroll_options = [1, 2, 4]    thread_options = [1, 2, 4]    return list(itertools.product(tile_options, vector_options,                                  unroll_options, thread_options))  def is_valid(cfg):    """剪枝判断: 合法性硬约束 + 启发式规则。"""    tile, vec, unroll, thr = cfg    if tile % vec != 0:          # 分块必须能被向量化宽度整除        return False    if thr > 4:                  # 线程数不能超过硬件上限        return False    if unroll > tile:            # 展开因子不应超过分块大小        return False    return True  def cost_model(cfg):    """代价模型: 用解析公式预估配置的性能, 越小越好。"""    tile, vec, unroll, thr = cfg    return 100 + (8 - vec) * 10 + unroll * 2 - thr * 3 + tile * 0.5  def main():    full_space = build_full_space()    print("原始调优空间大小:", len(full_space))     pruned_space = [c for c in full_space if is_valid(c)]    ratio = 100 * (1 - len(pruned_space) / len(full_space))    print("剪枝后调优空间大小:", len(pruned_space))    print("剪枝比例: %.1f%%" % ratio)     best = min(pruned_space, key=cost_model)    print("最优配置:", best, "预估代价: %.2f" % cost_model(best))  if __name__ == "__main__":    main()
目的:用纯 Python 复现“定义调优空间 → 剪枝 → 代价模型搜索”的完整流程,直观看到剪枝对空间规模的压缩效果。
  1. tile_options = [1, 4, 8, 16, 32]定义“肉块尺寸”的候选档位,即分块系数的取值域。
  2. list(itertools.product(...))把所有旋钮的取值做笛卡尔积,生成完整调优空间。
  3. if tile % vec != 0:合法性剪枝:分块必须能被向量化宽度整除,否则配置无效。
  4. if unroll > tile:启发式规则:展开因子超过分块大小通常没有收益,直接排除。
  5. pruned_space = [c for c in full_space if is_valid(c)]用列表过滤实现剪枝,保留通过全部约束的配置。
  6. min(pruned_space, key=cost_model)模拟搜索:用代价模型给每个配置打分,找出预估最优的一个。

常见误区

误区自动调优嘛,当然要把能想到的参数都放进空间,多多益善。反正搜索算法很智能,空间大才能找到全局最优解,空间小了反而会漏掉好配置。

正解空间越大,搜索器需要采样的点就越多,收敛速度急剧下降。在有限调优预算内,大空间可能只探索到很小一部分,最终找到的配置还不如精心设计的小空间。设计调优空间的目标不是“最大”,而是“够用且高效”——就像实验菜单不该写成百科全书,而该把最可能好吃的菜放进去。

为何常见:人们直觉认为搜索范围越大越不容易漏掉最优解,却忽略了搜索成本随维度指数爆炸的现实约束。

误区剪枝就是把一部分配置去掉,万一最优解正好在被去掉的那部分里,不就亏大了?所以干脆保留所有组合,一个都不删。

正解合理的剪枝利用的是确定性约束和强启发式规则。例如“分块大小必须能被向量化宽度整除”这类硬约束,违反它的配置在硬件上根本无法高效执行,不可能是全局最优。剪枝排除的是“必不可能好”的配置,而不是“可能好”的配置。高质量剪枝反而让搜索更聚焦,提高找到最优的概率。

为何常见:把“剪枝”理解成随机丢弃一部分候选,而实际上剪枝是有依据的定向排除。

误区既然都是深度学习算子,用同一套模板和参数范围跑调优就可以,省得为每个算子单独设计空间,多省事。

正解不同算子的数据流特征差异巨大:卷积侧重空间维度的分块与缓存复用,矩阵乘法侧重 M/N/K 三轴的切分,注意力算子则敏感于序列长度维度的处理。套用同一空间的后果是:要么空间里大量配置对某个算子无意义,要么遗漏了该算子特有的关键参数。好的实践是对每个算子(或相似算子簇)单独设计调优空间。

为何常见:初学者多用主流的卷积例子入门,容易把卷积的空间设计经验泛化到所有算子上。

误区剪枝不就是检查一下整除性、线程数这些硬性条件吗?把不合法的配置去掉就完事了,没什么技术含量。

正解合法性检查只是剪枝的第一层。更有效的剪枝还包括启发式规则(例如小分块配大展开通常没有收益)、结构性剪枝(在模板层级排除整类无意义的变换顺序)、以及层级限制(控制并行嵌套的深度)。实践中,好的剪枝往往能砍掉 80% 以上的配置,而这四类手段缺一不可。

为何常见:因为教程里剪枝的入门例子通常从整除约束讲起,导致误以为剪枝只有合法性检查这一种形式。

面试题

Q1. 在 TVM 自动调优中,“调优空间”指的是什么?

单选题 · easy

  • A.自动调优时可探索的调度参数组合集合← 正确答案
  • B.编译器内置优化选项的固定列表集合
  • C.神经网络全部权重参数的取值集合空间
  • D.硬件设备上所有缓存与寄存器的地址集

答案:A。调优空间是所有可探索调度参数组合的集合,就像实验菜单里全部菜谱卡。B 是编译选项列表,C 是模型权重,D 是硬件资源,都和调度参数无关。

Q2. 调优空间设计得过大,最直接的后果是什么?

单选题 · easy

  • A.编译后生成的代码体积变得非常庞大
  • B.自动调优的搜索时间会急剧地变长← 正确答案
  • C.编译器语法检查阶段的速度明显下降
  • D.模型的推理精度出现显著下降问题

答案:B。空间越大,搜索器要采样的点越多,收敛越慢,直接表现就是调优时间变长。A、C、D 分别混淆了代码体积、语法检查和推理精度,与空间大小没有直接关系。

Q3. 在调度参数中,“分块系数”主要决定的是?

单选题 · mid

  • A.训练过程中每个批次样本数量的多少
  • B.数据切块后缓存复用的粒度大小值← 正确答案
  • C.神经网络中隐藏层数量的深浅程度度
  • D.权重矩阵进行稀疏化处理的比例值

答案:B。分块系数决定数据怎么切块、缓存怎么复用,对应“肉块切多大”。A 是训练批次,C 是网络结构,D 是稀疏化,都不属于调度参数。

Q4. 向量化因子不宜设置得过大,根本原因是?

单选题 · mid

  • A.会占用目标设备上过多的显存容量
  • B.硬件 SIMD 通道宽度存在上限约束← 正确答案
  • C.会导致训练数据发生过拟合的风险
  • D.会改变算子原本的数学计算结果性

答案:B。向量化宽度受硬件 SIMD 通道数限制,比如 128 位寄存器一次并行处理 4 个 32 位浮点数,设得再大也会被硬件截断甚至退化。A 是显存、C 是训练、D 是数值语义,均不相关。

Q5. 以下选项中,哪些属于 TVM 调度常用的可调参数?

多选题 · mid

  • A.循环展开因子与向量化的宽度← 正确答案
  • B.分块大小与线程的绑定方式← 正确答案
  • C.学习率与权重衰减的系数值
  • D.数据重排与缓存复用的策略← 正确答案

答案:ABD。A、B、D 都是 TVM 模板中常见的调度旋钮。C 的学习率与权重衰减属于训练超参,与调度(代码生成层面的变换)无关。这道题考的是“调优空间管什么”的边界感。

Q6. 对调优空间执行剪枝操作之后,正确说法是?

单选题 · hard

  • A.全局最优配置一定会被完整地保留
  • B.通过约束排除掉明显低效的配置集← 正确答案
  • C.剪枝后的空间大小和原来完全相同
  • D.剪枝只能借助深度学习模型来执行

答案:B。剪枝是用合法性约束和启发式规则排除“必不可能好”的配置,而不是随机丢弃。A 说得太绝对,错误剪枝仍可能误伤最优;C 与事实相反;D 说剪枝必须用深度学习模型,不对,常见剪枝用解析规则即可完成。

Q7. 某团队把 Conv2d 调优空间过度剪枝到只剩十个配置,最可能的结果是?

单选题 · extreme

  • A.调优时间大幅缩短但可能错失更优调度← 正确答案
  • B.调优时间大幅缩短且必定找到全局最优
  • C.编译器会因空间过小而无法生成目标代码
  • D.模型推理精度必定下降因为搜索不充分

答案:A。过度剪枝只保留经验上“可能最优”的配置,确实大幅缩短调优时间,但一旦真正的最优配置不在保留范围内,就会永远错过它。B 的“必定”、C 的“无法生成代码”、D 的“精度必定下降”都与实际不符。

Q8. 关于调优空间与搜索效率的关系,下列描述正确的有?

多选题 · hard

  • A.空间越小则采样覆盖越容易做到密集← 正确答案
  • B.空间越大则收敛速度通常表现得越慢← 正确答案
  • C.空间大小对搜索效率完全没有影响性
  • D.代价模型可以减少真实测量的次数值← 正确答案

答案:ABD。空间小则同样预算下采样更密、收敛更快;空间大则要探索的点多、收敛慢。代价模型用预测替代实测,减少测量次数,提升搜索效率。C 说空间大小对搜索效率毫无影响,明显错误。

Q9. 设计一个合理的调优空间时,应遵循的原则有哪些?

多选题 · mid

  • A.保证覆盖充分的优化可能性选项← 正确答案
  • B.空间大小保持在可控的范围之内← 正确答案
  • C.参数粒度越细密就一定越优秀
  • D.针对算子特性进行任务适配优化← 正确答案

答案:ABD。合理空间要求覆盖充分、大小可控、针对算子特性适配。C 说粒度越细越好,忽视了粒度变细会指数级膨胀空间,反而不利于搜索。此题考设计原则的平衡观。

Q10. 自动调优中“代价模型”的主要功能是什么?

单选题 · easy

  • A.替代真实测量快速预估配置的性能← 正确答案
  • B.把最优调度方案固化成硬件电路板
  • C.调整神经网络训练阶段的损失函数
  • D.监督编译器生成代码的正确性规范

答案:A。代价模型是一个“尝味预测员”,用解析模型或机器学习预测配置性能,替代昂贵的真实编译加运行测量,从而加速搜索。B、C、D 分别扯到硬件固化、训练损失和代码正确性,与代价模型无关。