想象这样一个场景:你打算在全城几百万套房子里挑出一套性价比最高的,但你没有时间也没有精力把每套都住上一晚再决定。于是你请来一位房产估价师。他站在小区门口,看看地段、楼龄、面积、朝向,十几秒就能报出一个八九不离十的价格。虽然他的估价偶尔也会看走眼,但至少能帮你把选择范围从一百万套缩到一百套——剩下的,你亲自去实地看就好。 AI 编译器的自动调度(Schedule Search)面临的正是同样的问题。一个深度学习算子能在硬件上以成千上万种方式实现:循环怎么分块、线程怎么安排、向量怎么利用、访存怎么调整……这些调度决策排列组合起来,候选方案的数量动辄百万甚至上亿。每一种方案的真实性能,只有把它编译出来、放到目标硬件上真正跑一遍才能知道——一次就要几十毫秒到几秒。把整个搜索空间全部实测一遍,代价高到无法承受。 于是编译器请来了自己的“房产估价师”——Cost Model(成本模型)。它用少量真实测量数据训练而成,输入一个调度方案的特征,快速输出一个预估延迟,帮搜索算法把绝大多数候选先淘汰掉,只把最有希望的少数几个留给实测。更妙的是,这位估价师每接手一笔真实成交,都会立刻修正自己的判断——这就是“在线更新”。本篇文章我们就从估价师的视角,把 Cost Model 的建模方法、特征提取、训练策略,以及搜索精度与效率的平衡之道,一次讲透。

岗位关联

掌握 Cost Model 设计是深入 AI 编译器自动调度(Ansor / MetaSchedule)的必经之路,也是算子性能优化与编译优化工程师的核心竞争力。

目录
  1. 可视化演示
  2. 调度搜索背景:为什么需要一个“估价师”
  3. 特征提取之道:估价师在看什么
  4. 建模方法选择:估价师的经验如何沉淀
  5. 模型训练策略:每笔成交都让估价更准
  6. 搜索集成方式:估价师如何帮客户选房
  7. 精度效率平衡:估价快,也要估价准
  8. 工程实践落地:估价师事务所的运作
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示AI编译器中Cost Model的在线更新循环机制,以及渐进式搜索策略如何在精度与效率间取得平衡。

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

Cost Model在线更新循环 搜索阶段:用当前Cost Model评估候选调度方案 采样实测:对优质候选实际执行获取真实性能 增量更新:新数据反馈更新模型提升预测精度 search → measure → update → search 在线学习使模型持续适应新算子模式。

调度搜索背景:为什么需要一个“估价师”

你想在数百万套房子里挑出性价比最高的一间,却不可能把每套都住上一晚再决定——时间不允许,预算也受不了。此时你请来一位房产估价师,他不用进门,只在小区门口转一圈,看看地段、楼龄、户型,就能报出一个八九不离十的价格。你的选择范围瞬间从一百万缩到了一百套,剩下的再亲自实地体验。

AI 编译器里的调度搜索面对的局面一模一样。一个算子在硬件上的实现方式由一系列调度决策组成:循环怎么分块、线程怎么安排、向量怎么利用、访存顺序怎么调整。这些决策排列组合起来,候选方案的数量轻易就能达到百万甚至亿级。而“实地看房”对应的是把候选调度真正编译、加载到硬件上跑一遍测量延迟,一次就要花几十毫秒到几秒。把整个搜索空间全部实测一遍,代价高到无法接受。

于是编译器引入了 Cost Model:一个用少量实测数据训练出来的回归模型,输入一个调度方案的特征,输出预估延迟。它不追求绝对精确,只求把候选方案的优劣排序排得大体靠谱。搜索流程被拆成两阶段:先让 Cost Model 对所有候选粗筛一遍,挑出最有潜力的几十个;再把这几十个放到真实硬件上实测,选出最终冠军。搜索空间的规模可以用一个连乘公式描述:

如果把海选比作看全城房源,Cost Model 就是那位估价师,替你完成了 99% 的淘汰工作。真正需要“住进去”体验的,只有他郑重推荐给你的那几套。

