使用小型视觉语言模型(VLM)进行物体识别与计数

今天的重点是一个具有无数实际应用的功能:在边缘设备(如智能手机、物联网设备和嵌入式系统)上运行小型视觉语言模型(VLM)。 这些模型在识别和指出物体方面越来越出色。 具体来说,它们在检测制造缺陷、计数可用停车位或发现癌细胞方面表现优异。

今天的重点是一个具有无数实际应用的功能:在边缘设备(如智能手机、物联网设备和嵌入式系统)上运行小型视觉语言模型(VLM)。这些模型在识别和指出物体方面越来越出色。具体来说,它们在检测制造缺陷、计数可用停车位或发现癌细胞方面表现优异。尽管它们潜力巨大,但许多人并不知道这些小型VLM是专门为这些任务训练的。

使用小型视觉语言模型(VLM)进行物体识别与计数

模型:Molmo 7B

Molmo 是由 Allen Institute for AI 开发的一组开放视觉语言模型。它们在 PixMo 数据集上进行训练,该数据集包含 100 万对图像-文本对。基于 Qwen2–7B 和 OpenAI CLIP 构建的 Molmo 7B-D 几乎与 GPT-4V 和 GPT-4o 一样出色。

工具:MLX-VLM 以及 MLX 社区

MLX-VLM 是 Prince Canuma(Blaizzy)开发的一个工具,用于在 Mac 上使用 MLX 运行和微调视觉语言模型(VLM)。它支持多种模型,如 molmo、llava、llava_bunny、llava_next、mllama、multi_modality、paligemma、phi3_v、pixtral 和 qwen2_vl。这些模型可以在 Hugging Face 上的 MLX 社区中免费下载。

Hugging Face 上的 MLX 社区是一个共享 Apple 的 MLX 框架预转换模型权重的中心。它提供了适用于训练、微调和部署大型语言模型(LLM)和视觉模型的模型。流行的选项如用于语音识别的 Whisper 和用于图像生成的 Stable Diffusion 也可用。用户还可以通过上传自己的模型或在其项目中使用 MLX 工具来做出贡献。

我们的需求

要开始,我们需要设置一个虚拟环境并安装所需的库。以下是步骤列表:

(1) 创建并激活虚拟环境。

(2) 安装必要的包:

复制
pip install -U mlx-vlm
pip install einops
pip install torch torchvision
pip install matplotlib

我们将使用下图来测试我们的工作流程。你可以替换图像并调整提示以适应不同的应用。例如,你可以计算停车场中的汽车数量、人群中的人数或体育场中的空座位。

使用小型视觉语言模型(VLM)进行物体识别与计数

待识别的钢管

在 MLX 中运行 Molmo

在 MLX 中运行这个模型非常简单。你可以复制并粘贴以下代码行,然后就可以尝试这个模型了。确保根据你的用例更改图像路径。对于我来说,我将保留 pipes_test.jpg,并在提示中简单地问:“指出图像中的钢管。”

复制
from mlx_vlm import load, apply_chat_template, generate
from mlx_vlm.utils import load_image
import matplotlib.pyplot as plt

model, processor = load("mlx-community/Molmo-7B-D-0924-4bit",processor_config={"trust_remote_code": True})
config = model.config

image_path = "pipes_test.jpg"
image = load_image(image_path)

messages = [{"role": "user", "content": "Point the pipes in the images"}]

prompt = apply_chat_template(processor, config, messages)

output = generate(model, processor, image, prompt, max_tokens=1200, temperature=0.7)
print(output)

上述代码片段的输出如下:

复制
<points x1="12.3" y1="76.8" x2="17.0" y2="63.9" x3="19.8" y3="49.0" x4="20.7" y4="80.6" x5="24.9" y5="66.7" x6="26.8" y6="50.8" x7="30.9" y7="84.8" x8="33.6" y8="70.2" x9="40.0" y9="88.3" alt="pipes in the images">pipes in the images</points>

这是模型被训练来响应的方式。然而,为了验证这个输出,我们需要进行后处理并在图像上绘制这些点。所以,让我们来做吧!

在图像中指出和检测物体

让我们实现两个函数:第一个用于解析点的坐标,第二个用于绘制它们。在解析点时,重要的是要注意坐标是基于图像的宽度和高度进行归一化的。如下面的代码片段所示,我们需要将归一化的值除以 100,然后分别乘以图像的宽度和高度。

复制

