
用强化学习训练模型'画'出代码:9 个奖励信号砍到 4 个,训练效率翻 3 倍
两个开发者用 GRPO 训练 Qwen 写 p5.js 代码画水彩画,踩遍了奖励函数设计的所有坑:冗余信号、饱和的代码长度奖励、失效的绝对评分。他们的修复过程是 RL 奖励工程的一份实战教材。
原文来源:Training AI to Paint with Code — 用强化学习训练模型写代码作画,重点剖析奖励函数从 9 个信号精简到 4 个信号的全过程。
用 AI 模型生成图片,你唯一能参与的方式就是写提示词。图片生成之后想改?回到模型,再写一遍提示词。Surya Narreddi 对这种体验一直很不满意,于是他和朋友 Cameron 做了一个有点反常规的实验:不训练模型直接出图,而是训练它写代码——一段 p5.brush JavaScript 代码,渲染出来就是一幅水彩画。代码是产物,而代码是可以编辑的。想改细节,不用重新生成,直接改代码。
这个项目表面上是在做 AI 绘画,深层的实验目的是:如何在审美这类主观任务上做强化学习。RL 能跑通的前提是奖励可验证:数学题对就是对、错就是错,游戏赢了就是赢了。审美质量不属于这一类。于是"设计问题"变成了"设计奖励函数的问题"——评判标准定得太死,模型会收敛到套路;定得太松,模型会漂移。整篇文章记录的,就是这个奖励函数从粗糙到可用的迭代过程。
系统是怎么跑的
训练循环是四步,跑了成千上万轮:
- 模型收到提示词(比如"画一朵桃红色木槿花水彩"),写出一段完整的 p5.brush JavaScript 草图
- 草图在沙箱化的 Puppeteer 环境里渲染成 PNG
- PNG 和参考池里随机抽的两张画作对比,由另一个评判模型判断哪张更好
- 判断结果换算成奖励信号,GRPO 更新模型,循环继续
基础模型是 Qwen 3.5 35B。值得注意的几个非显然设计决策:评判对象是什么、评判怎么做、参考池里放什么、系统提示词怎么写。每个都值得单独拆开讲。
—— 广告 ——
第一个奖励函数:9 个信号,全在重复测量同一件事
最初的评分规则有 9 个独立信号:
- 编译门禁(代码能不能跑)
- 检查代码真的用了 p5.brush 而不是原生 p5
- 代码长度斜坡,目标约 3000 token
- HPSv3,一个人类偏好模型
- 提示词遵循度,由 GPT-5.4 和 Gemini 组成的评判团打分
- 另外 4 个质量评判:可辨识度、美感、技法、深度
结果模型在奖励 0.65 附近就停滞了。每轮 rollout 长得都一样:一朵扁平的、五片圆花瓣的剪贴画风格花朵。奖励还在涨,能力却不见提升。
诊断的关键在于把子奖励拆开单独看。四个质量评判加上提示词遵循度,互相之间的相关性高达 0.85 到 0.95——它们本质上是在用五种方式测量同一件事。代码长度贡献了总奖励的三分之一,但在第 30 步左右就饱和了,之后完全不产生梯度。而唯一真正有方差、有信息量的 HPSv3,权重只有 0.10。说白了,这套评分规则在翻来覆去地告诉模型同一句话。
修复一:用两两对比替代绝对打分
原来的规则让评判模型给每次 rollout 打 0 到 10 分,分数全都挤在零附近,毫无区分度。改成两两对比后,问题变成了:给评判模型看当前产出和参考池里的两张图,问它"哪张是更好的木槿花水彩?"奖励就是赢下对比的比例。动态范围一下子打开了——让模型做相对判断,比让它对着抽象量表打分可靠得多。
修复二:建一个人工评分的参考池
作者把 1,664 张生成图一张一张人工评级,分成 love、okay、nope 三档。其中 117 张 love 档的图成为对比池的种子,之后的每一次 rollout 都要跟"作者认为好的东西"做对比。再往后本来还有一步:用这些评分直接训练一个小型奖励模型(标准 RLHF 流程),这样模型对"好"的理解就不必每次靠对比参考池来体现——不过这一步没有来得及做。
新奖励函数:4 个信号,训练快 3 倍
精简后的规则只剩四个部分:二进制的编译+使用 brush 门禁(权重 0.05)、二进制长度检查(0.05)、HPSv3(0.30)、以及对比参考池的两两评判(0.60)。
同样的基础模型、同样的训练数据,新规则下模型三倍速到达了旧规则的天花板,然后继续往上爬。还有个意外收获:产出的代码从平均 13,500 token 压缩到 2,000 以下——模型学会了赢下对比的构图根本不需要啰嗦的代码。
系统提示词也在反向优化
系统提示词最初塞了 400 行 p5.brush API 参考文档。模型写出来的代码格式漂亮、信心十足,但发明了一堆不存在的 API。
修复用的是 GEPA,一个针对评分函数进化提示词的库。跑了 200 轮迭代后,收敛出一个只列了 8 个 brush 方法的严格白名单提示词——没有 API 文档,没有示例。扔掉那 400 行文档之后,第一次出现三张图都能看出木槿花轮廓的版本。
这个发现其实有普适性:系统提示词里放长文档,模型就会幻觉出不存在的 API;一段简短、有明确取舍的白名单,约束效果反而比完整规格说明更好。
经验总结
整个项目留下的核心经验是:RL 需要可验证的奖励,而主观任务没有现成的验证器,你必须手工设计奖励结构,并且设计得足够精细,让"品味"能够泛化到用户的偏好上。太具体,模型只会照着评过的例子抄;太宽松,模型什么都学不到。审美类任务的强化学习,本质上是在给"品味"搭一个能泛化的脚手架。
作者自己也承认,这不代表一种更好的图像生产方式——事实上慢得多。但这个项目的价值在于改变了参与方式:提示词、模型、产物,三个环节都可以投入注意力、都可以编辑。相关代码和完整技术报告会在后续发布。
顺带一提,这个项目在 Hacker News 上引发了热烈讨论(原帖),不少人在评论区讨论"用代码作为图像中间表示"这个思路的潜力——把生成过程从黑盒变成可编辑的产物,可能是比 prompt 工程更有意思的交互方向。
© 2026 四月
原文链接:https://www.aprilzz.com/ai/rl-training-ai-to-paint-with-code
相关文章
Ornith-1.5:从自脚手架到自改进,开源模型学会给自己出题
Ornith-1.5 把训练循环从'人类出题'变成'模型自己出题、自己搭脚手架、自己解题',397B 版本编程基准追平 Claude Opus 4.8,9B 小模型能跑在手机上。
Qwen3.8-27B 开放权重:27B 的小模型,SWE-bench Pro 拿下 61.7
阿里兑现开放权重承诺,Qwen3.8-27B 以 27.78B dense 参数、原生多模态和 262K 上下文,成为本地 ~30B 稠密模型新标杆。
Qwen-Image-3.0 发布:4.5k 长提示、10px 小字、12 种语言,图像模型终于开始"实用"了
阿里云发布第三代图像生成模型 Qwen-Image-3.0,主打"实":4.5k token 超长提示词、10px 微小文字渲染、12 种语言原生排版,把图像生成从"好看"推向"好用"。