∣S∣=∏i=1mci\displaystyle |\mathcal{S}| = \prod_{i=1}^{m} c_i
通俗说明:一个调度要经过 m 个决策环节,每个环节有 c_i 种选择,总候选数就是这些选择数相乘。哪怕每个环节只有 5 种选择、共 10 个环节,总组合数也高达 5^10 ≈ 976 万——这就是为什么不能全部实测。
  1. 搜索空间 \mathcal{S}所有合法调度方案的集合,相当于我们要从中挑出最优的那一批“房源”。
    S={s1,s2,…,sn}\mathcal{S} = \{ s_1, s_2, \ldots, s_n \}
  2. 环节下标 i第 i 个调度决策环节,如循环分块、并行、向量化,对应选房时的一个决策维度。
    i∈{1,2,…,m}i \in \{ 1, 2, \ldots, m \}
  3. 选项数 c_i第 i 个环节的可选方案个数,比如分块大小有 5 种选择。
    ci∈{2,3,5,…}c_i \in \{ 2, 3, 5, \ldots \}
  4. 连乘 \prod把所有环节的选择数依次相乘,得到所有组合方式的总数。
    ∏i=1mci=c1×c2×⋯×cm\prod_{i=1}^{m} c_i = c_1 \times c_2 \times \cdots \times c_m

特征提取之道:估价师在看什么

估价师在小区门口扫一眼,脑子里其实在飞快核对一套指标:位置在几环、面积多大、楼层高低、朝向好不好、装修新旧。这些看得见的线索决定了他报出的价格。如果只看“这房子挺大”一条,那他估价必翻车。

Cost Model 同样需要一组能够反映调度性能的“看房指标”,这就是特征提取。调度方案 p 会被编码成一个固定维度的向量 x:循环嵌套多深(串行与并行的层级结构)、tile 大小是多少、用了多少并行线程、向量化宽度是多少、数据复用和访存模式如何。除此之外,目标硬件的属性也很重要——核心数、缓存大小、内存带宽——同一个调度在不同的硬件上性能天差地别。

特征要进入模型,还得经过编码与归一化:离散的决策(比如“是否开启向量化”)转成 0/1 取值,连续的尺寸(线程数、分块大小)做对数变换和归一化,避免数值范围大的特征主导训练。特征维度 d 通常在几十到几百之间——太少则表达能力不足,太多则带来过拟合与训练开销。特征工程的质量,几乎决定了 Cost Model 的上限。

估价师的水平,一半来自他那双“会看”的眼睛。特征提取就是 Cost Model 的这双眼睛——看得准,后面再简单的模型也能给出靠谱的排序;看错了方向,再花哨的模型也是白搭。

x=ϕ(p)=[x1,x2,…,xd]⊤\displaystyle \mathbf{x} = \phi(p) = [x_1, x_2, \ldots, x_d]^\top
通俗说明:φ 是把调度方案“翻译”成数字向量的函数。估价师看房时打的每一项分,最后汇总成一张打分表,这张表就是喂给模型的输入。
  1. 特征函数 \phi从调度方案 p 中提取性能相关信息的映射,是估价师那套“看房打分规则”。
    ϕ:S→Rd\phi: \mathcal{S} \rightarrow \mathbb{R}^d
  2. 维度 d特征的总个数,相当于打分表上指标的条数,太少看不清、太多记不住。
    d∈N+d \in \mathbb{N}^+
  3. 第 i 维特征 x_i第 i 个指标的具体取值,如并行线程数取 4、分块大小取 32。
    xi=featurei(p)x_i = \text{feature}_i(p)
  4. 转置 \top把特征排成一列向量,方便与模型参数做矩阵运算。
    x⊤=[x1,x2,…,xd]\mathbf{x}^\top = [x_1, x_2, \ldots, x_d]

建模方法选择:估价师的经验如何沉淀

同一个估价师,不同阶段的本事不一样。入行第一年,他只懂几条粗线条:地段好就贵、面积大就贵,这是“线性经验”;干了十年,脑子里积累了上千笔成交,能做到一报一个准;再后来,他甚至能看出“这个户型结构虽然怪,但改造空间大”这种非线性规律。

Cost Model 的建模方法也走过类似的道路。最朴素的是线性回归:给每个特征配一个权重,预测延迟就是特征的加权和。它简单、训练快、可解释,但表达力有限——延迟与特征之间经常是复杂非线性关系。更强的方案是梯度提升树(GBDT):用一批决策树逐个修正前一轮的残差,对表格型特征非常友好,是 Ansor 等系统早期选用的主力模型。再进一步,可以用神经网络直接吃进结构化的程序表示,自动学习更深层的模式。