def parse_points(points_str):
    # Function was taken from https://github.com/Blaizzy/mlx-vlm
    if isinstance(points_str, tuple):
        return points_str

    x_coords = []
    y_coords = []

    # Handle multi-point format
    if 'x1="' in points_str:
        i = 1
        while True:
            try:
                x = float(points_str.split(f'x{i}="')[1].split('"')[0])
                y = float(points_str.split(f'y{i}="')[1].split('"')[0])
                x_coords.append(x)
                y_coords.append(y)
                i += 1
            except IndexError:
                break
    elif 'x="' in points_str:
        x = float(points_str.split('x="')[1].split('"')[0])
        y = float(points_str.split('y="')[1].split('"')[0])
        x_coords.append(x)
        y_coords.append(y)

    try:
        labels = points_str.split('alt="')[1].split('">')[0].split(", ")
        item_labels = labels
    except IndexError:
        item_labels = [f"Point {i+1}" for i in range(len(x_coords))]

    return x_coords, y_coords, item_labels

现在让我们使用 Matplotlib 在图像上绘制点的位置。你也可以绘制标签,但在我的情况下,我只需要点和数字就够了。

复制
def plot_locations(points: str | tuple, image, point_size=10, font_size=12):
    if isinstance(points, str):
        x_coords, y_coords, item_labels = parse_points(points)
    else:
        x_coords, y_coords, item_labels = points

    grayscale_image = image.convert("L")

    img_width, img_height = grayscale_image.size

    x_norm = [(x / 100) * img_width for x in x_coords]
    y_norm = [(y / 100) * img_height for y in y_coords]

    if len(item_labels) != len(x_norm):
        item_labels *= len(x_norm)

    plt.figure(figsize=(10, 8))
    plt.imshow(grayscale_image, cmap="gray")

    plt.axis("off")

    for i, (x, y, label) in enumerate(zip(x_norm, y_norm, item_labels), start=1):
        label_with_number = f"{i}"
        plt.plot(x, y, "o", color="red", markersize=point_size, label=label_with_number)

        plt.annotate(
            label_with_number,
            (x, y),
            xytext=(0, 10),
            textcoords="offset points",
            ha="center",
            color="red",
            fontsize=font_size,
        )

    plt.show()

最终结果

你可以看到钢管被正确识别,并且每个钢管都有一个关联的 ID。你可以修改代码并尝试许多其他用例。

使用小型视觉语言模型(VLM)进行物体识别与计数

你可以按照上述步骤在自己的 GPU 上运行这个模型。只要确保有足够的 RAM 以及较小的图像输入尺寸(本文示例使用 16GB 的 RAM,图像只有几百 KB)。

Article link:https://medium.com/@alejandro7899871776/point-and-count-objects-using-small-vlms-on-your-local-machine-3a769c7f2b6c

相关资讯

视觉语言模型导论:这篇论文能成为你进军VLM的第一步

近些年,语言建模领域进展非凡。Llama 或 ChatGPT 等许多大型语言模型(LLM)有能力解决多种不同的任务,它们也正在成为越来越常用的工具。这些模型之前基本都局限于文本输入,但现在也正在具备处理视觉输入的能力。如果能将视觉与语言打通,那么势必能造就多种多样的应用 —— 这实际上也正是当前 AI 技术革命的关键方向。即便现在已有不少研究将大型语言模型扩展到了视觉领域,但视觉与语言之间的连接尚未被彻底打通。举些例子,大多数模型都难以理解空间位置关系或计数 —— 这还需要复杂的工程设计并依赖额外的数据标注。许多视

用GPT-4V和人类演示训练机器人:眼睛学会了,手也能跟上

微软提出使用人手运动视频直接教机器人完成任务的新方法,这种方法使用 GPT-4V 分解视频中的动作,结合大语言模型生成对应的行为表述并作为任务列表,训练机器人只需要动动手就能完成。如何将语言 / 视觉输入转换为机器人动作?训练自定义模型的方法已经过时,基于最近大语言模型(LLM)和视觉语言模型(VLM)的技术进展,通过 prompt 工程使用 ChatGPT 或 GPT-4 等通用模型才是时下热门的方法。这种方法绕过了海量数据的收集和对模型的训练过程,展示出了强大的灵活性,而且对不同机器人硬件更具适应性,并增强了系

这些VLM竟都是盲人?GPT-4o、Sonnet-3.5相继败于「视力」测试

四大 VLM,竟都在盲人摸象?让现在最火的 SOTA 模型们(GPT-4o,Gemini-1.5,Sonnet-3,Sonnet-3.5)数一数两条线有几个交点,他们表现会比人类好吗?答案很可能是否定的。自 GPT-4V 推出以来,视觉语言模型 (VLMs) 让大模型的智能程度朝着我们想象中的人工智能水平跃升了一大步。VLMs 既能看懂画面,又能用语言来描述看到的东西,并基于这些理解来执行复杂的任务。比如,给 VLM 模型发去一张餐桌的图片,再发一张菜单的图片,它就能从两张图中分别提取啤酒瓶的数量和菜单上的单价,算