想象你经营着一家连锁饭店,把同一道红烧肉的菜谱发给了十家分店。结果发现:煤气灶的厨房要改火候,电磁炉的厨房要改油温,柴火灶的厨房连焯水的顺序都得变。深度学习编译器面临一模一样的困境——一个矩阵乘法算子,在英伟达 GPU、手机 NPU、自研 AI 芯片上跑,最优的执行参数完全不同,而且没有任何一个“万能菜谱”能覆盖所有厨房。 传统做法是请“手工优化大师”为每间厨房量身定制菜谱(手写算子库),但新硬件层出不穷,大师根本忙不过来。TVM 的解法是让编译器自己当厨师:AutoTVM 像一位守着老师傅菜谱框架反复试火候的学徒,Ansor 则像一位完全不受菜谱约束、从切配到出锅全程自由发挥的创意大厨,而 MetaSchedule 是统一管理所有厨房、所有菜系的那套标准化后厨体系。这篇文章,就是带你参观这三代“自动寻优大厨”是怎么工作的。
学会自动调优,你就能在模型部署时不再依赖手工算子库,用编译器自动为任意硬件榨出极致性能——这是 AI 编译器与推理优化工程师的核心竞争力。
目录
可视化演示
展示AutoTVM模板驱动参数搜索、Ansor自动搜索空间生成、以及不同调优方法在多种算子上的性能对比。
本节配有交互动效(进入视口后自动加载,约 3KB)。
'+_captions.autotvm+'
调优背景:为什么厨房里需要自动寻优
你的连锁饭店又开新店了,这次分店的厨房是一台从没见过的“分子料理机”。老菜谱上写着“油温七成热下锅”,可这台机器根本没有“油温”这个旋钮,只有“超声波功率”和“真空度”。深度学习世界正是如此:GPU、CPU、手机 NPU、自研 AI 芯片,每种硬件就像一种全新的厨房,而矩阵乘法、卷积这些算子就是必须端出来的招牌菜。
一个卷积算子在不同硬件上的性能差距可以高达几十倍,因为内存布局、缓存容量、向量指令宽度、核心数量都不同。传统的手工算子库(比如英伟达的 cuDNN)相当于请顶厨为高端厨房精心写菜谱,它们确实好,但只覆盖主流硬件。当你的模型要部署到一款新的边缘芯片时,没有现成菜谱可用,难道要派工程师去现场调几个月?
TVM 的思路是让编译器自己当“调菜师”:它把算子的计算逻辑和“怎么做”(调度)分开,再让搜索算法自动寻找最优做法。自动调优(Auto-tuning)的意义,就是让模型部署工程师从“手动试参数”的苦海中解放出来——你只需要告诉编译器目标硬件是什么,它自己会试出火候。
这就像给每家分店配了一位不知疲倦的学徒,他读得懂菜谱框架,也扛得住反复试错,唯一需要你做的,是给他一套统一的试菜流程。
AutoTVM 模板:守着菜谱框架反复试火候
AutoTVM 的“模板”(template),就是老师傅亲手写的菜谱框架。菜谱上写好了“先焯水、再炒糖色、最后收汁”这套固定流程,但“焯水几分钟、糖色炒到几分深、收汁的火开多大”这些位置留着空格。模板的意义在于:把调度的骨架固定下来,让人工经验注入进去,只留少量参数交给机器去搜。
在 TVM 里,开发者用调度(Schedule)描述算子的循环结构——循环怎么分块(tile)、哪一层做向量化(vectorize)、哪一层做并行(parallel)、哪一层展开(unroll)。AutoTVM 的模板就是通过配置变量(比如 sp.var)把其中几个关键数值“挖空”,所有可能的取值组合起来,就构成了搜索空间。模板越精细,搜索空间越小,但越依赖人的经验。
AutoTVM 的优化目标很单纯:找到让算子运行时间最短的一组参数。形式化地说,它要解决这样一个问题:
AutoTVM 的工作方式,就像学徒每天按菜谱框架做十遍红烧肉,每次只改一个空格——今天盐放 3 克,明天放 5 克,记录下来哪次客人吃得最快。它忠实地守着框架,效率高,但也注定被框架的天花板限制住。老师傅的菜谱再厉害,也写不出超出他想象力的做法。
- 最小值符号我们的目标是让括号里的耗时值尽可能小
- 参数组合c 代表一组具体的调度配置,比如分块大小设为 32、向量宽度设为 8
- 硬件耗时函数T(c) 表示把配置 c 放到真实硬件上跑一次需要多少微秒
搜索策略:大厨们的试菜智慧
有了菜谱框架,怎么快速试出好配方?AutoTVM 内置了好几位“试菜师傅”,各有各的招法。
模拟退火(Simulated Annealing)像一位谨慎的学徒:他先大胆地各种乱试(高温期),慢慢变得保守,只在当前最优方案附近微调(低温期)。它最聪明的地方在于——状态差的时候也愿意偶尔接受一个更差的方案,因为这能帮它从“局部好吃但远非最佳”的配方陷阱里爬出来。这在数学上有一个优雅的概率公式:
遗传算法(Genetic Algorithm)则是另一派:它同时养着 50 个候选配方,让表现好的互相“杂交”(交换参数),再随机“变异”(微调某个参数),一代代淘汰劣质方案。强化学习(Reinforcement Learning)请来了一位会总结经验的 AI 大厨,它根据历史搜索结果学习“哪些区域的参数大概率好吃”,从而跳过雷区。成本模型(Cost Model)则属于预言派:不做菜也能估算出某配方大约耗时多少,用机器学习(如 XGBoost)拟合“参数 → 耗时”的关系,先过滤掉明显不行的方案,减少真刀真枪的实测次数。
这些策略不是互相排斥的。AutoTVM 的 autotvm 模块允许你指定 sa、ga、xgb 等搜索器,也可以组合使用——先用成本模型粗筛,再用遗传算法精搜。选择哪种策略,取决于你的搜索空间有多大、实测一次有多贵、以及你愿意等多久。
- 性能差ΔE 是新方案与当前方案的耗时差,如果新方案更慢,ΔE 就是正数
- 温度参数T 是随时间下降的“冒险温度”,类比现实退火工艺中金属的冷却过程
- 指数衰减整体表示接受概率随 ΔE 增大而指数下降,随 T 减小而越来越保守
硬件实测:出锅试吃才算数
菜谱写得再漂亮,最终也得端到客人面前尝尝才知道好不好吃。TVM 自动调优里的“客人试吃”,就是让候选配置在真实硬件上真正跑一遍,测出实际耗时。这个环节叫硬件实测(measurement),它是整个搜索过程的最终裁判——成本模型说得天花乱坠,实测数据不认账。
但真实硬件像个情绪化的食客:今天的 GPU 可能因为散热降频变慢,后台程序抢占 CPU 导致计时抖动,甚至缓存里残留的数据都会让某次运行“虚假地快”。如果只测一次,你很可能被噪声骗了,选了一个靠运气跑出好成绩的配置。
处理办法很朴素:同一配置多跑几次,取最好的那次。我们相信,只有“状态最好”的那次实测才最接近硬件的真实上限:
实测虽准,但很贵——跑一个 kernel 需要毫秒到秒级,搜索空间动辄上万种配置,全测一遍可能要几天。所以 AutoTVM 会严格控制实测次数:先让成本模型过滤掉 90% 的明显劣等方案,再对幸存者做并行实测,并且随着搜索进行,相似配置的结果会自动缓存,避免重复测量。这就是厨房里的成本控制,让每次试菜都花在刀刃上。
- 单次实测值Ti(c) 是第 i 次运行配置 c 时硬件报出的耗时
- 取最小运算从 n 次测量结果里挑最小的一个,相当于只相信“手感最好”的那次
- 最终评估值T*(c) 是这个配置的最终评分,后续搜索策略都用它来比较优劣
Ansor 搜索:跳出菜谱的创意大厨
AutoTVM 的模板始终是“人写的框架”,框架一旦定死,最优解的天花板也就定了。老师傅无论如何也写不出“把焯水和炒糖色合并成一个步骤”这种反常识的做法——但 Ansor 能。
Ansor 是一套“无模板”的自动搜索方案。它不再接受人类提供的菜谱框架,而是从算子本身出发,自己设计做菜流程。具体分两步:第一步,根据计算图的算子结构生成一组“程序骨架”(sketch),比如循环嵌套长什么样、哪些层可以融合;第二步,为每个骨架随机采样出完整的程序——填上循环顺序、分块大小、向量化、并行化等所有细节,形成一个巨大的候选程序池。
接下来是进化搜索:每个候选程序如同一个“新菜配方”,Ansor 用成本模型快速预估耗时,筛出最有可能的几百个,再送去做真实硬件实测,让实测结果反过来指导进化方向。这个过程中,候选程序不限于任何模板,因此它能发现人类经验之外的优秀结构——比如把两层卷积的循环完全融合,或者采用一种反直觉的内存访问顺序。
进化搜索中,每个程序的“分数”是这样算的:
回看开头的比喻,Ansor 就像把老师傅的菜谱收起来,从食材的分子结构开始重新理解做菜的大厨。它往往能找到比 AutoTVM 更优的解,代价是搜索空间更大、调优时间更长。因此实际工程中,AutoTVM 和 Ansor 是互补的搭档,而不是替代关系。
- 实测耗时T(p) 是程序 p 在真实硬件上运行的耗时
- 复杂度惩罚C(p) 衡量程序结构的复杂程度,防止进化出“看起来快但难以维护”的怪物
- 权重系数λ 是调节惩罚力度的超参数
- 适应度函数整体取倒数,让耗时越短、结构越精简的程序获得越高分数
图级调度:整桌宴席的统筹艺术
前面讲的都是单道菜怎么做,但宴席上桌讲究的是整桌节奏。计算图级别的调度(graph-level scheduling),就相当于总厨统筹整场宴席:蒸蛋的同时顺便蒸包子,两样菜共用烤箱,葱姜蒜一次备好分给三个灶台——而不是盯着某一道菜的精雕细琢。
在深度学习模型里,计算图就是做菜依赖图:卷积的输出要喂给 BatchNorm,BatchNorm 的输出再喂给 ReLU。传统做法是每个算子独立执行,中间结果被写到显存,下一个算子再读回来。这一写一读,就是巨大的时间浪费。算子融合(operator fusion)把卷积、BatchNorm、ReLU 合并成一个 kernel,中间数据全程留在片上缓存里,不需要进出主存。
融合的收益可以这样直观理解:
除了算子融合,图级调度还做内存复用(让不再使用的中间张量的显存被后续算子重新利用)和执行顺序优化(优先执行被最多后续算子依赖的节点)。Ansor 在这方面更进一步,它支持把一个小型计算子图当作一个整体去搜索调度,而不是一个个孤立优化。要理解图级调度的价值,请记住一句来自总厨的忠告:让每道菜“单独最快”,不等于整桌宴席“最快上齐”。
- 分别执行耗时Top1 + Top2 是算子一和算子二各自独立运行的时间总和
- 数据搬运开销Ttransfer 是中间结果从显存写回再读入的时间,融合后这部分可省
- 融合后总耗时Tfused 是融合成单个 kernel 后的实际运行时间
MetaSchedule:统一的后厨管理体系
连锁饭店越开越多,每家分店的厨房设备不同、菜系不同,但老板需要一套统一的管理系统:不管是煤气灶还是分子料理机,不管是川菜师傅还是法餐厨师,都用同一套菜谱管理系统、试菜记录规范、以及上菜流程标准。TVM 的 MetaSchedule 就是这么一套“统一后厨管理体系”。
在 MetaSchedule 出现之前,AutoTVM 的模板调优和 Ansor 的自动搜索各有各的代码路径,硬件后端要分别适配,非常痛苦。MetaSchedule 把它们统一到一个框架里,背后是几个核心模块的分工协作——这就好比后厨管理系统的“台账”:
- SearchSpace(搜索空间):统一描述所有可能的调度方案,无论是模板挖出的空,还是 Ansor 生成的程序池
- SearchStrategy(搜索策略):调度搜索算法,如进化搜索、模拟退火,规则统一但可替换
- CostModel(成本模型):所有硬件共用的性能预测模型,新硬件也能快速冷启动
- Database(数据库):统一保存所有调优记录,模型中可以直接加载历史最优配置
这套框架最妙的设计是“底层调度指令抽象”:不管跑在 CUDA 还是自研 NPU 上,都通过一套统一的指令(比如 sch.fuse、sch.parallel、sch.vectorize)来描述如何变换循环。不同硬件后端只需实现这层抽象接口,上面的所有调优算法就全部通用——就像所有分店只要照同一套流程报账,总部就能统一核算。
从 AutoTVM 到 Ansor,再到 MetaSchedule,TVM 让自动调优从“某个算子的人工模板”进化成“整张计算图、所有硬件的统一自动优化”。对于 AI 编译器从业者来说,MetaSchedule 标志着自动调优从一门手艺变成了一套工程基础设施。未来的芯片公司做编译器适配,不再是每个算子手写优化几个月,而是写一套调度规则,剩下交给统一的调优框架自动完成。
AI 应用场景
手机美颜 App 的人脸分割模型部署
阶段:模型推理部署与算子优化
解决的问题:同一款人脸分割模型要跑在骁龙、天玑、麒麟三种手机芯片上,手工写 GPU/NPU 算子库成本极高,且每个新机型都要重写一遍。AutoTVM 用模板自动搜索让算法工程师在每款芯片上自动调出最优卷积参数,不需要为每个平台手写汇编级优化。
具体案例:某美颜 App 团队用 AutoTVM 在骁龙 8 Gen 2 上自动搜索卷积的 tile 与向量化参数,对比官方手工算子库提速 1.5 倍;再用 Ansor 自动生成融合算子,把归一化和激活函数并入卷积,内存带宽占用降低 30%,发热明显下降。
电商推荐系统的云端延迟优化
阶段:模型推理性能调优
解决的问题:推荐排序模型包含大量 Embedding 和 Transformer 结构,GPU 上算子间的数据搬运导致 P99 延迟偏高,直接影响用户点击率实验。传统 cuDNN 算子各自最优,但算子间的融合与调度无人统筹。
具体案例:某电商平台用 Ansor 对排序模型做子图级调度,自动搜索 LayerNorm 与 QKV 投影的融合方式,配合内存规划复用中间张量,最终 P99 延迟降低 40%,GPU 峰值内存占用减少 1.2 GB。
自动驾驶芯片的算子库快速适配
阶段:芯片软件栈开发
解决的问题:自研自动驾驶芯片流片后,配套算子库通常需要几十名工程师手工优化数月。MetaSchedule 统一框架把“写模板”变成“写统一调度规则”,一套规则适配所有算子和网络。
具体案例:一家芯片创业公司用 MetaSchedule 为自研 NPU 实现底层指令抽象后,一个月内完成了 ResNet、YOLO 等 8 个主流模型的自动调优部署,性能达到手工优化水平的 90% 以上,且后续新模型接入几乎零成本。
Python 演示
"""TVM 自动调优简化模拟:AutoTVM 模板搜索 vs Ansor 自由搜索"""import mathimport random def perf_model(params): """模拟真实硬件耗时:越接近全局最优(80,80,8),耗时越小""" tx, ty, vec = params cost = abs(tx - 80) * 0.05 + abs(ty - 80) * 0.05 + abs(vec - 8) * 0.5 cost += 6.0 * math.exp(-((tx - 32) ** 2 + (ty - 32) ** 2) / 200.0) return cost TEMPLATE = { 'tx': range(1, 65), 'ty': range(1, 65), 'vec': [1, 2, 4, 8, 16],} def autotvm_search(template, iters=3000): """AutoTVM:在模板限定的空间内随机爬山""" best = None best_cost = float('inf') for _ in range(iters): p = {k: random.choice(v) for k, v in template.items()} for _ in range(5): key = random.choice(list(p)) vals = list(template[key]) idx = vals.index(p[key]) idx = max(0, min(len(vals) - 1, idx + random.choice([-1, 1]))) q = dict(p) q[key] = vals[idx] if perf_model((q['tx'], q['ty'], q['vec'])) < perf_model((p['tx'], p['ty'], p['vec'])): p = q c = perf_model((p['tx'], p['ty'], p['vec'])) if c < best_cost: best_cost = c best = p return best, best_cost def ansor_search(iters=3000): """Ansor:不依赖模板,用进化搜索探索更大空间""" pop = [ {'tx': random.randint(1, 128), 'ty': random.randint(1, 128), 'vec': random.choice([1, 2, 4, 8, 16, 32])} for _ in range(50) ] for _ in range(iters // 50): pop.sort(key=lambda p: perf_model((p['tx'], p['ty'], p['vec']))) pop = pop[:25] while len(pop) < 50: parent = random.choice(pop[:10]) child = dict(parent) key = random.choice(list(child)) if key == 'vec': child[key] = random.choice([1, 2, 4, 8, 16, 32]) else: child[key] = max(1, min(128, child[key] + random.randint(-8, 8))) pop.append(child) best = pop[0] return best, perf_model((best['tx'], best['ty'], best['vec'])) if __name__ == '__main__': random.seed(42) a_best, a_cost = autotvm_search(TEMPLATE) s_best, s_cost = ansor_search() print('AutoTVM 模板搜索最佳:', a_best, '耗时', round(a_cost, 3)) print('Ansor 自由搜索最佳 :', s_best, '耗时', round(s_cost, 3))
cost += 6.0 * math.exp(-((tx - 32) ** 2 + (ty - 32) ** 2) / 200.0)在模板区内制造一个“局部最优陷阱”,让纯模板搜索容易陷进去p = {k: random.choice(v) for k, v in template.items()}从模板参数空间中随机采样一组配置,相当于随机选一个菜谱填空idx += random.choice([-1, 1])让参数在取值轴上走一小步,模拟在菜谱上微调一个配料if perf_model(...) < perf_model(...)爬山式贪心:只在变好时接受,保证每次迭代都不退步pop.sort(key=lambda p: perf_model((p['tx'], p['ty'], p['vec'])))进化搜索每轮按耗时排序,让劣质方案沉底pop[:25]只保留前 25 个“精英”个体,表现好的父本才有资格繁衍下一代child[key] = max(1, min(128, child[key] + random.randint(-8, 8)))变异操作在邻域内跳动,突破模板边界探索更大空间
常见误区
误区学了 Ansor 就够了,AutoTVM 是过时技术,新项目没必要再接触模板调优。
正解Ansor 的“无模板”优势也伴随着更大的搜索空间和更长的调优时间。对于常规算子,AutoTVM 的模板让搜索起点更聪明,几分钟就能出可用结果;而且 AutoTVM 的模板知识可以导入 MetaSchedule 作为初始解提速。两者是互补关系,就像创意大厨也会参考老师傅的底稿。
为何常见:Ansor 宣传强调“无需人工模板”,容易让人误以为它是完全取代性的升级,而非互补方案。
误区我在 A100 上调优好的卷积参数,部署到 V100 上应该也差不了多少吧?再说模型变一下尺寸也可以继续用。
正解调优结果严格绑定硬件型号、算子输入形状、甚至 TVM 编译版本。换芯片或改输入分辨率,最优 tile 与向量化参数都会变。生产上要按设备型号分别调优,保存成 record 数据库,部署时用 history_best 加载对应记录。
为何常见:人们习惯把“模型”看成自包含的实体,忽略了编译优化是模型与硬件之间的默契,换平台默契就失效。
误区搜索时反正要测时间,多测几次更准,把所有参数组合都测一遍最稳妥。
正解参数空间是组合爆炸的(tile、unroll、vectorize 组合轻松上亿),穷举不现实;且硬件噪声让穷举也不一定准。正确做法是成本模型粗筛 + 进化搜索聚焦 + 关键候选多次实测取最优,把宝贵的实测预算用在最有希望的方向上。
为何常见:直觉上“全测一遍最保险”,但忽略了搜索空间规模和测一次的时间成本完全不成比例。
误区Ansor 既然叫自动搜索,那它生成完程序直接就能用,应该不需要真机测量吧?
正解Ansor 的流程图里实测是不可或缺的一环——它先用成本模型把候选从几百万过滤到几百,再用真实硬件测量这几百个,用实测结果更新进化方向。没有真实耗时的反馈,进化搜索就像闭着眼睛调菜,永远无法知道哪道菜真的好吃。
为何常见:“自动生成”这个说法让人误以为答案直接在生成阶段确定,其实生成只是候选池,实测才是最终打分。
误区把计算图里每个算子分别用 AutoTVM 调优,整体性能肯定最优。
正解算子间还有数据搬运、内存分配、内核启动开销,单算子最优组合起来往往是次优的。图级调度(如算子融合、内存复用、执行顺序调整)能带来比单算子调优更大的收益,甚至改变算子边界后还要重新调优内核。
为何常见:TVM 教程多以单算子演示为主,容易让学习者忽略计算图这个更宏观的优化维度。
面试题
Q1. AutoTVM 的核心思路是什么?
- A.在人工模板空间内搜索最优调度← 正确答案
- B.每次编译都重新手写调度方案
- C.让编译器随机生成任何代码
- D.直接手工算子库跳过优化
答案:A。AutoTVM 的核心是“模板引导调优”:人类写好调度模板并留出参数空位,机器在参数空间里搜索最优组合。B 是 Ansor 的风格;C 过于绝对,AutoTVM 不随机生成整个程序;D 是传统手工算子的做法,与 AutoTVM 理念相反。
Q2. 在“后厨”比喻中,AutoTVM 的模板相当于什么?
- A.写清克数和火候的完整菜谱
- B.只写流程留白参数的菜谱框架← 正确答案
- C.客人试菜之后写下的反馈记录
- D.用来核算成本的电子收银台
答案:B。模板固定了调度的骨架(先做什么后做什么),但 tile 大小、向量化宽度等参数留空待搜索,像只写流程、不写具体克数的菜谱框架。A 说反了;C 是实测记录;D 与调度无关。
Q3. Ansor 相比 AutoTVM 的关键突破是什么?
- A.不再需要任何硬件的实测反馈
- B.自动生成搜索空间摆脱人工模板← 正确答案
- C.只能优化单算子不能做图级优化
- D.用固定模板约束全部搜索过程
答案:B。Ansor 从算子结构自动生成程序 sketch 和候选程序池,彻底摆脱人工模板,能搜索到模板外的更优结构。A 错误,Ansor 依然依赖硬件实测;C 错误,Ansor 支持子图级调度;D 是 AutoTVM 的特点。
Q4. 模拟退火中温度 T 的作用是什么?
- A.决定接受较差解的概率逐渐衰减← 正确答案
- B.控制硬件核心温度不能超上限
- C.标识数据搬运时的执行速率
- D.记录每个候选配置的实测温度
答案:A。模拟退火的接受概率 P = exp(-ΔE/T),T 高时接受差解概率大,利于全局探索;T 随着搜索递减,算法越来越保守,最终收敛到局部精修。B/C/D 都是把“温度”按字面理解的错误联想。
Q5. 硬件实测同一配置要多次测量并取最小值,原因是?
- A.取最小值可以放大测量中的噪声
- B.硬件运行时间抖动需要抗噪处理← 正确答案
- C.多次测量能缩短整体调优时长
- D.最小值等于理论计算的下界
答案:B。硬件受频率波动、缓存状态、后台任务影响,单次测量噪声大。多次测量取最小值,近似“无干扰”状态下的真实性能,是业界常用的抗噪处理。A 说反了;C 错误,多次测量增加时间;D 错误,最小值只是实测观测值,不是理论上界。
Q6. 算子融合主要解决什么问题?
- A.减少算子间数据搬运与启动开销← 正确答案
- B.把所有循环展开成单条指令
- C.让各算子独立使用独立内存块
- D.实现模型参数的自动量化压缩
答案:A。算子融合把多个算子合成一个 kernel,中间数据留在片上缓存,避免写回主存再读入,同时减少内核启动次数。B 是循环展开,C 与融合理念相反,D 是量化压缩,都与“融合”无关。
Q7. MetaSchedule 统一框架的核心价值是什么?
- A.把硬件全部替换成同一种设备
- B.统一搜索空间与数据库等接口← 正确答案
- C.将算子模板数量压缩到零个
- D.只支持 NVIDIA CUDA 一个后端
答案:B。MetaSchedule 的核心是统一抽象:SearchSpace、SearchStrategy、CostModel、Database 都有统一接口,模板调优和自动搜索共用一套基础设施,硬件后端只需实现底层指令抽象即可接入。A 不可能,C 说反(它仍保留模板入口),D 错误(它恰恰是多后端)。
Q8. AutoTVM 内置的搜索策略有哪些?
- A.模拟退火搜索策略← 正确答案
- B.遗传算法搜索策略← 正确答案
- C.成本模型预测引导← 正确答案
- D.一次性贪心生成方案
答案:ABC。AutoTVM 提供模拟退火(sa)、遗传算法(ga)、基于 XGBoost 成本模型(xgb)等搜索器,也支持组合使用。D 的“一次性贪心生成”不是 AutoTVM 的策略——搜索是一个反复迭代、采样—评估—反馈的过程。
Q9. Ansor 自动搜索的流程包括哪些环节?
- A.程序骨架 sketch 生成← 正确答案
- B.在搜索空间内随机采样← 正确答案
- C.进化搜索加成本模型筛选← 正确答案
- D.加载手写算子库替代搜索
答案:ABC。Ansor 流程是:从计算图生成程序 sketch → 在每个 sketch 内随机采样完整程序 → 用成本模型粗筛 → 进化搜索精修 → 少量真实硬件实测。D 是手工优化思路,与 Ansor 无关。
Q10. 关于 TVM 自动调优的正确说法有哪些?
- A.调优结果绑定硬件与输入形状← 正确答案
- B.Ansor 能找到模板外更优结构← 正确答案
- C.图级算子融合降低启动开销← 正确答案
- D.各后端无需实现调度接口即可用
答案:ABC。A 正确,调优记录通常按硬件和形状存储;B 正确,这是 Ansor 相对模板调优的核心突破;C 正确,融合减少内核启动次数和数据搬运。D 错误,硬件后端必须实现底层指令抽象接口,否则上层调度无法落地。