Can you bake Maven into a neural network?

TL;DR · AI 摘要
Can you bake Maven into a neural network? - The JetBrains Blog JetBrains AI Supercharge your tools with AI-powered featu...
核心要点
- 主题聚焦:Can you bake Maven into a neural network?
- 来源:The JetBrains Blog,建议结合原文判断细节。
- AI 分析暂不可用,本条为保底评分与摘要。
你能将 Maven 烘焙进神经网络吗?- JetBrains 博客
JetBrains AI
通过 JetBrains 产品中的 AI 功能增强你的工具
关注
- 关注:
- RSS RSS
查看更多
你能将 Maven 烘焙进神经网络吗?
Denis Shiryaev
我们尝试了,确实成功了。我们将 Maven 风格构建工具的决策部分编译成固定权重矩阵,并用它构建了一个真正的 Java 库。输出结果与 Apache Maven 完全一致。一次干净的构建(含测试)耗时是相同逻辑用 Python 实现的 1.49 倍(95% 置信区间 1.4 倍至 1.54 倍,30 次配对运行)。
网络权重表,每行对应一个条形。条形高度表示该行在一次 ZXing 构建中运行的频率;亮色点逐个步骤重放该构建的真实片段。
每个 Java 开发者都曾目睹过 Maven 的思考过程。它解析、编译、测试并打包。大部分时间消耗在 javac 和 JUnit 上,但贯穿其中的是一小段精巧的逻辑,决定着下一步会发生什么。当两个模块对库版本存在分歧时,哪个版本会胜出?哪些文件会发送给编译器,使用哪些标志?失败的测试是否会停止构建?
我们想知道这段逻辑是否能存在于神经网络中。不是训练模型猜测 Maven 通常会做什么的模型:这类模型大部分时间是正确的,但一个大部分时间正确的构建工具是失败的。我们想要的是将决策逻辑本身编译成权重,让网络能给出完全正确的答案或拒绝回答。
本文顶部的视频就是这个网络。它的 26,626 个条形对应权重表的每一行(模型 nmvn-exact-v2,在“降低成本”部分有解释),条形高度表示该行在一次 ZXing 构建中运行的频率,亮色点逐个步骤重放该构建的真实片段。所有决定构建走向的逻辑都在其中。
从程序到权重表
这个技巧来自 Handwired:你可以编写一个程序,然后设置网络的权重,使网络等同于该程序。我们在 Python 的受限子集中编写了一个小型的 Maven 兼容构建控制器,并将其编译成 29,625 × 7 的数字表,加上 7,382 个常量单元格(这是第一个版本 v1;后续部分会将表格缩小到上面看到的 26,626 行)。无需训练,无需梯度下降:零优化步骤。
运行它是一个循环过程。每一步,网络通过两次矩阵乘法查找其表中的一行,在小型寄存器文件上执行该行编码的算术运算,然后将结果写回内存。网络无法打开文件或启动 javac。当需要时,它会将请求写入内存中的固定槽位,一个轻量级桥接器将请求传出并写回原始答案。桥接器从不做出任何决定。所有选择都来自权重。
测试对象是 ZXing 3.5.3,这个条码库:其父项目和核心及 javase 模块,在干净打包和测试开启的情况下构建。
它真的能构建吗?
是的。它生成的 JAR 与 Apache Maven 完全一致,构建过程发生在 Maven 无法运行的沙箱环境中,网络关闭,逻辑的 Python 版本和 Maven 自身的输出都无法读取。所有 549 个上游测试均通过,新构建的 JAR 在 27 次检查中全部正确编码和解码了 QR 码。
519
手工编写的构建用例通过,每个都与真实 Maven 对比验证
10,000
生成的项目用例通过
33
other small projects built correctly with the same weights
4,796,191
完整ZXing构建的网络步骤
两个验证让我们确信工作确实发生在权重上。网络的CPU和GPU版本在完整构建时向权重文件发起了完全相同的1,731次请求,顺序也完全一致。当我们删除或破坏权重文件时,构建过程完全无法进行。
由新构建的ZXing JARs生成的二维码,再由它们读取回来。
观看构建过程
左:控制器作为普通Python代码。右:相同控制器作为神经网络。两者都在同一台Mac上先后真实构建ZXing,回放速度为实际速度。
两侧各记录了一次构建过程,实时回放。时间轴上的灰色部分表示在javac、JUnit、bnd和zip上消耗的时间。
性能对比
在我们测试的所有场景中,速度都更慢。Python可以直接执行控制器逻辑;神经网络需要为每个微小指令执行一轮矩阵运算,而一次ZXing构建需要执行4,796,191次这样的运算。
计时范围
经典Python
神经网络(CPU)
神经网络(GPU,Metal)
Apache Maven 3.9.11
神经网络CPU/Python
仅决策(不含Java工作)
146.54 毫秒
4.15 秒
27.97 秒
–
28.3×
首次决策前的冷启动
385.94 毫秒
4.80 秒
28.25 秒
12.4×
包含测试的完整构建
15.52 秒
23.12 秒
70.11 秒
15.29 秒
1.49×
中位数耗时(越低越好)。最后一列:神经网络CPU时间除以Python时间。
包含测试的完整构建,中位数秒数。条形=中位数;须部=p25到p75。
仅在决策层面,网络表现远不如Python。在完整构建中差距缩小到约1.5倍,因为大部分时间消耗在javac和JUnit上,两种版本使用相同的工具。在GPU上运行网络反而使情况更差,而非更好。逐条执行指令的程序无法为GPU提供并行计算的机会。
所以这不是更快的构建工具。这是一个你可以像张量一样握在手中的构建工具。
在不改动网络的情况下降低成本
时间大致等于步骤数 × 每步成本,所以我们统计了步骤的分布。我们在指令级模拟器中重放完整ZXing构建过程,统计了每条执行的指令。在v1的4,796,191个步骤中,652,773(14%)只是在寄存器之间复制值,另外553,333(12%)用于加载常量或跳转回循环顶部。这些都是编译器胶水代码,而非构建逻辑。
因此我们保持网络不变,优化了编译器。现在结果直接写入需要的寄存器,常量内嵌在使用它们的指令中,条件语句直接编译为分支,循环在底部测试而非跳转回顶部。机器、步骤图和GPU内核保持不变,仅数字表发生了变化,且规模更小。
完整ZXing构建的网络步骤减少23%(4,796,191 → 3,676,728)
权重表行数减少10%(29,625 → 26,626)
完全一致
决策:使用v1记录的输入,v2在CPU和GPU上按相同顺序发起相同的1,731次请求
2/2
v2重新通过正确性门禁(相同测试套件、沙箱构建、字节完全一致的JAR)
完整ZXing构建的每一步骤按指令类别分布(指令集模拟器重放记录的构建过程;两种模型的动作序列完全一致)。
神经网络CPU(v1)
神经网络CPU(v2)
Python(v2运行)
v1/Python
v2/Python(95%置信区间)
3.40 秒
140.81 毫秒
24.2×
(23.6× 至 25.2×)
4.14 秒
402.38 毫秒
10.3×
(10.1× 至 10.7×)
21.09 秒
14.83 秒
1.42×
(1.40× 至 1.43×)
3.70 秒
1.78 秒
2.08×
(2.05× 至 2.11×)
Neural CPU,v1 与 v2(中位墙时间)。比率来自同一会话中配对运行的神经时间与 Python 时间的比值;v1 来自 nmvn-bench-v0,v2 来自后续协议。
GPU 的收益更大,因为它几乎纯粹按步骤付费:使用 v1 时决策仅耗时 27.97 秒,使用 v2 时耗时 21.61 秒(减少 23%),接近步骤数的削减幅度。它仍然是最慢的引擎。
我们在新权重上重新运行了整个正确性链:每个测试套件、必须生成字节完全相同的 JAR 的沙箱构建、负对照以及 CPU/GPU 重放。削减是真实但适度的,Java 工具链仍占满构建的大部分,因此减少网络的占比对端到端时间的影响小于步骤数的削减。
不只是 Maven
为了确认编译器没有秘密针对某个程序进行优化,我们给了它一个无关的任务:迷宫求解器(广度优先搜索,programs/maze/maze_nml.py)。它编译成 279 行权重。一个小应用同时启动经典版和神经版,作为独立进程运行,并在每个程序报告时立即绘制每个单元格。
应用程序窗口的录制视频,该窗口在运行时会保存自己的帧;神经版在 CPU 上运行。GPU 版本耗时更长。
在 3 个不同的 171×121 迷宫中,纯 Python、Python 调试 shim、神经 CPU 运行和神经 GPU 运行产生了完全相同的事件序列:每个访问的单元格,顺序相同,距离相同。第一个迷宫耗时 2,572,288 次网络步骤。神经版在 CPU 上耗时是纯 Python 的 161× 至 168×,在 GPU 上耗时是 791× 至 812×(每个程序自己的计时器,每个迷宫运行一次,因此将这些视为粗略估计)。
所以它更慢。它甚至有用吗?
合理的问题。我们也问过同样的问题。如果你想更快地构建,答案是否定的:继续使用 Maven。更大的 GPU 也无法拯救它,因为网络一次只执行一条指令,构建控制器中的任何操作都无法分布在数千个核心上。
不过速度从来不是有趣的部分。我们最终得到的是一个每个权重都有明确含义的神经网络,这非常罕见。我们认为它有价值的地方,首先是以下这些。
为拆解网络的人准备的答案
可解释性研究试图仅从权重本身推断网络的功能。困难的部分是评估答案的正确性,因为对于训练好的模型,没有人知道真实结果。这个网络自带真实答案。除了 7 行启动存根外,它的 26,626 行中每一行都属于控制器 249 个已知功能中的一个,我们清楚每个功能的作用。因此我们可以直接指向 do_surefire 的行,这部分负责运行测试并决定失败是否停止构建。如果某个工具声称找到了“依赖解析电路”,你可以验证它。手工构建的测试网络通常只是小玩具。这个网络在真实代码库上执行真实任务,我们认为这才是它的最佳用途。
模型中可精确定位的组件
一个 99% 时间能正确选择库版本的模型,每 100 次构建会出错一次。编译后的权重是一种将精确子程序以与学习模型相同形式嵌入模型的方法:相同的张量、相同的运行时、相同的硬件。明确说明,我们尚未将它连接到训练好的模型。这是下一个实验,而非当前结果。但这也正是我们最兴奋的方向。
可哈希的决策逻辑
The whole policy is one file of numbers. Move it from CPU to GPU and it makes the same 1,731 decisions in the same order; feed it a recorded build and it replays it exactly. That’s how we compared v1 and v2 decision by decision in the section on making it cheaper. You can diff it, sign it, and show that a given build came from it. In fairness, ordinary code with a lockfile gets you most of the way. What the tensor version adds is that the thing running the policy is the same fixed loop of lookups and arithmetic for any program you compile into it, and a smaller runtime is a smaller thing to trust.
One more thing in its favour: the cost shrinks when the decisions are a thin layer over heavy tools. In a full ZXing build, javac and JUnit do most of the work, which is why the network costs about one and a half times the Python time there instead of twenty-odd times. Glue logic around expensive steps pays that same modest price.
Wrong tool for
- Faster builds, or anything where milliseconds matter
- Throwing more GPU at the problem
- Replacing Maven
Worth a look for
- Testing interpretability tools against a network with a known answer
- Exact subroutines living next to learned models
- Decision logic you can hash, replay and compare
What we’re not claiming
- This isn’t all of Maven. It handles one build ( clean package ) of one real project, with Enforcer, Checkstyle, Javadoc and source JARs skipped. Signing, deployment and everything that only runs in verify are out of scope. The plugins aren’t neural: javac, JUnit, bnd and zip run as ordinary programs.
- This isn’t machine learning. The weights were compiled from a program, not learned. We didn’t try a trained version, and we’d expect one to fail on projects it hadn’t seen.
Check our work
The weights, the runtime and the full results are on Hugging Face at shirman/neural-maven : the method, all eleven scenarios, memory use, the environment and evidence hashes, plus the raw measurements, both protocols, the analysis code and checksums. That’s enough to recompute every number in this post.
Maven
- Share
Prev post
How Netflix Made AI Coding Agents More Efficient with JetBrains IDE Intelligence