模型的选择本质是在表达力与代价之间做权衡。搜索早期数据只有几百条时,复杂模型容易过拟合,反而不如简单的线性模型或浅层 GBDT 稳;当实测数据积累到上千条,复杂模型才逐渐发挥优势。用公式表示 GBDT 的预测,它是一组树模型的加权求和:

选哪种模型,取决于你手头的数据量级和算力预算。手里只有几十笔成交,老练的“线性师傅”反而最可靠;数据攒够了,再请“学徒军团”(GBDT)和“神经网络大师”出马也不迟。

y^=∑t=1Tηtht(x)\displaystyle \hat{y} = \sum_{t=1}^{T} \eta_t h_t(\mathbf{x})
通俗说明:每一位“估算师学徒”(决策树 h_t)都专注于纠正前面同事留下的误差,最后把大家的判断按贡献加权加起来,就是最终报价。
  1. 决策树 h_t第 t 棵决策树,只看特征中的少数几个维度做划分,相当于一个经验片段的学徒。
    ht(x)∈Rh_t(\mathbf{x}) \in \mathbb{R}
  2. 权重 \eta_t第 t 棵树在最终报价中的占比,通常由学习率控制,防止单棵树说过头。
    ηt∈(0,1]\eta_t \in (0, 1]
  3. 累加 \sum把 T 棵树各自的修正量加起来,得到最终预测值。
    ∑t=1Tηtht(x)=η1h1(x)+⋯+ηThT(x)\sum_{t=1}^{T} \eta_t h_t(\mathbf{x}) = \eta_1 h_1(\mathbf{x}) + \cdots + \eta_T h_T(\mathbf{x})
  4. 树的数量 T模型容量。T 太大容易把历史成交背下来导致过拟合,T 太小则学不到位。
    T∈N+T \in \mathbb{N}^+

模型训练策略:每笔成交都让估价更准

估价师不是天生会估价的。他入行时也报错过无数次价格,只是每成交一套房子,他就会把“当初估价 vs 实际成交”这对数字记在心里,默默修正自己的判断。成交越多,报价越稳。

Cost Model 的训练过程一模一样。每实测一个候选调度,就得到一对数据:特征向量 x 与真实延迟 y。模型希望自己的预测 ŷ 尽量贴近 y,于是定义损失函数来衡量偏差。最常见的损失是均方误差(MSE):预测与实测之差的平方。训练就是不断调整模型参数,让这个损失变小。

这里的关键差异在于“在线”二字。传统的训练是攒齐一批数据再统一训练;而调度搜索中数据是一点一点“长”出来的——每搜一轮、实测一个候选,就多一条样本。如果等攒齐几千条再训练,搜索早就迷失了方向。所以 Ansor 等系统的做法是:每收集到一条新实测记录,就立刻做一次梯度下降更新模型参数,这就是在线更新:

不过,在线更新也有隐患:能进入实测环节的候选,都是模型自己挑出来的“优等生”。这就像估价师只看便宜片区的成交记录,对豪宅区完全没有概念。这种采样偏差是 Cost Model 训练中必须时刻警惕的问题。

wt+1=wt−η⋅∇w(yt−y^t)2\displaystyle \mathbf{w}_{t+1} = \mathbf{w}_t - \eta \cdot \nabla_{\mathbf{w}} \left( y_t - \hat{y}_t \right)^2
通俗说明:每来一笔真实成交,估价师就把“上次估价偏差”折算成一个修正步,沿着减小偏差的方向挪动自己的判断参数。一步一小步,越修越准。
  1. 当前参数 \mathbf{w}_t第 t 轮时模型内部的判断参数,相当于估价师此刻的经验状态。
    wt∈Rd\mathbf{w}_t \in \mathbb{R}^d
  2. 学习率 \eta每次修正的步长。太大一步跨过头,太小则几千笔成交也学不动。
    η∈(0,1)\eta \in (0, 1)
  3. 梯度 \nabla_{\mathbf{w}}损失函数对参数求导,指明“往哪个方向调、调多少能最快减小误差”。
    ∇wL=∂L∂w\nabla_{\mathbf{w}} \mathcal{L} = \frac{\partial \mathcal{L}}{\partial \mathbf{w}}
  4. 下标 t 与 t+1表示每收集一条新样本就更新一次参数,这是“在线”与“批量训练”的本质区别。
    wt+1←wt−η⋅gradientt\mathbf{w}_{t+1} \leftarrow \mathbf{w}_t - \eta \cdot \text{gradient}_t

