多模态AI旨在让机器像人一样,能够协同处理和理解来自多种渠道的信息,如文本、图像、声音和视频。本章将聚焦于多模态AI的核心应用,并提供代码实践。

22.1 图文匹配技术

图文匹配是多模态学习的基础,其核心是学习图像和文本之间的对应关系,将它们映射到一个统一的语义空间中。

  • 核心模型:CLIP (Contrastive Language-Image Pre-training) 是该领域的标杆。它通过对比学习,在海量图文对上进行预训练,学会了将语义相似的图文在表示空间中拉近,不相似的推远。

22.1.1 实践项目:使用CLIP实现图文匹配与零样本分类

我们将使用Hugging Face transformers库调用CLIP模型,实现图文相似度计算和零样本图像分类。

22.1.1.1 Python代码实战
import torch
from PIL import Image
import requests
from transformers import CLIPProcessor, CLIPModel

# 1. 加载预训练的CLIP模型
model_name = "openai/clip-vit-base-patch32"
model = CLIPModel.from_pretrained(model_name)
processor = CLIPProcessor.from_pretrained(model_name)

# 2. 准备数据
url = "http://images.cocodataset.org/val2017/000000039769.jpg" # 一张猫的图片
image = Image.open(requests.get(url, stream=True).raw)

# 候选文本
candidate_texts = ["a photo of a cat", "a photo of a dog"]

# 3. 预处理并进行推理
inputs = processor(text=candidate_texts, images=image, return_tensors="pt", padding=True)
with torch.no_grad():
    outputs = model(**inputs)

# 4. 获取图文匹配得分
logits_per_image = outputs.logits_per_image  # 图像与每个文本的匹配度
probs = logits_per_image.softmax(dim=1)  # 转换为概率

print("--- 图文匹配与零样本分类 ---")
print(f"图片与 '{candidate_texts[0]}' 的匹配概率: {probs[0][0]:.4f}")
print(f"图片与 '{candidate_texts[1]}' 的匹配概率: {probs[0][1]:.4f}")
print(f"\n结论:模型预测这是一张 '{candidate_texts[probs.argmax()]}'.")
22.1.1.2 项目总结

这个项目展示了CLIP的强大能力。我们不仅可以计算任意图文对的匹配度,还能通过提供一组候选文本描述来实现“零样本”图像分类——即模型在没有见过任何标注样本的情况下,仅凭文本描述就能完成分类任务。

22.2 视频理解模型

视频理解比图像理解更复杂,因为它需要处理时序信息。模型不仅要理解每一帧的内容,还要理解帧与帧之间的动态关系。

  • 主流模型:基于Transformer的架构,如TimeSformer、VideoMAE等,通过将视频切分为一系列的图像块(Patches),并引入时间维度的注意力机制,来同时学习时空特征。

22.2.1 实践项目:使用VideoMAE进行视频动作识别

我们将使用Hugging Face调用预训练的VideoMAE(Masked Autoencoders for Video)模型,对视频进行动作分类。

22.2.1.1 Python代码实战
import torch
import av
import numpy as np
from transformers import VideoMAEImageProcessor, VideoMAEForVideoClassification

# 这是一个需要下载大型视频数据集(如UCF101)才能完整运行的示例
# 我们将主要展示代码逻辑和API用法
def video_classification_demo():
    print("\n--- 视频动作识别(概念演示) ---")
    try:
        # 1. 加载模型和处理器
        model_name = "MCG-NJU/videomae-base-finetuned-kinetics-400"
        processor = VideoMAEImageProcessor.from_pretrained(model_name)
        model = VideoMAEForVideoClassification.from_pretrained(model_name)

        # 2. 假设我们有一个视频文件 'test_video.mp4'
        # 实际使用时需要提供一个真实的视频文件路径
        # container = av.open('path/to/your/video.mp4')

        # 3. 从视频中采样帧
        # num_frames_to_sample = model.config.num_frames
        # indices = np.linspace(0, container.streams.video[0].frames - 1, num_frames_to_sample, dtype=int)
        # frames = [container.decode(video=0)[i] for i in indices]
        # video = [frame.to_ndarray(format="rgb24") for frame in frames]

        # 4. 预处理并推理 (使用随机数据作为演示)
        num_frames = model.config.num_frames
        dummy_video = list(np.random.randn(num_frames, 224, 224, 3).astype(np.uint8))
        inputs = processor(dummy_video, return_tensors="pt")

        with torch.no_grad():
            outputs = model(**inputs)
            logits = outputs.logits

        # 5. 获取预测结果
        predicted_label_id = logits.argmax(-1).item()
        predicted_label = model.config.id2label[predicted_label_id]
        print(f"使用随机数据预测的动作类别为: {predicted_label}")
        print("注意:这是一个概念演示,真实结果需要使用真实视频。")

    except Exception as e:
        print(f"加载模型或执行演示时出错: {e}")
        print("这可能是因为网络问题或依赖库不完整。")

video_classification_demo()
22.2.1.2 项目总结

视频理解模型能够捕捉视频中的时空动态,使其在动作识别、事件检测、视频摘要等任务中发挥关键作用。通过Hugging Face,我们可以方便地使用这些强大的预训练模型。

22.3 跨模态检索

跨模态检索允许用户使用一种模态的查询来查找另一种模态的内容,例如“以文搜图”或“以图搜文”。

  • 实现方式:其核心仍然是像CLIP这样的图文匹配模型。通过将大量的图像和文本预先编码为特征向量并存入向量数据库(如FAISS, Milvus),就可以实现高效的检索。

