AI PLAY玩法更新持续收录
← 回到更新流

2026-09-03 · 原文发布日

用RL训练代码模型画水彩:开源复现

作者在Hugging Face上完整复现了此前走红的水彩画项目:语言模型只能调用p5.brush库的十个方法,写出约150行JavaScript来作画,用TRL加OpenEnv做GRPO强化学习,奖励混合方案可配。数据集、RL环境、评分模型、训练脚本和训出的模型全部开源,复制两个Space、设两个环境变量后一条hf jobs命令即可开训,文中还比较了三种奖励混合的效果。

原文要点

Hugging Face工程师Sergio Paniego开源复现了Surya Narreddi走红的水彩项目:语言模型只能调用p5.brush库47个方法中的10个,写约150行JavaScript作画,用TRL加OpenEnv做GRPO强化学习。奖励四项:门槛0.05(能编译、真上色、不作弊)、长度0.05、成对评委0.60(Qwen3-VL-30B经Inference Providers,与178张人工分级参考画比较)、HPSv3偏好模型0.30。他训练并比较了judge-led、hps-led、hps-only三种奖励混合,judge-led从0.45升到0.72。每步8个rollout、约15至18分钟,110步约需一张H200跑34小时,数据集、环境、评分模型、脚本和模型全部公开。

这次做成什么

按作者公开方案在Hugging Face上复现一次水彩GRPO训练:先复制两个Space、设好奖励混合的环境变量,用短跑验证管线,再决定是否发起110步完整训练;并先用本地小样例理解十方法限制。

准备什么

  • Hugging Face账号及HF_TOKEN,且能使用Jobs、Spaces和Inference Providers(多项为付费服务)
  • 本地装好hf CLI并能运行hf jobs命令
  • 接受作者给出的成本量级:单H200训练、一个a100-large评分Space常驻、一个cpu-upgrade环境Space
  • 已复制作者的水彩环境Space和HPSv3评分Space到自己的命名空间

具体怎么做

  1. 复制两个Space

    在Hub上分别Duplicate作者公布的watercolour-env(RL环境,Docker Space,cpu-upgrade档)和watercolour-hpsv3(评分模型,a100-large档)到自己账号,记下前者的Space地址。注意评分Space整个训练期间要常驻,训练结束记得暂停或设休眠,否则持续计费。

  2. 设定奖励混合环境变量

    按作者做法,用两个环境变量决定成对评委与HPSv3的权重:原始judge-led混合为评委0.60、HPSv3 0.30;验证管线可先用hps-only(评委0、HPSv3 0.90),作者先用它确认管线能学习,60步即停。

  3. 本地理解十方法限制(本站设计小练习)

    在发起昂贵训练前,先用下方材料中的p5.brush示例草图本地跑一遍:只用scaleBrushes、noStroke、fill、noFill、fillBleed、fillTexture、beginShape、vertex、endShape、circle这十个方法画一朵花,体会模型被限制的作画空间,便于之后读懂rollout数据集里的代码。

  4. 发起训练

    运行下方材料中的hf jobs命令:把<you>替换为自己的用户名,--env-url指向复制的环境Space,主题可用--subject 'a peach hibiscus',短跑验证可把--steps改小;硬件为h200,通过--secrets HF_TOKEN注入令牌,--push-to-hub把适配器推回Hub。

  5. 监控与判读

    在trackio里看分组平均奖励曲线;判读时记住作者的两个教训:奖励曲线的个别下探可能只是该步抽到了更难的参考画(成对评委每步随机抽4张),以及基础设施失败曾以0.0混入奖励(已改为返回None并剔除该rollout),看曲线要结合画廊里对应步的实际画作。

可直接复制的材料

训练启动命令(转自作者公开配方)

引自作者文章;<you>两处需替换为自己的Hub用户名,短跑验证可将--steps 110改为60(对应作者hps-only验证跑法);all-linear、5e-5、constant_with_warmup、scale-rewards none是作者解锁首个成功跑的四项关键修改。

hf jobs uv run train/watercolour_grpo.py --flavor h200 --timeout 48h --secrets HF_TOKEN -- \
  --env-url https://<you>-watercolour-env.hf.space \
  --model Qwen/Qwen3.5-35B-A3B --lora --all-linear --bf16 --gradient-checkpointing \
  --subject 'a peach hibiscus' --references 4 \
  --top-p 0.95 --top-k 20 \
  --lr 5e-5 --lr-scheduler constant_with_warmup --warmup-steps 5 \
  --scale-rewards none \
  --steps 110 --n-episodes 240 --num-generations 8 \
  --per-device-batch-size 1 --gradient-accumulation-steps 8 \
  --max-completion-length 8192 \
  --run-tag my-run --out <you>/watercolour-grpo --push-to-hub

