Canva 拿开源模型后训练,单次编辑成本降 46%:这套打法可以搬走
2026 年 10 月 29 日,Canva 发布了 Brush——一个面向设计的视觉语言模型,由 Canva Research 那个 160 人的 AI 实验室做出来,跑在 Canva AI 里为 Pro 订阅用户提供编辑能力。发布稿里有两个数字最能说明问题:通用的设计编辑任务最多快 69%,单次编辑任务成本比 Canva 上一代设计 Agent 低 46%。这不是模型榜单的进步,这是单位经济学的进步。而对做产品的人来说,这件事真正的价值在于它可复制的部分:一个开源基座、在真实编辑任务上后训练、再用大规模强化学习把它拉到一个可用的水平。
生成的自由度高,编辑的自由度必须被约束住——其余全部不动。
一、Brush 做的事,和它取代的东西
Brush 读得懂一份设计的结构:布局、图层、整体调性,然后按你的指令去改——从改一行文案,到调整一份演示文稿里每一页。它接在 Craft 后面一周发布,Craft 是 Canva 的图像生成模型;按 Canva 自己的说法,那把 Canva 抬到了 DesignArena 图像生成榜的第二名。这两个模型的定位差别很清楚:Craft 负责生图,Brush 负责在图上把设计改好。Canva 的原话是"好的设计发生在编辑里"——生成一份能看的东西已经不容易,改一份已有的东西更难。
二、为什么"改"比"生成"更难
生成是从零开始,模型有全部自由。编辑不是:它要知道你想改什么、这份设计是怎么搭起来的,以及同样重要的一点——什么必须一动不动。最后这条最容易被忽略,也最容易毁掉结果。一句"把标题放大",模型可能顺手把整套版式重排了。所以编辑类产品的核心指标不是"改得像不像",而是"改对的地方、没动不该动的地方"。这条约束写不进提示词,只能写进校验。
# A design is a tree. An edit that touches one text node must not silently
# reflow the other eleven. Diff the tree before and after and fail loudly.
import json
def nodes(doc, prefix=""):
for child in doc.get("children", []):
nid = f"{prefix}/{child['id']}"
yield nid, child
yield from nodes(child, nid)
def scope_violations(before, after, allowed_ids):
b, a = dict(nodes(before)), dict(nodes(after))
bad = []
for nid in set(b) & set(a):
if nid in allowed_ids:
continue
if json.dumps(b[nid], sort_keys=True) != json.dumps(a[nid], sort_keys=True):
bad.append(nid)
bad += [f"deleted:{n}" for n in sorted(set(b) - set(a))]
return bad
# This check is why "make the title bigger" does not turn into "make the title
# bigger and also restyle every slide". Boring, deterministic, and load-bearing.三、46% 这个数字到底在说什么
46% 是"单次编辑任务的成本",69% 是"通用编辑任务的速度"。对一个每天处理几十亿份设计、服务几亿人的产品来说,每次编辑多几分钱,乘起来就是财报上的一个大洞。Canva 在公告里把动机写得很直:这些效率提升让它们能把更强的 AI 体验给到几亿人,同时把价格做得更可承受。换句话说,这不是省钱本身,这是把单位成本压到能免费或低价供给的水平——这是消费级 AI 产品唯一能走通的路。
# The reward signal is the product decision. Canva had to define what makes a
# design good before it could train against it, and so do you.
# Helper functions (type_scale, palette, coverage, contrast) omitted on purpose.
def reward(before, after, brief):
score = 0.0
# Brand consistency: the type scale and palette come from the source doc.
score += 2.0 * (type_scale(after) == type_scale(before))
score += 2.0 * (set(palette(after)) <= set(palette(before)))
# Instruction coverage: everything the brief names should actually change.
score += 3.0 * coverage(after, brief.targets)
# Collateral damage: untouched nodes must stay byte-identical.
score -= 5.0 * len(scope_violations(before, after, brief.allowed))
# Legibility floor: not negotiable, and not something to learn from votes.
score -= 10.0 * count_contrast_failures(after)
return score四、训练配方:开源基座 + 后训练 + 大规模强化学习
Brush 从一个领先的开源权重模型出发,在真实设计文件与真实编辑任务上做后训练,用的是设计专业知识和用户主动选择共享的匿名化使用洞察。在此基础上叠加大规模强化学习,让模型完整地做设计任务、从结果里学、然后不断修正行为。这里的关键设计是奖励系统:Canva 必须先定义"什么是好设计",才能拿它训练。品牌一致性、指令覆盖、误伤范围、可读性——这些可以被计算的特征,才是一个设计奖励系统真正的骨架。
# The loop worth copying: act with code, then look at the page. An agent that
# cannot see the result of its own edit is guessing.
def edit_loop(design, brief, model, max_turns=4):
history = []
for _ in range(max_turns):
action = model.propose(design, brief, history=history)
result = run_in_sandbox(action.code, working_copy=design)
if result.error:
history.append(f"runtime error: {result.error}")
continue
shot = render(design) # screenshot the actual page
verdict = verify(shot, brief) # cheap, deterministic checks
if verdict.ok:
return design
history.append(verdict.summary) # "title overflows frame 3"
return design # ship last good state, still editable五、Agentic 循环:写代码改,然后回头看页面
Brush 的执行方式值得一提:它用一个 agentic 循环,写代码去调整设计元素,然后检查页面上实际发生了什么,用看到的结果指导下一步。这个"执行—观察—修正"的闭环,是它能处理多页一致性、跨格式适配这类任务的原因。另一个工程上很重要的选择是:它产出的东西完全可编辑,不是一张烤死的图。这一条决定了它能不能进真实的设计流程——设计师要接着改,客户要换文案,市场要出十个尺寸。
# "46% cheaper per edit" is a unit-economics claim, so measure it as one.
def cost_per_edit(runs, price_in, price_out, gpu_usd_per_second):
gen = sum(r.tokens_in * price_in + r.tokens_out * price_out for r in runs) / 1_000_000
infra = sum(r.gpu_seconds for r in runs) * gpu_usd_per_second
retries = sum(max(0, r.turns - 1) for r in runs)
retry_gen = gen * (retries / max(len(runs), 1))
return (gen + infra + retry_gen) / len(runs)
# The line that moves when you post-train your own model is tokens and GPU
# seconds. The invoice from a model provider is the line you are trying to
# shrink, and it only shrinks if the task is narrow enough to specialise on.六、想抄的话,先想清楚三件事
第一,你的任务够不够窄。后训练能在窄任务上打败更大的通用模型,任务越宽,优势越小。第二,你有没有奖励信号。没有可计算的"好"的定义,强化学习只是在放大噪声;而定义"好"这件事本身就是产品判断。第三,你有没有验证器。写完不看结果的 Agent 是在猜,而设计这种高维输出的验证,必须同时有确定性检查(对比度、溢出、越界)和视觉检查。三件事齐了再谈训练,否则先老老实实做提示词和流程。
# Head-to-head on the same edit set, with humans voting. Offline similarity
# will not tell you whether the design is usable.
def pairwise_wins(old_agent, new_agent, cases, raters):
wins = total = 0
for case in cases:
a = old_agent.edit(case.design, case.brief)
b = new_agent.edit(case.design, case.brief)
for rater in raters:
if rater.prefers(b, a, case.brief):
wins += 1
total += 1
return wins / total
# Report it next to the share of edits a user accepts without a second pass.
# That second number is what the product actually sells, and it is the one a
# pure cost optimisation will quietly destroy.编辑类产品的核心指标不是像不像,而是改对了没、有没有误伤。
📌 常见问题 FAQ
Canva Brush 是什么,和 Craft 有什么区别?
Brush 是 Canva Research 做的视觉语言模型,专门做设计编辑:读得懂布局、图层和风格,按指令修改已有设计。Craft 是 Canva 在 10 月 22 日发布的图像生成模型,负责从零生成图。按 Canva 的说法,Craft 负责生成,Brush 负责围绕生成结果把设计改好。
69% 更快、46% 更便宜是相对什么比的?
相对 Canva 上一代的设计 Agent。69% 是通用设计编辑任务上的速度提升上限,46% 是单次编辑任务的成本下降。这两个都是 Canva 自己公布的内测数字,衡量对象是它自己的旧系统,不是竞品。
Brush 是基于自研模型还是开源模型?
按 Canva 的说法,Brush 从一个领先的开源权重模型出发,然后在真实设计与编辑任务上做后训练,并结合大规模强化学习。也就是说基座是开源权重,差异化来自后训练数据、奖励系统与推理流程。
为什么它要"写代码"去改设计?
因为设计编辑需要精确操作:改哪个图层、改到什么值、保持哪些属性不变。用代码表达这些操作比让模型直接吐出一张新图更可控,也更可验证——执行完还能回头检查页面实际状态,再决定下一步。
小团队能复现这套思路吗?
思路能,规模不能。可行的小版本是:选一个开源基座,把任务收窄到一类明确编辑,用真实数据做后训练,定义可计算的奖励(品牌一致性、误伤范围、可读性),再加确定性验证器。没有奖励信号和验证器就上强化学习,只会得到更自信的错误。