想象一条开满甜品店的巷子。老张的蛋糕店生意火爆,但要命的是,每个顾客的胃口都不一样:王奶奶要一人份纸杯蛋糕,李叔叔要六层的婚礼蛋糕,刘太太只要无糖迷你款。老张的古老做法是一款款单独烘焙,常常折腾三天三夜,烤箱就没停过。直到他想通了一个道理——为什么不先烤一个超级大的万能蛋糕胚,顾客要几层切几层?从超大号到一口酥,全在这一胚里。 这个故事就是 Once-for-All(简称 OFA)的真实写照。AI 工程师面对的“顾客”是五花八门的硬件设备:手机、平板、车载芯片、云服务器……每个设备的算力、内存和延迟要求都不同。传统做法是每个设备单独设计并训练一个神经网络模型,耗时耗力。OFA 的思路和老张一样:先训练一个巨大的“超网”,再从这个超网中抽取各种大小的“子网”,一次训练,处处可用。 接下来,让我们跟着老张的烘焙手册,看看 OFA 是如何用“一次烘焙”解决“千般口味”的。

岗位关联

掌握 OFA 的“一次训练、多端复用”思想,你就能大幅降低深度学习模型在多设备部署中的工程成本——这是从“调参工程师”迈向“模型平台架构师”的核心能力。

目录
  1. 可视化演示
  2. 诞生背景
  3. 核心思想
  4. 超网设计
  5. 渐进式收缩
  6. 子网采样
  7. 知识蒸馏
  8. 部署应用
  9. 对比与效果
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示Once-for-All的核心机制,通过概览/流程/对比/趋势四种模式展示关键概念与交互流程。

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

Once-for-All:OFA核 OFA核心理念与多端部署 渐进式收缩训练策略 核心机制可视化 Once-for-All整体架构与关键组件

诞生背景

在繁华的甜品一条街,老张开了一家蛋糕店。每天都有顾客提出不同要求:王奶奶要一人份小蛋糕,李叔叔要五层大蛋糕,刘太太想要无糖迷你款……老张只能一次次从零开始烘焙,同一款蛋糕反复做不同尺寸,累得团团转。AI 工程师面对的场景几乎一模一样:同一个神经网络模型要部署到手机、平板、电脑、车载芯片等多种设备,每种设备的算力、内存、功耗都不同。

传统的做法是“点一次菜,烤一次蛋糕”:每部署一个新目标,就从头跑一遍神经架构搜索(NAS),再重新训练一个专用模型。NAS 搜索动辄消耗数十甚至上千 GPU 小时,训练又要几天。如果公司有 10 个部署目标,就得把这件事重复 10 遍,成本呈线性爆炸。

OFA(Once-for-All)正是为了解决这个痛点提出的:用一次训练的投资,换来来所有部署场景的模型,把“每家设备单独烤”变成“一胚多切”。它把传统 NAS 中“搜索 + 重训”的反复循环,压缩成一次性的超网训练。

Ctotal=N×(Csearch+Ctrain)\displaystyle C_{\mathrm{total}} = N \times (C_{\mathrm{search}} + C_{\mathrm{train}})

1. 单次搜索成本 \(C_{\mathrm{search}}\):每次用 NAS 在庞大的架构空间里搜索一个合适子网络,需要数千次评估,GPU 消耗巨大。

CsearchC_{\mathrm{search}}

2. 单次训练成本 \(C_{\mathrm{train}}\):架构确定后,还需要从零开始训练整个模型的参数。

CtrainC_{\mathrm{train}}

3. 部署目标数 \(N\):需要适配的手机型号、芯片平台、延迟档位的个数。

NN

4. 线性倍增关系:目标越多,总成本同比上涨,没有任何摊薄效应。

×\times

老张痛定思痛:与其一个个烤,不如一次烤一个巨大的、可以任意切分的蛋糕胚?这个念头,正是 OFA 的起点。

核心思想

老张终于想通了。他要做的是“万能千层蛋糕”:一次烘焙一个足够大的蛋糕胚,顾客要多少切多少,从 1 层到 6 层都能切出来,而且每块豆沙、每粒水果都提前分布均匀,切哪块都独立成形、口感依旧。

