news 2026/9/7 15:11:46

深入理解 Transformers 中的 CLIPSeg:基于冻结 CLIP 的零样本与一次性图像分割模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入理解 Transformers 中的 CLIPSeg:基于冻结 CLIP 的零样本与一次性图像分割模型

深入理解 Transformers 中的 CLIPSeg:基于冻结 CLIP 的零样本与一次性图像分割模型

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

导读

CLIPSeg(CLIP Segmentation)是 Transformer 库中一个以“文本 / 图像提示驱动图像分割”为核心能力的模型家族。本文以 clipseg 模型文档 为骨架,结合 配置源码、建模源码、处理源码 与集成测试,系统讲解:为什么 CLIPSeg 能在不重新训练分割模型的情况下理解"任意提示";它的文本、视觉、解码器三大子模块如何组织;每个配置项的含义与默认值;以及如何仅凭数行代码完成一次零样本(zero-shot)或一次性(one-shot)分割推理。读完本文,你将能独立加载CIDAS/clipseg-rd64-refined这类检查点,并把它接入基于图像生成式文本查询的实际业务。

模型概览:一份提示、三类分割任务

CLIPSeg 由 Timo Lüddecke 与 Alexander Ecker 提出,论文题目为Image Segmentation Using Text and Image Prompts,于 2021 年 12 月 18 日在 Hugging Face Papers 发布,并在此后(2022 年 11 月 8 日)正式合入 Transformers 代码库。它的核心思想非常直接:在冻结的 CLIP 骨干之上添加一个极小的 Transformer 解码器,从而实现零样本与一次性图像分割。

传统图像分割通常针对固定的类别集合训练,想要加入新类别或更复杂的查询,就得在包含这些表达的数据集上重新训练。CLIPSeg 的方案是"一次训练、随时查询":推理阶段允许任意提示(prompt),提示可以是一段文本,也可以是一张图片。由此,同一个统一模型可覆盖三种常见分割任务:

  • 指代表达分割(Referring Expression Segmentation):用自然语言指代图中某个对象并分割出来;
  • 零样本分割(Zero-shot Segmentation):分割训练时从未见过的类别;
  • 一次性分割(One-shot Segmentation):用一张查询图片作为示例,分割出同类对象。

该混合输入设计还支持"动态适应"任何能用文本或图片表达的二值分割任务,包括关于物体 affordance(可操作性)或属性(properties)的泛化查询。模型在扩展版 PhraseCut 数据集上训练后,能为图像基于自由文本提示或表达查询的附加图像生成二值分割图。

事实来源:上述信息直接出自 clipseg.md 中论文摘要的转述,仓库未对其训练数据集规模做更多声明,故本文不补充任何额外性能数字。

该模型由 nielsr 贡献到本仓库,源码级入口与实现集中在src/transformers/models/clipseg/目录下。

架构解读:冻结的 CLIP 骨干 + 轻量 Transformer 解码器

从源码结构看,src/transformers/models/clipseg/目录将 CLIPSeg 拆成了清晰的三层结构:

模块文件职责
配置类configuration_clipseg.py定义文本、视觉、整体三类 Config
模型类modeling_clipseg.py双塔编码器、解码器与前向逻辑
处理器processing_clipseg.py将文本与图像统一打包成模型输入
转换脚本convert_clipseg_original_pytorch_to_hf.py官方原始权重转换工具

模型相关的模块化源文件为 modular_clipseg.py,该文件会自动生成上面的建模与配置文件(文件头注释明确提示不要手动编辑生成产物)。

双塔基础模型 CLIPSegModel

CLIPSegModel与标准CLIPModel结构一致,构成方式是文本塔 + 视觉塔 + 投影层。在 modeling_clipseg.py 的构造函数中可以看到:

  • self.text_model = CLIPSegTextModel(...):文本编码器,输出序列级 hidden states;
  • self.vision_model = CLIPSegVisionModel(...):视觉编码器,ViT 风格 patch embedding + Transformer 编码器;
  • self.visual_projectionself.text_projection:将两塔输出投影到共同的projection_dim
  • self.logit_scale:可学习的对比学习缩放参数,初始值取logit_scale_init_value(默认 2.6592)。

CLIPSegModel对外暴露三个主要方法:

  • forward:计算图像与文本的相似度 logits,可用于训练对比学习损失;
  • get_text_features:返回文本侧特征(供条件 embedding 使用);
  • get_image_features:返回图像侧特征(视觉塔前向的正式入口)。

当作为分割模型使用时,CLIP 双塔几乎全程处于torch.no_grad()冻结状态,只有新增的轻量解码器参与梯度计算,这是 CLIPSeg "最小解码器 + 冻结骨干"设计的直接体现。