搜索集成方式:估价师如何帮客户选房

估价师的使命不是亲自买房,而是给出建议:客户拿着他列出的“最值得一看”清单,亲自去实地看几套。如果估价师只推荐自己最有把握的,万一判断失误,客户就错过好房;如果他推荐一堆“看走眼也可能捡漏”的房子,客户又会累死。

搜索集成解决的就是这个问题:如何用 Cost Model 的预测指导搜索,让每一轮实测都花在刀刃上。基本流程是:对候选集合逐一用 Cost Model 打分排序,取出预测延迟最低的一批(Top-K)去实测;实测结果返回后,既用于更新模型,也用于下一步选点——形成“预测 → 实测 → 更新 → 再预测”的闭环。

纯粹的贪心“只挑预测最低的”容易陷入局部最优,因为模型对某些区域还不了解,预测可能严重低估或高估。更好的策略是把不确定性也纳入评分:候选的得分 = 预测值 − κ × 不确定性。预测低得分低,不确定性大也加分(因为值得探索)。这个思想就是“上置信界”(LCB)选点:

于是客户拿到的清单,既不是清一色“便宜得可疑”的房子,也不是天马行空的随机看房。每一套都有着落——要么是估价师很有把握的低价,要么是充满不确定性的潜在惊喜。

x∗=arg⁡min⁡x∈S(y^(x)−κ⋅σ(x))\displaystyle x^* = \arg\min_{x \in \mathcal{S}} \left( \hat{y}(x) - \kappa \cdot \sigma(x) \right)
通俗说明:客户最终去看的房子,不是“估价师最有把握便宜”的那套,而是“既可能便宜、又还没被看过、说不定有大惊喜”的那套。κ 是客户对惊喜的渴望程度。
  1. 预测延迟 \hat{y}(x)Cost Model 对候选 x 的估价,分越低越好。
    y^(x)∈R≥0\hat{y}(x) \in \mathbb{R}_{\geq 0}
  2. 不确定性 \sigma(x)模型对 x 的把握程度。实测样本越少、离已知样本越远,这个值越大。
    σ(x)≥0\sigma(x) \geq 0
  3. 探索系数 \kappa平衡“利用已知”与“探索未知”的旋钮,κ 越大越爱冒险。
    κ>0\kappa > 0
  4. arg min在全部候选中找出综合得分最低的那个,交给实测环节验证。
    x∗=the candidate with the smallest scorex^* = \text{the candidate with the smallest score}

精度效率平衡:估价快,也要估价准

估价师也有失手的时候。报得太急,他可能把一套实际很差的房子排在前面,客户实地跑一趟白费功夫;报得太慢,每套房都研究三天,客户早就不耐烦了。优秀的估价师懂得在速度与准确之间找平衡。

对 Cost Model 而言,“快”意味着评估成本低,可以让搜索覆盖更多候选;“准”意味着排序靠谱,实测名额不浪费。这里有个容易被忽略的关键点:搜索真正需要的不是“预测值精确”,而是“排序正确”。只要模型把快的方案排在慢的前面,哪怕所有预测值都系统性偏大或偏小,搜索依然能高效工作。

因此业界用排序类指标而非回归误差来衡量 Cost Model 的质量。Kendall Tau 系数是常用的一种:把候选两两配对,看预测排序与实测排序有多少对一致。τ = 1 表示完全一致,τ = 0 表示随机乱序。另一个实用指标是 Top-K 命中率:模型挑出的前 K 名里,有多大比例真的落在实测的前 K 名里。公式如下:

冷启动阶段实测样本少,τ 通常不高,这时就该多实测、少依赖预测;随着在线更新积累样本,τ 稳步上升,搜索就可以逐步加大预测的权重、减少实测预算。这就是精度与效率的动态平衡之道。