OFA 的核心思想与此完全一致:训练一个超网(SuperNet),超网中从“最浅最窄”到“最深最宽”蕴含了海量的子网络(SubNet)。部署时,只需从超网中“切出”满足当前硬件约束的那一个子网,把它的权重拷贝出来,即可直接上线推理,无需任何额外训练。

这里的魔法在于“权重共享”:子网并不是各自独立地拥有参数,而是从超网参数中切出一块来用——就像蛋糕胚里的奶油和水果本来就在那,切哪块都能吃到。OFA 发布的超网可以衍生出超过 \(10^{19}\) 种子网配置,覆盖从 20 MFLOPs 到 500 MFLOPs 的广阔算力区间。

Wsub(α)⊂Wsuper,∀α∈A\displaystyle W_{\mathrm{sub}}(\alpha) \subset W_{\mathrm{super}}, \qquad \forall \alpha \in \mathcal{A}

1. 超网参数 \(W_{\mathrm{super}}\):训练阶段维护的一份完整的、覆盖最大网络规模的参数集合。

WsuperW_{\mathrm{super}}

2. 子网参数 \(W_{\mathrm{sub}}(\alpha)\):配置为 \(\alpha\) 的子网络实际使用的参数切片,来自超网的某个子集。

Wsub(α)W_{\mathrm{sub}}(\alpha)

3. 包含关系 \(\subset\):表示子网参数“包含于”超网参数,而不是独立新建。

⊂\subset

4. 任意配置 \(\alpha\):只要 \(\alpha\) 落在合法配置空间 \(\mathcal{A}\) 内,都能从超网中切出对应权重。

∀α∈A\forall \alpha \in \mathcal{A}

这就是老张的“万能大蛋糕”——只要胚子够大够结实,想切哪块切哪块,块块都能吃,而且不用重新烤。

超网设计

万能蛋糕胚不是随便做的。老张得提前规划:蛋糕做多高(几层)、每层多宽、表面装饰颗粒多大——这些都必须预设好弹性空间,否则顾客要的时候无从下手。OFA 的超网设计同样围绕三个弹性维度展开。

第一个维度是弹性深度,即网络有多少层卷积。OFA 的超网从第 1 层到第 \(d_{\max}\) 层按序排列,部署时抽掉后面几层,就得到一个更浅的子网。第二个维度是弹性宽度,即每层有多少个通道。OFA 约定每层只取前 \(w\) 个通道,取多取少都能形成合法子网。第三个维度是弹性核大小,即卷积核是 \(3\times3\)、\(5\times5\) 还是 \(7\times7\),通过中心裁剪实现切换。

这三个维度的设计要保证一个关键性质:任何组合都能工作。子网不是一个静态网络里的“删除部分”,而是从超网的完整计算图中切出的一个连通的子图。这就像蛋糕胚里每层都均匀布满水果和奶油,无论怎么切,都能保证结构完整。

A={(d, w, k)∣d∈D,  w∈W,  k∈K}\displaystyle \mathcal{A} = \{(d,\, w,\, k) \mid d \in \mathcal{D},\; w \in \mathcal{W},\; k \in \mathcal{K}\}

1. 弹性深度集合 \(\mathcal{D}\):可选的网络层数,例如 \(\{2,3,4,5,6\}\)。

D={d1,d2,…,dmax⁡}\mathcal{D} = \{d_1, d_2, \ldots, d_{\max}\}

2. 弹性宽度集合 \(\mathcal{W}\):每层可选的通道数,例如 \(\{8,16,32,64\}\)。

W={w1,w2,…,wmax⁡}\mathcal{W} = \{w_1, w_2, \ldots, w_{\max}\}

3. 弹性核大小集合 \(\mathcal{K}\):卷积核尺寸的候选集合,例如 \(\{3,5,7\}\)。

K={3,5,7}\mathcal{K} = \{3, 5, 7\}

4. 笛卡尔积组合:三个维度任意组合,共同定义一个具体的子网配置。

×\times

有了可伸缩的设计图纸,老张的蛋糕胚才能根据顾客“切哪儿、切多少”游刃有余——这就是超网设计的核心价值。

渐进式收缩

