对影阁的鉴画人
一、千幅画像锁在库房里,谁都认不全
刑部画影司的库房里存着三千七百幅画像。
不是名画,是人像。每一幅画像都是一个有案底的人——逃犯、骗子、惯偷——画影司的职责就是在有人报官的时候,调出画像让目击者辨认。但画影司管画像只管了半截。画像是按编号存的,文牒是按姓名存的——画像库和文牒库是两个完全独立的院子,中间隔着一道照壁,互不相通。
每次有人报官,情形是这样的:书吏先问目击者——"你看清他长什么样了吗?"目击者说了一堆——"大约四十岁、高颧骨、鼻子有点歪、左眼角有颗痣"。书吏记下来,拿到文牒库里去翻——翻姓名、翻案底、翻记录。翻出来的文牒上有编号,再拿着编号去画像库里找对应的画像。画像拿出来给目击者看——"是这个人吗?"目击者摇头。
重来。换一个。再摇头。再换。反复折腾。
"你们难道不能直接用目击者说的话去找画像吗?"有一次,一位被折腾了整整一个下午的老妇人终于忍不住了,"我说的每一个字都在纸上写着,你们的每一幅画都在库房里存着——为什么对不上?"
书吏尴尬地搓着手:"因为……字和画是两样东西。字没法看画,画没法读字。"
老妇人走了以后,画影司的主事顾影山在库房门口站了很久。他在刑部干了二十年,这句话他不是头一次听到了。字没法看画,画没法读字。每一次有人来辨认,就是一场手动的、缓慢的、常常出错的对账。
他转身朝后院走去。后院有一间他从不让别人进去的旧屋子。屋门上挂着一块匾,上面是他自己写的三个字:对影阁。
二、文灯画灯,投在同一面墙上
对影阁里什么都没有。没有画像,没有文牒,没有卷宗。只有一面雪白的墙壁,和两盏灯。
两盏灯一模一样——黄铜灯座、水晶灯罩、盛满清油的灯池。唯一不同的是灯座上的刻字:一盏刻着"文",一盏刻着"画"。
"小陆,"顾影山把新来的学徒叫进来,"你把这张画放进画灯前面的卡槽里。"
小陆照做了。画灯亮起来,光穿过那张画像——画的是一个四十来岁的男人,高颧骨,歪鼻子,左眼角有颗痣——投在对面的白墙上。墙上出现了一片模糊的光影,像一团暗黄的雾,完全看不出画中人长什么样。
"看不懂。"小陆说。
"因为画灯的光没调过。把这张文牒放进文灯的卡槽。"
小陆又照做。文灯亮起来,光穿过那张写着字的纸——"四十余岁,颧骨高耸,鼻梁偏斜,左眼外眦有黑痣一粒"。白墙上又出现了一团暗黄的光雾,同样模糊,同样什么都看不清。
"还是看不懂。"
"现在——同时点亮两盏灯。"
小陆把两盏灯的油池都续满,同时点燃。
两道模糊的黄光交叠在白墙上。交叠的那一瞬间,奇怪的事情发生了——模糊的光影忽然变得清晰起来。两团暗黄的雾叠在一起,反而勾勒出了一个清晰的轮廓。高颧骨的阴影、歪鼻梁的线条、眼角那颗痣的位置——全都清清楚楚地浮在墙上。像一张素描,又像一页写了字的纸。既不是纯粹的画,也不是纯粹的文——而是两者的影子叠在一起生出的一种新东西。
"文灯和画灯,"顾影山说,"单独亮的时候什么都看不出来。两盏灯叠在一起——如果文牒和画像说的是同一个人——影子就会自己'咬'上。文里的'高颧骨'对上画里的高颧骨,文里的'歪鼻梁'对上画里的歪鼻梁。一处一处咬住,影子就清楚了。"
"如果不是同一个人呢?"
"叠不起来。"顾影山拿起另一张文牒——描写的是一个二十出头的年轻女子,"你换这张试试。"
小陆换上文牒,两盏灯同时亮。墙上那团光影变得比单盏灯的时候更糊了——两团暗黄的雾互相搅在一起,什么都不像,像一池搅浑了的水。
"不是同一个人,影子就打架。"
三、五百组正对,五千组错对
小陆在对影阁待了一个月以后,终于弄明白了这两盏灯的门道。
灯亮了以后是模糊的——因为灯罩上的水晶不是平的。每一片水晶上都刻着密密麻麻的细微纹路——成千上万条,细得像蚕丝。这些纹路决定了光穿过水晶以后投在墙上的形状。纹路对了——光和光叠在一起就变清楚。纹路不对——光和光叠在一起就变成一池浑水。
"这些纹路是谁刻的?"小陆问。
"没人刻。"顾影山拿出一个沉甸甸的樟木箱子,打开。里面整整齐齐叠着五百对卡纸——五百张画像,五百张文牒,每一对的右下角都写着同一个编号。"这些是过去二十年我亲自核对过的——每一对画像和文牒,确定是同一个人。五百对。"
他从箱子底下又翻出一本厚厚的册子:"这是五千组错对。"
"什么叫错对?"
"随便拿一张画像,随便拿一张文牒——只要编号不一样,就是错对。画像上的人不是文牒里写的人。"
他翻到第一页给小陆看。每一行记录着:画像编号、文牒编号、对影结果、贴合得分。下面是密密麻麻的数字。
"对影阁的灯,是从一片完全没有纹路的白水晶开始的。"顾影山把手掌按在画灯的水晶罩上,"第一张画像放进去——光投在墙上是均匀的一团,什么形状都没有。第一张文牒放进去——同样是一团。两团光叠在一起——还是一团。"
"然后呢?"
"然后我用第一组正对。"顾影山从樟木箱子里拿出第一对卡纸,"画像上的人叫赵大,文牒上写的人也确定是赵大。我同时点亮两盏灯——光投在墙上是一片模糊。但我知道它们应该是同一个人——所以我开始改水晶上的纹路。"
"怎么改?"
"一片一片地试。在两盏灯的水晶罩上同时划一道纹路——方向、深浅、长短——看看墙上的光影变了没有。变清楚了一点点——说明这道纹路是对的,留着。变更糊了——说明这道纹路不对,擦了重来。"
小陆望着满墙的纹路,头皮发麻:"五百对——每一对都要这样试?"
"不止。每一对试完之后,还要用错对来验。"
"验什么?"
"你用水晶上的纹路把正对的影子调清楚了——但如果你忽然换上一组错对,影子又变清晰了呢?那就说明你刻的纹路有问题——你刻出来的不是'这两个人像不像',而是'这两个人是不是同一张纸'。错对必须糊。正对必须清。"
小陆懂了。纹路的训练是双向的:正对→把两盏灯的影子拉近;错对→把两盏灯的影子推远。只有拉近没有推远——所有东西都会被拉成一团。只有推远没有拉近——什么都不可能对上。
"五百组正对拉近,五千组错对推远。"顾影山把樟木箱子合上,"正对练一千次是对的,错对练一万次也是对的——因为每一次错对都在告诉这盏灯:这个方向不对,别往那边凑。"
四、两盏灯必须是一种光
训练了三个月之后,小陆以为自己已经摸透了这套东西的门道。但他犯了一个错误。
有一天他自己试了几组——用自己的方法调整纹路。他发现如果在画灯的水晶上多下一点功夫——把画灯投出来的影子调得特别清晰——同时不管文灯,文灯还是一团模糊——墙上叠出来的影子反而更糊了。
"不对。"顾影山看了他一眼,"你让画灯太亮了。画灯投出来的影子越清晰,它就越看不起文灯的影子。两道影子重叠的时候,画灯的影子会压住文灯的影子——你以为墙上是两个人的影子叠在一起,其实只有一个人的。另外一个人的影子被你压没了。"
小陆愣住了:"那怎么办?"
"两盏灯的亮度、水晶上的纹路密度、光打出来的层次——必须一模一样。画灯不能比文灯亮,文灯也不能比画灯亮。画灯水晶上刻了多少道纹路,文灯水晶上就得刻多少道。不然你对出来的结果不是'画和文都指向同一个人'——而是'画得很清楚、文随便凑上去也行'。"
顾影山走到两盏灯中间,一手按住画灯,一手按住文灯。
"你记住——对影阁的灯,画和文是平等的。画不会写字,文不会画画。但它们必须能说出同一种语言。而这种语言——"他拍了拍两盏灯的水晶罩,"是你教它们的。你教得好,它们说的就是同一种话。你教得偏——画在说画的,文在说文的——叠在一起,永远是一池浑水。"
小陆从头重新来过。他把画灯和文灯的水晶纹路并排对照,确保两边的复杂度完全对等。然后重新跑了一遍五百组正对和五千组错对——这一次,拉近的时候两边各走一半,推远的时候也是两边各退一半。
第三个月的最后一天,他放进去一组从来没见过的正对——墙上两道影子叠在一起,清晰得像一幅工笔画。
顾影山看了三弹指,点了点头。这是他三个月以来第一次点头。
五、一句模糊的口供,三千七百幅画像
腊月出了一桩大案。
京城西市发生了一起劫银案,五万两官银在光天化日之下被劫走,押送的兵丁两死三伤。唯一的目击者是路边馄饨摊的老陈头——他吓得够呛,说话颠三倒四,反复被追问才勉强挤出了几句话:
"男的。大概……三十出头?也可能四十。个不高。脸……脸挺长的。眼睛小。对了——他左手缺了半截小拇指。"
没有姓名,没有籍贯,没有任何可以翻文牒的线索。
"从口供给的信息——男性、三十到四十岁、长脸、小眼、左手缺半截小指——能对上多少个人?"刑部侍郎亲自来了画影司。
书吏翻了半天:"文牒库里按这些条件筛——至少两三百人。"
"两三百人,一幅画像一幅画像拿出去给老陈头认?他吓得话都说不利索,你觉得他有耐心翻两三百幅画像?"
书吏不吱声了。
"对影阁。"侍郎忽然说,"顾影山那个对影阁——能派上用场吗?"
小陆看了看顾影山。顾影山已经在往对影阁走了。
他们把三千七百幅画像全部搬进了对影阁。画像堆在画灯旁边,堆成了一堵墙。小陆把老陈头的口供誊写好,放进文灯卡槽。
"开始。"
画灯放进去第一幅画像——一个长脸的瘦子,大约三十五岁。两道影子叠在墙上——模模糊糊,看不清轮廓。贴合得分很低。
第二幅——更糊。第三幅——几乎全花。第四幅——微微有了点轮廓。第五幅——又花了。
小陆的手开始发酸。三千七百幅画像,一幅一幅地换。顾影山站在墙前面,一言不发地盯着交叠的影子。他的眼睛从第一幅开始就没有离开过那面墙。
第六十一幅——墙上的影子忽然清晰了很多。长脸——对上了。年龄感——对得上。但左手的部分模糊一团——画像上那只左手是完整的。贴合得分中等偏上,但没到能判定的门槛。
"不是。"顾影山说。
第三百零四幅——墙上的影子又出现了。五官的轮廓比第六十一幅更清楚。小陆屏住呼吸。顾影山往前倾了倾身子。贴合得分爬到了七成——但眼睛周围的影子有点散。文牒里写"眼睛小",画像上的眼睛不算小。
"不是。"
第一千二百零九幅。第一千五百六十六幅。第两千一百三十幅。
小陆的手已经完全是一个机械的动作了——取画、装卡槽、点灯、看墙、读数、灭灯、换画。他忽然明白了顾影山为什么花二十年攒那五百组正对和五千组错对——因为对影阁能在一两弹指之内判断一幅画像和一段文字描述是不是同一个人,但它必须先被教会"什么是像、什么是不像"。
第两千七百八十三幅。
墙上交叠的影子忽然安静了下来。不是模糊,不是打架,而是各处的线条都稳稳地咬合在了一起。长脸。小眼。三十多岁的年纪感。左手的阴影——只露出了四根手指。
贴合得分——九成三。
顾影山没说话。他把这幅画像从卡槽里拿出来,翻过来看了看背后的编号,递给侍郎。
"传老陈头来认。"
半个时辰以后,老陈头哆哆嗦嗦进了画影司的值房。侍郎把画像亮在他面前。老陈头看了一眼——手不抖了。
"就是他。"
三天后,疑犯在城南一间客栈里被抓获。左手缺了半截小拇指。和画像、文牒、老陈头的口供——全部对上了。
案子结了以后,侍郎来了一趟画影司。他站在对影阁那面白墙前面,看着两盏灯上密密麻麻的水晶纹路,半天没说话。
"顾主事,"他最后说,"你这个法子——如果给它足够多的正对和错对——是不是以后不管什么画像、什么文牒,都能自己对上?"
"能。"
"那用来找逃犯呢?"
"那就是它本来的用处。"
"用来辨认无名尸首呢?用来对比各地呈报的失踪人口呢?用在城门关卡——"
"侍郎大人。"顾影山打断了他,"对影阁能做所有你说的事。但它需要第一样东西——"
"什么?"
"人。肯花工夫、一组一组地告诉它'这个是正对'和'这个是错对'的人。没有这五百组正对和五千组错对——这两盏灯就是两块玻璃。"
侍郎看了看那面白墙,又看了看顾影山。
"你知道最难的是什么吗?"
顾影山等着。
"最难的不是那五千组错对。是那五百组正对。"侍郎用手指在空中画了一个框,"错对随便拿两张卡纸就能凑——画像库里三千七百幅,文牒库里三千七百份,随便拿两个不一样的就是错对,要多少有多少。但正对——"
"正对必须一个字一个字地核实,一幅画一幅画地比对,确认文牒里写的这个人,就是画像上画的这个人。"顾影山替他说完了,"二十年,五百组。"
"对。"
"对。"
两个人同时说出的这个字,在对影阁空荡荡的屋子里响了一下,然后消散在满墙细密的水晶纹路里。
画不会读字,字不会看画。但人可以教会它们——用一种让它们互相理解的语言。这种语言不在画里,也不在字里。在教它们的人心里。
技术解读
CLIP(Contrastive Language-Image Pre-training)是 OpenAI 于 2021 年(Radford et al., PMLR 2021)提出的多模态对比学习模型,它彻底改变了计算机视觉与自然语言处理的融合范式。CLIP 的核心思想简单而强大:用 4 亿组(图像,文本描述)对训练一个双塔模型——图像编码器(Vision Transformer 或 ResNet)将图像映射为向量,文本编码器(Transformer)将文本映射为同维度的向量——然后通过对比损失(Contrastive Loss)让匹配的图文对在向量空间中靠近、不匹配的图文对彼此远离。训练完成后,图像和文本被对齐到同一个语义空间中:一张"猫在沙发上"的照片,和文字"a cat on a sofa",在这个空间里只相隔一个很小的夹角。这一特性使 CLIP 具备了强大的零样本泛化能力——不需要在特定分类任务上微调,只需用自然语言描述类别,即可在任意图像分类任务上取得接近监督学习的表现。CLIP 也是 DALL·E 2、Stable Diffusion 等文生图模型以及 GPT-4V 等多模态大模型的核心组件之一。
核心概念回顾
| 概念 | 通俗解释 |
|---|---|
| 多模态 | 同时处理图像和文本两种不同形式的信息 |
| 双塔模型 | 图像编码器和文本编码器独立运行,只在最后的向量空间中交互 |
| 图像编码器 | 将图像转换为固定维度向量(如 512 维)的神经网络 |
| 文本编码器 | 将文本描述转换为同维度向量的神经网络 |
| 共享嵌入空间 | 图像向量和文本向量处于同一个坐标系中,可直接计算相似度 |
| 对比学习 | 让匹配对靠近、不匹配对远离的训练范式 |
| 正样本对 | 描述同一事物的图像和文本——应该被拉近 |
| 负样本对 | 描述不同事物的图像和文本——应该被推远 |
| 批内负样本 | 同一训练批次中其他图文对自动作为彼此的负样本 |
| 余弦相似度 | 两个向量夹角的余弦值,衡量它们在方向上的一致性 |
| 零样本分类 | 不提供训练样本,直接用类别名称的文本描述进行分类 |
| 提示工程 | 为文本编码器设计合适的提示模板,如"a photo of a {}" |
故事中的隐喻对照
| 故事元素 | 映射的技术概念 | 解释 |
|---|---|---|
| 画像(三千七百幅人像) | 图像数据 | 待编码的视觉输入,由图像编码器处理 |
| 文牒(三千七百份文字描述) | 文本数据 | 待编码的语言输入,由文本编码器处理 |
| 画灯(水晶灯罩刻满纹路) | 图像编码器 | 将图像投影为向量;水晶纹路=神经网络权重,密密麻麻的参数矩阵 |
| 文灯(同款水晶灯罩、同样的纹路密度) | 文本编码器 | 将文本投影为同维度向量;编码器架构对称,确保公平比较 |
| 对影壁(白墙,两道影子交叠之处) | 共享嵌入空间 | N 维向量空间,图像和文本向量在此直接计算余弦相似度 |
| 影子交叠→清晰(贴合得分高) | 余弦相似度高 | 匹配的图文对在向量空间中方向接近,内积/余弦值大 |
| 影子交叠→模糊/打架 | 余弦相似度低 | 不匹配的图文对向量方向差异大,相似度得分低 |
| 五百组正对(画和文确定是同一人) | 正样本对 | 训练批次中匹配的(图像,文本)对,对比损失将其拉近 |
| 五千组错对(随便拿两张不一样的就是) | 负样本对 / 批内负样本 | 训练批次中不匹配的图文组合自动成为负样本,数量远超正样本 |
| "正对拉近,错对推远" | 对比损失(InfoNCE Loss) | 最大化正样本对的余弦相似度,最小化负样本对的相似度 |
| "让画灯太亮,压住了文灯" | 编码器不对称 | 如果图像编码器过于主导,文本信息将被淹没——两个编码器必须对等训练 |
| 刻纹路→调对了一处就留着→调错了擦掉重来 | 梯度下降 | 沿对比损失的梯度方向更新参数,正确的方向累积,错误的方向回退 |
| 老陈头的模糊口供直接对三千七百幅画像 | 零样本分类 | 不经过额外训练,直接用文本查询在图像库中检索最匹配的图像 |
| 贴合得分九成三,一眼锁定 | 高置信度检索 | 对比学习使得匹配对的相似度远超不匹配对,区分度极高 |
| "画不会读字,字不会看画——但可以教会它们一种共同语言" | 跨模态对齐 | CLIP 的本质:通过对比学习在两种模态之间建立语义等价映射 |
为什么这个故事对应 CLIP / 多模态对比学习?
双塔编码 + 共享空间是 CLIP 的架构核心:画灯和文灯——同样的灯座、同样的水晶、对等的纹路密度——精确对应 CLIP 的图像编码器和文本编码器。两个塔独立运行,不在输入端交互,只在对影壁(共享嵌入空间)上交汇。这种设计使图文匹配可以离线预计算——把所有图像编码一次存入向量库,查询时只需编码文本再检索。
对比学习的本质是"拉近正对、推远错对":对影阁五百组正对拉近、五千组错对推远——这就是 InfoNCE 对比损失的全部。在一个训练批次中,N 组真实匹配的图文对被施加"拉近"梯度;同一批次中剩余的 N²-N 组不匹配组合自动成为负样本,被施以"推远"梯度。错对的数量天然比正对多几个数量级,正如故事中五千对远多于五百对。
批内负样本让训练极度高效:侍郎说出"错对随便拿两张卡纸就能凑"——这正是 CLIP 最巧妙的设计。不需要人工标注负样本——同一个训练批次中任何不属于同一对的图文组合自动构成负样本。一个 batch size 为 32768 的训练步中,正样本对只有 32768 组,而负样本对超过 10 亿组。海量的自然负样本是对比学习成功的关键。
编码器对称性是公平比较的前提:小陆"让画灯太亮、压住了文灯"导致读取失败——映射编码器不对称的问题。如果图像编码器的容量远大于文本编码器,对比损失会被图像特征主导,文本分支学不到有效的表示。CLIP 的两塔虽架构不同(ViT vs Transformer),但输出维度和训练步调必须对等。
零样本泛化是 CLIP 最惊艳的能力:老陈头的一句模糊口供直接筛查三千七百幅画像——这完美映射 CLIP 的零样本分类。训练完成后,模型不再需要该类别(该疑犯)的任何训练样本。只需用自然语言描述"长脸、小眼、左手缺半截小指",即可在全部图像中找到最匹配的那一个。这种"描述即检索"的能力是传统监督学习完全不具备的。
规模是涌现零样本能力的前提:顾影山花了二十年攒下五百组正对——CLIP 用了 4 亿组。当训练数据从几千组扩展到数亿组时,零样本迁移能力发生了质变。CLIP 的 ImageNet 零样本准确率从 2020 年的 30% 级跃升到 76%+——规模的突破带来了能力的涌现,正如对影阁需要足够多的高质量正对才能准确匹配。
CLIP 重新定义了"视觉识别":传统的视觉识别是"先收集各类别的标注图像,再训练分类器"。CLIP 把它变成了"用文字描述你要找的东西,模型在图像库中检索最匹配的"。这一范式转变直接催生了文生图(DALL·E 2, Stable Diffusion)、图生文(图像描述)和多模态大模型(GPT-4V, Gemini)——正如对影阁改变了画影司辨认嫌犯的方式:从"翻文牒→找编号→取画像→人眼比对"变成了"描述→投影→检索→匹配"。
后记:画不会读字,字不会看画——这是两种完全不同的存在。但顾影山用二十年的时间证明了:它们可以被教会同一种语言。对影阁的两盏灯之间没有一根线连着——它们唯一的共同点,是它们投在墙上的影子。正对拉近,错对推远,一遍又一遍——直到有一天,一句模糊的口供投在白墙上,三千七百幅画像中的一幅自动"亮"了起来。画像和文字之间的距离,不是纸和墨的距离——是肯花多少工夫去教它们的距离。

