原文出处:Using Pretrained VLMs 原作者:Hugging Face · 许可证:Apache-2.0 License 中文译本由诸葛AI学院整理,仅供学习参考,版权归原作者与 Hugging Face 所有。
视觉语言模型(vision language model, VLM)会同时处理图像和文本,能做生成图片描述、回答视觉问题、跨模态推理这类进阶任务。本节重点是VLM 怎么工作,以及怎么实际用起来。
架构总览
原文此处有一张图,画的是 VLM 的整体架构:图像先经过视觉编码器,再经投影/融合模块,与文本表示汇合后进入文本解码器输出文字。
VLM 把图像处理组件和文本生成组件拼在一起,形成统一的多模态理解能力。主要部件有:
- 图像/视觉编码器(Image/Vision Encoder):把图像转成紧凑的数值表示。代表例子:CLIP、SigLIP。
- 嵌入投影器(Embedding Projector):把图像特征和文本嵌入(embedding)对齐,通常是一个小的 MLP 或线性层,针对多模态任务微调过。
- 多模态投影器 / 融合模块(Multimodal Projector / Fusion Module):融合并加强视觉表示和文本表示之间的联系。这一步不只是对齐,还让两种模态之间产生充分的交互。
- 文本解码器(Text Decoder):从融合后的多模态表示生成文本(或其他输出)。
多数 VLM 的做法是:直接采用预训练好的图像编码器和文本解码器,再在图文配对数据集上微调,训练省、泛化也好。
实际能干什么
VLM 可以用在这些任务上:
- 图像描述(Image Captioning):给图片生成文字描述
- 视觉问答(Visual Question Answering, VQA):回答关于一张图的问题
- 跨模态检索(Cross-Modal Retrieval):图文互搜,用文字找图、用图找文字
- 创意应用:设计、艺术生成、多媒体内容
高质量的图文配对数据集是关键,🤗 transformers 则提供现成的预训练模型和顺手的微调流程。
原文此处还有一张图,画的是 VLM 的典型用法:输入图像加提问,输出对图像的描述或答案。
对话格式
很多 VLM 支持聊天式交互,消息按下面的结构组织:
- 系统消息(system message):设定角色和上下文,例如
"You are an assistant analyzing visual data."(你是一个分析视觉数据的助手) - 用户提问(user query):文本和图像混合。
- 助手回复(assistant response):基于多模态分析生成的文本。
示例:
json
[
{
"role": "system",
"content": [{"type": "text", "text": "You are a VLM specialized in charts."}]
},
{
"role": "user",
"content": [
{"type": "image", "image": "<image_data>"},
{"type": "text", "text": "What is the highest value in this chart?"}
]
},
{
"role": "assistant",
"content": [{"type": "text", "text": "42"}]
}
]
VLM 还能处理多张图像或视频帧:把图像序列按同样的对话模板传进去即可。
用 pipeline 调用 VLM
如我们在第 1 单元所见,用 VLM 最省事的方式是 🤗 的 pipeline 封装:
```python from transformers import pipeline
用一个 VLM 初始化 pipeline
pipe = pipeline("image-text-to-text", "HuggingFaceTB/SmolVLM2-2.2B-Instruct", device_map="auto")
定义带图像的对话
messages = [ { "role": "user", "content": [ { "type": "image", "image": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg", }, {"type": "text", "text": "Describe this image."}, ], } ]
outputs = pipe(text=messages, max_new_tokens=60, return_full_text=False)
生成回复——pipeline 会自动处理多模态输入
response = pipe(messages, max_new_tokens=128, temperature=0.7)
print(response[0]['generated_text'][-1]['content']) # 打印模型生成的描述 ```
输出
```text The image depicts a close-up view of a flower garden, specifically focusing on a pink flower. The flower is the central subject of the image, and it is a prominent feature due to its vibrant color and intricate details. The flower has a circular shape, with petals that are slightly curled and have a gradient from light to dark pink. The petals are arranged symmetrically around the central pistil, which is visible in the center of the flower. The pistil is a small, yellow structure that is surrounded by a cluster of stamens, which are visible as small, yellow structures. The flower also has a small, black ```用 Transformers 直接调用(完全掌控)
进阶用法是透过 🤗 Transformers 直接访问 VLM,这样你可以完全控制每个组件。
为了省内存、加快推理,可以用 bitsandbytes 做 4-bit 量化(quantization)。
和普通的 LLM 用法不同,VLM 需要一个处理器(processor),光有分词器(tokenizer)不够。处理器同时负责文本分词和图像预处理,把多模态输入的准备工作一并搞定。
```python import torch from transformers import AutoProcessor, AutoModelForImageTextToText, BitsAndBytesConfig from transformers.image_utils import load_image
device = "cuda" if torch.cuda.is_available() else "cpu"
量化,省显存
quant_config = BitsAndBytesConfig(load_in_4bit=True) model_name = "HuggingFaceTB/SmolVLM2-2.2B-Instruct" model = AutoModelForImageTextToText.from_pretrained(model_name, quantization_config=quant_config).to(device) processor = AutoProcessor.from_pretrained(model_name) ```
示例:描述一张图
我们可以用对话模板(chat template)来描述图像。消息里每张图用一个 {"type": "image"} 占位,真正的图像数据通过 images 参数传给处理器。文本和图像输入都由处理器统一处理。
```python
加载图像
image_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg" image = load_image(image_url)
构造输入消息
messages = [ { "role": "user", "content": [ {"type": "image"}, {"type": "text", "text": "Can you describe the image?"} ] }, ]
准备输入
prompt = processor.apply_chat_template(messages, add_generation_prompt=True) inputs = processor(text=prompt, images=[image], return_tensors="pt") inputs = inputs.to(device)
生成输出
generated_ids = model.generate(**inputs, max_new_tokens=500) generated_texts = processor.batch_decode( generated_ids, skip_special_tokens=True, )[0]
只保留助手的回复部分
assistant_response = generated_texts.split("Assistant:")[-1].strip()
print(assistant_response) ```
输出
```text The image is of a bee on a flower. ```处理器把文本输入和图像输入拼在一起,模型因此能生成连贯的多模态输出。
提示 类似的模板还能处理多图输入、OCR 任务,甚至视频帧,VLM 的适用范围因此非常广。