视觉语言预训练 本节摘要:编码器、投影、解码器都接好了,现在一起训。两个目标驱动学习:对比图文损失(InfoNCE)把配对在联合嵌入空间拉近,语言建模损失要解码器为每图写字幕。组合教网络既能为字幕找对图、又能为图写字幕。视觉语言模型需两技能:排名(给字幕从多图找对图)与生成(给图写字幕)。单技能预训给半个系统——CLIP 拿下排名但不能写字幕,GPT-4V 能写字幕但用独立检索头排名。多目标预训一次拿两。InfoNCE 处理排名半:对 N 配对批,模型把 N 匹配当正、 不匹配当负,在结果 相似矩阵上跑交叉熵。LM 损失处理生成半:标准条件于图像的下一 token 预测。两损失可微,共享编码器、投影器、解码器权重。 对应原课程:Phase 19 · Lesson 62 · (原英文 )。
本节摘要:编码器、投影、解码器都接好了,现在一起训。两个目标驱动学习:对比图文损失(InfoNCE)把配对在联合嵌入空间拉近,语言建模损失要解码器为每图写字幕。组合教网络既能为字幕找对图、又能为图写字幕。视觉语言模型需两技能:排名(给字幕从多图找对图)与生成(给图写字幕)。单技能预训给半个系统——CLIP 拿下排名但不能写字幕,GPT-4V 能写字幕但用独立检索头排名。多目标预训一次拿两。InfoNCE 处理排名半:对 N 配对批,模型把 N 匹配当正、
N^2-N不匹配当负,在结果(N,N)相似矩阵上跑交叉熵。LM 损失处理生成半:标准条件于图像的下一 token 预测。两损失可微,共享编码器、投影器、解码器权重。
对应原课程:Phase 19 · Lesson 62 ·
vision-language-pretraining(原英文phases/19-capstone-projects/62-vision-language-pretraining/docs/en.md)。本节属「多模态/VLM」赛道第五节。
阅读完本节,你应当能够:
视觉语言模型需两技能:排名(给字幕从多图找对图)与生成(给图写字幕)。单技能预训给半个系统。CLIP 拿下排名但不能写字幕;GPT-4V 能写字幕但用独立检索头排名。多目标预训一次拿两。
把 N 图像嵌入作行、N 文本嵌入作行,L2 归一两者。算 N x N 矩阵 S = I T^T / tau,tau 是学习温度。对角项是匹配对,非对角是负。施交叉熵目标 argmax 沿对角走:行 i 最高项应在列 i。沿列对称同做。总是两者均值。这是 CLIP 损失八行。
logits = (image_emb @ text_emb.T) / tau # N x N, 归一化后 labels = arange(N) # 对角是真配对 loss_i2t = cross_entropy(logits, labels) # 图 -> 文 loss_t2i = cross_entropy(logits.T, labels) # 文 -> 图 info_nce = (loss_i2t + loss_t2i) / 2 # 双向均值
温度 tau 控 softmax 多尖。太小(如 tau=0.01)梯度只来自最难负,训练噪;太大 softmax 平、梯度消失。CLIP 把 tau 作参数学,demo 同。
解码器经交叉注意力吃图像记忆 token,在每位置预测下一文本 token。损失是标准交叉熵带下一位置目标。填充位掩出损失。
total = contrastive + lm_weight * lm,lm_weight 是标量(常 1.0)。两损失共享进编码器与投影的梯度;只解码器收 LM 损失梯度。这是 CoCa、BLIP、SigLIP 风格模型都用多任务配方,各权重不同。
| 组件 | 损失面 | 影响 |
|---|---|---|
| InfoNCE | 联合空间配对排名 | 编码器 + 投影 + 文本头 |
| LM | 条件于图像的 token 预测 | 编码器 + 投影 + 解码器 |
| 合并 | 多任务 | 整栈 |
mock 语料是合成 200 对,随机图与随机字幕 id。50 步 SGD 批 16 后,两损失可见降,即便绝对值高于真数据模型。demo 的点是确认梯度管道端到端工作,加 LM 损失不稳掉对比目标。
code/main.py 实现:
MultimodalModel:组小 ViT 编码器、MLP 投影器、小文本侧编码器(id 嵌入均值池)、第 59 节交叉注意力解码器。info_nce_loss(image_emb, text_emb, temperature):双向 CLIP 风格对比损失。lm_loss(logits, target_ids, padding_id):掩码下一 token 交叉熵。make_mock_corpus(seed, n_pairs):返 200 确定性(图像,字幕 id)对。class MultimodalModel(nn.Module): def __init__(self, ...): self.vision = VisionEncoder(...) # 第 56-57 节 self.projector = MLPProjector(...) # 第 58 节 self.text_embed = nn.Embedding(vocab, D) self.decoder = VisionLanguageDecoder(...) # 第 59 节 self.log_tau = nn.Parameter(torch.zeros(1)) # 学习温度 def forward(self, images, caption_ids): img_tok, cls = self.vision(images) img_emb = self.projector(cls) # N x D 排名 txt_emb = self.text_embed(caption_ids).mean(1) # N x D 排名 tau = torch.exp(self.log_tau) contrastive = info_nce_loss(img_emb, txt_emb, tau) logits = self.decoder(caption_ids, img_tok) # N x T x V 生成 lm = lm_loss(logits, caption_ids, padding_id) return contrastive + lm_weight * lm, contrastive, lm
code/test_main.py 覆盖:InfoNCE 跨图/文行对称;InfoNCE 在相似矩阵是大正对角时返 0;LM 损失正确掩填充位;模型前向无错产两损失;5 步训练循环降合并损失。
设计要点:InfoNCE 的双向(图→文 + 文→图)是关键——单向只推图找字幕,双向同时推字幕找图。学习温度防手动调——太小梯度噪、太大梯度灭,作参数自找最优。合并损失
contrastive + lm_weight*lm共享编码器与投影梯度,只解码器收 LM 梯度——这是多任务的本质:重件(编码器)被两任务共塑,轻件(解码器)只被 LM 塑。50 步够证梯度管道,真模型训百万步但动力学同。
这是同损失配方发于:CLIP(2021,仅图文对比,带独立冻编码器字幕探针);CoCa(2022,图文对比加图字幕 LM 损失一模型,本节建的精确模式);BLIP(2022)与 BLIP-2(对比加 LM 加图文匹配头,三损失合并);SigLIP(2023,InfoNCE 换 sigmoid 配对损失,同对比角色不同函数形式);LLaVA 族(两阶段,阶段一对齐冻 LM 上余弦=第 58 节,阶段二加 LM 损失解冻 LM=本节)。本节手写让你看清 InfoNCE 的相似矩阵、学习温度、双损失合并——这些在用 CLIP/LLaVA 时是黑盒。open_clip、HuggingFace transformers 的 CLIP/BLIP 实现是同数学的产品化版。
code/main.py + code/test_main.py。demo 在 CPU 上约一分钟跑完:对比损失从约 ln(16)=2.77 降到 2.4,LM 损失从 ln(512)≈6.24 降到约 4.7,两降证梯度接对。MultimodalModel、info_nce_loss、lm_loss 可独立复用——任何「对比 + 生成」多任务 VLM 场景。第 61 节用此训后模型跑三评估面。
lm_weight=0 与 =1 各训,比对比损失(LM 不应退排名目标)。N x N 相似矩阵交叉熵。contrastive + lm_weight*lm:共享编码器/投影梯度,只解码器收 LM 梯度。下一节(本章最后一节),我们做「多模态评估」——检索 R@K、VQA 精确匹配、字幕 BLEU-4 三评估面,合成套件上秒级跑。