Sean Ren AI 体验产品设计师

输入访问码

这份作品集仅供受邀查看。

跳到​章节

Vibe Coding绘画​与​代码2026 年​秋

未完成

我把​衬衫​留​成了​空白​的​纸。一个​模型​从中​读​出了​一件​衬衫。代码​用​模型​的​数字​把​它​画出来。

每个数字是它所在位置的明度,0 最暗,9 最亮,用这幅画八种颜色中最接近的一种,按模型排列图块的顺序一块一块地读出。把指针移到画上,或者按住它,就能读到这些数字。

模型​读​到a painting of

a 90%man 1%the 1%

一幅肖像,以及两个开源模型在我的笔记本电脑上对它做的一切。图像描述模型读这幅画,把空白的纸叫作白衬衫;图像模型起草这件衬衫;代码再用图像模型运行时的数字,把它织在画上。下面的每一个词、数字和画面都来自这些运行。

角色
艺术​家
创意​技术​专家
模型
BLIP、SDXL Inpainting
运行​环境
本地​设备
渲染
Canvas 2D 实​时​渲染
工具
Claude Code、Python、PyTorch、React

绘画

在​任何​模型​之前:笔触、明度​和​一套​色​板。

这是我作为画家读同一幅画的方式。笔触顺着形体走,色调落在明度阶上,每种颜色都来自同一套色板。在这里,每一笔都重画成一行属于它自己的明度数字,0 最暗,9 最亮,用构成这幅画的八种颜色。线条从最暗的开始自己画出来,就像我起稿一幅肖像那样。

明度,0 最​暗,9 最​亮

我的​色​板,从​颜料​中​取样​的​八​种​颜色

钴蓝,机器的颜色:在我的色板之外,在色轮上与色板里的赭石色相对。

解读

它​一个​词​一个​词​地​读​这​幅​画。

图像描述模型 BLIP 从“a painting of”开始,从一张排好序的列表里选下一个词。束搜索保留整体得分最高的句子,所以它选了 21% 的“in”,而不是 23% 的“with”,又选了 9% 的“looking”。接着它以 82% 的概率给一幅画安上了一台相机(camera)。在动笔之前,我换上了它自己的第二选择:5% 的“viewer”(观者)。

  1. a painting of给​它的​开头
  2. a
    • a90%
    • man1%
    • the1%
    • an1%
    • young<1%
  3. man
    • man60%
    • young13%
    • painting4%
    • portrait3%
    • close2%
  4. in
    • with23%
    • in21%
    • is8%
    • wearing7%
    • looking5%
  5. a
    • a67%
    • white18%
    • an1%
    • front1%
    • yellow1%
  6. white
    • white62%
    • shirt10%
    • yellow3%
    • polo2%
    • baseball1%
  7. shirt
    • shirt88%
    • sweater1%
    • polo1%
    • collar1%
    • t1%
  8. looking
    • is13%
    • and9%
    • looking9%
    • with8%
    • looks7%
  9. at
    • at21%
    • to10%
    • off7%
    • into7%
    • away5%
  10. the
    • the68%
    • something16%
    • a5%
    • camera2%
    • his1%
  11. viewer我的​修改
    • camera82%
    • viewer5%
    • side1%
    • right1%
    • left<1%

它​本​可能​写​出​的​解读

  • a young man wearing a white shirt and a brown hat
  • a man with a baseball bat in his hands
  • a man in a white shirt stares off into the distance

温度 0.6。 比​它​自己​的​概率​更“冷”:它​会​贴近​最初​的​选择,解读​也就​保持​合理。 它​抽出​的 8 个​解读​中的​三​个;碰巧​点了​人名​的,我​都没​放。

注视

它​写下“shirt”时,看​的是​空白​的​纸。

它的视觉部分把画切成 576 个图块。对每个词,方块标出那些因注意力而提高了这个词概率的图块:用梯度加权的注意力,也是 BLIP 作者用来显示词语落在图中哪里的方法。“Man”找到了脸,“shirt”落在领口和下面的空白纸面上,而它说的“camera”,其实是他的眼睛。

我的​肖像,标​出​图像​描述​模型​为“shirt”看​过的​图​块

为了“shirt”,它​看了​领​口​和​下面​的​空白​纸​面。我​从​没​在​那里​画​过​衬衫。

576 个​图​块,24 × 24。方​块​的​大小,表示​这个​图​块​的​注意力​把“shirt”的​概率​提高​了​多少;它​给“{word}”的​概率​是 88%。

为什么​是​白​衬衫

它​用​通常​出现​在​那里​的​东西​填满​空白​的​纸,用​的是​纸​的​颜色。

