先说一件挺尴尬的事。
现在的AI写科学计算代码,已经练出了一手不错的手活儿。你让它写个电力系统求解器,它能给你一份能跑、能出结果、语法毫无问题的代码。可问题是,这份代码跑出来的答案可能慢得要命,或者在某些刁钻的电网状态下直接崩掉,而AI自己完全不知道为什么。
这就好比你请了一个很会打字的助理,他能把任何一份病历都整理得工工整整,字迹清晰,格式规范。但要是让他诊断病情,他只会说"病人体温偏高",却说不出来是感染、中暑还是别的什么原因,更别提开出对症的药方了。
这篇来自UC Berkeley和阿里巴巴达摩院的论文,就是在死磕这个问题。他们给这套方法起名叫ADSD(Auto-Diagnosis and Skill Discovery,自动诊断与技能发现)。核心思路一句话就能说清:先搞清楚求解器为什么差,再去找对症的方法,而不是瞎改一通。
数值求解器*:一种计算机程序,用来求解数学方程的近似解,比如电网的电压分布、化学反应的浓度变化曲线等,这类方程往往没有解析解,只能靠迭代逼近。
为什么"跑得动"和"跑得好"是两件事
你可能觉得,代码只要能运行、能出数字,不就算成功了吗?
还真不是。
电网里有一类计算叫潮流计算(Power Flow),目标是算出每个节点的电压大小和相位角,让整张电网的电力供需方程全部平衡。这个方程组本身没有显式解,得靠牛顿法这类迭代算法一步步逼近。
牛顿法*:一种通过不断用切线逼近函数零点的数值迭代方法,每一步都要重新计算一次雅可比矩阵(函数的导数矩阵)并做一次矩阵分解,计算量不小。
问题是,这套迭代过程特别容易踩坑。电网结构变了(比如一条线路检修断开了),或者用电负荷逼近系统极限(比如夏天用电高峰),矩阵就可能变得"病态",也就是数值上极其敏感,稍微有点误差就被无限放大。专业说法叫"病态条件"(ill-conditioning),还有一种叫"刚性"(stiffness)的问题,常见于化学反应动力学方程里,意思是系统里有些变化特别快、有些特别慢,普通的显式算法为了保证稳定,步长必须切得极细,算起来又慢又费资源。
这些坏毛病,表面上看起来都长得差不多:程序跑得慢,或者报错,或者给出一个看似合理但误差很大的答案。可是导致这些症状的病因天差地别。同样是"跑得慢",可能是矩阵分解次数太多,也可能是步长选择策略太保守,还可能是算法本身的收敛阶数不够高。方子不对症,吃了也没用。
这就是论文作者观察到的核心矛盾:现在的AI科学计算助手,能执行代码、能看报错信息、能去网上搜文献、能把论文转换成可执行的工具,但这些能力各自为战,互相之间没有配合。执行反馈告诉你"这里错了",但不会告诉你"这是因为矩阵病态";文献搜索能找到一堆论文,但关键词搜索出来的东西,跟你手头这个具体的求解器症状,未必对得上号。
于是就出现了这篇论文反复强调的一个场景:AI能看出求解器表现不好,却说不出病根在哪儿,更别提精准地从几百篇论文里挑出那一篇能治病的方法。
诊断优先:把黑箱拆成三层
ADSD的做法,是把"改进求解器"这件事拆成三层清晰的阶段,而不是让AI一股脑儿地去"优化代码"。
第一层叫可观测行为(observable behavior),就是求解器跑起来之后留下的原始痕迹:残差怎么变化的、迭代了多少次、每次迭代花了多长时间。这些是硬邦邦的事实,谁也改不了。
第二层叫诊断知识(diagnostic knowledge),这是最关键的一跳:把观察到的症状和背后的数值病因连接起来,形成一个可以验证、可以被推翻的假设。比如"当雅可比矩阵最小奇异值低于某个阈值时,求解器需要更多次迭代"——这句话听起来简单,但它把一个模糊的直觉(矩阵看起来很弱)变成了一个可以用代码检测的具体条件。
第三层才是可执行的求解器知识(executable solver skill),也就是真正把诊断结果对应到具体的数值算法,写成能直接插进原求解器里用的代码模块。
如果你直接把第三层拿出来单独做,跳过前两层会怎样?论文里专门做了这个对比实验,让AI不经过诊断,直接"自我改进"求解器。结果五组对比里有四组误差确实降了,但另外五组反而变差了。这就像让一个没有体检报告的人直接去药房抓药,抓中了算运气好,更多时候是蒙的。
更狠的是,论文还试了让AI连续改五轮,每一轮都能看到之前所有版本的代码。结果呢,GPT基线模型一开始误差反而变大,后来慢慢爬回来一点,但最终还是卡在比原始版本更高的误差水平上,再也突破不了。Claude基线几乎是原地踏步,五轮下来几乎没有任何进展。这说明给AI更多"自我反思"的机会,并不能替代真正的诊断过程。诊断不是锦上添花,是整个流程里省不掉的那一环。
诊断阶段具体怎么做
整个诊断流程分成三步。
第一步是生成并冻住一个基线求解器(论文里叫N0),让它在一批公开测试样例上跑一遍,把所有的运行轨迹、残差历史、迭代次数统统记录下来。这里有个细节值得注意:整个流程里AI被明确禁止调用现成的成熟求解器库,因为研究目的是提升AI自身已经掌握的数值能力,如果直接套用别人写好的成熟工具,就没法判断提升到底来自哪里了。
第二步是构建诊断技能。AI先快速浏览文献库里每篇论文的摘要、引言、结论,筛出可能包含"症状-病因"关系的论文,这一步相当于先看目录再决定要不要读全文。被选中的论文会被完整通读,每一条症状病因对应关系都要配上论文里的具体证据,比如某个公式、某条定理的适用条件。相近的诊断逻辑会被打包成一组可执行的诊断探针。
诊断探针*:一段可以自动运行的检测代码,输入某次求解过程的痕迹数据,输出判断这次求解是否符合某个假设的症状特征。
第三步是假设的生成与验证。这一步设计得挺巧妙:把公开样例随机切成几轮"诊断轮次"和一个独立的"验证池"。比如在IEEE-118这个电网基准上,5000个公开样例被切成5轮、每轮200个用来生成假设,剩下4000个专门用来验证假设站不站得住。为什么要这么切?因为如果直接在全部数据上一次性找规律,很容易把偶然的巧合当成普遍规律。分轮次操作,逼着AI每次只看一小块数据,提出的假设必须在完全没见过的4000个样例上也站得住才算数,论文设的门槛是通过率超过90%才算"验证通过"。
这跟科学实验设计里"训练集和测试集分开"的逻辑是一个道理,但这里分得更细,还多了一道"先在小范围里提想法,再去大范围里验证"的保险。
举个具体例子。AI观察到,当某个求解出的电网状态对应的雅可比矩阵最小奇异值低于0.16时,求解器往往需要更多轮迭代才能收敛。这个0.16不是文献里抄来的,也不是写死在代码里的,是AI在200个诊断样例里看到四分之一分位点大概是0.16左右,主动试出来的一个邻近阈值。符合这个条件的50个样例平均要迭代5.78次,不符合的那些平均只要5.01次。这个差距看着不大,但放到4000个验证样例上反复验证,确实稳定存在,这才被收进"已验证假设"名单里。
如果这个假设通不过验证池的检验,会直接被扔掉,不会进入下一步。这种"先怀疑、再验证、通不过就作废"的机制,跟临床医学里药物试验的思路很像:不是医生觉得这药有效就上市,得经过双盲对照才算数。
从假设到技能:精准狙击,而不是大海捞针
诊断阶段给出的不是最终答案,而是一个精确的搜索指令。拿GPT基线在IEEE-118上的案例来说,诊断结论是"矩阵病态会拖慢收敛速度",对应的搜索问题就变成了:哪些已发表的方法,能用更少的矩阵分解次数换来更多的非线性迭代进展,同时还不破坏原求解器的方程结构?
这个问题精确到什么程度?从312篇相关文献里,筛出82篇候选,最终只有6篇被完整通读,产出9份方法评审,最后真正落地成可执行技能的只有2个方法。这个比例说明,诊断不是让AI去读更多论文,而是让它少读、但读得准。
如果没有诊断这一步,直接让AI去读这300多篇文献找方法会怎样?大概率会读得又多又散,因为它不知道该往哪个方向使劲。这就像在图书馆里找一本书,如果你知道书名和作者,直奔那一排书架就行;如果只知道"我想要一本关于数学的书",你可能得把整个数学分区翻一遍,还未必找得到真正合用的那本。
技能发现这一步,论文把它拆成四个环节:根据假设筛选相关论文、核对论文里的理论假设是否跟自家求解器兼容、实际把方法实现成代码、最后打包成可复用的"技能包"。每一步都要求AI留下可追溯的证据,比如论文具体哪一页、哪个公式、什么假设条件。
技能包*:一份打包好的代码模块,包含具体的数值算法实现、使用说明,以及这个方法背后的理论依据摘要,可以直接插进其他求解器里用,不需要重新实现。
两个真实案例,看技能怎么起作用
论文里有两个案例讲得特别细,值得拆开说说。
第一个案例是GPT基线在IEEE-118潮流求解上的改进。原始的N0求解器用的是标准牛顿法:每迭代一次,就要重新算一次雅可比矩阵、做一次矩阵分解、解一次线性方程组。这三件事是绑死在一起的,意味着"多迭代一次"和"多做一次矩阵分解"完全是同一回事,分解次数直接决定了计算成本。
诊断找到的病因是"矩阵病态会拖慢收敛",对应找到的两个方法很有意思,方向完全相反。第一个方法叫"多步分解复用",核心思路是固定住当前这次算出来的矩阵,在它的基础上连续做好几次修正,不用每次都重新分解矩阵。打个比方,这就像修一条路,与其每铺十米就重新测量一次地基(每次都要重新计算昂贵的矩阵分解),不如先把整段地基测量清楚,然后连续铺很长一段路都不用再测。实际效果是,平均每个样例的矩阵分解次数从5.116次降到2.755次,几乎砍掉了一半,运行时间从0.727秒降到0.494秒,误差基本没有变化。
第二个方法叫"七阶方法9",走的是另一条路:不是省分解次数,而是让每一次迭代的收敛精度大幅提升,哪怕多做一次矩阵分解也值得。它用两次矩阵分解换来了四次线性求解,收敛阶数更高,结果平均误差从9.10×10???降到7.46×10???,整整小了三个数量级,但运行时间反而变长了一点。
这两个方法一个管效率、一个管精度,正好对应诊断出来的两类不同需求。如果不做诊断,直接把两个方法随便捏在一起用会怎样?论文做了组合实验,把两者叠加后,分解次数3.114次、误差2.76×10???,介于两者之间,相当于各让了一步,哪个指标都不是最优,但整体更均衡。这说明,搞清楚每个技能解决的是哪个具体问题,才能知道什么时候该用哪个、或者怎么搭配着用。
第二个案例是Qwen基线在AC-OPF(交流最优潮流,一种在满足电网物理约束前提下寻找最低发电成本方案的优化问题)上的改进,这个案例更戏剧性,通过率直接从14.42%飙到98.36%。
原始求解器用的是内点法(interior-point method),一种常见的约束优化算法。诊断发现一个很奇怪的现象:所有失败案例里,报告出来的"稳定性残差"几乎都卡在同一个数值附近,跟目标函数梯度的无穷范数几乎完全一致。这说明,求解器在失败案例里,它的拉格朗日乘子(衡量约束"紧不紧"的量)几乎始终停留在接近零的状态,根本没有真正启动优化过程。
往深挖一步,原因出在第一步迭代的步长上:由于目标函数的梯度数值(大约3719)比约束方程的数值(大多在1左右)高了近3700倍,导致步长被压缩到极小极小,小到相当于原地踏步。这就好比两个人一起拉一根绳子,一个人力气是另一个的3700倍,结果那个力气小的人根本感觉不到绳子在动,优化算法也是同样的道理,强弱悬殊的两类数值混在一起算,弱的那部分根本推不动。
对应的技能来自一篇经典但依然管用的老论文(Wachter & Biegler, 2006),这篇论文正是内点法求解器Ipopt背后的理论基础。技能包含两个动作:一是对不同约束行做等比例缩放,把悬殊的数量级拉到同一水平线上;二是重新设计一个"归一化进度指标",用来判断优化到底有没有在往前走,而不是用原始的、容易被数量级差异扭曲的残差。这两步做完,求解器终于能正常推进优化过程,通过率因此大幅跃升。
这个案例特别值得琢磨的地方是:Wachter and Biegler这篇论文发表于2006年,是内点法领域的经典之作,理论上现在的大模型训练语料里肯定见过它。但基线模型自己写的求解器,偏偏没有用上这两个关键机制。这说明,知道一个方法存在,和知道这个方法该用在哪个具体场景里,是两件完全不同的事。诊断的价值,恰恰就在这道鸿沟上。
四个战场的实测成绩
论文在四个差异很大的数值计算领域里都做了测试,分别是电力系统潮流方程求解、交流最优潮流控制、刚性常微分方程积分、以及非均匀扩散偏微分方程求解。参与测试的基座模型有三个:GPT-5.5、Claude-Sonnet-5,以及开源模型Qwen3.8-2.4T。
在电网潮流求解这个场景里,最亮眼的数字是GOC-500基准上,Qwen基线经过ADSD改造后,误差从约1.0×10??降到约1.4×10???,缩小了将近71倍,运行时间基本没变化。
在交流最优潮流优化的边缘案例测试里(专门挑选了接近电网最大承载能力、高需求又高拥堵的极端场景),Qwen基线的通过率从14.42%提升到98.36%,这个提升幅度相当惊人。
在刚性常微分方程积分测试里,用了111个系统生物学模型,涵盖了反应网络里常见的"快慢混合"问题。GPT基线的通过率从70.1%提升到90.6%,误差中位数从9.39×10??降到3.93×10??,缩小了约24倍。Claude基线更是直接做到100%通过率。
在高对比度扩散方程求解测试里,用的是128×128网格、涉及16384个未知数的二维扩散问题。GPT基线的误差缩小了超过3倍,而且求解器调用底层运算的次数从215次降到71次,意味着同样精度下省了大量计算资源。
泛化能力:学到的东西能不能用在新场合
光是在训练用的数据上表现好,说明不了太多。真正值得关心的是,学到的技能能不能用在之前没见过的情况里。
论文设计了两种泛化测试。第一种叫拓扑泛化,训练时只给AI看"少两个组件"的电网结构(叫N2),测试时拿"少一个组件"(N1)和"完整电网"(N)去检验。结果显示,学到的技能在这些没见过的拓扑结构上依然有效,各个基座模型、各个电网基准上几乎全部实现误差下降,降幅从百分之二十几到百分之九十几不等。
这个结果其实挺重要的,因为真实世界里的电网工程师,天天都要应对不同的网络拓扑:一条线路检修了、一台变压器退出运行了,电网结构随时在变。如果一套改进方案只认一种拓扑结构,换个场景就失效,那在实际工程里基本没法用。
第二种是可行性泛化,训练时只用"状态良好"的电网样例(叫F),测试时拿"接近系统崩溃边界"的样例(叫IF)去检验。这类样例贴近电压稳定性的极限,数值上天然更难处理。结果显示,提升幅度确实比拓扑泛化小一些,这在情理之中:越接近系统物理极限,留给算法腾挪的空间本来就越小。但即便如此,学到的技能依然带来了实打实的改进,没有出现"训练时有效、换个场景就失灵"的情况。
这就像一个老师教学生解题,如果只会套用一道例题的固定步骤,换一道题稍微变个数就不会做了,那说明学生学的只是表面套路。而ADSD展现出来的泛化能力,更接近于学生真正理解了背后的数学原理,所以换个场景照样能用。
诊断这件事,到底难在哪
读完这篇论文,我反而觉得最有意思的不是技能发现这一半,而是诊断这一半暴露出来的一个认知偏差。
我们通常以为,AI缺的是知识。给它更大的训练数据、更多的文献、更强的检索能力,它就能变得更聪明。但这篇论文的几个案例恰恰证明了一件更微妙的事:Wachter和Biegler那篇2006年的经典论文,它里面的方法大概率早就被塞进了GPT、Claude这些大模型的训练数据里。问题从来不是"AI不知道这个方法",而是"AI不知道这个方法该用在眼前这个具体的失败场景里"。
知识的拥有量和知识的检索精度,是两件完全不同的事。这跟人类专家的成长路径其实很像:一个刚毕业的工程师,可能把所有教科书上的公式都背得滚瓜烂熟,但面对一台实际出故障的设备,却不知道从哪里下手。而一个有经验的老工程师,未必记得住所有公式的具体形式,却能一眼看出"这个振动频率不对,大概是轴承磨损",然后翻书去确认具体该换哪种型号的轴承。
诊断,本质上就是在模拟这种经验性的直觉,把它变成一套可以验证、可以复用的流程。
Q&A
Q1:ADSD是什么?
A:ADSD全称Auto-Diagnosis and Skill Discovery(自动诊断与技能发现),是UC Berkeley和阿里巴巴达摩院提出的一套框架,先诊断数值求解器性能差的根本原因,再据此从文献中找到对症方法并打包成可复用的求解器技能,用来改进AI生成的科学计算代码。
Q2:ADSD和直接让AI自己改代码有什么区别?
A:论文做了对比实验,直接让AI反复自我改进求解器,五组实验里四组误差反而变差,连续改五轮也没能缩小和ADSD的差距。ADSD通过诊断先锁定病因、再精准检索对症方法,效果明显更稳定,比如在GOC-500电网基准上误差缩小了近71倍。
Q3:ADSD在哪些场景测试过效果?
A:论文在四个数值计算领域测试过:电力系统潮流方程求解、交流最优潮流优化、刚性常微分方程积分、高对比度扩散偏微分方程求解,分别用GPT-5.5、Claude-Sonnet-5和Qwen3.8-2.4T作为基座模型,均观察到准确率、稳定性和效率的提升。







