基于VLM的图像聊天应用

APPLICATION Dec 6, 2024

视觉功能与大型语言模型 (LLM) 的集成正在通过多模态 LLM (MLLM) 彻底改变计算机视觉领域。这些模型结合了文本和视觉输入,在图像理解和推理方面表现出令人印象深刻的能力。虽然这些模型以前只能通过 API 访问,但最近的开源选项现在允许本地执行,这使得它们对生产环境更具吸引力。

在本教程中,我们将学习如何使用开源 Llama 3.2-Vision 模型与我们的图像聊天,你会惊叹于它的 OCR、图像理解和推理能力。所有代码都方便地提供在方便的 Colab 笔记本中。

1、Llama 3.2-Vision

Llama 是“大型语言模型 Meta AI”的缩写,是 Meta 开发的一系列高级 LLM。他们的最新产品 Llama 3.2 推出了先进的视觉功能。视觉变体有两种大小:11B 和 90B 参数,可在边缘设备上进行推理。 Llama 3.2 具有高达 128k 个 token 的上下文窗口,支持高达 1120x1120 像素的高分辨率图像,可以处理复杂的视觉和文本信息。

Llama 系列模型是仅解码器的 Transformer。Llama 3.2-Vision 建立在预训练的 Llama 3.1 纯文本模型之上。它采用标准的密集自回归 Transformer 架构,与其前身 Llama 和 Llama 2 并无太大差异。

为了支持视觉任务,Llama 3.2 使用预训练的视觉编码器 (ViT-H/14) 提取图像表示向量,并使用视觉适配器将这些表示集成到冻结语言模型中。适配器由一系列交叉注意层组成,允许模型专注于与正在处理的文本相对应的图像的特定部分 [1]。

适配器在文本-图像对上进行训练,以使图像表示与语言表示对齐。在适配器训练期间,图像编码器的参数会更新,而语言模型参数保持冻结以保留现有的语言能力。

Llama 3.2-Vision 架构。视觉模块(绿色)集成到固定语言模型(粉红色)中

这种设计使 Llama 3.2 在多模态任务中表现出色,同时保持其强大的纯文本性能。生成的模型在需要图像和语言理解的任务中展示了令人印象深刻的能力,并允许用户与他们的视觉输入进行交互式交流。

2、让我们编码吧!

有了对 Llama 3.2 架构的了解,我们可以深入研究实际实现。但首先,我们需要做一些准备。

2.1 准备

在 Google Colab 上运行 Llama 3.2 — Vision 11B 之前,我们需要做一些准备:

GPU 设置:

  • 建议使用至少具有 22GB VRAM 的高端 GPU 进行高效推理 [2]。
  • 对于 Google Colab 用户:导航至“运行时”>“更改运行时类型”>“A100 GPU”。请注意,高端 GPU 可能不适用于免费的 Colab 用户。

模型权限:

  • 此处请求访问 Llama 3.2 模型。

Hugging Face 设置:

  • 如果你还没有 Hugging Face 帐户,请在此处创建一个。
  • 如果你没有 Hugging Face 帐户,请在此处生成访问令牌。
  • 对于 Google Colab 用户,请在 google Colab Secrets 中将 Hugging Face 令牌设置为名为 HF_TOKEN的秘密环境变量。
  • 安装所需的库。

2.2 加载模型

设置环境并获得必要的权限后,我们将使用 Hugging Face Transformers 库来实例化模型及其相关处理器。处理器负责为模型准备输入并格式化其输出。

model_id = "meta-llama/Llama-3.2-11B-Vision-Instruct"

model = MllamaForConditionalGeneration.from_pretrained(
    model_id,
    torch_dtype=torch.bfloat16,
    device_map="auto")

processor = AutoProcessor.from_pretrained(model_id)

2.3 预期聊天模板

聊天模板通过存储“用户”(我们)和“助手”(AI 模型)之间的交流,通过对话历史记录来维护上下文。对话历史记录的结构为一个称为消息的字典列表,其中每个字典代表一个对话轮次,包括用户和模型响应。用户轮次可以包括图像文本或纯文本输入,其中 {"type": "image"} 表示图像输入。

例如,经过几次聊天迭代后,消息列表可能如下所示:

messages = [
    {"role": "user",      "content": [{"type": "image"}, {"type": "text", "text": prompt1}]},
    {"role": "assistant", "content": [{"type": "text", "text": generated_texts1}]},
    {"role": "user",      "content": [{"type": "text", "text": prompt2}]},
    {"role": "assistant", "content": [{"type": "text", "text": generated_texts2}]},
    {"role": "user",      "content": [{"type": "text", "text": prompt3}]},
    {"role": "assistant", "content": [{"type": "text", "text": generated_texts3}]}
]

此消息列表随后传递给 apply_chat_template() 方法,以将对话转换为模型期望格式的单个可标记字符串。

2.4 主要功能