如果老张一开始就按最笨的 1 层小蛋糕的做法反复训练,那和以前没区别。他的秘诀是“先大后小”:先烘焙一个 6 层、每层很宽的大蛋糕胚,然后逐步尝试切掉多余部分,让每一种小切法都自然好吃。OFA 的渐进式收缩训练,正是这种“先大后小”的课程式策略。

整个训练分成四个阶段。第一阶段只训练最大深度的子网,让网络先学会提取丰富的语义特征;第二阶段放开深度维度,同时支持 2~6 层的子网训练;第三阶段引入多种宽度;最后一个阶段加入多种核大小。每一阶段都在上一阶段基础上,让新加入的弹性维度适应超网现有权重。

为什么要这样安排?如果一开始就随机采样所有维度,小模型很难学好,而大模型又会被小模型的梯度拖累,训练不稳定。渐进式收缩相当于让大蛋糕先定型,再慢慢学会“切开后依然好吃”,既保住了大模型的精度,又给小模型留足了优化空间。

min⁡Wsuper  Eα∼P(α)  L(f(x; Wsub(α)), y)\displaystyle \min_{W_{\mathrm{super}}} \;\mathbb{E}_{\alpha \sim P(\alpha)} \;\mathcal{L}\big(f(x;\, W_{\mathrm{sub}}(\alpha)),\, y\big)

1. 最小化目标:我们要找到一组超网参数,使期望损失尽可能小。

min⁡Wsuper\min_{W_{\mathrm{super}}}

2. 数据分布期望:对所有训练样本的损失取平均,保证泛化到整个数据分布。

E(x,y)∼D\mathbb{E}_{(x,y)\sim\mathcal{D}}

3. 配置采样期望:对所有可能的子网配置按分布 \(P(\alpha)\) 采样,求期望损失。

Eα∼P(α)\mathbb{E}_{\alpha \sim P(\alpha)}

4. 子网损失函数:子网 \(f(x; W_{\mathrm{sub}}(\alpha))\) 的预测与真实标签 \(y\) 之间的差异度量。

L(f(x; Wsub(α)), y)\mathcal{L}\big(f(x;\, W_{\mathrm{sub}}(\alpha)),\, y\big)

大蛋糕先成型,再一层层、一块块地练习“切出小块依然好吃”——这就是老张的独家烘焙心法,也是 OFA 渐进式收缩的精髓。

子网采样

老张发现,光把蛋糕做大还不够。如果总切同一个位置试吃,其他位置的蛋糕胚始终没被烤透,顾客切到那里就难吃。于是他每次训练时有意识地随机切不同位置、不同大小的蛋糕块来品尝。OFA 在训练超网时,也必须有意识地采样各种子网配置。

如果只训练少数固定的配置,那么未被采样到的子网性能就会很差,这叫“欠拟合”。OFA 的做法是:在每个训练 batch 中,随机采样一个子网配置,只让这个子网对应的路径参与前向和反向传播。下一个 batch 再换一个配置,让所有配置都有机会被优化到。

这里还要警惕“子网耦合”问题:某些子网之所以表现好,是因为它和其他子网共享权重的过程中“搭了便车”,一旦被单独部署就露馅。OFA 通过均匀采样覆盖所有配置,并结合渐进式收缩逐层放开弹性维度,从根源上缓解了子网间的过度耦合。

P(α)=1∣A∣,∀α∈A\displaystyle P(\alpha) = \frac{1}{|\mathcal{A}|}, \qquad \forall \alpha \in \mathcal{A}

1. 配置空间大小:\(\mathcal{A}\) 中全部可能的子网配置总数。

∣A∣|\mathcal{A}|

2. 等概率采样:每个配置的采样概率为配置总数的倒数。

P(α)=1∣A∣P(\alpha) = \frac{1}{|\mathcal{A}|}

3. 作用于全部配置:这条规则对 \(\mathcal{A}\) 中的任意配置都成立,没有偏袒。

∀α∈A\forall \alpha \in \mathcal{A}

每个位置的蛋糕都经常被“试吃”,所以顾客随便切哪块,口感都有保证——均匀采样就是 OFA 对每一位“子网顾客”的公平承诺。

知识蒸馏