领口以下什么都没画,而在画室的灯光下,纸面拍出来是暖黄色。于是我每次只改一处,用同样的开头再问同一个模型。每组测试都列出给它的图、它读出了什么,以及在“a man in a”之后每个词的概率。

  1. 按​我​画​的​样子:给​模型​的​图。按​我​画​的​样子“a man in a white shirt looking at the camera”white 62%
  2. 纸​面​填​成​黑色:给​模型​的​图。纸​面​填​成​黑色“a man in a black shirt and tie”black 53%white 1%
  3. 纸​面​填​成​蓝色:给​模型​的​图。纸​面​填​成​蓝色“a man in a blue shirt looking at the camera”blue 85%white <1%
  4. 纸​面​填​成​黄色:给​模型​的​图。纸​面​填​成​黄色“a man in a yellow shirt looking at the camera”yellow 83%white 3%
  5. 只留​头部,裁​掉​纸​面:给​模型​的​图。只留​头部,裁​掉​纸​面“a man in a suit and tie in front of a painting”suit 11%white 9%
  6. 没有​图,只有​平​涂​的​灰色:给​模型​的​图。没有​图,只有​平​涂​的​灰色“a man riding a surfboard on top of a wave”suit 11%white 5%
颜色​来自​纸​面。
把​纸​面​填​成​黑、蓝​或​黄,衬衫​就​变成​黑、蓝​或​黄:53%、85% 和 83%。我的​纸​拍​出来​是​暖​奶油​色,但​作为​画​里​最​浅​的​东西,它​被​读​成了​白色,62% 对​黄色​的 3%。
脸​的​下面,它​预期​是​衣服。
无论​纸​面​是​什么​颜色,后面​那个​词​都是“shirt”,51% 到 88%。把​纸​面​裁​掉,它​还是​给​他​穿上​了​衣服:西装​和​领带。
不只是​词语​的​作用。
没有​图​时,“a man in a”后​面接“white”的​概率​只有 5%。那 62% 来自​看​那​张​纸。
它​没有​表示“未完成”的​词。
从“an unfinished painting of”开始,它​仍然​写​出“a young man in a white shirt”。它​读​不出​空白​纸​面​就是​空白。

数字

图像​模型​拿到​的是​数字,不是​词。

在​图像​模型​能​用​上​这​段​解读​之前,它​自己​的​分词​器​要​把​每​个​词​拆​成​从​训练​文本​里​学​到​的​片段,再​换​成 ID。这 13 个​数字,就是​它​看到​的​全部​解读,也是​衬衫​将要​织​成​的​数字。

  1. 字母shirt</w>
  2. 第 41 次​合并shirt</w>
  3. 第 71 次​合并shirt</w>
  4. 第 1,445 次​合并shirt</w>
  5. 第 2,012 次​合并shirt</w>
  6. Token ID2523

CLIP 的分词器从字母开始,不断合并它最早学到的那一对,直到“shirt”成为它认识的一个片段。名次是这一对在它从训练文本学到的 48,894 次合并中的位置;</w> 表示一个词的结尾。图像​描述​模型​在​自己​的​词表​里​把​同​一个​词​记​作 3797:两​个​模型​并不​共用​数字。

草稿

它​从​噪声​里​起草​衬衫,先​画​大​形。

图像模型拿到这 13 个 ID,以及遮住空白纸面的画。在 29 步里,它不断猜测完成后的画面,先粗后细。我把它的草稿只当草稿:它决定褶皱和阴影的位置,但它的颜料一点也不会落到画布上。

图像​模型​起草​衬衫,第 1/29 步
步 1 / 29

提示词,来自它自己的解读:a man in a white shirt looking at the viewer。每一帧都是它在那一步对完成画面的猜测。轮廓之外,画保持我留下的样子。

它​做的​每​一份​草稿,每​个​种子​一份

衬衫​的​另​一份​草稿衬衫​的​另​一份​草稿

代码

代码​用​这些​数字​织出​衬衫。

在我的画上,代码用这 13 个 ID 重画衬衫。草稿里越暗,数字就越粗重;模型在哪一步确定了某个位置,那里的数字就在哪一步落下。可以在我的画、模型的草稿和代码之间切换,并拖动查看每一步。

衬衫由图像模型收到的 13 个 token ID 织成。草稿里越暗,数字就越粗重;模型在哪一步确定了某个位置,那里的数字就在哪一步落下。我起稿的线条始终在最上层。

320308653932078653032015792523131253651815061

研究

每一​幅​图​都​建立​在​模型​的​工作​方式​之上。

在此​之前,我​研究​过 AI 是​如何​被​描绘​的,也​用​代码​画​过​模型​内部​的​机制。下面​的​每​一个​来源,都是​这​幅​画​绘制​方式​中的​一条​规则。

Justin Jay Wang,OpenAI 与 Cursor

以​代码​为​媒介

他的​图形​是用​代码​写成​的​规则​集,每​一套​都由​系统​的​行为​构​建。这里​的​图​也是​规则​集:一套​决定​数字​落在​哪里、有​多​粗重,一套​决定​注意力​方​块​长​多大,一套​决定​一次​合并​何时​亮起。

用​代码​做​设计
Better Images of AI,始​于 2021 年

如​实​呈现​机器