文本子模型 CLIPSegTextModel

CLIPSegTextModelinput_ids为唯一必选输入,内部流程为:token embedding → causal mask 的 Transformer encoder → final LayerNorm → 取EOS token位置向量作为pooler_output。实现细节(见 modeling_clipseg.py)中有一处值得注意的历史处理:若配置中eos_token_id == 2(PR #24773 之前的旧行为),会退回到"取序列最大 token id"位置的老逻辑;否则按"第一个等于eos_token_id的位置"取值,以兼容 tokenizer 新增 token 的场景。

默认文本配置(CLIPSegTextConfig)对应 CLIP 风格:vocab_size=49408hidden_size=512intermediate_size=2048num_hidden_layers=12num_attention_heads=8max_position_embeddings=77、激活函数为quick_gelupad_token_id=1bos_token_id=49406eos_token_id=49407

视觉子模型 CLIPSegVisionModel

CLIPSegVisionModelpixel_values为输入,流程为:patch embedding(含 class token)→ pre LayerNorm → Transformer encoder → 取 CLS token 做 post LayerNorm 得到pooler_output。默认视觉配置(CLIPSegVisionConfig):hidden_size=768image_size=224patch_size=32num_hidden_layers=12num_attention_heads=12,这也是 CLIP ViT-B/32 的规格。

视觉塔前向支持interpolate_pos_encoding参数(默认True),允许把预训练的位置编码插值到更高分辨率输入上使用——集成测试 test_inference_interpolate_pos_encoding 验证了 180×180 分辨率下该能力:关闭插值会因 patch 数量不匹配而抛出ValueError,开启后则正常输出(1, 26, 768)的 hidden states。

分割头 CLIPSegDecoder 与三步前向

真正把 CLIPSeg 与纯 CLIP 区分开的是CLIPSegDecoderCLIPSegForImageSegmentationCLIPSegForImageSegmentation的前向(见 modeling_clipseg.py)可归纳为严格的三步流水线:

  1. 冻结视觉塔前向查询图像:以torch.no_grad()调用clip.get_image_features,同时要求output_hidden_states=True,按extract_layers(默认第 3、6、9 层)取出对应激活值,并记录pooler_output
  2. 计算条件 embedding:优先使用调用方直接传入的conditional_embeddings;否则根据input_ids(文本提示)或conditional_pixel_values(图像提示)调用get_conditional_embeddings(见 modeling_clipseg.py)在no_grad下生成。代码里校验了提示数量必须等于查询图像 batch 数,且自定义 embedding 的维度必须等于projection_dim
  3. 解码器产出 logits:把多层视觉激活与条件 embedding 一起送入CLIPSegDecoder,得到逐像素二值分割 logits。

条件 embedding 的三种来源(文档 Usage tips 明确列出)正好对应三种输入形态:

提示形式传入字段说明
文本提示input_ids文本经冻结文本塔编码为条件向量
图像提示conditional_pixel_values示例图片经冻结视觉塔编码为条件向量,用于一次性分割
自定义条件conditional_embeddings调用方预先算好的任意条件向量,可跳过模型内部计算

解码器内部:多尺度激活 + FiLM 调制 + 转置卷积上采样

CLIPSeg 之所以能输出精细的分割图,得益于解码器对"多尺度中间层激活"的利用。CLIPSegDecoder 的实现要点:

  • extract_layers指定的多层激活逆序处理(hidden_states[::-1]),每层先用一个线性层reduces[i]hidden_size压缩到reduce_dim(默认 64),并逐层累加形成由粗到细的特征;
  • conditional_layer(默认 0,含义是"若为 0 则使用最后一层")指定的那一层,通过FiLM(Feature-wise Linear Modulation)把条件向量注入特征:film_mul生成逐通道缩放、film_add生成逐通道偏移,两者与激活相乘相加,实现"条件调制主干特征"的效果;
  • 每步累加结果送入一个CLIPSegDecoderLayer。该层与编码层唯一的区别是归一化放在残差之后(post-layer norm,见 modeling_clipseg.py),这是解码器在结构上区别于编码器的核心;
  • 最后移除 CLS token、把序列重排成(batch, reduce_dim, h, w)的空间网格,再用转置卷积上采样回图像分辨率输出单通道 logits。

转置卷积有两档实现,由配置开关use_complex_transposed_convolution控制(默认False):简单版是一个reduce_dim → 1、kernel/stride 等于patch_size的单层ConvTranspose2d;复杂版则叠加了 3×3 卷积与两层 ReLU + 转置卷积的级联,kernel 尺寸取patch_size // 4,以支持更细粒度的分割上采样。当labels(二值掩码,shape(batch, height, width))存在时,模型用BCEWithLogitsLoss计算分割损失——因此同一模型既能推理也能在自有数据上做二值分割微调。

配置体系:从单 Config 到三 Config

CLIPSeg 遵循"复合 Config"设计:整体CLIPSegConfig内部持有text_configvision_config两个子配置(源码见 configuration_clipseg.py)。构造时可以只给CLIPSegConfig()(两个子配置自动取默认值并打印日志),也可以显式传入两个子 Config 实例:

from transformers import CLIPSegConfig, CLIPSegTextConfig, CLIPSegVisionConfig config_text = CLIPSegTextConfig() config_vision = CLIPSegVisionConfig() config = CLIPSegConfig(text_config=config_text, vision_config=config_vision)

向后兼容层面,__post_init__还会处理历史参数text_config_dict/vision_config_dict:若某个键同时出现在旧字典与新 Config 中且值不同,以旧字典为准并打印日志提示。

CLIPSegConfig独有的、与分割任务强相关的参数如下(configuration_clipseg.py):

参数默认值作用
extract_layers[3, 6, 9]从冻结视觉骨干提取中间激活的层号列表,解码器据此获得多尺度信息
reduce_dim64每层视觉 embedding 压缩后的维度
decoder_num_attention_heads4解码器各层自注意力的头数
decoder_attention_dropout0.0解码器注意力 dropout
decoder_hidden_actquick_gelu解码器 MLP 的激活函数配置(解码层内部层归一化配置还会将 MLP 激活硬编码为relu
decoder_intermediate_size2048解码器 MLP 中间维度
conditional_layer0应用 FiLM 调制的编码层序号,0 表示最后一层
use_complex_transposed_convolutionFalse是否使用级联的多级转置卷积做更细粒度上采样
projection_dim512文本/视觉投影到的公共对比学习维度
logit_scale_init_value2.6592对比学习 logit 缩放的初始化值

在 CLIPSegDecoder 构造中,解码器会深拷贝vision_config,再覆写hidden_size=reduce_dimnum_attention_heads=decoder_num_attention_headsintermediate_size=decoder_intermediate_size,因此extract_layersreduce_dim与视觉塔patch_size的数值会直接影响最终 logits 的空间分辨率与感受野。

Processor:把文本与图像统一打包

CLIPSegProcessor(见 processing_clipseg.py)同时持有文本 tokenizer 与图像 image processor。__call__方法的组合逻辑覆盖了推理的全部四种场景:

  • text + images:文本提示分割查询图 → 输出input_idsattention_maskpixel_values
  • visual_prompt + images:一次性(one-shot)提示分割 → 输出pixel_valuesconditional_pixel_values
  • 仅传 text 或 visual_prompt 时返回对应单项编码;
  • 三者全空或 text 与 visual_prompt 同时给出都会抛出ValueError,强制"文本提示与图像提示二选一"。

由于同一批图片会被图像处理器执行相同的尺寸归一化,文本提示与图像提示可以自由切换而无需改动下游模型代码。

开箱即用的推理示例

官方文档给出的端到端零样本分割示例如下(可在transformers安装环境中直接运行):

import torch from transformers import AutoProcessor, CLIPSegForImageSegmentation from transformers.image_utils import load_image processor = AutoProcessor.from_pretrained("CIDAS/clipseg-rd64-refined") model = CLIPSegForImageSegmentation.from_pretrained("CIDAS/clipseg-rd64-refined") url = "http://images.cocodataset.org/val2017/000000039769.jpg" image = load_image(url) texts = ["a cat", "a remote", "a blanket"] inputs = processor(text=texts, images=[image] * len(texts), padding=True, return_tensors="pt") with torch.inference_mode(): outputs = model(**inputs) logits = outputs.logits print(logits.shape) # torch.Size([3, 352, 352])

几个关键点:

  1. 官方与社区最常用的检查点是CIDAS/clipseg-rd64-refined("rd64"即reduce_dim=64架构的命名来源),CLIPSegForImageSegmentation通过AutoProcessor+ 类名直接加载,无需手工拼装 tokenizer/image processor;
  2. 同一条image被重复len(texts)次后与各文本一一配对,模型为每个(图, 文本)对输出一张352×352的 logits 掩码(本尺寸来自检查点内置的图像预处理与解码器上采样配置,而非模型 docstring 中数值的臆测——集成测试 test_inference_image_segmentation 用同一检查点精确断言了(3, 352, 352)的输出形状与 logits 取值);
  3. 把 logits 过 Sigmoid 即得到 0~1 的软掩码,可继续做阈值化、叠加到原图、计算目标裁剪框等下游处理;
  4. 若把processor(text=..., images=...)换成processor(visual_prompt=示例图, images=查询图, ...),同一套模型即可切换到一次性分割模式。

如果想先看清CLIPSegForImageSegmentation输出对象的完整字段,其返回类型CLIPSegImageSegmentationOutput(modeling_clipseg.py)包含:loss(可选,传入 labels 时返回 BCE 损失)、logitsconditional_embeddingspooled_outputvision_model_outputdecoder_output。纯文本与纯视觉子模型也可独立加载——例如 CLIPSegTextModel 的 docstring 示例演示了如何仅用 tokenizer 提取pooler_output

支持的注意力实现与质量保障

CLIPSegPreTrainedModel(modeling_clipseg.py)继承自PreTrainedModel并声明了多项现代能力:支持 gradient checkpointing、SDPA(_supports_sdpa = True)、Flash Attention 与 Flex Attention(_supports_flash_attn/_supports_flex_attn),以及基于ALL_ATTENTION_FUNCTIONS的注意力后端选择;_no_split_modules保证了其在设备并行、TP 等场景下可以正确切分。模型自带的自定义初始化(_init_weights)遵循 OpenAI CLIP 风格的缩放规则。

模型的回归质量由 tests/models/clipseg/test_modeling_clipseg.py 覆盖,包括三套 Tester(CLIPSegVisionModelTesterCLIPSegTextModelTesterCLIPSegModelTester)对应文本/视觉/完整模型,以及继承自ModelTesterMixin/PipelineTesterMixin的通用能力测试(forward signature、gradient checkpointing、hidden states、SDPA 编译、feature-extractionpipeline 映射等)。两个@slow集成测试直接以真实权重做端到端数值对齐,可作为接入新输入前自行校验的参考基线。CLIPSegModel同时也被注册为feature-extractionpipeline 的支持模型,而图像分割任务通常更适合直接调用CLIPSegForImageSegmentation类以获得掩码输出。

总结

CLIPSeg 在 Transformers 中的落地形态可概括为一句话:冻结的 CLIP 双塔负责把任意"文本/图片提示"翻译成条件向量,一个后置归一化的轻量 Transformer 解码器用 FiLM 把这些条件调制进多尺度视觉特征,最终由转置卷积上采样为二值分割图。整个实现被井井有条地拆分为配置(CLIPSegConfig及双子配置)、模型(CLIPSegModel/CLIPSegForImageSegmentation)与处理(CLIPSegProcessor)三部分,无论做零样本文本分割、一次性示例分割,还是自定义条件向量的特殊分割任务,都可以用同一套 API 完成,且无需任何针对新类别的重新训练。深入阅读时建议按 模型文档 → 配置源码 → 建模源码 → 集成测试 的顺序,从"对外用法"逐步下沉到"数值如何产生",能获得对该模型最完整的理解。

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 15:11:32

ML-KWS-for-MCU源码评测:在MCU上部署实时关键词唤醒的工程架构

这几年边缘AI和MCU的组合被反复提起,但真正能跑在Cortex-M级别微控制器上的完整工程案例,远没有大家想象中那么多。ARM官方开源的ML-KWS-for-MCU是一个很好的切入点:它在只有几百KB RAM、主频通常不到200MHz的MCU上,做成了一个实时…

作者头像 李华
网站建设 2026/9/7 15:10:24

猫抓浏览器插件教程:3 步搞定网页视频音频下载

猫抓浏览器插件教程:3 步搞定网页视频音频下载 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓(cat-catch)…

作者头像 李华
网站建设 2026/9/7 15:10:07

【单片机毕业设计】基于 STM32 或 51 单片机的环境参数采集与 LCD 阈值显示预警系统设计 基于 STM32 或 51 单片机的智能环境监测与风扇联动报警装置开发(024506)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/7 15:10:00

单片机计算机毕设之基于 STM32 或 51 单片机的按键可调阈值环境监测联动控制系统 基于 STM32 或 51 单片机的 LCD1602 环境参数显示智能预警终端设计(024506)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/7 15:08:49

Maven 4.0.0正式版深度解析:核心重构、升级实操与踩坑指南

Maven 4.0.0正式版出来了。这消息在Java圈子刷屏得很厉害,我一点也不意外。Apache Maven作为Java生态里占有率最高的构建工具,从3.0.0到4.0.0这一跳,中间隔了将近15年。这次不是小打小闹的版本号递进,是一次真正意义上的重构&…

作者头像 李华
网站建设 2026/9/7 15:08:46

GiteeMiniMan:命令行打造极简仓库管理自动化工具

从“网页里点五次”到“命令行敲一句话”,中间差的其实就是一个小小的自动化脚本。我手上维护的Gitee仓库数量常年维持在二三十个上下,有公司项目、个人练手、开源备份,还有帮朋友维护的Demo。时间一长就会遇到一个很尴尬的问题: …

作者头像 李华