大蛋糕味道醇厚,但小蛋糕胚毕竟是少了几层的“边角料”,要让它也有大蛋糕的浓郁口感,老张发明了一个办法:把小蛋糕放在大蛋糕旁边,让大蛋糕的香气“熏”它,让它模仿大蛋糕的内部组织。OFA 在训练中使用同样的招数:知识蒸馏。

具体来说,OFA 在渐进式收缩的每一阶段,都把完整超网(或当前阶段的大网络)当作教师网络,把目标子网当作学生网络。学生不仅要学真实标签,还要学教师的“软输出”——即教师对每个类别的预测概率分布。软分布中隐藏着类别间的相似性信息,比如“猫”和“狗”比“猫”和“卡车”更接近,这些小模型单靠硬标签学不到。

蒸馏时常用 KL 散度来度量学生输出分布与教师输出分布的差异,并用一个温度参数 \(T\) 把分布变“软”,放大那些被低估的类别概率。最终损失是硬标签的交叉熵损失与软标签的 KL 散度损失的加权和。

L=α⋅LCE(y, σ(zs))+β⋅LKL(σ(zt/T), σ(zs/T))\displaystyle \mathcal{L} = \alpha \cdot \mathcal{L}_{\mathrm{CE}}\big(y,\, \sigma(z_s)\big) + \beta \cdot \mathcal{L}_{\mathrm{KL}}\big(\sigma(z_t / T),\, \sigma(z_s / T)\big)

1. 硬标签交叉熵:学生的预测与真实类别标签 \(y\) 之间的交叉熵损失,保证基础分类能力。

LCE(y, σ(zs))\mathcal{L}_{\mathrm{CE}}\big(y,\, \sigma(z_s)\big)

2. 软标签 KL 散度:学生的软输出与教师的软输出之间的 KL 散度损失,传递类别间相似性知识。

LKL\mathcal{L}_{\mathrm{KL}}

3. 温度缩放:将 logits 除以温度 \(T\) 后再做 softmax,使概率分布更平滑、信息更丰富。

σ(zt/T),σ(zs/T)\sigma(z_t / T), \quad \sigma(z_s / T)

4. 平衡系数:\(\alpha\) 和 \(\beta\) 分别控制硬标签与软标签两项损失的权重。

α,β∈[0,1]\alpha, \beta \in [0,1]

大蛋糕的“香气”和“组织质感”通过蒸馏传给小蛋糕,块块都有大师级口感——这就是知识蒸馏在 OFA 中的妙用。

部署应用

蛋糕店终于开张了。手机用户要小纸杯,平板用户要中等切块,电脑用户要整层大块。老张不重新烤,只按顾客需求拿刀比划一下,自然分毫不差。OFA 的部署阶段正是这样:给定目标硬件的延迟约束,比如手机推理必须控制在 20 毫秒内,工程师只需要在超网中搜索一个满足约束且精度尽量高的子网。

搜索过程通常用进化算法完成:从超网的所有配置里随机生成一批候选子网,在验证集上快速评估它们的准确率,并在目标硬件上实测或估算延迟。因为子网的权重直接来自超网,所以评估时只需做前向推理,不需要任何梯度计算,一个子网几十毫秒就能评估完,整个搜索几分钟内就能收敛。

这就是 OFA“一次训练、处处部署”的最终兑现:训练阶段只要做一次(约 40 GPU 天),之后每增加一个新设备,只需花几分钟做一次子网搜索。与大模型每目标重训数天相比,边际成本几乎可以忽略不计。

min⁡α∈A  Lval(Wsub(α))s.t.Latency(α)≤Ttarget\displaystyle \min_{\alpha \in \mathcal{A}} \;\mathcal{L}_{\mathrm{val}}\big(W_{\mathrm{sub}}(\alpha)\big) \quad \mathrm{s.t.} \quad \mathrm{Latency}(\alpha) \leq T_{\mathrm{target}}

1. 验证集损失:子网在验证集上计算出的损失,用来衡量它的真实精度水平。

Lval(Wsub(α))\mathcal{L}_{\mathrm{val}}\big(W_{\mathrm{sub}}(\alpha)\big)

2. 延迟函数:子网配置 \(\alpha\) 在目标硬件上完成一次前向推理所需的毫秒数。

Latency(α)\mathrm{Latency}(\alpha)