十方法限制内的p5.brush示例草图(本站独立编写)

本站编写的练习代码:花瓣与花心的绘制只使用十方法白名单(scaleBrushes、noStroke、fill、noFill、fillBleed、fillTexture、beginShape、vertex、endShape、circle),createCanvas/background/三角函数为 p5.js 基础画布函数;需在加载了 p5.js 与 p5.brush 的页面运行。仅作理解作画限制之用,非训练数据,也不保证能通过作者环境的反作弊门槛(门槛要求以库方法作画而非直接 p5 调用)。

function setup() {
  createCanvas(600, 600);
  scaleBrushes(1.2);
  noStroke();
  background('#f5f0e6');
}

function draw() {
  // 花瓣:大片湿画法打底,内部再叠一层更浓的小花瓣
  const cx = 300, cy = 300;
  for (let i = 0; i < 6; i++) {
    const a = (TWO_PI / 6) * i;
    const px = cx + cos(a) * 90;
    const py = cy + sin(a) * 90;
    fill('#e86a8a', 60);
    fillBleed(0.25);
    fillTexture(0.4);
    beginShape();
    vertex(cx, cy);
    vertex(px - 40, py - 40);
    vertex(px, py - 60);
    vertex(px + 40, py - 40);
    endShape(CLOSE);
    fill('#c2185b', 90);
    fillBleed(0.12);
    circle(px, py - 20, 46);
  }
  // 花心
  fill('#f2b705', 120);
  fillBleed(0.08);
  circle(cx, cy, 40);
  noLoop();
}

三种奖励混合对照配置

权重数值来自作者文章;具体通过哪两个环境变量传入请以复制的Space与训练脚本README为准,本站未实测该界面。

{"judge-led":{"pairwiseJudge":0.60,"hpsv3":0.30,"gate":0.05,"length":0.05,"note":"原始混合,作者跑到110步停"},"hps-led":{"pairwiseJudge":0.30,"hpsv3":0.60,"gate":0.05,"length":0.05,"note":"中间点,110步停"},"hps-only":{"pairwiseJudge":0.00,"hpsv3":0.90,"gate":0.05,"length":0.05,"note":"管线验证用,60步停"}}

输入与输出示例

本站虚构演示,未运行;作者原60步hps-only实跑为0.58升至0.71,本例数字是按20步缩短后自拟的合理示意。

输入

本站设定的缩短练习:主题'a peach hibiscus',hps-only混合,--steps 20,每步8个rollout,仅验证环境、评分与推回Hub是否走通。

对应输出

示意性trackio关键行(本站虚构):step 1 平均组奖励0.52、门槛通过率0.75;step 10 平均0.61、门槛通过率0.875;step 20 平均0.66、门槛通过率1.0,Hub上出现<you>/watercolour-grpo适配器仓库。曲线抬头、坏画(总分低于0.3)从5幅降到1幅,与作者描述的『先学会不画坏画』一致。

做完检查这些

  • 两个Space复制成功,环境Space的渲染接口能返回一张画作而非超时
  • 短跑结束后trackio里平均奖励呈上升趋势,且无整段恒为0的平线
  • 每组8个rollout未出现奖励全同(GRPO梯度死亡的征兆),作者确认其实跑无此问题
  • Hub上生成适配器仓库和rollouts数据集,能打开任意一幅画对应的JavaScript源码
  • 训练结束后评分Space已暂停或设好休眠,不再持续计费

容易卡住的地方

  • 成本不低:作者实跑110步约34小时单H200,评分Space全程常驻;作者称单步15到18分钟,其中七八成在渲染
  • Qwen3.5-35B-A3B是MoE架构,LoRA必须all-linear,否则只训练到四十层中的十层(作者踩过的坑)
  • 基础设施失败曾以0.0计入奖励(最差一次占5.2%),作者已改为返回None,复现旧代码时注意核对
  • 成对评委每步随机抽4张参考画,单步奖励下滑可能只是抽签难,别急于中断
  • 奖励含作者个人口味(178张人工分级参考池),换主题需自建参考池,工作量在人工分级
  • 界面与参数以作者仓库为准,本站未实测,文中两条环境变量的具体名称需在Space设置页核对

原文与作者资料 ↗

本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。

原文标题
Training a coding model to paint watercolours with TRL and OpenEnv
原作者
Hugging Face / 文章署名作者
原始发布日期
2026-09-03T00:00:00+00:00
来源
https://huggingface.co/blog/train-to-paint-with-code