核心思路:把 N 层切成恰好 K 段连续非空区间,最小化各段和的最大值。答案有单调性:若峰值上限 x 可行,则所有 y>x 也可行,因此对答案二分。判定时从左到右贪心装箱:当前段再放下一项就会超过 x 就新开一段,最后看需要的段数是否不超过 K。因为 N≥K,段数偏少时可以继续切开,最大负载不会变差,所以「至多 K 段」与「恰好 K 段」等价。下界取 maxf[i],上界取总和。
实现方法:读入后先算 lo=maxf[i]、hi=∑f[i]。二分中点 mid,扫描数组统计段数;单层超过 mid 直接判不可行。可行则缩小上界,否则抬下界。结束时 lo 即为最小可行峰值。
每次判定 O(N),二分次数 O(log∑f[i])。时间复杂度 O(Nlog∑f[i]),空间复杂度 O(N)。在 N≤5000、f[i]≤1000 下足够。
要把一个神经网络的 N 个层切到 K 块 GPU 上做流水线并行。切完后每一段叫做一个 Stage,训练时按 Stage 顺序接力计算。
一个 Stage 的负载等于它包含的各层前向传播时间之和。若 Stage s 覆盖连续层 l1,…,lt,则
Loads=f[l1]+⋯+f[lt]其中 f[i] 是第 i 层的前向时间。流水线由最慢的 Stage 卡住,因此要最小化所有 Stage 负载的最大值。
切分必须同时满足:
第一行两个整数 N、K,依次为层数和 Stage 个数。
第二行 N 个整数 f[0] f[1] … f[N−1],表示各层前向时间(毫秒)。
输出一行一个整数,即最小化后的最大 Stage 负载。
输入:
7 3
4 6 3 8 2 5 4
输出:
11
解释:
| 方案 | Stage 0 | Stage 1 | Stage 2 | 最大负载 |
|---|---|---|---|---|
| 按层数尽量均分 | [4,6,3] | [8,2] | [5,4] | max(13,10,9)=13 |
| 最优 | [4,6] | [3,8] | [2,5,4] | max(10,11,11)=11 |
只有这一种划分能把峰值压到 11。
输入:
4 2
2 8 3 5
输出:
10
解释:
四层耗时为 [2,8,3,5],要切成 2 个 Stage。
| 方案 | Stage 0 | Stage 1 | 负载 | 最大负载 |
|---|---|---|---|---|
| A | [2] | [8,3,5] | 2 vs 16 | 16 |
| B | [2,8] | [3,5] | 10 vs 8 | 10 |
| C | [2,8,3] | [5] | 13 vs 5 | 13 |
最优为方案 B,峰值负载 10。
Scan the QR code below with WeChat to sign in
First-time scan will create your account automatically
请使用微信扫描下方二维码完成注册