3. 约束条件:必须满足开发板或手机芯片给出的延迟上限要求。

s.t.Latency(α)≤Ttarget\mathrm{s.t.} \quad \mathrm{Latency}(\alpha) \leq T_{\mathrm{target}}

4. 约束内最小化:在延迟上限之内,挑选验证损失最低的那个子网。

min⁡α∈A\min_{\alpha \in \mathcal{A}}

切蛋糕的手起刀落之间,每一位顾客都拿到了最合口的尺寸——部署阶段的高效,正是 OFA 最迷人的商业价值。

对比与效果

街坊都在传老张的新蛋糕店。隔壁李大妈原来的点心铺(传统 NAS)一次只出一种点心,出一次要熬夜做三天。老张的店里却高朋满座,大家想切哪儿切哪儿,还能当场试吃比较。OFA 的实测效果也印证了这种“降维打击”。

在 ImageNet 分类任务上,OFA 抽取出的子网在同等精度下比 MobileNetV3 快 1.5 倍;在相同延迟下,准确率高出约 2.9%。与 BigNAS 等同类超网方法相比,OFA 最大的区别在于真正做到了“先训超网、后选子网”,不需要在部署时重新采样训练,而是直接利用渐进式收缩得到的成熟权重。

从成本角度算一笔账:传统 NAS 要为单个目标消耗上千 GPU 小时,而 OFA 的一次性训练约 40 GPU 天,之后每个新目标只需几分钟搜索。精度-算力曲线上,OFA 抽取的子网几乎贴着“每目标专训模型”的帕累托前沿,让“一胚多切”的边缘成本逼近于零。

Acc(α)  vs  FLOPs(α),α∈A\displaystyle \mathrm{Acc}(\alpha) \;\mathrm{vs}\; \mathrm{FLOPs}(\alpha), \qquad \alpha \in \mathcal{A}

1. 子网精度:子网在 ImageNet 等测试集上的分类准确率。

Acc(α)\mathrm{Acc}(\alpha)

2. 计算量:子网完成单次前向推理所需的浮点运算数,是算力需求的直接度量。

FLOPs(α)\mathrm{FLOPs}(\alpha)

3. 权衡比较:在二维平面上比较每个子网“精度 vs 算力”的坐标位置。

vs\mathrm{vs}

4. 覆盖所有配置:所有子网在曲线上描绘出一条完整的性能边界,供部署时挑选。

α∈A\alpha \in \mathcal{A}

一张精度-成本曲线,就是老张的顾客满意度地图——每一分钱都花在刀刃上。OFA 用一次耐心的大烘焙,换来了满店皆大欢喜。

AI 应用场景

手机厂商多机型适配

阶段:模型部署与优化

解决的问题:手机厂商每年推出几十款机型,芯片从旗舰到入门算力差距超过 10 倍。传统做法是每款机型单独训练和压缩模型,一个算法团队同时维护几十个模型版本,训练资源与人力成本居高不下。OFA 让团队只训练一个超网,部署时针对每款机型的芯片跑几分钟子网搜索,自动生成满足该机型延迟和内存约束的模型。

具体案例:某手机厂商的相册分类功能需要覆盖高中低三档芯片。算法团队用 OFA 训练一个超网,旗舰机型抽取大子网(50 MFLOPs,精度 78%),中端机型抽取中子网(30 MFLOPs,精度 75%),入门机型抽取小子网(15 MFLOPs,精度 71%),三个模型一次训练全部搞定。

云端推理服务降本

阶段:推理服务与资源调度

解决的问题:云服务商面向不同客户提供 API,调用量有高有低,SLO 要求各不相同。如果所有请求都走最大模型,成本浪费巨大。OFA 允许服务端预训练一个超网,根据实时负载动态切换不同大小的子网——高峰期用大模型保证精度,低峰期用小模型节约 GPU 成本。

具体案例:某内容推荐公司用 OFA 超网替代多个独立模型。白天流量高峰时抽取 500 MFLOPs 的大子网,夜间低峰时切换到 100 MFLOPs 的小子网,GPU 账单下降约 40%,且无需重新训练任何模型。

边缘 IoT 设备群

阶段:模型压缩与适配