τ=P−QP+Q\displaystyle \tau = \frac{P - Q}{P + Q}
通俗说明:把所有房子两两“决斗”,预测说 A 比 B 便宜、实测也是——这就是一致对 P;预测说 A 便宜、实测却是 B 便宜——这是不一致对 Q。一致的多,τ 就高。
  1. 一致对 P预测排序与实测排序相同的候选对数量,比如预测快且实测也快的方案对。
    P=∣{(i,j):y^i<y^j∧yi<yj}∣P = |\{ (i,j) : \hat{y}_i < \hat{y}_j \land y_i < y_j \}|
  2. 不一致对 Q预测与实测结论相反的候选对数量,是误导搜索的“噪音”来源。
    Q=∣{(i,j):y^i<y^j∧yi>yj}∣Q = |\{ (i,j) : \hat{y}_i < \hat{y}_j \land y_i > y_j \}|
  3. 归一化分母 P+Q所有有比较结论的候选对总数,把 τ 压到 [-1, 1] 区间便于比较。
    τ∈[−1,1]\tau \in [-1, 1]
  4. τ 的语义τ 越接近 1,说明模型的相对判断越可信,搜索时就越敢信任预测。
    τ→1⇒排序质量越高\tau \to 1 \Rightarrow \text{排序质量越高}

工程实践落地:估价师事务所的运作

一个成熟的估价机构不只是靠一位估价师单打独斗。它有一套标准流程:客户要来,先查历史成交库;新成交录入系统,全员共享;多组估价师并行看房,互不干扰。这些工程细节,决定了估价效率的天花板。

调度搜索系统里的 Cost Model 同样需要工程化的支撑。第一,实测结果必须缓存:同一个调度方案不要重复实测,命中缓存直接查表,省下的时间都是实打实的搜索加速。第二,在线更新需要触发策略:每测一条就更新一次虽理想,但模型重训、特征重算都有代价,工程上通常攒够一个小批次(比如几十条)才触发一次增量更新,或达到一定轮次再重训。

第三,搜索要并行:多个 worker 同时评估不同候选手,模型更新后要能快速同步给大家,避免旧模型带偏新搜索。第四,跨任务复用:不同算子、不同输入形状之间的实测数据并非完全无关,把历史数据迁移到新任务的初始模型上,可以显著缓解冷启动。数据集的累积过程可以这样描述:

一位孤胆估价师再厉害,也敌不过一套运转良好的估价体系。Cost Model 的工程落地,就是要让“实测缓存、增量更新、并行评估、经验复用”各司其职,把在线更新从理念变成每天都能稳定运行的生产流程。

Dt+1=Dt∪{(xt,yt)}\displaystyle D_{t+1} = D_t \cup \left\{ \left( \mathbf{x}_t, y_t \right) \right\}
通俗说明:估价机构的成交记录库每完成一笔交易就多一条档案。这个档案库是全体估价师共同的“经验池”,越滚越厚,后来者站在前人的肩膀上,报得更准。
  1. 当前数据集 D_t第 t 轮搜集到的全部“特征-实测”记录,是模型的经验池。
    Dt={(x1,y1),…,(xt,yt)}D_t = \{ (\mathbf{x}_1, y_1), \ldots, (\mathbf{x}_t, y_t) \}
  2. 新样本 (\mathbf{x}_t, y_t)本轮新实测的候选特征与真实延迟,对应一笔新成交。
    xt∈Rd,yt∈R≥0\mathbf{x}_t \in \mathbb{R}^d, \quad y_t \in \mathbb{R}_{\geq 0}
  3. 并集 \cup把新记录追加进库中,经验池单调增长,模型训练数据随之扩充。
    Dt+1⊇DtD_{t+1} \supseteq D_t
  4. 下标 t → t+1一轮搜索的结束,就是下一轮搜索更聪明的开始,在线闭环由此形成。
    search(Dt)→Dt+1\text{search}(D_t) \rightarrow D_{t+1}

AI 应用场景

算子自动调优:把“全量实测”变成“粗筛 + 精测”

阶段:模型编译与算子代码生成阶段

解决的问题:一个算子的调度候选可达几十万,手工调优规则需要专家逐硬件编写且难以迁移;传统放全套实测代价是数天,AI 方式用 Cost Model 快速粗筛,把实测范围压缩到 Top-K,大幅节省时间。