22.3.1 实践项目:构建一个迷你图文检索引擎

我们将扩展CLIP的应用,构建一个简单的“以文搜图”系统。

22.3.1.1 Python代码实战
import torch
from PIL import Image
import requests
from transformers import CLIPProcessor, CLIPModel

# 1. 加载模型
model_name = "openai/clip-vit-base-patch32"
model = CLIPModel.from_pretrained(model_name)
processor = CLIPProcessor.from_pretrained(model_name)

# 2. 构建一个小型图片“数据库”
image_urls = {
    "cat": "http://images.cocodataset.org/val2017/000000039769.jpg",
    "dog": "http://images.cocodataset.org/val2017/000000039775.jpg",
    "car": "http://images.cocodataset.org/val2017/000000039801.jpg"
}
images = {name: Image.open(requests.get(url, stream=True).raw) for name, url in image_urls.items()}

# 3. 预处理所有图片并提取特征
image_inputs = processor(images=list(images.values()), return_tensors="pt", padding=True)
with torch.no_grad():
    image_features = model.get_image_features(**image_inputs)

# 4. 定义文本查询并提取特征
query_text = "an animal sitting on a couch"
text_inputs = processor(text=query_text, return_tensors="pt")
with torch.no_grad():
    text_features = model.get_text_features(**text_inputs)

# 5. 计算查询文本与所有图片的相似度
# 使用余弦相似度进行比较
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
similarity = (text_features @ image_features.T).squeeze(0)

# 6. 检索结果
print("\n--- 跨模态检索(以文搜图) ---")
print(f"查询: '{query_text}'")
best_match_idx = similarity.argmax().item()
best_match_name = list(images.keys())[best_match_idx]
print(f"最佳匹配图片: {best_match_name} (相似度: {similarity[best_match_idx]:.4f})")
22.3.1.2 项目总结

这个项目模拟了跨模态检索的核心流程:首先对目标数据集(这里是图片)进行编码,然后对查询(这里是文本)进行编码,最后通过计算特征向量的相似度来找到最佳匹配。在实际应用中,这些特征向量会被存储在专门的向量数据库中以实现毫秒级检索。

22.4 多模态对话系统

多模态对话系统(或称多模态大模型,LMMs)是当前AI领域最前沿的方向之一。它将大语言模型(LLM)的强大推理能力与视觉等其他模态的理解能力相结合。

  • 代表模型:GPT-4V, LLaVA, Gemini等。
  • 工作原理:通常通过一个“连接器”(Projection Layer)将预训练的视觉编码器(如CLIP的ViT)的输出映射到语言模型的输入空间。这样,模型就能“看到”图片,并像处理文本一样处理视觉信息,从而实现对图像内容的理解、分析、推理和描述。

22.4.1 实践项目:与LLaVA进行多模态对话(概念)

直接运行一个像LLaVA这样的模型需要大量的计算资源。这里我们通过一个概念性的代码框架来展示其工作方式。

22.4.1.1 Python代码框架
from PIL import Image
import requests
from transformers import LlavaNextProcessor, LlavaNextForConditionalGeneration
import torch

def llava_demo():
    print("\n--- 多模态对话系统(概念演示) ---")
    try:
        # 1. 加载LLaVA模型和处理器
        model_name = "llava-hf/llava-v1.6-mistral-7b-hf"
        processor = LlavaNextProcessor.from_pretrained(model_name)
        model = LlavaNextForConditionalGeneration.from_pretrained(model_name, torch_dtype=torch.float16, low_cpu_mem_usage=True)
        # model.to("cuda:0") # 需要GPU

        # 2. 准备图片和对话提示
        url = "https://www.ilankelman.org/stopsigns/australia.jpg"
        image = Image.open(requests.get(url, stream=True).raw)
        prompt = "[INST] <image>\nWhat is unusual about this image? [/INST]"

        # 3. 预处理并生成回答
        # inputs = processor(prompt, image, return_tensors="pt").to("cuda:0")
        # output = model.generate(**inputs, max_new_tokens=100)
        # response = processor.decode(output[0], skip_special_tokens=True)

        # 4. 打印结果 (由于资源限制,我们打印预期结果)
        print(f"用户提问: What is unusual about this image? (关于一张颠倒的停车标志图片)")
        expected_response = "The unusual aspect of this image is that the stop sign is upside down."
        print(f"预期模型回答: {expected_response}")
        print("注意:实际运行需要GPU和大量内存。")

    except Exception as e:
        print(f"加载模型或执行演示时出错: {e}")
        print("这通常是因为计算资源不足或网络问题。")

llava_demo()
22.4.1.2 项目总结

多模态对话系统将AI的交互能力提升到了一个新的高度。它不再局限于文本,而是能够围绕用户提供的视觉信息进行深入、有逻辑的对话,完成解释、推理、创作等复杂任务,是通往通用人工智能的重要一步。

22.5 总结

本章我们深入了多模态AI的四大关键应用领域。从作为基础的图文匹配技术,到处理动态世界的视频理解模型,再到实现高效信息查找的跨模态检索,最后到代表AI前沿的多模态对话系统。通过结合代码实践,我们不仅理解了这些技术的原理,也体验了它们如何让AI更全面地感知和理解我们的世界。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