简介:《Cadence Cerebrus User Guide》面向借助 Cadence Cerebrus 优化电子设计自动化流程的工程师和技术人员,围绕 22.1x 版本说明工具的功能、特定指令与使用案例,帮助读者理解软件在真实设计流程中的定位与操作要点。资源包仅含 1 个 PDF 文件,大小约 6.19MB,单文件便于本地保存、关键词检索和按章节查阅。目前已有 543 人学习下载,在同类工具文档中具备一定参考需求。指南更新至 2023 年 12 月,可用于了解 Cerebrus 的功能入口、应用场景与流程优化思路,适合作为日常查询和方案比对资料,对希望系统掌握该版本功能、提升设计效率的读者较为实用,也可用于团队内部培训和技术交流时快速定位知识点;由于内容由 OCR 扫描生成,个别字词可能存在识别偏差,阅读时需结合上下文核对。文档还附有版权、商标和受限使用声明,提醒读者在引用与传播时注意合规边界。
1. 一份 22.1x 的 Cerebrus 用户指南,能替你挡掉多少次白跑的 run
去年冬天我盯着一轮跑了十几个小时的 Cerebrus run,几十个 scenario 的 cost 曲线像心电图一样上下跳,最后定位到的问题很朴素:primitive 的注入时机压在 flow phase 之前,那个阶段压根不参与成本核算,等于白调。这类问题不需要多深的数学,只需要有人提前告诉你"哪个阶段算什么、哪个旋钮在哪一步才有效"。这份 22.1x 的用户指南(2023 年 12 月更新)就是干这个的:它把 Cerebrus 这套 ML 驱动的 RTL-to-GDS 流程优化框架拆成 flow phase、primitive、scenario 三层,再往上叠 config、Web UI、RAK 和几个专用 App。适合已经能跑通综合到 STA 全流程、但一提到 PPA 收敛就靠手工试参数的实现工程师,也适合刚接手集群、需要判断"这次 run 值不值得等"的负责人。
2. 先把三层模型立住:flow phase、primitive 与 scenario
在动手改任何一行配置之前,得先接受一个事实:Cerebrus 不是"自动帮你调参"的黑盒,它是一台把设计师经验编码成可搜索空间的机器。你对 flow 的理解越结构化,它搜得越准;你糊弄它,它就还你一堆看起来收敛、signoff 时全崩的解。这三层模型就是编码方式。
2.1 手工调参为什么在 signoff 前失效
手工调参的隐含假设是"参数之间近似独立":改一下 placement 的 effort,面积涨一点,时序好一点,凭经验能预判方向。这个假设在单个 phase 内勉强成立,跨 phase 就崩了。prects 阶段为了 WNS 把某条路径的逻辑层级压平,到 postcts 时钟树一插,这条路径的 skew 变成主导项,前面省下的裕量全被吃掉;再往后到 postroute,RC 提取一上来,原本靠估算撑住的 slack 直接翻负。
更麻烦的是搜索空间本身就是乘积级的。假设你有 6 个 primitive,每个 4 个取值,那就是 4096 种组合,而每种组合要跑完一整条 flow 才能拿到真实 PPA。人肉试 20 组已经是极限,采样率不到 0.5%,剩下的空间里有多少个更优解完全靠运气。血泪经验是:手工调参出来的"最优解"往往只是"你试过的那几个里最好的",不是空间里最好的。
Cerebrus 换了个思路,它不要求参数独立,而是把整条 flow 的每个 phase 当作一次可观测的状态转移,用强化学习在组合空间里做有偏采样——跑到当前看起来有希望的区域就多采,明显变差的区域就少采。这解释了为什么它能在几十个 scenario 内找到比手工试两百组更好的解,也解释了为什么 cost function 写错时它比手工更容易跑偏:它真的会朝你写的方向全力优化。
2.2 flow phase 是成本核算的坐标系
flow phase 是这份指南里最容易被跳过的概念,也是最容易踩坑的地方。Cerebrus 把一条实现流程切成若干可命名的阶段,成本核算和 primitive 评估都挂在这些阶段上。指南里反复出现的是 syn_opt、prects、postcts、postroute、signoff_opt 这五个,22.1x 版本默认对它们计算 cost;而 syn_generic、syn_map、floorplan、route 这几个在早期版本里默认是被忽略的。
这里有个版本差异必须记牢。22.14 起,cts 和 postcts 的 primitive 统一在 postcts 阶段评估,route 和 postroute 的 primitive 统一在 postroute 阶段评估——也就是说同一个物理动作的旋钮被归并到同一个成本观测点上,避免"在 cts 阶段评估、但效果要到 postroute 才显形"这种错位。如果你拿的是更早版本的指南,看到 primitive 表里的评估阶段和 22.14 不一致,不是你理解错了,是版本真的改了。
为什么这个坐标系重要?因为 cost 是在 phase 结束时采样的。你在一个不参与 cost 计算的 phase 里定义 primitive,它照样会被注入、照样改变网表,但优化器看不到它的贡献,于是它在这一轮里学到的"这个方向没用"其实是假信号。后面第 5 章会专门讲这个坑。
2.3 primitive 是唯一可以被机器拧的旋钮
primitive 这个词在指南里出现频率最高,本质就是把一条 set_db 命令、一个 Tcl 变量或者一个 flow step 命令,包装成带类型、带取值范围、带作用阶段的"可调参数对象"。它规定了三件事:调什么(命令模板)、能调到哪(取值范围或枚举)、什么时候调(作用阶段)。
数据类型上,指南列的是整型、浮点、字符串、枚举、布尔这几类,属性上关键的是默认值、取值范围、作用阶段(applies_to)和过滤条件(filter)。过滤条件的作用是让某个 primitive 只在特定条件下才进入搜索空间,比如只在某个 design 或某种 flow 变体下生效,避免把不适用的旋钮也塞进去稀释采样预算。
有个容易被忽略的区分:不是所有 primitive 都在同一个时刻被评估。指南里专门有一节讲延迟评估(delayed assessment),意思是某些旋钮的效果必须等后续 phase 才稳定,那就不在注入它的那个 phase 打分,而是延后到效果可见的阶段。这跟 2.2 说的合并评估是同一个设计哲学的两面。
2.4 scenario 是 phase 与取值的一次采样
一个 scenario 就是"在某个 flow phase 上,给一组 primitive 赋一组具体取值"的一次完整执行。base scenario 是不做任何调整的基线,其他所有 scenario 的 cost 都相对它计算。指南里两处默认值变动值得注意:max_scenarios 在 22.13 起不再依赖 primitive 的数量,而是根据可用机器资源和时间预算自动调整;WNS(100) 在 22.14 起取代 WNS 成为默认的时序指标,显示在 HTML 报告的 QoR 页面。
WNS(100) 这个改动看起来小,实际影响不小。WNS 只取最差的那一条路径,噪声极大,一条路径的估算误差就能让整个 cost 抖动;WNS(100) 取最差的一百条路径做聚合,对单点噪声更鲁棒,优化器收到的梯度信号更平滑。如果你发现升级后 cost 曲线比以前"平"了,不是优化器变懒了,是评价指标变稳了。
2.5 用目录结构反查:哪一章解决你的问题
指南正文十章加一个 FAQ,从头读到尾大概要两天,实际没人这么干。我的用法是把它当查询手册,按症状找章节:
| 你现在的症状 | 翻哪一章 | 关键内容 |
|---|---|---|
| 不知道 config 里该写什么 | 第 6 章 配置优化 | 路径组、权重、bootstrap 取值、cost 函数 |
| primitive 定义了但没效果 | 第 5 章 使用 primitive | 数据类型、属性、注入命令、延迟评估 |
| run 卡住或作业排队不动 | 第 4 章 运行与第 10 章 FAQ | 日志、distribution script、TMP 目录、重启 |
| 想复用上一轮的模型 | 第 4 章 模型复用 | 统一输出模型、scenario 重放 |
| 想看实时状态或报告 | 第 7 章 Web UI | Live 模式、静态 HTML、cost 改善图 |
| 想先跑个现成的例子 | 第 8 章 RAK | 快速上手包、命令行与浏览器输出 |
| 要做 floorplan 或 VT 专项 | 第 9 章 Apps | FP-Opt、Margins、VT、Clock 等 |
| 环境或 setup 报错 | 第 10 章 FAQ | setup 指南、输出检查、调试技巧 |
这张表的价值在于它省掉的是"通读两章才发现答案在第三行"的时间。新手建议从第 2 章和第 4 章起,把三层模型和一次完整 run 的骨架建立起来,再回头补第 5、6 章的细节。
3. 跑通第一个 run:从 config 到 live UI 的最小闭环
理论立住之后就该动手。这一章的目标很明确:在你自己的机器或集群上,用最小的配置量跑出一个有 base scenario、有 cost 比较、能在浏览器里看的 run。跑通一次比读十遍指南有用。
3.1 前置条件不止是 license
指南开篇列的前置条件写得客气:熟悉完整实现流程(综合、布局布线、静态时序分析)、熟悉 UNIX 和 Tcl/Tk。翻译成人话是——你得能手工把这条 flow 跑通,能看懂 log 里的时序报告,能自己写 Tcl 改 flow step。Cerebrus 不负责帮你搭 flow,它负责在你搭好的 flow 上做搜索;flow 本身有错,它会忠实地把错误放大几十倍。
动手前我会强制检查四件事。第一,版本对齐:cerebrus -version出来的版本号要和你手上这份指南的 22.1x 对得上,跨大版本的配置语法和默认值差异足以让你怀疑人生。第二,flow 能否单跑:不加任何 Cerebrus 参数,用原始脚本跑一遍完整流程,确认没有 setup 违例、没有缺失的库、STA 能出报告。第三,路径组是否定义:时序成本离不开路径组,指南把路径组列为必需项,空着跑出来的 cost 没有意义。第四,集群侧是否通:如果用 LSF,先确认提交一个空作业能正常排队和回收,再让 Cerebrus 去派发。
flow 接入方式有两种,指南第 3 章讲得很细。一种是外层控制流包装(outer control flow wrapping),把现有脚本拆成一个个 flow step,由 Cerebrus 调度;另一种是在现有脚本里注入 Cerebrus 的库调用,改动量小但耦合深。新手优先选前者,因为出问题时边界清晰,日志也好定位。包装的骨架大概是:
# flow_wrap.tcl —— 把已有的实现脚本拆成可调度的 flow step create_flow_step -name synth_opt -command {source scripts/synth.tcl} create_flow_step -name place -command {source scripts/place.tcl} create_flow_step -name cts -command {source scripts/cts.tcl} create_flow_step -name route -command {source scripts/route.tcl} create_flow_step -name signoff -command {source scripts/sta.tcl}这段的作用是把整条 flow 切成五个可命名的阶段。-name必须和后续 config 里引用的 phase 名一致,写错一个字母,对应的 primitive 就找不到挂载点,表现是"配置没报错但成本纹丝不动"。-command里用source而不是直接内联几千行脚本,是为了让每个 step 的失败点能单独定位——哪个 step 挂了,看它 source 的那个脚本的日志就行。
3.2 一份最小可跑配置
配置文件的字段很多,但第一次跑不需要全写。能撑起一次有效搜索的最小集合是:路径组、scenario 数量上限、cost 权重、统一模型开关。其余的先留默认。
# config.tcl —— 最小可跑骨架,属性名以本地 get_db -help cerebrus_* 为准 # 1) 时序成本依赖的路径组,必填,空着 cost 没有意义 set_db cerebrus_path_groups {clk_group reg_group} # 2) 本轮最多生成多少个 scenario,按机器核数和时间预算估 set_db cerebrus_max_scenarios 24 # 3) 多输入模型合并成统一输出模型,22.14 起默认 true set_db cerebrus_ml_generate_unified_model true # 4) cost 权重:时序占大头, leakage 和面积做约束 set_db cerebrus_cost_metric_weights { timing.setup.wns 0.60 power.leakage 0.25 area 0.15 }逐项说清楚。路径组是成本计算的分组维度,指南把它标为必需项,实际含义是"你关心哪些路径的时序",常见做法是按时钟域和关键数据路径分两组,不要图省事只写一个全局组。scenario 数量上限不要拍脑袋往大里写,先在单机小规模验证 10 到 20 个能跑通、cost 曲线有区分度,再上集群放大。统一模型开关在 22.13 是新功能、22.14 变成默认,只有在用-in_models复用人模型时才有意义,第一次跑保持默认即可。
cost 权重这块最容易翻车。三个数加起来必须是 1(或者按比例归一),时序权重低于 0.5 基本等于放弃时序,跑出来的解面积漂亮但 signoff 全红。另外注意 22.14 起 hold 成本默认参与计算,你如果在旧版本上调过"关闭 hold 成本"的开关,升级后要重新确认权重表——报告的权重表格式也跟着变了。
3.3 启动命令与参数
配置齐了之后启动就一行,但每个参数都影响后续几小时的资源占用:
# 启动一轮 Cerebrus;-j 是并行作业数,-max_scenarios 与 config 取其一即可 cerebrus \ -design top_core \ -flow flow_wrap.tcl \ -config config.tcl \ -j 32 \ -max_scenarios 24-design是这次 run 的标识,日志目录、临时目录、HTML 报告都按它命名,起名要能一眼看出是哪个模块哪一轮。-flow指向 3.1 里的包装脚本。-config指向 3.2 的配置。-j是同时跑多少个 scenario 的并行度,这个数字直接决定你会不会把集群打爆——常见错误是按机器总核数填,结果每个 scenario 自己还要多线程,实际占用翻三倍。我的经验值是总可用核数除以单 scenario 峰值核数,再留两成余量。
启动后终端会打印 live UI 的访问地址。指南第 7 章把 Web UI 分成 live 模式和静态 HTML 模式:live 模式连着正在跑的 run,能看到 scenario 的实时状态、过滤基线值、cost 改善图,还能对单个 scenario 做 kill、重跑、下压、解压这些交互操作;静态模式是 run 结束后生成的报告,适合发给不看命令行的人。第一次跑建议全程挂着 live 页面,它对"这次 run 是不是在正常工作"的判断比翻日志快得多。
3.4 日志、临时目录与 base scenario 健康判断
run 启动后最该做的不是等结果,是确认 base scenario 是否健康。指南第 4 章专门有一节讲怎么判断 base scenario 跑成功,核心逻辑是:base scenario 是零调整的基线,它挂了后面所有对比都没意义。判断方式不复杂,看三处——日志里有没有 setup 阶段的致命错误、distribution 日志里每个子作业的退出码是不是零、base scenario 的 cost 是否落在你手工跑一遍时的合理区间。
日志的组织方式值得提前摸清,因为出问题时你要在两分钟内定位到是哪一步挂的。cerebrus 主日志记录调度和决策,每个 scenario 有自己的子日志,distribution 日志记录作业派发和回收。指南里提到的 TMP 目录是临时工作区,每个 scenario 在这个目录下有一份独立的中间产物,磁盘水位要盯着——一轮几十个 scenario,每个都留一份网表和报告,几百 GB 很容易吃满,吃满之后的表现是作业莫名其妙失败,报错还跟你说是 license 问题。
3.5 run 之间怎么接续:restart、加 -j、model reuse
第一次跑完通常会遇到三种情况,指南第 4 章各给了一条路。
第一种,跑到一半想加并行度。正在跑的 run 不能直接改-j,但可以重启并继承已完成的 scenario,不必从头再来。第二种,跑完想接着跑更多 scenario。这时候用模型复用,把上一轮的模型作为输入喂给下一轮,避免从零开始重新学。22.13 起支持把多个输入模型合并成一个统一输出模型,22.14 把这个特性变成默认开启,对多轮迭代的场景很实用。第三种,想复现某个特别好的 scenario。用 scenario replay,把那一组 primitive 取值单独重放一遍,验证它是真的更优还是采样噪声——这个动作后面第 6 章会展开。
有一点要提醒:模型复用的前提是输入模型的维度对得上。如果你上一轮用的是 6 个 primitive,这一轮加了 2 个新的,直接复用会报维度不匹配,正确做法是先只复用旧的那 6 个跑一轮,让新 primitive 从 bootstrap 区间开始探索。
4. 把 primitive 写对:定义、注入与评估
这一章是整份指南密度最高的部分,也是最值得反复读的。primitive 写错的表现往往不是报错,而是"跑了很久但结果没变化",排查成本极高。
4.1 数据类型与属性:先想清楚这个旋钮的形状
定义 primitive 之前先回答四个问题:它是连续的还是离散的、取值范围是多少、在哪个 phase 生效、什么条件下才启用。这四个问题对应指南里的类型、取值、作用阶段、过滤条件。
| 类型 | 适用场景 | 取值写法 | 常见误用 |
|---|---|---|---|
| 整型 | 线程数、迭代次数、切割份数 | 上下界或离散列表 | 范围给太宽,采样大量落在无效区 |
| 浮点 | 目标裕量、derate 系数、RC 因子 | 上下界加步长 | 步长太小,几十个 scenario 才覆盖一小段 |
| 枚举 | effort 档位、策略选择 | 有限字符串列表 | 混入当前版本不支持的档位 |
| 布尔 | 开关类特性 | true / false | 与实际生效条件冲突,开了也不起作用 |
类型选错的代价是采样浪费。一个本该是枚举的 effort 档位,你写成整型 0 到 10,优化器会在 3、4、7 这些不存在的档位上反复试探,每次都要跑完整个 phase 才知道无效。反过来,一个本该连续调节的裕量你写成三档枚举,搜索精度直接砍掉一个数量级。
4.2 定义一个 primitive 的四个必填信息
定义语句的形态在各版本略有差异,但结构稳定:名字、类型与取值、作用阶段、命令模板。下面是一个贴近实际用法的骨架:
# 定义一个作用于 postcts 阶段的连续型 primitive define_primitive \ -name cts_target_margin \ -type float \ -range {0.00 0.30} \ -applies_to postcts \ -command {set_db ccopt_target_margin $VALUE} \ -description "CTS 阶段的目标裕量,单位 ns"-name是唯一标识,后面 config 里引用、报告里显示都用它,起名要能看出物理含义,别用 p1、p2。-type配-range(连续型)或-values(离散型),两者不要同时给。-applies_to决定它在哪个 phase 被注入和评估,这是最容易写错的一项,见 5.1。-command里用$VALUE做占位符,Cerebrus 在生成 scenario 时把它替换成具体取值;如果你的命令需要拼接多个参数,模板里的引号和转义要格外小心,Tcl 的解析顺序会让一个多余的引号变成运行时错误而不是语法错误。
命令模板写完后强烈建议先在交互式环境里手工替换一次取值跑一遍,确认命令本身能执行、效果能被观测到,再交给优化器。指南里提到用 eval_legacy 定义 primitive 的旧方式,新写的一律走标准路径,旧方式只在维护历史脚本时用。
4.3 注入时机与 filter:让旋钮只在该出现的时候出现
注入不是把所有 primitive 一股脑塞进每个 scenario,而是按作用阶段和过滤条件决定谁上场。指南里有一节专门讲在定义或注入时应用过滤,用途是控制搜索空间的维度——每多一个 primitive,组合空间翻好几倍,无关的旋钮会稀释采样预算。
常见做法是按 design 变体和 flow 变体做两级过滤:只在特定模块上生效的 primitive 加模块过滤,只在开启某条 flow 分支时才有效的 primitive 加条件过滤。这样同一份 primitive 定义可以在多个项目间复用,不用为每个项目维护一份拷贝。
另一个容易忽略的点是注入的层级。指南第 3 章讲在现有 flow 脚本里注入 Cerebrus 库时提到,注入位置决定了 primitive 相对于用户自定义 flow step 的执行顺序。如果你的 primitive 必须在某个 setup 步骤之后才生效,注入点就要放在那个步骤之后,否则命令执行时依赖的对象还不存在。
4.4 动态添加与延迟评估:run 跑起来之后还能改
22.13 引入了在 run 进行中动态添加 primitive 的能力,这对长时间跑的场景很实用:发现某个方向值得探索,不用停掉整轮重启,直接追加 primitive,后续 scenario 会用上。用法上有约束——新加的 primitive 只影响尚未生成的 scenario,已经跑完的不受追溯影响,所以追加的时机越早越好。
延迟评估(delayed assessment)解决的是另一类问题:某些旋钮的效果要等好几个 phase 才稳定,在注入点直接打分等于用噪声训练模型。延迟评估允许你把打分点挪到效果可见的阶段,代价是这一轮反馈变慢,需要更多的 scenario 才能收敛。典型的取舍是:CTS 相关的旋钮如果直接影响时钟树结构,延后到 postcts 阶段统一评估;纯 setup 类的约束调整可以在本阶段就评估。
4.5 校验:注入有没有真的生效
写完 primitive 别急着跑大轮,先做一次单点验证。最省事的办法是用 scenario replay 只跑一个指定取值的 scenario,然后翻两个地方:一是该 scenario 的子日志,搜索你命令模板里的关键字,确认命令被执行且没有报错;二是 HTML 报告的 QoR 页面,确认 cost 分项确实发生了变化。两处都对上,才说明这个 primitive 从定义到注入到评估整条链路是通的。
这一步花十分钟,能省掉后面几小时的无效 run。我见过太多次"primitive 定义得很漂亮,但作用阶段写错,整轮跑完才发现 cost 曲线是平的",那时候已经浪费掉的时间和机时都回不来了。
5. 避坑:五类把 run 跑废的操作
这一章的每一条都是能让你损失半天到两天的坑。指南 FAQ 里有一部分,剩下的是我在实际 run 里撞出来的。按"现象 → 原因 → 解决"写,照着比对。
5.1 坑一:primitive 作用阶段写错,cost 根本没算进去
现象:run 正常结束,scenario 之间的 cost 差异极小,几乎是一条直线,但翻日志能看到 primitive 命令确实被执行了。
原因:primitive 的-applies_to指向了一个不参与成本核算的 flow phase。22.1x 默认只对 syn_opt、prects、postcts、postroute、signoff_opt 计算成本,早期版本还会忽略 syn_generic、syn_map、floorplan、route 这几个阶段的成本。把旋钮挂在这些阶段上,命令照样注入、网表照样变,但优化器看不到收益,于是判定"这个方向没用",后续采样就会避开它。
解决:先确认你手上的版本对哪些 phase 计算成本,再把-applies_to改到效果真正被观测的那个阶段。注意 22.14 起 cts 和 postcts 合并到 postcts 评估、route 和 postroute 合并到 postroute 评估,跨版本迁移时这张映射表要对一遍。改完用 4.5 的单点验证法确认 cost 分项真的有变化,别只看日志里命令执行成功。
5.2 坑二:max_scenarios 拍脑袋设大,机器被撑爆
现象:run 启动后大量作业卡在排队,live 页面上一片 pending,跑了几个小时完成的 scenario 数还是个位数。
原因:scenario 数量上限和并行度是两个独立参数,一起放大会产生乘法效应。每个 scenario 自身还要多线程,按机器总核数填-j会让实际占用远超物理核数,调度器开始频繁换页,单个 scenario 的耗时翻倍。指南在 22.13 说明里特别提到 max_scenarios 的默认值改成了按机器资源和时间可用性自适应,就是在堵这个口子。
解决:先用小规模摸清单个 scenario 的峰值核数和平均墙钟时间,再反推合理的-j和 scenario 上限。经验公式是可用核数 / 单 scenario 峰值核数 × 0.8,scenario 上限按"能在你愿意等待的时间窗口内跑完"倒推。跑的过程中盯 live 页面的完成速率,如果每个 scenario 的耗时随着并发上升而明显变长,说明已经超过机器的舒适区,降并发比加 scenario 划算。
5.3 坑三:cost 权重只写时序,跑出一堆面积爆炸的解
现象:时序指标确实改善了,但面积涨了三成以上,后端评估时被直接打回。
原因:cost 权重表里只配了 timing 一项,或者时序权重给到 0.8 以上,其余分项可以忽略不计。优化器没有价值观,你写什么它就优化什么,没有面积约束它就朝面积无限膨胀的方向走——反正面积不进 cost。
解决:至少配三项:时序、漏电功耗、面积,权重按项目实际的约束优先级分配,时序通常占 0.5 到 0.6,剩下两项分配余量。指南第 6 章给了功耗分项的计算示例,也支持把运行时加进 cost 函数、支持约束驱动的成本计算,这些在项目早期就该配好。另外 22.14 起 hold 成本默认参与计算、WNS(100) 成为默认时序指标,升级后要重新核对权重表和报告格式,别沿用旧的心算。
5.4 坑四:distribution script 没验证,作业排队排到天亮
现象:本地小规模跑得好好的,一上集群就大面积失败,报错信息五花八门,有的说路径不存在,有的说环境变量未定义。
原因:distribution script 负责把 scenario 派发到集群节点,它继承的是提交节点的环境,但执行节点上的工作目录、环境变量、库路径可能完全不同。指南第 4 章专门讲怎么验证 distribution script、怎么通过 distribution 日志定位失败点,这段被跳过的后果就是"本地能跑、集群不能跑"。
解决:在正式跑大轮之前,先用 distribution script 提交一个极小的测试作业,确认三件事——工作目录在执行节点上可写、依赖的环境变量在执行节点上可见、作业结束后临时文件能被正确回收。出问题时直接看 distribution 日志,它会记录每个子作业的提交命令和退出码,比自己猜快得多。集群环境有变动(换了队列、改了挂载点)之后要重新验一遍。
5.5 坑五:拿旧模型直接复用,输入维度对不上
现象:模型复用启动后立刻报错退出,或者跑起来了但优化效果还不如不复用。
原因:两种情况。一是这一轮的 primitive 集合和上一轮不一致,模型输入的特征维度对不上,直接加载就崩。二是维度碰巧对上了但语义变了——某个 primitive 的取值区间被改过,模型学到的"高值更好"在新区间里可能是反的。
解决:复用前先对齐 primitive 集合,新增的 primitive 从 bootstrap 区间独立探索,不要指望旧模型对它有先验。22.13 起支持把多个输入模型合并成统一输出模型,22.14 起默认开启,多轮迭代时按这个机制接续比手工拼模型可靠。如果升级过版本,复用前还要确认 cost 函数的定义没变——权重或指标定义一变,模型学到的映射就失效了。
6. 复现一个"好结果":用 scenario replay 加自定义指标做验收
前面几章讲的是怎么让 run 跑起来、跑对。真正决定这套流程能不能沉淀下来的,是你能不能把一个"看起来不错"的结果复现并验证。我的做法固定成三步,每轮 run 结束都走一遍。
6.1 先重放,再相信
优化器给出的最优 scenario 有可能只是采样噪声,尤其在 scenario 数量偏少、指标方差偏大的时候。指南第 4 章给的 scenario replay 就是干这个:把那一组 primitive 取值单独拎出来重跑一遍,看 cost 是否落在同一区间。重放支持几种包装方式,用外层控制流包装的 flow 直接用对应的 replay RAK,用 Stylus 流程包装的走另一套,还能通过禁用指定 primitive 的方式做消融——把某个旋钮关掉再跑,看它到底贡献了多少。消融这一步很多人省掉,但它能告诉你"这 8 个 primitive 里其实只有 2 个在起作用",下一轮就可以把搜索空间砍掉四分之三。
6.2 自定义指标进报告
默认的 QoR 页面只显示内置指标,项目里真正关心的往往是别的量,比如某个特定路径组的 slack、某个模块的动态功耗。指南第 4 章讲怎么定义自定义指标并配置 HTML 的 YAML,把自定义量挂进报告页面。我的习惯是每接一个新模块,先花二十分钟把两三个项目特有指标接进去,后面每一轮 run 的报告都能直接看出这些量有没有被牺牲掉,不用再翻原始报告。
| 验收项 | 判断标准 | 不通过时的动作 |
|---|---|---|
| 最优 scenario 重放一致性 | cost 落在原值 ±5% 以内 | 增加 scenario 数量重跑,判定为噪声 |
| primitive 消融 | 至少能定位出 2 个有效旋钮 | 检查作用阶段和过滤条件 |
| 自定义指标 | 在 HTML 报告中正常显示且趋势合理 | 检查 YAML 配置和指标名拼写 |
| 权重表 | 与项目当前阶段优先级一致 | 调整权重后小规模重跑验证 |
6.3 从那以后我每次都要走一遍
有一轮我图快,跳过重放直接把最优 scenario 的配置推给了下游,结果下游复跑时时序差了 40ps,回头一查是那一轮的 WNS 采样恰好落在一次库加载抖动上,纯粹是噪声。从那以后我每次 run 结束都强制走一遍"重放 + 消融 + 自定义指标核对",哪怕只花二十分钟,也比返工一天划算。这份 22.1x 指南里那些看起来啰嗦的验证章节,恰恰是最该先读的部分。希望帮到你。
本文还有配套的精品资源,点击获取