具体案例:某推理团队要在新款 GPU 上部署 YOLOv8,搜索空间约 10^6 个调度候选。全量实测需要约 3 天;接入 Ansor 风格的 Cost Model 在线更新后,只实测前 200 个候选,3 小时即找到比手工 kernel 快 15% 的实现。

新硬件适配期:没有历史数据的冷启动

阶段:新芯片 / 加速器平台适配阶段

解决的问题:自研 NPU 或新架构 GPU 刚流片时没有任何性能数据,Cost Model 无法预训练;靠工程师手工调 kernel 周期长,且经验不可复用。

具体案例:某公司自研 NPU 适配团队采用“边搜边学”策略:启动时用少量随机实测初始化模型,之后每实测一个候选立即在线更新。适配 CycleMLP 推理任务从两周缩短到三天,实测样本随搜索自动积累成新硬件首个性能数据库。

云端推理服务:算子库持续进化

阶段:在线推理服务运行与优化阶段

解决的问题:线上流量变化导致算子热点转移,固定的 kernel 库随时间失去最优性,需要在不打断服务的前提下持续搜索更新。

具体案例:云厂商在推理集群上周期性触发后台调优任务,Cost Model 复用历史实测数据在线更新,当新的热点算子出现时立刻搜索最优 kernel,保持 P99 延迟稳定。

Python 演示

python80 行
import mathimport random  def true_latency(s):    # 真实硬件延迟, 模拟函数, 只有实测才能获得    t = 1.2    t += 0.6 * (s[0] - 4) / 60.0    t += 0.8 * (8 - s[1]) / 7.0    t += 0.3 * (s[2] - 8) / 120.0    t += 0.1 * math.cos(s[0] / 5.0)    return max(0.1, t)  def random_schedule(rng):    # 随机生成候选: [分块大小, 并行度, 向量宽度]    return [rng.choice([4, 8, 16, 32, 64]),            rng.choice([1, 2, 4, 8]),            rng.choice([8, 16, 32, 64, 128])]  class CostModel:    # 简易线性成本模型, 参数 w 与偏移 b     def __init__(self, dim=3):        self.w = [0.0] * dim        self.b = 0.0     def _feat(self, s):        # 特征归一化, 把三个维度的取值压到 0~1        return [s[0] / 64.0, s[1] / 8.0, s[2] / 128.0]     def predict(self, s):        x = self._feat(s)        return sum(wi * xi for wi, xi in zip(self.w, x)) + self.b     def update(self, s, y, lr=0.1):        # 在线更新: 一条新实测样本做一次梯度下降        x = self._feat(s)        pred = sum(wi * xi for wi, xi in zip(self.w, x)) + self.b        err = pred - y        for i in range(len(self.w)):            self.w[i] -= lr * err * x[i]        self.b -= lr * err  def model_guided_search(pool, model, rounds):    # 用成本模型选点, 实测后立刻在线更新    best = float("inf")    for _ in range(rounds):        cand = min(pool, key=model.predict)        lat = true_latency(cand)        best = min(best, lat)        model.update(cand, lat)        pool.remove(cand)    return best  def random_search(pool, rounds):    # 随机抽样实测, 作为对照基线    best = float("inf")    for cand in pool[:rounds]:        best = min(best, true_latency(cand))    return best  def main():    rng = random.Random(42)    pool_a = [random_schedule(rng) for _ in range(300)]    pool_b = list(pool_a)    model = CostModel()    best_model = model_guided_search(pool_a, model, 30)    best_random = random_search(pool_b, 30)    print("cost model best:", round(best_model, 4))    print("random     best:", round(best_random, 4))    print("improvement:", round((best_random - best_model) / best_random * 100, 1), "%")  if __name__ == "__main__":    main()
目的:用 30 次实测预算,对比“Cost Model 引导搜索 + 在线更新”与“纯随机实测”谁找到的调度延迟更低。
  1. def true_latency(s):模拟“在真实硬件上跑一遍”得到的延迟,搜索中只有它算数,模型永远看不到它的内部逻辑。
  2. rng.choice([4, 8, 16, 32, 64])随机生成候选的一个特征维度:分块大小,特征提取的原始素材。
  3. class CostModel:定义一个朴素线性模型:每个特征配一个权重 w,加一个偏移 b。
  4. x = self._feat(s)特征归一化:把不同量纲的特征压到 0~1,避免大数值特征主导梯度更新。
  5. return sum(wi * xi for wi, xi in zip(self.w, x)) + self.b预测公式,即线性回归的 ŷ = wᵀx + b。
  6. def update(self, s, y, lr=0.1):在线更新核心:拿一条实测样本,计算预测与真实值的误差 err。
  7. self.w[i] -= lr * err * x[i]梯度下降修正权重:误差越大、对应特征越突出,该权重被修正得越多。
  8. cand = min(pool, key=model.predict)搜索算法把“预测延迟最低”的候选挑出来实测,相当于估价师推荐的“最值得看”的房子。
  9. lat = true_latency(cand)真正在“硬件”上测量一次延迟,得到一条带标签的训练样本。
  10. model.update(cand, lat)立刻把新样本喂给模型做一次梯度下降,这就是逐样本的在线更新。
  11. pool.remove(cand)已实测候选移出待选池,避免重复评估,对应实测缓存与去重。