AI 的​图​库​图片​总是​机器​人​和​发光​的​大脑,掩盖​了​系统​在做​什么、由​谁​制造。所以​模型​的​部分​从不​伪装​成​颜料,而是​以​它​自己​的​材料​呈现,接缝​清晰​可见。

Better Images of AI
Selvaraju 等,2017;Darcet 等,2024

模型​看向​哪里

无论是哪个词,原始注意力大多落在几个背景图块上,也就是视觉 Transformer 长出来的“寄存器”。用这个词概率的梯度来加权,只留下那些真正改变了这个词的注视。

Grad-CAM
Model Studies,我的​第​一个​研究

从​玩具​模型​到​真实​模型

我最早是用为页面写的小模型来画这些机制的:一个在一页文本上训练的分词器、一个三元组采样器、基于规则的注意力头、一个线性去噪器。在这里,同样的四样东西,是真实模型在一幅画上的真实数字。

第​一个​研究

在​界面​中

这​会​给​创作​工具​带来​什么​改变。

我​设计 AI 产品。用​模型​来​完成​我​自己​的​画,是​我​找到​的​最​清楚​的​方式,去​感受​它的​帮助​应该​止于​哪里,以及​怎样​把​它​展示​出来。

先​展示​解读

模型​根据​它的​词​行动,而不是​根据​我的​意图。它​给​我的​画​安​了​一台​相机;正​因为​它的​解读​和​第二​选择​就​摆​在​我​面前,我​才能​在​它​画​任何​东西​之前​换​上“viewer”。

让​作者​的​笔迹​留在​最​上层

代码​图​层​放在​我​起稿​的​线条​下面,从不​盖​在​上面。AI 的​贡献​应该​围绕​作者​已有​的​东西​展开,而不是​把​它​涂掉。

让​接缝​看得见

一种​无法​冒充​颜料​的​材料,能​准确​显示​机器​在​哪里​工作​过。出​处​被​设计​进​画面​本身,而不是​画​旁边​的​一张​标签。

把​输出​当作​草稿

模型​的​草稿​决定​光影​和​形体,最后​一层​则​是​一个​独立、可​检查​的​选择。人们​可以​保留​指引,拒绝​颜料。

方法

它是​怎样​做​出来​的。

笔触

笔触的方向来自颜料色调的结构张量,经过平滑,让它顺着笔触和形体走,而不是顺着画布的纹理。线条是等间距的流线,越暗越密;每个数字是它所在位置的明度,用八种颜色中最接近的一种,最暗的线最先画。

色​板

八​种​颜色,是​对​这​幅​画​照片​中​上过​颜料​的​区域​聚​类​得到​的,空白​的​纸​不计​在内,按​从​暗​到​亮​排序。照片​是在​暖​光​下​拍的,所以​色​板​偏​赭石​色。

解读

BLIP 图像描述(large),从“a painting of”开始,用五束的束搜索。我唯一的修改替换了它的最后一个词;候选词是修改后句子每一步的概率。其他解读是普通的温度采样,每个温度 8 个。

注视

写​出​每​个​词​的​那​一步​对 24 × 24 个​图​块​的​交叉​注意力,乘​以​它​相​对于​这个​词​对​数​概率​的​正​梯度,再​对​文本​解码​器​的 12 个​头​和 12 层​取​平均。

为什么​是​白​衬衫

同一个图像描述模型,同样的开头。把空白的纸,也就是衬衫所在的蒙版,平涂成一种颜色,上过颜料的部分和我起稿的线条保持原样;或者把头部以下裁掉;或者只给一张平涂的灰图。每个词的概率来自对“a painting of a man in a”的一次前向计算,解读则来自和上面相同的束搜索。

数字

用 CLIP 那张含 48,894 次合并的合并表,重放它的字节对编码:从字母开始,不断合并它最早学到的那一对,直到没有可合并的为止。ID 就是图像模型收到的那些。

草稿

Stable Diffusion XL inpainting 0.1,约一百万像素,29 步 Euler,强度 0.99,引导系数 7,两个种子;每一步的预览用的是小型 SDXL 自编码器。某个位置的猜测在某一步之后始终与最终值相差不到 4%,就算在那一步确定。

影片​里​的​数字

画面像 ASCII 渲染那样变成字符(three.js 内置了一个),但每个字符都是一个数字:它所在位置从 0 到 9 的明度,按这幅画自己的明暗范围拉伸,用八种颜色中最接近的一种,越暗越大、越粗。它一块一块、一行一行地翻转,顺序就是视觉编码器排列 576 个图块的顺序。空白的纸留给衬衫。

数字

空白​纸​面上​的​一张​格子​网,每隔​一行​错​开​半​格。和​纸​一样​亮​的​地方​留空,越​暗​的​地方​数字​越​粗重,每​个​数字​都在​它的​位置​确定​的​那​一步​落下。

在​笔记​本​电脑​上

一切都运行在一台 M1 Pro 的 MacBook Pro 上,通过 PyTorch 使用 Apple GPU,模型是 Hugging Face 上的开源模型。这幅画从未离开过这台电脑。