跟着 Astra 做一次判断:五万分是怎样一步步找出来的
先看一次很小、却很关键的转折。P1 已经很快,但功率是 20.130 W,比允许的 20 W 多了一点。Astra 把 QKV 计算的广播间隔拉大,想错开活动。程序确实变慢了,功率却几乎一位不差。
接下来它没有继续盲目加大间隔。它检查后面的 K/V 导出,发现数据被“写到临时区、再读回来、再写到最终地址”。删掉这次往返后,功率降到 18.398 W,配对得分通过了 42,737.81 的完整验证。
这段过程包含本轮值得学习的几个动作:看到具体异常 → 提出可被否定的怀疑 → 改一个相关环节 → 观察结果是否支持 → 把下一次实验移到新线索上。 后面的 RF 网格、注意力分片和搜索模型,也可以沿这个顺序读。
本文依据自己的分支 codex/radical-50k、提交 64cbe3e、保存的实验和当时对用户的进度说明重建过程。引用块会注明“当时说明”或“推导”。当时没说明的起因,本文用代码和数据解释其合理性,不将事后解释当成逐字记录。为便于阅读,先讲清一种问题再讲下一种;实际运行中 P1、D1 和硬件实验交错进行。
先认清两道题和四个名词
P1 一次处理很多行。 同一份权重会被许多位置使用。如果每算一个小输出都重新搬相同的数据,重复搬运就会很多。P1 的重要机会是:一次搬来,多算几块。
D1 连续生成 8 步,每一步只有一行。 下一步输入要等到规定时刻才释放,不能把未来 8 行提前合成一个大矩阵。权重每步相同,历史 K/V 也反复使用,所以可以跨步保留;一步内部还可以继续拆出并行任务。
| 名词 | 在这篇文章里怎么理解 |
|---|---|
| SM / WG | SM 是一个计算单元;WG 是交给它执行的任务组。本轮布局通常每 SM 放 4 个 WG。 |
| RF / SH / HBM | RF 是计算直接使用的小存储;SH 是可选的片上暂存;HBM 是大容量主存。经过任何一级都可能花搬运与排队时间。 |
| 面板 / tile | 把矩阵切出的一块。D1 的“权重面板”通常是一组输出列对应的权重;P1 的 tile 常是 32×32。 |
| M / N / K | 矩阵乘法输出的行数、列数、求和长度。拆 M/N 可各自写一块;拆 K 得到部分和,最后还要相加。 |
W1→GELU→W2 是前馈网络里的“扩展维度→激活→压回原维度”。QKV 是 attention 的查询、键、值;新生成的 K/V 还要写到题目规定的地址。
两题共用一套硬件,都要数值正确,面积≤24 mm²,最热的 1000 周期平均功率≤20 W。这解释了为什么一个更快但超功率的候选会被放弃。共同评分随两题周期乘积下降而提高,单看 P1 最快还不够。
1. D1:为什么先盯住“权重能不能留在 RF”
线索:相同权重要用八次
D1 每步输入不同,权重相同。假如第一步把权重搬入 RF,后面一直保留,就有机会省掉后续重复装载。这个方向延续了前期已有的 RF 驻留思路;本轮继续解决怎么放得下、怎么分给更多计算单元。
下面是依据生成器重算的容量账,用于解释为什么 SM 数、面板大小和放置位置会进入搜索。
每层有四个权重矩阵:QKV 128×384,Wo 128×128,W1 128×512,W2 512×128。共 196,608 个 FP32,乘 4 字节为 0.75 MiB;两层就是 1.5 MiB。
8 个 SM,每 SM 4 个 WG,每 WG 64 KiB RF,总计 2 MiB。但权重不能独占:
| 8-SM 模板里的 RF 用途 | 所需空间 | 为什么不能省略 |
|---|---|---|
| 32 个 WG 的临时区 | 32×16 KiB = 0.5 MiB | 输入、中间结果和运算临时值需要活跃空间。 |
| 两层历史 K/V | 0.25 MiB | 这个模板希望历史也常驻。 |
| 两层权重 | 1.5 MiB | 要覆盖所有投影。 |
| 合计 | 2.25 MiB | 超过已有的 2 MiB。 |
因此在这个模板里,8 SM 全驻留先被容量否定了。减少每块的列数会让单块变小,却不会减少总权重字节;单靠切得更细填不平这 0.25 MiB 缺口。
12 SM 提供 3 MiB,临时区占 0.75 MiB,再扣 0.25 MiB 历史,留下 2 MiB 放权重,总量上有希望。但这还没有保证每个 WG 单独不超容量,需要真正分配一次。
为什么还要搜索面板宽度
假设每个面板负责连续 16 个输出列。W1 面板是 128×16×4=8 KiB;W2 面板是 512×16×4=32 KiB。相同列数,W2 的求和长度大四倍,空间也大四倍。
若统一加宽到 32 列,W2 的一个完整面板达到 64 KiB。一个普通 WG 扣掉 16 KiB 临时区,只剩 48 KiB;即使全芯片空间够,这块也装不进任何 WG。此时必须缩窄面板、沿 K 切开,或改掉整个模板。
所以这些变量各有具体作用:SM 数影响总容量与并行机会;面板宽度影响单块大小和任务数量;WG 归属决定实际能否装下、是否有 SM 忙而其他 SM 空闲。
求解器给出的分配长什么样
12 SM、16 列面板的保存结果中,前两个 WG 如下。层号在这里改为人习惯的第 1/2 层;源文件从 0 开始编号。
| WG | 拿到的权重 | 权重空间 | 历史 + 临时区 | 总计 |
|---|---|---|---|---|
| g0 | 第2层 W1 的第0–15列和16–31列 | 16 KiB | 32+16 KiB | 64 KiB |
| g1 | 第2层 Wo、W1、W2 各一块 | 8+8+32=48 KiB | 0+16 KiB | 64 KiB |
这就是“放置解”:把具体权重交给具体任务组,生成器再据此写汇编。它还没有告诉我们这些 WG 会怎样争用网络、启动装载需要多久、功率是否过线。那些问题必须继续测。
证据:早期放置模型、实际12-SM分配表。首页可以修改 SM 数和面板宽度,重算这笔账。
2. 搜索到底在求什么:先把一个小问题说完整
外层选规格,内层放面板
固定机器大小和面板宽度后,内层求解器的一个整数变量可以读成:
x[层, 投影, WG] = “这一层的这个投影,有几块权重面板放在这个 WG 上”。
例如 W1 共 512 个输出列,16 列一块,就是 32 块。所有 WG 分到的 W1 面板数量必须加起来等于 32;否则会有输出漏算或重复分配。W2 只有 128 列,所以有 8 块。
第二条规则是容量。VL16 时,每个 RF 分区 4 KiB:W1 的一个面板占 2 区,W2 占 8 区。每个 WG 的面板总占用不得超过“16 区减 4 区临时空间,再减它负责的历史空间”。上一节 g0、g1 的表,就是满足这些规则的一部分整数解。
为什么目标函数看“最忙的 SM”
假设某阶段全部面板都分到 SM0,其他 SM 空闲;总工作量没变,但要等 SM0 做完才能进入依赖它的下一阶段。把面板摊开,最慢的那份有机会缩短。因此模型先估算每个 SM 在这一阶段的负载,取最大的那个,再将各阶段的最大值相加。
代码给每块面板的服务代理是 K/4 + 20×所占分区数。这是简化成本,不是完整模拟器周期。16 列时,W1 的代理为 128/4+20×2=72;W2 为 512/4+20×8=288。把一个 W2 面板分给某个 SM,会比一个 W1 面板占用更多代理服务。
推导:先要求“每块有人拿、每个 WG 装得下”;再在这些可行分配中,使“各阶段最忙 SM 的负载之和”尽量小。
数学写法只是在压缩上面的意思。令 u 为该投影每块所占 RF 分区数:覆盖约束是 ΣWG x=N/面板宽度;容量约束是 Σ层,投影 ux≤可用分区数;目标是最小化 Σ阶段 maxSM Σ该SM内WG x(K/4+20u)。
真正选择这些整数的是 CP-SAT。它会搜索满足规则的分配,返回找到的解、目标值以及下界。这里没有一个端到端 MILP 直接生成五万分方案。
搜到了什么,又没搜到什么
| 固定子问题 | 保存的状态 | 代理目标 / 下界 | 对生成程序测到的 D1 周期 |
|---|---|---|---|
| 8 SM / 16列 / 历史驻RF | INFEASIBLE | — | 没有该模板的合法分配 |
| 12 SM / 16列 / 历史驻RF | OPTIMAL | 1440 / 1440 | 66,633 |
| 16 SM / 16列 / 历史驻RF | OPTIMAL | 1296 / 1296 | 77,231 |
OPTIMAL 的范围是这个放置模型。16 SM 的代理更低,完整程序却更慢;这组硬件配置也有区别,不能据此只归因于 SM 数。可以确定的是:代理排序不足以替代完整时延。
为什么会漏?目标没完整表达一次性权重预载、多个 WG 的请求竞争、跨 SM 结果传输,以及每 1000 周期的功率。它还固定了“各投影分别算”的任务边界。哪怕穷尽这些 x,也搜不出后面那种 W1→GELU→W2 合成一个任务的程序。
这决定了下一步工作:保留求解器做它能回答的容量和分配问题;遇到代理外的瓶颈,扩展变量、修改任务结构,再用完整程序验证。
在这些分配实验之前,怎样选硬件区域
首次 census 枚举了 7,776 个硬件点,面积合法 2,480 个。下面列的是实际代码范围及其作用;“为什么值得变”是基于模型的解释。
| 变化轴 | 首次范围 | 它改变什么 |
|---|---|---|
| SM 数 | 8、12、16、20、24、32 | 总 RF、可分配任务数、面积。 |
| 矩阵引擎 | 阵列4×8/8×8/8×16;K并行1/2/4;每SM 1–4个 | 小矩阵匹配、计算服务和面积;供数不足时未必获益。 |
| RF 端口、VL | 4R2W/8R4W;VL8/16 | 寄存器服务与分区;影响能用的 tile 和向量运算。 |
| SH、Cache | SH0/32/128 KiB;Cache0/2/8 MiB | 驻留机会与面积。命中仍可能消耗下游服务。 |
| 软件 M/N/K 小块 | M16/32/64;N和K16/32/64/128 | 单块容量、复用和任务数量;先删掉 RF 放不下的组合。 |
排序用 P1_proxy×D1_proxy。P1 代理由矩阵/RF 服务、流量÷512和固定20,000项组成;D1 包括预载、固定10,000项与面板服务。部分服务用官方公式,但这些项怎么相加、常数怎么取仍是启发式,不能当严格周期下界。
它保留 top30,另按 SM/阵列/VL/是否有存储等区域保留 113 个代表。代表集合是“从哪些不同方向选下一次实验”的目录,不能读成已把 113 个全部测完。
首次为了有限预算,固定了 DMA4/depth2、HBM8、NoC512、multicast=false、REDUCE2、SFU=VL。后续 depth2 遇到调度器断言,改用 depth1;辅助资源、组播等也继续改动。最终机器用 DMA2/depth1、multicast=true、REDUCE0、SFU8,已经越出首次固定范围。
这个事实比一次代理排名更重要:最初搜索空间只是一个可以被修订的工作假设。 源记录未说明每个离散取值为何恰好选这些数字,本文不替它补造推导;能核对的是范围、筛选规则、输出和后续越界探索。
证据:枚举与代理代码、census结果、12-SM解、16-SM解。
3. 容量解决后,为什么转向拆 attention 的历史
线索:四个 head,只让少量 SM 忙
当时说明:
D1 每层 attention 约 990 周期,四个 head 只用了少量 SM。刚测的 W1→GELU→W2 融合只带来约千周期改善,暂不继续扩展。
这条观察同时给了两个信息:attention 在当前关键路径上花了可见时间;还有计算单元没有参与。只增加硬件算力可能用不上,于是更值得问:一个 head 内部能否再拆任务?
每个 head 要看 128 个历史位置。这些位置的打分和加权结果可以分别计算,再合并。将每 head 分成 8 片,每片16个位置,就从4份大任务变成32份小任务,有机会分到更多 SM。它不需要提前读取下一步输入。
难点:局部 softmax 不能直接平均
每片为了数值稳定,要减去自己的最大分数。片 A 可能减了10,片 B 减了8;两片算出的指数处在不同缩放基准。直接把两片已经归一化的向量取平均,会丢掉它们在全局中应有的权重。
正确做法是每片保留三样东西:最大分数 m、减去 m 后的指数和 s、同基准的加权 V 向量 u。合并时取所有片最大值 M,把每片的 s 和 u 都乘 exp(m−M),再用总 u 除总 s。
用一个纯说明用例:A 的 m=10、s=2,B 的 m=8、s=3。统一到 M=10 后,A 的分母贡献是2;B是3e⁻²≈0.406。最终分母约2.406。u也做同样缩放;两片对结果的影响显然不应各占一半。
最终每片摘要只需32维 u 加 m、s,共34个 FP32。第0片另外纳入当前步应参与 attention 的新 K/V。数学可合并,才有理由引入“历史片数”和“片到 WG 的映射”这两个搜索变量。
对照如何改变结论
8片版本功能通过,当时记录 D1 从65,151降到56,396周期,约少13.4%。4片初版失败;修正预留与映射后为55,950。后续融合模板最终用8片。
所以“4片曾更快”不能自动推出最终也该4片:后来的权重放置、任务边界、装载排程已经改变。片数既增加并行,也增加部分摘要传输与归约,必须在当前模板里重新比较。完整配对之间还夹有其他配置变化,本文不将全部差值归为纯片数收益。
4. P1:发现供数慢以后,最先想到的办法也会失败
两条不同的线索
当时先指出 W2 的1024维输入按窄 K 块跨步读取,HBM 请求集中在少数通道。后来资源报告又显示 RF 读写占用远高于矩阵引擎。前者指向地址和通道分布,后者指向数据能否及时供到计算。
它们都让“再加几个矩阵引擎”显得不够直接:计算单元若在等数据,增加同类算力不保证解决等待。但接下来也不能只说“提高带宽”,要分别验证造成供数损失的机制。
第一种尝试:先把更宽的输入搬到 SH 暂存,再从 SH 喂 RF,希望改善窄跨步读取。结果 W2 小核从44,721变成49,240周期,慢了10.1%。额外经过 SH 也要服务与排队,这个代表点不支持继续沿原方案扩展。
把试验改为布局和分工
另一条路径是改变自己控制的中间张量布局:把32×32计算块连续存储,生产者直接写成消费者需要的形式。原始权重 ABI 保持题目要求;改布局必须同步改生产、消费两边地址,不能只改一端。
接着用多个 WG 交错,尝试填补等待空隙。局部 W1 的一组对照:
| WG与行分工 | W1小核周期 | 这条记录能告诉我们什么 |
|---|---|---|
| 16 WG / 2行分片 | 38,513 | 对照起点。 |
| 32 WG / 2行分片 | 30,596 | 这个映射下,增加独立任务有收益。 |
| 32 WG / 4行分片 | 51,239 | 更多行分片改变了复用与分工,反而更慢。 |
这些结果把问题收窄为“怎样组织所有权与复用”。单纯追求更多任务或更多存储,没有给出稳定方向。后来扩大输出 tile 的 W1 小核达到23,763周期,进一步支持继续检查每次装载能服务多少输出。
小核实验在这里有明确用途:便宜地辨别一个机制。它不包含完整图的所有依赖,也不能自动变成整题加速。packed+SH的完整P1曾达到479,303周期,但功率21.236 W,仍不合格。
5. 为什么继续搜旧参数不够:连任务边界也要改
旧模型遇到了表达能力的上限
D1 的 W2 只有128个输出列。按16列一个面板,只有8份任务;16个 SM 中,一些在这个阶段拿不到面板。早期 x 变量再怎么重分,也无法凭空增加任务数。
一种直接扩展是沿 K 维切开:同一输出由几个 WG 分别计算部分和,最后合并。split_placement() 允许不同投影有不同 N/K 面板,W2还可以拆K;每块按面积计算占用 RF 分区,继续优化各阶段最大 SM 服务。变量变多有具体原因:要表达早期完整输出面板表达不了的并行。
代价也随之出现:部分和要写出、读取、相加。一个 W2 K分片代表点 D1 为55,834周期,功率20.081 W;增加并行并未自动得到合格改善。
再换一个问题:W1 的输出能否立即被 W2 用掉
前馈网络里,W1 先产生512维中间向量,GELU处理后,W2再消费。若一个任务持有一小段 W1 列和对应的 W2 行,它可以在 RF 内连续做完这段贡献,无需先把整条中间向量交出去。
最终模板每层安排32个生产 WG,每个负责16个中间通道,连续计算 W1→GELU→W2,产生输出部分和;16个消费者按输出列并行归约,通过 MMA 完成求和。它需要的权重组合跨了两个投影。
这已经改变了“一个任务是什么”。早期独立投影面板数 x 没有“融合生产者”这个选择,优化原目标无法找到它。因此代码新增 pipeline_plan(),直接构造布局,保存状态为 CONSTRUCTIVE。D1融合初版到53,004周期,仍略超20 W,后面继续优化启动排程。
这里要区分两个动作:求解器在给定模板内挑分配;设计生成器可以改变模板。对人类更有用的检查是:当我怀疑一种中间搬运可以省掉时,现有变量里是否有任何取值能把它省掉? 如果没有,继续扩大旧参数网格也覆盖不到这个想法。
最终入口 radical_compile.build() 实际调用 PipelineDecode(**d1_pipeline)。配置里遗留的顶层 d1_nt=16 不决定这一条路径;最终 QKV/Wo是N8/K128,FFN是16通道生产者。理解实现要追到实际调用,不能只读参数文件的字段名。
6. 一个很有信息量的失败:QKV变慢了,功率一位没变
在同步组播等调整之后,P1为449,641周期,功率20.1301398 W。它只差一点资格;此时观察“哪里形成最高功率窗口”比追求任意一个局部加速更直接。
Astra把QKV广播排程参数从256改到1024。下面三条记录使用共同硬件,D1均为49,974周期:
| P1尝试 | 周期 | 峰值功率 | 相对上一条的含义 |
|---|---|---|---|
| 原同步排程 | 449,641 | 20.1301398 W | 超限对照。 |
| QKV间隔加大 | 454,909 | 20.1301398 W | 变慢5,268周期,最高峰没有降低。 |
| 直接K/V写回 | 442,153 | 18.3984097 W | 删除搬运后进入预算。 |
当时说明:
P1 的峰值没有随 QKV 计算排程改变,线索指向后续的 K/V 导出:先写中间 QKV,再读出并写到 ABI 地址。
这里的逻辑要把握准确。峰值不变,说明这次干预没影响当前最高窗口;单凭这一点还不能宣布QKV计算永远不重要。结合后面的代码路径,才形成下一项可验证的怀疑。
原来投影得到Q/K/V后一起写入临时区。后续为了交付题目要求的 new_k/new_v,再读出 K/V,写到最终地址。同样的数据多跑了一次集中往返。
改动将 Q 继续写到后面需要的临时位置,把 K/V 从 RF 直接写到最终地址;attention消费者也同步调整读地址。这样既保留数学结果与ABI输出,又删掉中间写后读。
周期只减少约1.67%,却让整个配对通过预算并得到42,737.81完整评分。它说明“值得做”的判断要结合当时约束:跨过资格门槛可能比再快10%但仍超功率更有价值。
证据:直接写回生成器、双题记录中的broadcast-v2、qkv1024、direct-kv、完整grade摘录。
7. 为什么会想到二维 RF 网格:沿着重复读取往回看
线索来自前面的供数试验
前面已观察到 RF 服务繁忙,多WG映射对结果影响很大,扩大输出tile的局部核又有收益。代码中还存在一个明确复用关系:同一个 A 行块能配多个 B 列块,同一个 B 列块也能配多个 A 行块。
当时没有逐字记录“网格想法第一次如何形成”。下面是依据代码的机制解释:要继续少搬数据,可以让一个 WG 同时保留多行、多列的输出累加器,让 A/B 的两种复用同时发生。
用2×4算一轮,就能看懂好处和代价
一个 WG 留住2行块×4列块,共8块输出。每个 K=32 轮搬2块 A、4块 B,就能配出8次小矩阵乘。若8个输出各自独立搬 A/B,需要16次逻辑块装载;共享之后是6次。
这些输出不能立即扔掉,因为下一轮 K 还要继续累加。因此8个输出块必须同时留 RF。每块32×32 FP32=4 KiB,64 KiB RF只有16区:
| 活跃内容 | 占用分区 |
|---|---|
| 8块输出累加器 | 8 |
| 2块A,使用双缓冲 | 4 |
| 4块B,使用单缓冲 | 4 |
| 合计 | 16 / 16 |
这也解释了为什么最终 W1 的 B 不用双缓冲:再加4区就放不下。更大的网格虽然复用更多,也会占更多累加器;“让所有东西都驻留、都双缓冲”没有满足容量的取值。
这里16→6是单WG单K轮的逻辑比较,不能推出整题快16/6倍。实际还包含其他WG复制、组播、epilogue、同步等成本。首页 RF 演示可以直观看到哪些组合放不下。
W2为何还要另一种分工
P1的 W2 求和长度1024,输出列相对少。最终将 K 分2片,使用2个行分片×4个列owner×2个K分片,共16 WG;每 WG 维护2×2局部网格,之后归并部分和。这里沿K拆开的收益与额外归并成本共同存在。
完整网格初版 P1为380,668周期,比442,153少约13.9%,功率却升到20.397 W。继续调整网格、存储与排程后更快,但约束问题再次变为:活动重叠太集中,怎样平滑最高窗口?
这条过程可读成“复用减少搬运→更多有效活动能重叠→功率成为新限制”。前半段成功并不免除后半段的验证。
8. D1权重只搬一次以后,为什么还要搜装载节奏
线索:同样的必要数据,发出的时刻影响结果
RF常驻避免了重复搬权重,但第一次装入1.5 MiB权重仍要付成本。多个SM一起发请求,会争用HBM、网络、DMA和RF写口,也会形成动态功率峰。
早期进度已提到“分批装载反而比全部同时装载快”,把启动竞争列为独立问题。后来一组 wave 对照显示另一种速度/资格权衡:16个SM同时装载为45,385周期、20.089 W;9个一批为49,084周期、18.876 W。前者快但超限,后者有功率余量却多了等待。
所以“wave越小越好”同样不成立。真正要问的是:放行多少请求、相隔多久,能让服务持续进行又不堆出过高峰值?
为什么从“按SM批次”改成“按字节桶”
各SM持有的权重数量不同。一次放行同样数量的SM,不代表放行同样多的数据。代码进一步对每条LD覆盖的64-byte内存行计数,累计到一个字节桶预算后换下一个时间事件。
由WG63使用普通WAIT/VEC发出这些时间事件,其他WG等相应事件再继续装载;它没有新增硬件调度器。WG63的第二层数据延后到第一层计算期间装入,使用前补齐依赖。这样把“何时搬”也放入软件排程。
先后试了SM wave、桶大小和时间间隔。桶有16,384/28,672/32,768 B等候选。但比较间隔的效果时必须固定桶和程序阶段,否则会混入其他改动。
同一代码系列里,间隔缩小到哪一步
下面四项均来自“fast epilogue + 延后WG63”的同系列,桶为28,672 B:
| 事件间隔参数 | D1周期 | 峰值功率 | 从这组可得的判断 |
|---|---|---|---|
| 104 | 48,265 | 18.919680 W | 仍有功率余量。 |
| 102 | 48,103 | 19.197199 W | 略快,峰值上升。 |
| 100 | 47,904 | 19.724952 W | 继续略快,仍合格。 |
| 98 | 47,635 | 19.866022 W | 四个已测点中最快。 |
最终选98;再对D1做直接K/V写回,降到47,049周期,功率保持19.866 W。日志中还出现别的间隔,但所属代码版本或其他设置不同,不能连接成同一条单变量曲线,也不能据此声称98是整个连续区间最优。
字节桶/间隔只是发射安排,不能直接视为真实持续带宽。请求可能排队、被其他活动延迟,最终仍以官方模拟的周期和窗口功率判断。
证据:分桶与事件生成代码、fast104/102/100/98及directkv98记录。
9. 最后117个周期:最高峰的位置会改变
为什么这时需要看功率时间线
P1已有更激进的异步batch候选:326,828周期,却达到21.709 W。更快还不够。D1的改进让两题周期乘积已有五万分余量,因此P1可以花一点周期,把最热窗口压进预算。
只看“峰值20.10 W”不知道该改哪里。radical_profile.py按模拟事件的动态能量与持续时间重建功率序列,计算每个1000周期窗口,找到最大者,再列出与该窗口重叠的指令;代码核对重建峰值与官方结果一致。这把一个全局数字变成可检查的具体时间和操作。
第一次定位后改W1;改完要重新定位
| 候选状态 | 最热1000周期窗口 | 窗口覆盖的指令 | 峰值 |
|---|---|---|---|
| 网格、移除SH后的版本 | 241,058–242,058 | 94条VEC、64条ST | 20.099857 W |
| 改逐块epilogue写回之后 | 16,432–17,432 | 23条VEC、64条ST | 20.051679 W |
第一处结合指令与地址对应 W1 的GELU结果写回。当时说明明确把注意力转向“等整批激活完成后写回”与“逐块写回”的对照。
改完后,最高峰移到了前面的QKV写回。此时继续只修改W1可能没有效果,因为决定资格的是新的最高窗口。于是继续尝试QKV写回间隔、写回相位等控制。
表里的VEC/ST条数是窗口覆盖计数,不能当作各类操作的功率占比。定位依赖事件时间、操作数地址和代码阶段的对应,不能仅凭“ST多”认定所有功率都来自ST。
为什么只多117周期就够
| P1写回安排 | P1周期 | 峰值功率 | 资格 |
|---|---|---|---|
| 逐块epilogue,尚未加QKV间隔 | 337,359 | 20.051679 W | 超限。 |
| 增加QKV写回间隔16 | 337,476 | 19.971397 W | 进入预算。 |
只多117周期,约0.035%,就跨过20 W。等待集中在已经定位的写回附近,其对全程序的代价很小。期间也试了48/128/256等间隔,以及集体写回相位;它们是保留下来的其他候选,并非16有理论最优证明。
最终配D1的47,049周期、共同面积22.494565 mm²,完整seed7评分为 50,416.649483。P1功率余量约0.029 W,D1约0.134 W;这是该教学模型中的合格点。
证据:W1峰值窗口原报告、峰值移位后的原报告、分析程序、最终grade摘录。
10. 怎样把这个过程变成人类下次能用的方法
如果只记“用RF网格、用分片、做融合”,下次遇到不同工作负载,还是不知道先做哪一个。更可执行的是保留什么观察触发什么试验,以及怎样判断该换方向。
| 看到的现象 | 接着问什么 | 能检验它的下一步 |
|---|---|---|
| 数据跨步反复使用 | 全驻留需要多少活跃空间? | 先像8-SM例子那样扣临时区、历史,再做真实放置。 |
| 一个阶段只有少数SM忙 | 任务能沿哪个数学维度拆? | 查可合并的部分结果;测片数,同时计算归约代价。 |
| 计算单元空闲、RF忙 | 同一输入块被谁反复读取? | 沿生产消费关系列复用,再测布局、网格或融合。 |
| 改了某段,峰值却没动 | 干预是否碰到真正最高窗口? | 重新定位窗口并查后续搬运,保留不改善的对照。 |
| 代理更优、完整程序却慢 | 代理漏了启动、通信、依赖中的哪项? | 补代表对照;若变量无法表达所需结构,就改模板。 |
| 加速后刚好超功率 | 哪些活动集中到同一窗口? | 只在相关装载/写回试节奏,重新检查全局最高峰。 |
给下一次实验写一张短卡,可以具体到这个程度:
观察: QKV广播间隔从256改1024,P1多5,268周期,峰值仍20.1301398 W。
怀疑: 当前最高峰可能在没有被这次干预改变的后续K/V导出。
试验: 固定硬件和D1,把K/V从RF直接写最终地址,同步改消费者;先查数值,再测周期和功率。
支持它的结果: 峰值显著降低,并进入20 W;若仍不动,就继续查新窗口,而不能宣布问题已解决。
实际结果: 442,153周期、18.398 W;随后完整配对grade为42,737.81。
搜索也可以用同一张卡约束:每个变量必须对应一个怀疑的机制,每个固定项要注明当前没有覆盖,每个代理“最优”都要带范围。反复返回这张卡,能避免把大量枚举误当作有效探索。
关于“我的先验为何只到一万多分”
现有记录不足以判断“注入先验”本身导致分低。两轮起点、可修改的生成器、时间和覆盖区域都不同;本轮也继承了前期RF驻留等成果。可观察到的是,Astra多次因新证据扩大可改的对象:从面板归属到融合任务,从总流量到具体发射节奏,从一个功率峰到下一个峰。
因而可以迁移的一条做法是:把先验写成带适用范围、允许被对照推翻的假设。 例如“更多WG能填等待”后面必须同时保留32WG/4行分片变慢的反例;“K分片无收益”也只能限定在当时模板,后来的RF网格组合需要重测。
证据范围和阅读入口
最终两题完整seed7 grade合格,seed13功能也均通过,最大绝对误差约2.998×10⁻⁶ / 9.537×10⁻⁷。本复盘核对了保存报告与配置、程序hash,没有重新运行长时搜索和评分。
导入的157条记录包括61双题、33个D1、63个局部核,保留各自追加顺序。三个完整grade检查点为30,217.71、42,737.81、50,416.65;其他记录会注明估计、局部核、超限或失败。失败消息为空时,不补写原因。
没有完整全因素消融,不能把总提分精确拆成每个技巧的独立贡献;也没有覆盖全部软硬件空间或证明全局最优。本文的“为什么”有当时明确说明,也有根据代码补的机制解释,已在相关处区分。
- 打开交互复盘:8个问题逐步阅读;需要时展开157条实验、候选比较、RF演示与精确模型。
- 最终摘要与最终参数:核对最终选择。
- 聊天外显说明摘录:核对当时对用户报告的线索和下一步。它是摘录,不能代替完整原生agent trace。
- 最终grade展示摘录:保留原报告SHA256;完整报告仍在源worktree,展示摘录不能用于提交。