常见误区

误区我觉得 Cost Model 就是用来预测延迟的,所以预测误差越小越好,最好跟实测一模一样才算合格。

正解搜索真正依赖的是“相对排序”。只要模型把快的方案排在慢的前面,哪怕所有预测值都系统性偏高或偏低,搜索依然能高效工作;反之,排序一乱,误差再小也会把搜索带偏。就像估价师不必报出精确房价,只要能判断哪几套相对便宜,就能帮客户缩小看房范围。

为何常见:人们习惯用回归任务“预测值要准”的直觉来套成本模型,忽略了它在搜索中真正扮演的是排序器角色。

误区训练好 Cost Model 之后,就可以一直用它跑完整个搜索,中间不用再管了。

正解搜索初期只有几条样本,模型充满猜测;随着实测数据积累,必须在线更新,预测才逐渐可靠。若不更新,模型会一直用旧眼光看待新候选,搜索会卡在错误区域。就像估价师不吸收新成交记录,就会停留在过时的房价行情上。

为何常见:传统机器学习是“训练→部署”两阶段,初学者容易把这种离线思维直接套到搜索场景。

误区在线更新嘛,就是每隔一阵子把所有历史数据拿出来重新训练一遍呗。

正解全量重训开销大,搜索每测一条就重训一次不现实。在线更新通常是在每条新样本上做一次小步梯度下降(或增量更新树结构),计算代价远小于全量重训。Ansor 等系统也是阶段性触发微调,而非每次全量训练。

为何常见:“在线”一词容易被理解为“定期批处理”,而忽略了“每来一条就更新一条”的本质含义。

误区既然要训练模型,那就把实测过的所有方案都塞给模型,样本越多肯定越准。

正解实测样本由搜索产生,天然偏向“模型认为好的区域”,这就是采样选择偏差。直接全部拿来训练,模型会对热门区域过拟合、其他区域仍一片空白。业界会采用多样化采样、去偏加权等方法,就像估价师如果只盯着便宜片区的成交,对贵片区就会完全没概念。

为何常见:只看到“数据驱动”的表象,忽略了数据生成过程本身的偏斜。

面试题

Q1. Cost Model 在自动调度中的核心作用是什么?

单选题 · easy

  • A.直接生成最优的调度方案并输出
  • B.快速预估性能以避免全部实测← 正确答案
  • C.代替编译器直接执行目标代码
  • D.专门负责收集整理性能数据

答案:B。Cost Model 不直接生成调度方案,也不替代编译器执行,它像一位估价师,只负责快速报价帮客户缩小看房范围。核心价值是用低成本预测替代高成本实测,把有限的实测预算留给最有希望的候选。

Q2. 调度搜索空间的总规模由什么决定?

单选题 · easy

  • A.各调度决策环节的选项数乘积← 正确答案
  • B.训练数据集中样本的实际数量
  • C.特征向量包含的特征总个数
  • D.目标硬件核心数的多少规模

答案:A。每个调度决策环节有 c_i 种选择,m 个环节组合起来就是连乘 Πc_i,这是候选方案的总数。硬件核心数、数据量、特征维度都只是影响模型或搜索的间接因素,不直接决定候选方案有多少种。

Q3. 下列关于在线更新触发时机的说法正确的有?

