专业书籍精读 · Generative AI System Design Interview · 第 5 章
Generative AI System Design Interview · Ch 5 · Ali Aminian, Hao Sheng & Alex Xu · 2024
你刷手机看到一张图,一眼就知道里面在发生什么。可对看不见屏幕的人、对要把上亿张图归档的系统来说,这张图得先变成一句话。这一章讲的就是:怎么让机器看一眼图,说出一句人话——不是「狗、草地、飞盘」三个词,而是「一只狗在草地上接住了飞盘」。
贴标签机器很在行:这图里有人、有狗、有飞盘,八九不离十。可你把这三个词念给看不见的朋友听,他还是不知道发生了什么——是人把飞盘扔给狗,还是狗把飞盘叼还给人?标签把东西列全了,却把它们之间的关系全丢了。而关系往往才是一张图里最要紧的部分。
那把标签拼成句子行不行?拼出来是「人 狗 飞盘 草地」式的机器腔,读着像清单。更麻烦的是:同一张图,十个人会写出十句都对的话——有人写动作,有人写天气,有人写那条狗多高兴。没有唯一正确答案,于是「教它写」和「检查它写得对不对」同时变难。
办法是让两个人接力。第一个人负责看图:他不写字,只把画面切成几百个小方块,每块留下一张「速记卡」——这块毛茸茸、那块是绿草地。第二个人负责说话:他看不见原图,只能摸着这叠速记卡,一个词一个词往下说;而且每要说下一个词,他都会回头在卡堆里翻一遍,挑出此刻最相关的那几张。说「狗」时他盯着毛茸茸那几张,说「飞盘」时盯着另外几张。
怎么教会这两个人?靠网页。互联网上无数图片自带一句「配图说明」,白送几亿组「图 + 一句话」的对子。代价很实在:这些话很脏,大量是「点击查看大图」这种废话,得先筛掉一大半才能用。
最土的办法:请五个人给同一张图各写一句标准答案,再看机器那句和这五句用词重合了多少。但换个说法就会被冤枉——「小狗」和「犬」算不上重合。于是有了第二招:再找一个「看图打分员」,它不读标准答案,只回答一个问题:这句话和这张图,配不配?
看懂图只是入场券;真正难的是没人说得清「描述对了」是什么,所以从训练到验收,靠的都是一堆互相补台的近似办法。而最危险的失败不是说不出话,是说得流利、却把图里根本没有的东西说了出来——听的人看不见图,核对不了。
想进到具体机制、记号和示意图? → 切到精读版
你以为图像描述(image captioning)的难点是「看懂图」,其实视觉那一半早被现成的预训练模型解决得差不多了;这一章真正在解的是两件说不清的事:怎么把视觉空间和语言空间对齐成一条能自回归往下写的链路,以及当一张图有无数个都对的描述时,凭什么判分。核心工程直觉只有一句:别从头造一个看图说话的模型,拿两个各自已经很强的现成模型,只训中间那层薄薄的「翻译层」。
Part II 十道真题的第四道。上承 Ch4 ChatGPT——那里输入输出都是文字;这一章第一次跨模态:图进、文出,也正好是后面 Ch7–Ch11(文进图出)的镜像。现实对应无障碍 alt text、图库与电商的图文检索、内容审核的前置理解,以及今天所有多模态助理的「看图说话」那一环。
先把它和上一代任务分清楚:图像分类和目标检测给的是标签,「人、狗、飞盘」。但标签把关系丢了——「人把飞盘扔给狗」和「狗把飞盘叼给人」,标签集合一模一样。读屏软件念出三个名词,视障用户仍然不知道发生了什么。这一章要的是一个带谓语的句子。
第二层是规模。人工写 alt text 不是不能做,是做不完:一个中型图片平台日增 1000 万 张图,按一条人工描述 30 秒算,就是约 83000 小时,一万个人日的活——每天。而模型跑一张图是几十毫秒量级。这道题从一开始就只有自动化一条路。
第三层最麻烦:「对」没有唯一形态。翻译至少有参考译文,分类至少有标准标签;而同一张图的合格描述有无穷多个,写得粗有写得粗的用法(检索索引),写得细有写得细的用法(无障碍)。评估方式必须整套重做——这也是本章后半篇幅最重的地方。
不解决会怎样?视障用户在信息流里只听见「图片」两个字;平台上几十亿张图片成了搜不到、审不了、也归不了档的黑洞。
标准骨架是视觉编码器 + 语言解码器。ViT 把一张 224×224 的图切成 16×16 的 patch,得到 196 个视觉 token,每个是一个 d 维向量;解码器则是一个普通的自回归语言模型。中间必须有一层投影 / 适配器,把视觉向量搬进语言模型的词嵌入空间——两边本来各说各话,这一层就是翻译官。
生成时,解码器每写一个词都做一次 cross-attention:对那 196 个视觉 token 算一组权重,等于「回头在速记卡里翻一遍、挑出此刻最相关的几张」。写「狗」时权重压在毛茸茸那几块,写「草地」时挪到下半张图。这正是标签做不到的事:注意力权重随着句子往下走而移动,关系就是在这个过程里被说出来的。
为什么这个设计便宜得惊人:视觉侧是一次性的百级 token,caption 通常只有 10–20 个 token,整条链路的生成量比文生图小两三个数量级——同样一块 GPU,出一张图要几秒,出一句描述是几十毫秒级。代价在另一头:patch 切得越细看得越清(448×448 就是 784 个 token),而注意力成本随 token 数平方涨,小字、密集场景的识别力就是拿这个换的。
训练要的是「图 + 描述」配对,来源只有两类,而它们几乎在所有维度上相反。
人工标注:COCO Captions 给约 12 万张图各配了 5 句人写描述——一张图五句,本身就是「合格答案不止一个」的直接证据。干净、句式完整,但规模封死在十万级,而且题材偏日常场景。
网页 alt text:白送十亿级配对,但脏得厉害——大量是文件名、「点击查看大图」、SEO 关键词堆砌,或者和图根本无关。所以真正的工作量在过滤流水线:按长度和词性筛掉非句子、用现成检测器核对文中提到的东西图里有没有、把具体人名地名泛化成上位词(「奥巴马」→「政治人物」)以免模型把名字背下来。Google 的 Conceptual Captions 就是这么从网页 alt text 里洗出 330 万条的。
第三条路是合成回填:先用一个还不太行的 captioner 给脏图重写一句,再用一个打分器把明显不配的筛掉,得到「规模接近网页、干净度接近人工」的中间产物。本质是用算力的钱换标注的钱——代价是模型的偏好会被写进它自己的训练数据,错误容易自我强化。
训练用 teacher forcing:每一步都把参考描述里的正确前缀喂进去,让模型只学「给定正确前文,下一个词是什么」。这样训得快、能并行。后遗症叫 exposure bias:真实推理时前文是模型自己写的,一旦第三个词跑偏,它从没见过这种局面,只能一路错下去。
解码策略于是变成一个诚实的取舍。束搜索选总概率最高的句子,结果是描述普遍安全而无聊——满屏的「一个男人在……」,因为最高概率的句子天然是最平庸的那句。采样(温度 / nucleus)让描述生动,但幻觉率同步上升:模型更敢说出图里没有的细节。k=3~5 的束搜索加一个长度惩罚是无障碍场景的常见落点——那里说错的代价远高于说得无聊。
还有一条容易被忽略的裂缝:训练优化的是交叉熵(逐词对不对),验收看的是 CIDEr(整句像不像人写的),两者并不是一回事。于是有了直接把指标当奖励的做法(如自评判序列训练 SCST):让模型自己采样几句、用 CIDEr 打分、往高分方向挪。它能把指标显著抬上去,但也把「刷指标」的空间一并打开了——这是第 4 章 reward hacking 的同一个故事换了张皮。
自动指标分三代,各自补上一代的洞。
n-gram 重合派(BLEU / METEOR / ROUGE):看生成句和几句参考答案的词组重合度。问题是同义改写会被冤枉,而「一个男人」这种到处都出现的词组又白送分。CIDEr 是专为 captioning 设计的改良:用 TF-IDF 给词组加权,把所有图都通用的套话压到近乎零分,只有说出这张图特有的东西才得分。
结构派(SPICE):把句子解析成场景图——对象、属性、关系——再和参考答案的场景图比。它正好抓住了标签丢掉的那一层:「狗叼飞盘」和「飞盘砸狗」在 n-gram 上几乎同分,在场景图上是两件事。
无参考派(CLIPScore):干脆不要标准答案,把图和句子各自编码进同一个空间,量它们有多近。好处是能评那些参考答案里压根没有的正确描述,坏处是它继承了 CLIP 自己的盲区——数数、方位、否定都不灵。
三代全上也替代不了人评。真正上线前还要专门测一项:物体幻觉率——生成句里提到、但图中并不存在的物体占比。它和流畅度无关,却是无障碍场景里唯一致命的错误类型。
第一个决策是怎么接线:视觉侧和语言侧各有一堆现成的强模型,问题是训哪部分、冻哪部分。
表 1 · 四种接线方式
| 从头训 | 冻结双塔 + 适配器 | 全量微调 | 直接调通用 VLM | |
|---|---|---|---|---|
| 可训练参数 | 全部 | 通常 1%–5% | 全部 | 零 |
| 数据需求 | 千万级配对 | 十万到百万级 | 百万级,且要高质量 | 零(顶多给几个示例) |
| 训练成本 | 最高,多数团队做不起 | 最低,单机多卡即可 | 高,且要小心灾难性遗忘 | 无训练成本 |
| 领域适配 | 想怎么定制都行 | 换编码器 / 换解码器都只需重训那层 | 最贴合垂直领域 | 医学影像、工业质检这类专业域往往不达标 |
| 推理成本 | 自己托管,可量化裁剪,单张几十毫秒量级 | 按 token 计费,量一大就贵;还多一跳网络 | ||
| 代价 | 纯烧钱,除非你就是造基座的那家 | 上限受制于冻结的两端;细粒度识别常不如全微调 | 一次只服务一个领域,换域要重来 | 数据出境、限流与版本漂移全不受控 |
| 适合 | 基础模型团队 | 绝大多数团队的默认起点 | 有独占数据的垂直场景 | 验证期、量小、通用题材 |
第二个决策是用什么验收。这里最常见的错误是只报一个 CIDEr 就上线。
表 2 · 五种评估口径
| 要参考答案 | 量的是什么 | 漏掉什么 | 什么时候用 | |
|---|---|---|---|---|
| BLEU | 要(多句) | 词组重合 | 同义改写被冤枉;套话白送分 | 只做回归测试的快照 |
| CIDEr | 要(多句) | TF-IDF 加权后的词组重合 | 仍是表层匹配,关系错了照样得分 | 离线迭代的主指标 |
| SPICE | 要 | 对象 / 属性 / 关系是否对账 | 依赖句法解析,解析错就全错 | 怀疑模型在乱编关系时 |
| CLIPScore | 不要 | 图与句在同一空间里的贴合度 | 数数、方位、否定;继承 CLIP 的偏见 | 线上无参考的批量巡检 |
| 人评 + 幻觉率 | 不要 | 可用性,以及提到了图里没有的东西的比例 | 贵、慢、不可回归 | 上线前的最终闸门 |
第三个决策常被当成小事,其实直接定义产品:描述写多细。检索索引要的是密集名词(越多可命中的词越好,读起来像不像人话无所谓);无障碍要的是一句完整、准确、不猜测的话;社交场景还想要点语气。同一个模型很难同时最优——多数系统的做法是同一套视觉表示、按场景配不同的提示词与解码参数,而不是训三个模型。
三个已经在大规模跑的落点:无障碍(社交平台给没有 alt text 的图自动补一句,读屏软件念出来)、图文检索(把生成的描述丢进倒排索引,图片从此可以被文字搜到,这是电商和图库的主线需求)、内容理解前置(先把图转成文本,后面的审核、打标、推荐链路就都能复用已有的文本管线,省掉一整套多模态基础设施)。第三个尤其值钱:captioning 在很多公司的真实身份不是面向用户的功能,而是把图片塞进文本世界的转接头。
330 万条配对。数据侧的真实工作量不在采集,在过滤。google-research-datasets/conceptual-captions ↗① 这章解的不是「看懂图」,是跨模态对齐与无标准答案下的判分这两件说不清的事。
② 标签丢关系:「人扔飞盘给狗」和「狗叼飞盘给人」标签集合相同——要的是带谓语的句子。
③ 骨架是视觉编码器 + 投影 / 适配器 + 语言解码器;cross-attention 让注意力随句子往下走而移动。
④ 量级感:224×224 → 196 个视觉 token,caption 仅 10–20 token,单张几十毫秒级;图放大到 448×448,成本按 token 数平方涨。
⑤ 默认起点是冻结两端、只训中间那层:可训练参数常只有百分之几,换件成本极低。
⑥ 数据上人工干净但止步十万级、网页 alt text 十亿级但脏;真功夫在过滤流水线,合成回填是用算力换标注。
⑦ teacher forcing 带来 exposure bias;束搜索安全无聊、采样生动易幻觉,无障碍场景选前者。
⑧ 评估分三代:n-gram 重合(CIDEr 用 TF-IDF 压套话)→ 场景图对账(SPICE)→ 无参考贴合度(CLIPScore),互相补台,谁也不能单独作结论。
⑨ 上线闸门是人评 + 物体幻觉率:流畅的错误比笨拙的正确危险得多。
⑩ 产品红线:只描述可见事实、不推断身份;数据集里的共现会被模型当成规律照抄。