AI自动生成你会提交的代码改进PR
Hugging Face介绍AI工具自动发现并生成代码改进建议的能力和实现
Hugging Face介绍AI工具自动发现并生成代码改进建议的能力和实现
我们提供了一个 Skill 和测试框架,帮助将语言模型从 transformers 移植到 mlx-lm,使得模型一旦被添加到 transformers 就能(几乎)立即在 MLX 上可用。这个 Skill 设计初衷是为贡献者和审查者提供辅助,而非自动化工具。我们将解释为什么这样做,以及在 AI 智能体时代如何有意义地为开源项目做出贡献。
到了 2026 年,代码智能体终于真正奏效了。曾经存在于编辑器一隅的自动补全,已经演变成一个系统——它能从简洁的规范一次性生成合理的解决方案。生成的代码通常开箱即用,覆盖你所要求的内容,并对你未明确指定的细节做出合理假设。这太棒了。正如黄仁勋所说,我们瞬间把全球编码人数从 3000 万扩展到了 10 亿。创意正在被释放。
但这迫使我们重新思考开源。
以 transformers 库为例。它有数百名贡献者,被数千个项目使用,下载次数超过 10 亿。突然,任何拥有智能体的人都可以指示它寻找某个开放议题、修复它,然后提交一个 PR。这正是正在发生的事情。这些人感到高兴,因为他们在为一个伟大的库做贡献,但悲哀的现实是,大多数时候他们并没有意识到自己其实并未在做出贡献。
为什么呢?有两个假设是智能体生成的 PR 通常会忽视的。
像 transformers 这样的代码库对代码本身有着深入的关注。构建一些不在乎代码长什么样的项目很酷,但 transformers 不在其中。由于被数千人使用,transformers 主要是被构建为一种人与人之间的沟通方式——通过代码。模型文件从上到下地被阅读,因为我们希望实践者无需跳过复杂的抽象就能理解它们。这贯穿了整个库的设计,也是我们(例如)偏好扁平层次结构的原因。
智能体缺乏这个背景。因为设计决策并不明确,智能体通过遵循"最佳实践"来建议重构以"改进"代码库,却没有意识到这些改进会破坏库与其用户之间的隐性契约。它们过于冗长,过早地进行泛化,不会注意到某个改动对其他区域的影响,引入微妙的 bug,破坏性能。它们也很谄媚,接受任何想法都是好的并坚决执行,包括维护者本应用简洁评论早期否决的想法。
少数维护者仍然必须阅读每个 PR,理解它,决定设计方向是否正确,找出副作用,并给出反馈。PR 数量增加了十倍,但维护者数量没有增加(也不能增加,因为团队协调无法按比例扩展)。
transformers 是首批感受到这种压力的项目之一,原因是数量庞大,但这种动态正在各地发生。比如从另一个领域举例,App Store 审查人员应接不暇,因为任何人现在都能构建和提交应用,很多人确实在这样做。
同样的逻辑适用于 MLX:他们的维护者对代码有着深入的关注,并仔细阅读每个 PR。我们想看看智能体是否能帮助贡献者快速落地高质量的模型移植,同时支持审查者的工作。我们不仅希望生成看起来像是来自仔细的人工提交的 PR,还提供额外的工件来增加信号:生成示例、数值比较,以及一个独立的非智能体测试框架用于可重现性。
transformers 和 MLX 之间的另一个联系是,大多数时候,mlx-lm 模型是从 transformers 实现移植而来的。因为 transformers 专注于清晰性和可读性,它已经成为模型定义的真实来源。下游贡献者等待 transformers 实现准备好后才移植到其他框架。作为副作用,这为智能体创造了一个绝佳的环境,因为它自然地限制了范围:与其从头创建一个实现,不如让智能体依赖 transformers 代码作为真实来源。
这种方法支持我们的目标:当一个模型进入 transformers 时,它应该在不久之后在 MLX 上可用。
我们构建了一个 Skill,mlx-lm 贡献者可以使用它将一个模型从 transformers 移植到 MLX。给定一个提示,比如"将 olmo_hybrid 架构转换为 MLX",该 Skill 设置一个虚拟环境来工作,发现并从 Hub 下载相关模型,读取 transformers 建模代码,编写 MLX 实现,并运行一系列测试。如果结果看起来不对,它会调试并迭代,不会声称成功直到它确信结果是对的。
我们设计它的目的是对审查者和贡献者同样有用。
对贡献者而言,该 Skill 当然处理了所有的脚手架工作:在 Hub 上查找模型变体,比较它们的配置以发现在模型变体间变化的参数,下载检查点,设置 mlx-lm 和 transformers 的可编辑安装。但它也处理了更困难的建模任务。它关注突出的架构细节并验证敏感区域,比如 RoPE 配置,这些可能导致难以发现的 bug。它检测配置何时未声明数据类型,并从 safetensors 元数据头推断。它在 transformers 和 MLX 之间运行逐层比较,以精确定位分歧发生的位置。这些是只有具有移植经验的人才会想到运行的检查。
对审查者而言,该 Skill 生成的 PR 坦诚是由智能体辅助的,但看起来像是仔细的人工提交。审查者会看到代码遵循 mlx-lm 的惯例:习语解决方案、没有不必要的评论、没有投机的抽象、没有对共享工具的修改而不获得明确批准。鉴于代码是智能体辅助的,我们尝试包含比中位数 PR 更多的数据,以提供尽可能多的信号。PR 主体包含一份报告,内容涵盖变体的总结和它们的架构差异、生成示例、数值比较、数据类型验证、针对 transformers 基线的逐层比较。该 PR 总是披露它是由智能体辅助的,Skill 在贡献者接受结果之前不会打开它。
对于验证,Skill 为一个独立的、非智能体的测试框架生成一个测试清单,该框架在设计上很容易重现,不受 LLM 幻觉或自满的影响(下文会详细讨论)。
Skills 是智能体的配方:带有指导的简单文本文件,引导模型完成复杂任务。它们不是魔法;你可以通过提示和迭代实现相同的结果。但它们提供一致性(每次运行都遵循相同的流程,而不同的人会采用不同的提示方式),最小化歧义并充当文档:任何人都可以阅读该 Skill 来了解它的作用,找出缺失的情况并建议改进。
我们通过在与 Claude 的对话中自己移植一个模型来引导 Skill。我要求它从 transformers 向 mlx-lm 移植 GLM 4.7,给出像在一个普通会话中那样的指导。一个技巧是:我指向 Claude 一个 mlx-lm 的检查,我从中删除了已经存在的实现,这样我就可以将输出与真实情况进行比较。经过几次迭代,我有了一个可工作的实现、一个揭示 Claude 如何解决问题的对话,以及 Skill 的第一稿,Claude 创建它作为该过程的总结。我重度编辑了它,并融入了来自 @gabegoodhart 的学习成果,他们友好地分享了他们对另一个模型的移植对话 🙌。
我们多次重复这一循环,Skill 也随之不断完善。在技术层面,我们涵盖了诸如以下问题:RoPE bug——它可能产生看似合理的输出,但在长序列中逐渐劣化;float32 精度污染——它会悄无声息地拖垮推理速度(你可能会惊讶于这类问题出现得有多频繁!);不同模型变体之间存在差异、实现必须妥善处理的配置字段;以及针对无法装入单台机器的超大模型进行分布式推理。我们还教会它如何调用 hf CLI 来发现和下载模型。最重要的是,我们要求它运行经验丰富的移植者会运行的测试,并且在这些测试通过之前不得宣告成功。
来源:@Prince_Canuma
在文化层面,我们涵盖了一些更软性的特征,并解释了哪些约定能让 PR 更易于审查:不要用注释解释代码(审查者不得不同时解析注释和代码 🤦♂️);绝不要提出重构;未经询问,不要修改共享工具。这些规则对 AI 智能体来说毫无成本,却能为审查者节省大量时间。
最终的结果是:贡献者输入一段提示词,Skill 就会生成一个像这样的 PR,以及一份供外部测试工具使用的测试清单。
Skill 会在 PR 中附上一份完整的结果报告。这些结果都来自 AI 智能体在转换过程中运行的测试,但我们不希望审查者只能凭信任接受它们。为了更进一步,我们创建了一个独立的、非智能体式的测试工具,对转换后的代码运行系统化测试。这带来了以下好处:
消除了对 LLM 伪造结果或对结果过于宽松的担忧。
保证可复现性:任何人都可以下载测试工具仓库并运行测试。
文档化与透明度。所有结果都会以不同粒度保存:汇总报告、各模型的详细信息,以及以 JSON 文件保存的原始输入和输出。测试也会被复制到结果文件夹中,因此即使未来修改了测试工具,我们也能知道当时运行的具体测试内容。
测试工具并不是一道 CI 门禁。有些检查很直接(输出 dtype 是否正确?),但大多数都是定性的。预训练模型在长序列中重复自身是否正常?相对于 transformers 基线,logits 有 4% 的相对差异是否可以接受?这些都需要根据处理类似架构的经验作出判断。测试工具可以提供有用的信号,但最终仍需要审查者和贡献者作出决定。
Skill 面向的是那些已经在为 mlx-lm 提交模型 PR,或者本来就会自己手动完成这项工作的人。它并非面向大众,因为提交到 mlx-lm 的 PR 很少会直接被接受。典型流程是:贡献者提交 PR,审查者指出需要改进的地方,双方反复迭代,直至达到质量标准。既然专家提交的代码也需要经历这一过程,那么 AI 智能体辅助的提交同样如此。
如果你不准备参与这一迭代过程,那你可能就不应该提交 PR。审查者会努力理解你的代码(即使知道它是在 AI 智能体辅助下完成的),所以你也应该这样做。你需要对代码负责,并做好根据他们的反馈进行修改的准备。尤其不要把审查意见直接交回给 AI 智能体,然后不加判断地发布它生成的内容。LLM 往往会固执己见、偏离主题,也无法有效提出异议。一旦你开始与审查者沟通,这就变成了人与人之间的对话,因此轮到你亲自参与讨论,并尊重他们投入的时间。
你也可以使用 Skill 来学习;在建立足够的信心和经验之前,你不必提交任何内容。阅读 Skill,找出自己之前未曾意识到的问题领域:Skill 文件、参考文档和实用脚本合计包含近 1.5 万字。让它处理你自己的 mlx-lm fork,尝试进行一次转换,并在官方仓库合入相应实现后,将你的输出与已被接受的实现进行比较。如果这样做几次,你会学到很多有关 Transformer、MLX 和语言模型架构的知识。
uv run https://raw.githubusercontent.com/huggingface/transformers-to-mlx/main/install_skill.py
uvx hf skills add --claude
我们使用 Claude Code 开发并测试了这个 Skill。同样的方法应该也适用于 Codex 或其他编码 AI 智能体,但我们尚未进行测试。如果你在不同环境中尝试这个 Skill,请告诉我们使用效果如何!
这个 Skill 对 mlx-lm 中的 LLM 支持得很好,但仍有很大的提升空间。
mlx-vlm。视觉语言模型位于一个独立的仓库中,遵循不同的约定。除了建模代码之外,mlx-vlm 还需要处理器在 LLM 接收输入之前完成图像预处理。我们期待与 Prince Canuma 合作,帮助他完成他一直在做的工作。
llama.cpp。其中也存在一些相同的挑战。处理器需要用 C++ 重新实现图像处理算法,而且数值差异不可避免。这或许是一个职责范围严格限定的 AI 智能体能够发挥作用的领域。
测试工具。我们希望扩充测试集,并可能探索安全的自动化方案,在我们的基础设施上自动运行测试。
mlx-lm 中的共享工具。相比 transformers,mlx-lm 在将通用模式提取为共享函数方面没有那么严格。Skill 有意偏向自包含的模型文件(与 transformers 相同),但审查者经常会要求重构,将重复代码移入共享模块。
如上所述,VLM 和其他架构尚未支持。
量化模型上传。Skill 会测试量化,但不会将量化模型上传到 Hub。我们认为在 PR 审查期间上传并不合理,但之后可以创建相应的流程。
思考测试。目前尚未设计针对思考过程的专用测试。Skill 会转换并验证这些模型生成的内容,但不会验证思考结构。
开源领域的瓶颈并不是打字速度,而是理解代码库,从而在不破坏其与用户之间显式和隐式契约的前提下修改代码。如果我们教会 AI 智能体哪些事情最重要,它们就能在这个过程中提供帮助。我们探索了这种方法在 mlx-lm 场景中的具体形态,希望它能帮助贡献者和审查者更快地合入高质量的模型转换!
transformers-to-mlx Skill 仓库
针对 fork 的 AI 智能体辅助转换示例
mlx-lm,目标库
transformers,建模代码的事实来源
Claude Code Skills 文档
Transformers 设计理念
Transformers 库:标准化模型定义
非常感谢 Ben、Shaun 和 Aritra 阅读本文的早期版本,并让它变得好得多 🙌
我们无比感谢 Apple 将 MLX 打造为开源项目,也感谢社区迅速认识到它的价值并积极贡献 🙏
本文提及的 Spaces 1
来自我们博客的更多文章
开源社区正在支持用于 Agentic RL 的 OpenEnv
DeepSeek-V4:AI 智能体真正能够使用的百万 token 上下文
· 注册或登录后发表评论
本文提及的 Spaces 1