对于本教程,我提供了一个 chat_with_mllm 函数,该函数可实现与 Llama 3.2 MLLM 的动态对话。此函数处理图像加载、预处理图像和文本输入、生成模型响应并管理对话历史记录以启用聊天模式交互。

def chat_with_mllm (model, processor, prompt, images_path=[],do_sample=False, temperature=0.1, show_image=False, max_new_tokens=512, messages=[], images=[]):

    # Ensure list:
    if not isinstance(images_path, list):
        images_path =  [images_path]

    # Load images 
    if len (images)==0 and len (images_path)>0:
            for image_path in tqdm (images_path):
                image = load_image(image_path)
                images.append (image)
                if show_image:
                    display ( image )

    # If starting a new conversation about an image
    if len (messages)==0:
        messages = [{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": prompt}]}]

    # If continuing conversation on the image
    else:
        messages.append ({"role": "user", "content": [{"type": "text", "text": prompt}]})

    # process input data
    text = processor.apply_chat_template(messages, add_generation_prompt=True)
    inputs = processor(images=images, text=text, return_tensors="pt", ).to(model.device)

    # Generate response
    generation_args = {"max_new_tokens": max_new_tokens, "do_sample": True}
    if do_sample:
        generation_args["temperature"] = temperature
    generate_ids = model.generate(**inputs,**generation_args)
    generate_ids = generate_ids[:, inputs['input_ids'].shape[1]:-1]
    generated_texts = processor.decode(generate_ids[0], clean_up_tokenization_spaces=False)

    # Append the model's response to the conversation history
    messages.append ({"role": "assistant", "content": [  {"type": "text", "text": generated_texts}]})

    return generated_texts, messages, images

3、与 Llama 聊天

蝴蝶图像示例

在我们的第一个示例中,我们将与 Llama 3.2 聊天,讨论一张孵化蝴蝶的图像。

由于 Llama 3.2-Vision 在使用图像时不支持使用系统提示进行提示,我们将直接将说明附加到用户提示中,以指导模型的响应。通过设置 do_sample=Truetemperature=0.2,我们可以在保持响应连贯性的同时实现轻微的随机性。对于固定答案,你可以设置 do_sample==False 。保存聊天历史记录的 messages 参数最初为空,如 images 参数中所示。

instructions = "Respond concisely in one sentence."
prompt = instructions + "Describe the image."

response, messages,images= chat_with_mllm ( model, processor, prompt,
                                             images_path=[img_path],
                                             do_sample=True,
                                             temperature=0.2,
                                             show_image=True,
                                             messages=[],
                                             images=[])

# Output:  "The image depicts a butterfly emerging from its chrysalis, 
#           with a row of chrysalises hanging from a branch above it."

我们可以看到,输出准确而简洁,表明模型有效地理解了图像。

对于下一次聊天迭代,我们将传递一个新的提示以及聊天历史记录 (history) 和图像文件 (images)。新提示旨在评估 Llama 3.2 的推理能力:

prompt = instructions + "What would happen to the chrysalis in the near future?"
response, messages, images= chat_with_mllm ( model, processor, prompt,
                                             images_path=[img_path,],
                                             do_sample=True,
                                             temperature=0.2,
                                             show_image=False,
                                             messages=messages,
                                             images=images)

# Output: "The chrysalis will eventually hatch into a butterfly."

我们在提供的 Colab 笔记本中继续聊天,并获得了以下对话:

对话通过准确描述场景,突出了模型的图像理解能力。它还通过逻辑连接信息来正确得出蛹会发生什么,并解释为什么有些是棕色的,而另一些是绿色的,展示了它的推理能力。

模因图像示例

在此示例中,我将向模型展示我自己创建的模因,以评估 Llama 的 OCR 能力并确定它是否理解我的幽默感。

instructions = "You are a computer vision engineer with sense of humor."
prompt = instructions + "Can you explain this meme to me?"


response, messages,images= chat_with_mllm ( model, processor, prompt,
                                             images_path=[img_path,],
                                             do_sample=True,
                                             temperature=0.5,
                                             show_image=True,
                                             messages=[],
                                             images=[])

这是输入 meme:

这是模型的响应:

我们可以看到,该模型展示了出色的 OCR 能力,并理解了图像中文本的含义。至于它的幽默感——你觉得怎么样,它明白了吗?你明白了吗?也许我也应该努力培养我的幽默感!

4、结束语

在本教程中,我们学习了如何在本地构建 Llama 3.2-Vision 模型并管理类似聊天交互的对话历史记录,从而增强用户参与度。我们探索了 Llama 3.2 的零样本能力,并对其场景理解、推理和 OCR 技能印象深刻。

可以将高级技术应用于 Llama 3.2,例如对独特数据进行微调,或使用检索增强生成 (RAG) 来进行预测并减少幻觉。

总体而言,本教程深入了解了快速发展的多模态 LLM 领域及其在各种应用中的强大功能。


原文链接:Chat with Your Images Using Llama 3.2-Vision Multimodal LLMs

汇智网翻译整理,转载请标明出处

Tags