本篇文给出PaliGemma代码使用案例。关于PaliGemma介绍,可参考PaliGemma – 谷歌的最新开源视觉语言模型(一)
Mix 基准
下表显示了 Mix 检查点的得分。
模型MMVP 准确率POPE 准确率(随机/流行/对抗)mix-22446.0088.00 86.63 85.67mix-44845.3389.37 88.40 87.47
微调检查点
除了预训练和混合模型,谷歌还发布了已经转移到各种任务上的模型。它们对应于学术基准,可以被研究社区用于比较其性能。下表列出了一些选定的模型。这些模型也有不同的分辨率。你可以查看任何模型的模型卡以了解所有指标。
模型名称数据集/任务转移任务中的得分paligemma-3b-ft-vqav2-448图表理解VQAV2 的准确率为 85.64paligemma-3b-ft-cococap-448COCO 字幕144.6 CIDErpaligemma-3b-ft-science-qa-448科学问答ScienceQA Img 子集的准确率为 95.93(无 CoT)paligemma-3b-ft-refcoco-seg-896理解图像中特定对象的引用refcoco 的平均 IoU 为 76.94,refcoco+ 的平均 IoU 为 72.18,refcocog 的平均 IoU 为 72.22paligemma-3b-ft-rsvqa-hr-224远程感知视觉问答测试中的准确率为 92.61,测试2中的准确率为 90.58
演示
作为本次发布的一部分,我们提供了一个演示,它包装了 big_vision 仓库中的参考实现,并提供了一个简单的方法来体验 Mix 模型。
我们还提供了一个与 Transformers 兼容的演示,展示如何使用 PaliGemma transformers API。
type=“video/mp4”>
如何进行推理
要访问 PaliGemma 模型,你需要接受 Gemma 许可证条款和条件。如果你已经拥有 Hugging Face 中其他 Gemma 模型的访问权限,就可以直接使用。否则,请访问任何 PaliGemma 模型,并在同意许可条款后接受许可。一旦获得访问权限,你需要通过 notebook_login 或 huggingface-cli login 进行认证。登录后,即可使用!
你也可以直接在这个 notebook中尝试推理。
使用 Transformers
你可以使用
PaliGemmaForConditionalGeneration
类进行推理。只需使用内置的处理器预处理提示词和图像,然后传递预处理的输入进行生成。
from transformers import AutoProcessor, PaliGemmaForConditionalGeneration
model_id ="google/paligemma-3b-mix-224"
model = PaliGemmaForConditionalGeneration.from_pretrained(model_id)
processor = AutoProcessor.from_pretrained(model_id)
prompt ="What is on the flower?"
image_file ="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg?download=true"
raw_image = Image.open(requests.get(image_file, stream=True).raw)
inputs = processor(prompt, raw_image, return_tensors="pt")
output = model.generate(**inputs, max_new_tokens=20)print(processor.decode(output[0], skip_special_tokens=True)[len(prompt):])# bee
你还可以如下加载 4-bit 模型。
from transformers import BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16
)
model = PaligemmaForConditionalGeneration.from_pretrained(
model_id,
quantization_config=bnb_config,
device_map={"":0})
除了 4-bit(或 8-bit)加载外,transformers 集成还允许你利用 Hugging Face 生态系统中的其他工具,例如:
- 训练和推理脚本和示例
- 序列化为安全文件(safetensors)
- 与 PEFT(参数高效微调)等工具的集成
- 用于运行模型生成的 实用程序和助手
详细的推理过程
如果你想编写自己的预处理或训练代码,或者想更详细地了解 PaliGemma 的工作原理,以下是输入图像和文本的处理步骤。
输入文本正常地进行标记化。开头添加
<bos>
标记,并在末尾附加一个额外的换行符(
\n
)。这个换行符是模型训练时输入提示词的一个重要部分,因此显式添加它确保它始终存在。标记化文本还以固定数量的
<image>
标记为前缀。数量取决于输入图像分辨率和 SigLIP 模型使用的补丁大小。PaliGemma 模型预训练于三种方形大小之一(224x224、448x448 或 896x896),并始终使用 14 的补丁大小。因此,对于 224 模型,前缀的
<image>
标记数量为 256(
224/14 * 224/14
),对于 448 模型为 1024,对于 896 模型为 4096。
请注意,较大的图像会导致输入序列变得更长,因此需要更多的内存来处理语言部分的模型。在考虑使用哪个模型时,请记住这一点。对于 OCR 等精细任务,较大的图像可能有助于获得更好的结果,但对于大多数任务而言,增量质量提升很小。在决定使用更高分辨率之前,请先在你的任务上进行测试!
这个完整的“提示词”经过语言模型的文本嵌入层生成每个标记具有 2048 维的标记嵌入。
与此并行,输入图像使用双三次重采样调整为所需的输入大小(最小分辨率模型为 224x224)。然后它经过 SigLIP 图像编码器生成具有 1152 维的补丁嵌入。在这里,线性投影器发挥作用:图像嵌入被投影以获得具有 2048 维的表示,与从文本标记获得的表示相同。最终的图像嵌入与
<image>
文本嵌入合并,这是用于自回归文本生成的最终输入。生成过程在自回归模式下正常进行。它使用完整块注意力处理完整输入(图像 + bos + 提示词 + \n),并使用因果注意力掩码处理生成的文本。
所有这些细节都在处理器和模型类中自动处理,因此可以使用熟悉的高级 transformers API 进行推理,如上例所示。
微调
使用 big_vision
PaliGemma 是在 big_vision 代码库中训练的。同一个代码库已经用于开发 BiT、原始 ViT、LiT、CapPa、SigLIP 等模型。
项目配置文件夹 configs/proj/paligemma/ 包含一个
README.md
。可以通过运行 transfers/ 子文件夹中的配置文件来进行预训练模型的转移,我们的所有转移结果都是通过运行其中提供的配置文件获得的。如果你想转移自己的模型,请分叉示例配置 transfers/forkme.py 并按照注释中的说明进行调整以适应你的用例。
还有一个 Colab 运行一个简化的微调,可以在免费的 T4 GPU 运行时上运行。为了适应有限的主机和 GPU 内存,Colab 中的代码仅更新注意力层中的权重(170M 参数)并使用 SGD(而非 Adam)。
使用 transformers
借助 transformers 微调 PaliGemma 非常简单。还可以进行 QLoRA 或 LoRA 微调。在这个示例中,我们将简要微调解码器,然后展示如何切换到 QLoRA 微调。我们将安装最新版本的 transformers 库。
pip install transformers
与推理部分一样,我们将进行身份验证以访问模型,使用
notebook_login()
。
from huggingface_hub import notebook_login
notebook_login()
在此示例中,我们将使用 VQAv2 数据集,并微调模型以回答关于图像的问题。让我们加载数据集。我们将仅使用列 question、multiple_choice_answer 和 image,因此让我们移除其余的列。我们还将拆分数据集。
from datasets import load_dataset
ds = load_dataset('HuggingFaceM4/VQAv2', split="train")
cols_remove =["question_type","answers","answer_type","image_id","question_id"]
ds = ds.remove_columns(cols_remove)
ds = ds.train_test_split(test_size=0.1)
train_ds = ds["train"]
val_ds = ds["test"]
现在我们将加载处理器,其中包含图像处理和标记化部分,并预处理我们的数据集。
from transformers import PaliGemmaProcessor
model_id ="google/paligemma-3b-pt-224"
processor = PaliGemmaProcessor.from_pretrained(model_id)
我们将创建一个提示模板,以条件化 PaliGemma 回答视觉问题。由于标记化器会填充输入,因此我们需要将标签中的填充设置为标记化器中的填充标记和图像标记以外的内容。
import torch
device ="cuda"
image_token = processor.tokenizer.convert_tokens_to_ids("<image>")defcollate_fn(examples):
texts =["answer "+ example["question"]for example in examples]
labels=[example['
multiple_choice_answer']for example in examples]
images =[example["image"].convert("RGB")for example in examples]
tokens = processor(text=texts, images=images, suffix=labels,
return_tensors="pt", padding="longest")
tokens = tokens.to(torch.bfloat16).to(device)return tokens
你可以直接加载模型,也可以加载 4-bit 模型以进行 QLoRA。下面是如何直接加载模型。我们将加载模型,冻结图像编码器和投影器,仅微调解码器。如果你的图像在特定领域内,可能不在模型预训练的数据集中,你可能想跳过冻结图像编码器。
model = PaliGemmaForConditionalGeneration.from_pretrained(model_id, torch_dtype=torch.bfloat16).to(device)for param in model.vision_tower.parameters():
param.requires_grad =Falsefor param in model.multi_modal_projector.parameters():
param.requires_grad =True
如果你想加载 4-bit 模型以进行 QLoRA,可以添加以下更改。
from transformers import BitsAndBytesConfig
from peft import get_peft_model, LoraConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_type=torch.bfloat16
)
lora_config = LoraConfig(
r=8,
target_modules=["q_proj","o_proj","k_proj","v_proj","gate_proj","up_proj","down_proj"],
task_type="CAUSAL_LM",)
model = PaliGemmaForConditionalGeneration.from_pretrained(model_id, quantization_config=bnb_config, device_map={"":0})
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()#trainable params: 11,298,816 || all params: 2,934,634,224 || trainable%: 0.38501616002417344
现在我们将初始化 Trainer 和 TrainingArguments。如果你要进行 QLoRA 微调,请将优化器设置为
paged_adamw_8bit
。
from transformers import TrainingArguments
args=TrainingArguments(
num_train_epochs=2,
remove_unused_columns=False,
per_device_train_batch_size=16,
gradient_accumulation_steps=4,
warmup_steps=2,
learning_rate=2e-5,
weight_decay=1e-6,
adam_beta2=0.999,
logging_steps=100,
optim="adamw_hf",
save_strategy="steps",
save_steps=1000,
push_to_hub=True,
save_total_limit=1,
bf16=True,
report_to=["tensorboard"],
dataloader_pin_memory=False)
初始化
Trainer
,传入数据集、数据整理函数和训练参数,并调用
train()
开始训练。
trainer = Trainer(
model=model,
train_dataset=train_ds,
eval_dataset=val_ds,
data_collator=collate_fn,
args=args
)
trainer.train()
附加资源
- 视觉语言模型解释
- 模型文档
- 推理 notebook
- Big vision PaliGemma 演示
- 🤗 transformers PaliGemma 演示
- 所有 PaliGemma 模型集合
- 所有 PaliGemma 微调模型集合
- 原始实现
我们要感谢 Omar Sanseviero、Lucas Beyer、Xiaohua Zhai 和 Matthias Minderer 对这篇博文的详细审查。我们还要感谢 Peter Robicheaux 对 transformers 微调更改的帮助。
版权归原作者 微凉的衣柜 所有, 如有侵权,请联系我们删除。