多选题 · mid

  • A.每实测一条新样本后就更新一次← 正确答案
  • B.攒够小批次样本后触发增量更新← 正确答案
  • C.只在搜索刚开始前更新一次即可
  • D.搜索全程完全不需要更新模型

答案:AB。在线更新强调“随到随学”:逐样本更新和小批次增量更新都是工程上合理的策略。只在开始时更新和全程不更新都违背了在线闭环思想——就像估价师拒绝吸收新成交记录,报价必然越来越偏离行情。

Q4. 在线梯度下降更新的是模型中的什么量?

单选题 · mid

  • A.损失函数对模型参数的梯度← 正确答案
  • B.损失函数对模型输出的梯度
  • C.特征向量对样本标签的梯度
  • D.搜索空间对实测开销的梯度

答案:A。我们需要知道“参数往哪个方向调能让损失变小”,所以要计算损失对参数(权重 w 和偏移 b)的梯度。对输出的梯度不能直接指导参数调整,特征对标签的梯度在监督学习中并不存在。

Q5. 以下哪些属于 Cost Model 常用的调度特征?

多选题 · mid

  • A.循环嵌套层数与分块的大小← 正确答案
  • B.并行线程数与向量化的宽度← 正确答案
  • C.论坛用户头像与昵称的特征
  • D.数据访存方式与复用距离← 正确答案

答案:ABD。循环结构、分块大小、线程数、向量化宽度、访存方式都是经典的调度特征,它们决定了性能表现;用户头像与昵称与算子性能毫无关系。特征工程决定了 Cost Model 这双“眼睛”能否看清候选调度的本质。

Q6. 为什么搜索更看重排序质量而非绝对预测误差?

单选题 · mid

  • A.搜索只依赖候选之间的相对优劣← 正确答案
  • B.因为绝对误差通常无法被计算
  • C.因为排序不需要对特征做归一化
  • D.因为硬件噪声不会影响相对排序

答案:A。搜索每轮只挑出“最值得实测”的少数候选,模型预测值只要保持一致的偏差,就不影响候选之间的先后顺序。因此业内用 Kendall Tau、Top-K 命中率等排序指标评估模型质量。

Q7. 选点公式 ŷ(x) − κσ(x) 中,探索系数 κ 变大会导致什么?

单选题 · hard

  • A.更偏好高不确定性的未知区域← 正确答案
  • B.更偏好预测得分最低的候选
  • C.直接让模型的训练速度成倍加快
  • D.让搜索空间范围变得更大更广

答案:A。κ 越大,不确定性 σ(x) 在综合得分中的权重越高,搜索就越倾向探索模型不了解的区域,避免陷入局部最优。它不改变训练速度,也不改变搜索空间本身。

Q8. 在线更新 Cost Model 时需要注意哪些工程问题?

多选题 · hard

  • A.采样选择偏差让数据分布偏移← 正确答案
  • B.硬件实测噪声带来标签数据波动← 正确答案
  • C.缓存已实测候选避免重复评估← 正确答案
  • D.随机丢弃历史数据以控制存储

答案:ABC。模型只测自己偏爱的候选会造成数据分布偏移,硬件波动会污染标签,重复评估浪费实测预算,所以需要去偏、防噪、缓存去重。随机丢弃历史数据会让模型“失忆”,反而损害在线更新的效果。

Q9. 在 Cost Model 的训练中,实测得到的真实延迟扮演什么角色?

单选题 · easy

  • A.模型输入中的特征向量
  • B.监督学习中的目标标签← 正确答案
  • C.控制更新步伐的学习率
  • D.防止过拟合的正则化项

答案:B。真实延迟是模型学习的目标,即监督学习里的标签 y;特征向量是输入 x,学习率是训练超参数,正则项是防过拟合的手段。实测延迟之于 Cost Model,正如成交价之于估价师。

Q10. 冷启动阶段模型严重不准,最佳应对策略是什么?

单选题 · hard

  • A.增加实测并提高探索权重的策略← 正确答案
  • B.暂停搜索静候模型自我提准确
  • C.直接对全部候选做随机抽取实测
  • D.清空历史数据重新初始化模型库

答案:A。冷启动时样本少、模型不可靠,正确做法是增加实测、调大探索权重 κ,让模型尽快积累经验。暂停等待不会产生新数据,随机方案浪费预算,清空数据更是雪上加霜。