解决的问题:IoT 设备碎片化严重,摄像头、传感器、门锁的算力各不相同,有的有 NPU 加速,有的只有 MCU。逐个优化不现实。OFA 的超网训练一次,即可覆盖整个设备群的算力谱系。

具体案例:一家安防公司需要把入侵检测模型部署到 20 种不同规格的摄像头上。利用 OFA,算法团队训练一个覆盖全部算力范围的超网,对每种摄像头自动搜索出满足帧率要求的子网,2 天内完成全部 20 个固件的模型生成与验证。

Python 演示

python80 行
import torchimport torch.nn as nnimport numpy as np  class ElasticConv2d(nn.Module):    """支持弹性宽度和弹性核大小的卷积层。"""     def __init__(self, in_ch, max_out_ch, max_kernel):        super().__init__()        self.conv = nn.Conv2d(in_ch, max_out_ch, max_kernel,                              padding=max_kernel // 2)        self.out_ch = max_out_ch        self.kernel = max_kernel     def forward(self, x):        w = self.conv.weight[:self.out_ch]        if self.kernel < self.conv.kernel_size[0]:            pad = (self.conv.kernel_size[0] - self.kernel) // 2            w = w[:, :, pad:pad + self.kernel, pad:pad + self.kernel]        return nn.functional.conv2d(x, w, self.conv.bias[:self.out_ch],                                    padding=self.kernel // 2)  class ToySuperNet(nn.Module):    """玩具版超网:弹性深度包含多个块,可抽取任意前缀子网。"""     def __init__(self, in_ch=3, max_depth=4, width=32, kernel=5):        super().__init__()        self.blocks = nn.ModuleList([            nn.Sequential(ElasticConv2d(in_ch if i == 0 else width,                                        width, kernel),                          nn.BatchNorm2d(width), nn.ReLU())            for i in range(max_depth)        ])        self.pool = nn.AdaptiveAvgPool2d(1)        self.fc = nn.Linear(width, 10)        self.depth = max_depth     def forward(self, x):        for i, block in enumerate(self.blocks):            if i >= self.depth:                break            x = block(x)        x = self.pool(x).flatten(1)        return self.fc(x)  def sample_subnet(net):    """均匀采样子网配置:深度、每层宽度、核大小。"""    net.depth = np.random.randint(1, len(net.blocks) + 1)    for block in net.blocks:        el = block[0]        el.out_ch = np.random.randint(8, el.conv.weight.shape[0] + 1)        el.kernel = np.random.choice([3, 5])  def train_one_step(net, x, y, opt):    """每个 batch 采样一次子网并做一次反向传播。"""    sample_subnet(net)    out = net(x)    loss = nn.functional.cross_entropy(out, y)    opt.zero_grad()    loss.backward()    opt.step()    return loss.item()  def main():    net = ToySuperNet(max_depth=4)    opt = torch.optim.Adam(net.parameters(), lr=1e-3)    x = torch.randn(8, 3, 32, 32)    y = torch.randint(0, 10, (8,))    for step_i in range(10):        loss = train_one_step(net, x, y, opt)        print(f'step {step_i}: loss={loss:.4f}')  if __name__ == '__main__':    main()
目的:演示 OFA 风格超网训练的核心循环——每个 batch 随机采样一种子网配置,用共享权重做一次反向传播,让所有子网共同受益。
  1. sample_subnet(net)每个 batch 重新随机采样一个子网,模拟 OFA 的均匀采样策略。
  2. net.depth = np.random.randint(1, len(net.blocks) + 1)弹性深度:随机决定前向传播使用 1~4 个块中的哪一段。
  3. el.out_ch = np.random.randint(8, el.conv.weight.shape[0] + 1)弹性宽度:随机截取前若干个输出通道,实现子网变窄。
  4. el.kernel = np.random.choice([3, 5])弹性核大小:随机选择 3 或 5 的卷积核尺寸。
  5. w = self.conv.weight[:self.out_ch]从超网权重中切片出子网对应部分,体现权重共享。

常见误区

误区OFA 训练好超网后就万事大吉,部署时随便抽一个子网就能用,不需要任何搜索环节。

正解OFA 的超网训练只解决了“权重从哪来”的问题。部署时仍需要针对具体硬件搜索最优子网配置,即在延迟约束下找精度最高的 \(\alpha\)。不过这个搜索不需要训练,只需几分钟的推理评估,成本与训练相比可以忽略。“不用再搜索”是错误的。

为何常见:因为“一次训练”的宣传太深入人心,大家容易忽略“一次训练”后面还跟着“按需搜索”这一部署步骤。

误区以为 OFA 训练超网时,每个子网都被当作独立模型从头训练了一遍,超网只是把一堆小模型打包在一起。

正解子网并非独立训练,它们共享超网的全部或部分权重。每个训练 batch 只采样一个子网路径进行前向和反向传播,更新的是超网中的共享参数。所有子网是在同一份权重之上协同优化的,而不是各练各的。

为何常见:看到“超网包含子网”的说法,容易脑补成“大箱子里装了很多小盒子”的独立关系,而忽略了权重共享这一核心机制。

误区渐进式收缩和网络剪枝差不多,都是先把大网络变小,然后扔掉多余的部分。

正解剪枝是训练完成后的后处理压缩技术,目标是删除不重要的权重或通道;而渐进式收缩是训练过程中的课程式策略,按照“深度 → 宽度 → 核大小”的顺序逐步放开弹性维度,让子网从训练一开始就和超网一起优化,二者目的和时机完全不同。

为何常见:两者都涉及“从大变小”的直观印象,初学者容易把训练期策略与部署期压缩混为一谈。

误区让所有子网共享同一套权重,必然互相干扰,精度一定比每个模型单独训练差很多。

正解权重共享确实会带来一定冲突,但 OFA 通过渐进式收缩、均匀采样和知识蒸馏三重机制,大幅缓解了子网间的干扰。实验表明,OFA 子网在相同 FLOPs 下精度与单独训练的模型基本持平,甚至因为超网的“多任务正则化”效应,还能略微提升性能。

为何常见:直觉上“一套参数不可能同时满足所有模型”,但忽略了超网参数本身就是在采样分布下联合优化的,并非简单复用。

误区以为 OFA 只是把通道数变窄,本质上类似 MobileNet 里的宽度乘子,做不到深度和核大小的弹性。

正解OFA 同时支持弹性深度、弹性宽度、弹性核大小三个维度的任意组合,三者形成庞大的笛卡尔积配置空间。深度体现为保留网络的前缀层数,宽度体现为截取前若干通道,核大小通过中心裁剪在同一条卷积路径中切换。

为何常见:因为宽度弹性最容易理解和实现,许多文章习惯用“变窄”概括超网思想,导致读者忽略了三维弹性才是 OFA 的完整设计。

面试题

Q1. OFA 的核心思想是什么?

单选题 · easy

  • A.为每个设备单独训练一个专用模型
  • B.一次训练超网然后按需抽取子网← 正确答案
  • C.只训练一个固定大小的网络部署到所有端侧
  • D.把多个模型压缩成一个小模型再部署

答案:B。OFA 的核心是“一次训练超网、多次抽取子网复用”,选项 B 准确表达了这一思想。A 是传统 NAS 的做法,C 忽略了对不同设备的适配,D 描述的是一般模型压缩而非超网思路。

Q2. OFA 中的“超网”指的是什么?

单选题 · easy

  • A.由多个互不相关的独立模型组成的集合
  • B.只包含最大配置、不可裁剪的单一网络
  • C.一个蕴含大量可抽取子网的母网络← 正确答案
  • D.知识蒸馏中使用的教师网络本身

答案:C。超网是一个参数共享的母网络,内部包含大量可通过裁剪得到的子网配置,C 正确。A 中的独立模型没有权重共享,B 忽略了吗弹性,D 中的教师网络只是 OFA 训练中的一个角色,不是超网定义的本身。

Q3. 渐进式收缩训练的正确顺序是?

单选题 · mid

  • A.宽度收缩 → 核大小收缩 → 深度收缩
  • B.核大小收缩 → 深度收缩 → 宽度收缩
  • C.深度收缩 → 宽度收缩 → 核大小收缩← 正确答案
  • D.三个维度同时随机开始收缩

答案:C。OFA 的渐进式收缩顺序是“深度优先、宽度次之、核大小最后”,故 C 正确。这个顺序让网络先稳定深度结构,再细化宽度,最后调节核大小,是课程式训练策略的关键。

Q4. 在 OFA 的知识蒸馏方案中,教师网络通常是?

单选题 · mid

  • A.当前训练阶段中最大的那个网络← 正确答案
  • B.一个完全独立训练的更大模型
  • C.上一轮迭代中精度最高的子网
  • D.每次采样出的学生网络自身

答案:A。OFA 在渐进式收缩的每个阶段,用完整超网或上一阶段的大网络作为教师,指导当前阶段的子网学习,A 正确。独立训练的更大模型不是 OFA 的标准做法,C 和 D 曲解了“教师-学生”的静态关系。

Q5. OFA 部署阶段搜索子网时主要考虑什么?

单选题 · mid

  • A.只最大化精度,完全不考虑推理延迟
  • B.只最小化参数量,忽略精度指标
  • C.在给定延迟约束下尽量提高精度← 正确答案
  • D.随机挑选一个固定配置直接上线

答案:C。部署搜索是一个约束优化问题:延迟不超过目标硬件上限的前提下,选择验证损失最低的子网,C 正确。A 忽略硬件限制,B 忽略精度,D 随机选择无法保证满足部署要求。

Q6. 以下哪些属于 OFA 超网支持的弹性维度?

多选题 · mid

  • A.弹性深度(网络层数)← 正确答案
  • B.弹性宽度(通道数量)← 正确答案
  • C.弹性核大小(卷积核尺寸)← 正确答案
  • D.弹性注意力头数(多头注意力)

答案:ABC。OFA 的三大弹性维度是深度、宽度、核大小,故 A、B、C 正确。D 的注意力头数是 Transformer 架构中的概念,OFA 主要面向卷积网络,不在其弹性维度之列。

Q7. OFA 完成超网训练后,新增一个部署目标大约需要多少成本?

单选题 · easy

  • A.每个新目标仍需数天 GPU 重新训练
  • B.每个新目标仅需几分钟的子网搜索← 正确答案
  • C.每个新目标不需要任何额外计算
  • D.每个新目标必须重新采集训练数据

答案:B。OFA 的子网权重已存在于超网中,新目标只需通过进化搜索在验证集上评估精度并检测延迟,几分钟即可完成,B 正确。A 是传统 NAS 的成本,C 忽略了部署时仍要搜索最优配置,D 与部署无关。

Q8. 关于渐进式收缩的课程式设计,正确的说法有?

多选题 · hard

  • A.先训练最大深度以稳定网络基础← 正确答案
  • B.三个弹性维度从训练一开始就同时放开
  • C.深度收缩完成后再逐步扩展宽度维度← 正确答案
  • D.每个阶段都需要切换一套全新数据集

答案:AC。渐进式收缩先训练最大深度,再逐步放开宽度,最后放开核大小,A 和 C 正确。B 与“渐进”思想矛盾,D 错误——所有阶段使用同一数据集,变化的是采样的弹性维度。

Q9. OFA 中部署子网的权重从哪里获得?

单选题 · hard

  • A.从超网的权重中直接切取对应切片← 正确答案
  • B.在超网之外重新初始化并单独训练
  • C.从教师网络逐层复制全部参数
  • D.从预训练模型微调五轮之后得到

答案:A。子网权重通过权重共享从超网参数中直接切取,不做额外训练,A 正确。B 违背 OFA 的权重共享前提,C 混淆教师网络的功能(教师提供软标签而非参数),D 不是 OFA 的子网获取方式。

Q10. 关于 OFA 子网的训练方式,下列说法正确的有?

多选题 · extreme

  • A.每个被采样的子网路径独立计算梯度并更新共享权重← 正确答案
  • B.所有子网共享超网中同一套权重参数← 正确答案
  • C.采样策略需要尽可能覆盖全部配置组合← 正确答案
  • D.子网必须借助比自身更大的辅助模型才能训练

答案:ABC。每个 batch 只对采样子网路径做前向反向,A 正确;所有权重共享,B 正确;均匀采样覆盖全部配置以避免欠拟合,C 正确。D 错误——知识蒸馏是可选的性能增强手段,不是子网训练的必要条件。