全部笔记All notes

大模型多模态输入处理

阅读 7m 04s7m 04s read

多模态输入处理

图像、音频、视频、PDF 等多模态内容的 API 调用方式。


什么是多模态?

多模态是指模型能够理解和处理多种类型的输入,不仅限于文本。现代大模型已经可以”看图”、“听音”、“读文档”。

多模态能力让 AI 应用场景大大扩展:

  • 图像理解:识别图片内容、OCR 文字提取
  • 文档分析:直接阅读 PDF、提取关键信息
  • 音视频处理:转录、摘要、内容分析

多模态的价值:

传统方式多模态方式优势
OCR + 文本处理直接理解图像保留上下文、理解布局
PDF 解析 + 文本直接阅读 PDF理解表格、图表
语音转文字 + 文本直接理解音频保留语气、情感
视频抽帧 + 图像直接理解视频理解动作、时序

多模态支持矩阵

类型OpenAIClaudeGemini说明
图像✅✅✅全部支持
PDF❌✅✅OpenAI 需转换
音频✅ (Whisper)❌✅Claude 不支持
视频❌❌✅仅 Gemini

选择建议:

需求推荐
图像理解三家都可
PDF 文档Claude、Gemini
音频处理Gemini、OpenAI Whisper
视频分析Gemini
综合多模态Gemini

图像处理

图像是最常用的多模态输入。三家厂商都支持图像理解,但输入格式略有不同。

输入方式

有三种方式传递图像:

  • Base64 编码:将图像转为文本,适合小图、本地图片
  • URL 链接:直接传递图片地址,适合网络图片
  • 文件上传:先上传到云存储,再引用(Gemini)

Base64 方式最通用,但会增加请求体积(约增大 33%)。

flowchart LR
    A[图像] --> B{输入方式}
    B --> C[Base64 编码]
    B --> D[URL 链接]
    B --> E[文件上传]

方式对比:

方式优点缺点适用场景
Base64通用、无需网络请求体大本地图片、小图
URL请求体小需要公开访问网络图片
文件上传支持大文件需要额外步骤大文件、重复使用

格式对比

厂商Base64URL
OpenAIimage_url.url: data:image/jpeg;base64,...image_url.url: https://...
Claudesource.type: base64source.type: url
GeminiinlineData.datafileData.fileUri

代码示例

import base64

# 读取图像并编码
with open("image.jpg", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()

# OpenAI 格式
openai_image = {
    "type": "image_url", 
    "image_url": {
        "url": f"data:image/jpeg;base64,{b64}",
        "detail": "high"  # low/high/auto
    }
}

# Claude 格式
claude_image = {
    "type": "image", 
    "source": {
        "type": "base64", 
        "media_type": "image/jpeg", 
        "data": b64
    }
}

# Gemini 格式
gemini_image = {
    "inlineData": {
        "mimeType": "image/jpeg", 
        "data": b64
    }
}

图像限制:

厂商最大大小支持格式每次最多
OpenAI20MBPNG, JPEG, GIF, WebP多张
Claude20MBPNG, JPEG, GIF, WebP多张
Gemini20MBPNG, JPEG, GIF, WebP多张

PDF 处理

PDF 是企业场景中最常见的文档格式。Claude 和 Gemini 原生支持 PDF 输入,可以直接”阅读”文档内容。

原生 PDF 支持的优势:

  • 保留文档布局和格式
  • 理解表格结构
  • 识别图表和图像
  • 处理多页文档

OpenAI 不直接支持 PDF,需要先转换:

  • 转为图像(每页一张)
  • 提取文本(丢失格式)

如果你的应用需要处理大量 PDF,建议优先选择 Claude 或 Gemini。

flowchart TD
    A[PDF 文件] --> B{厂商}
    B -->|Claude| C[直接支持]
    B -->|Gemini| D[直接支持]
    B -->|OpenAI| E[需转换]
    
    E --> F[转图像]
    E --> G[提取文本]

Claude PDF

Claude 原生支持 PDF,可以理解文档结构:

import base64

with open("doc.pdf", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()

message = {
    "role": "user",
    "content": [
        {
            "type": "document", 
            "source": {
                "type": "base64", 
                "media_type": "application/pdf", 
                "data": b64
            }
        },
        {"type": "text", "text": "总结这份文档的要点"}
    ]
}

Gemini PDF

message = {
    "role": "user",
    "parts": [
        {"inlineData": {"mimeType": "application/pdf", "data": b64}},
        {"text": "总结这份文档"}
    ]
}

音频处理

音频处理主要用于语音转文字、会议记录、播客摘要等场景。

Gemini 原生支持

Gemini 可以直接理解音频内容,支持多种格式。这是目前最便捷的方案。

# 支持格式: mp3, wav, aac, flac, ogg
message = {
    "role": "user",
    "parts": [
        {"inlineData": {"mimeType": "audio/mp3", "data": audio_b64}},
        {"text": "转录这段音频"}
    ]
}

OpenAI Whisper

OpenAI 通过独立的 Whisper API 提供语音转文字功能,准确率很高,支持多语言。

# 语音转文字(独立 API)
transcript = client.audio.transcriptions.create(
    model="whisper-1",
    file=open("audio.mp3", "rb")
)

OpenAI Realtime API (音频对话)

GPT-4o 支持通过 WebSocket 进行实时音频对话,无需先转录为文本。这对于低延迟语音助手至关重要。

// 需使用 WebSocket 连接 wss://api.openai.com/v1/realtime
// 详见 06-传输协议对比.md

视频处理

视频理解是 Gemini 的独特优势。它可以分析视频内容、提取关键帧、生成摘要。

由于视频文件通常较大,需要先上传到 Google Cloud Storage,再通过 URI 引用。Gemini 1.5 Pro 支持最长 2 小时的视频。

flowchart LR
    A[视频] --> B[上传到 GCS]
    B --> C[Gemini API]
    C --> D[分析结果]

Gemini 视频分析

# 需要先上传到 Google Cloud Storage
message = {
    "role": "user",
    "parts": [
        {"fileData": {"mimeType": "video/mp4", "fileUri": "gs://bucket/video.mp4"}},
        {"text": "描述视频内容"}
    ]
}

统一处理方案

flowchart TD
    A[多模态输入] --> B{文件类型}
    
    B -->|图像| C[统一转 Base64]
    B -->|PDF| D{厂商支持?}
    B -->|音频| E{厂商支持?}
    B -->|视频| F[仅 Gemini]
    
    D -->|是| G[直接发送]
    D -->|否| H[转图像/文本]
    
    E -->|是| I[直接发送]
    E -->|否| J[Whisper 转文字]

工具函数

def prepare_image(path):
    """统一图像处理"""
    with open(path, "rb") as f:
        return base64.b64encode(f.read()).decode()

def get_mime_type(path):
    """获取 MIME 类型"""
    ext = path.split(".")[-1].lower()
    return {
        "jpg": "image/jpeg", "jpeg": "image/jpeg",
        "png": "image/png", "gif": "image/gif",
        "pdf": "application/pdf",
        "mp3": "audio/mp3", "wav": "audio/wav",
        "mp4": "video/mp4"
    }.get(ext, "application/octet-stream")

限制与注意

厂商图像大小图像数量特殊限制
OpenAI20MB多张-
Claude5MB20张PDF < 100页
Gemini20MB多张视频 < 2小时

图像最佳实践

分辨率选择

图像分辨率直接影响 Token 消耗和识别效果。需要在成本和质量间平衡。

场景建议分辨率说明
文字识别 OCR高分辨率需要清晰细节
图片分类低分辨率整体特征即可
图表分析中等分辨率需要看清数字
人脸识别中等分辨率面部特征

图像预处理

from PIL import Image

def optimize_image(path, max_size=1024):
    """优化图像尺寸,减少 Token 消耗"""
    img = Image.open(path)
    
    # 等比缩放
    ratio = min(max_size / img.width, max_size / img.height)
    if ratio < 1:
        new_size = (int(img.width * ratio), int(img.height * ratio))
        img = img.resize(new_size, Image.LANCZOS)
    
    # 转换格式(JPEG 更小)
    if img.mode == 'RGBA':
        img = img.convert('RGB')
    
    return img

多图像策略

当需要分析多张图像时:

flowchart TD
    A[多张图像] --> B{数量}
    B -->|少量 < 5| C[一次请求]
    B -->|中等 5-20| D[分批请求]
    B -->|大量 > 20| E[并行处理]
    
    C --> F[合并分析]
    D --> F
    E --> F

常见问题

Q: 图像识别不准确怎么办?

问题解决方案
图像模糊提高分辨率、增强清晰度
对比度低预处理增强对比度
目标太小裁剪关键区域
缺少上下文在 Prompt 中说明背景
# 图像增强示例
from PIL import Image, ImageEnhance

def enhance_image(img):
    # 增强对比度
    enhancer = ImageEnhance.Contrast(img)
    img = enhancer.enhance(1.5)
    
    # 增强锐度
    enhancer = ImageEnhance.Sharpness(img)
    img = enhancer.enhance(2.0)
    
    return img

Q: PDF 页数太多怎么处理?

flowchart TD
    A[大型 PDF] --> B{页数}
    B -->|< 50 页| C[直接处理]
    B -->|50-200 页| D[分批处理]
    B -->|> 200 页| E[提取关键页]
    
    D --> F[每批 30 页]
    E --> G[目录/摘要页]

处理策略:

  1. 分批处理:每批 20-30 页,合并结果
  2. 提取关键页:目录、摘要、结论
  3. OCR + 文本:先提取文本,再分析
  4. 向量检索:建立索引,按需检索

Q: 视频太长怎么办?

  1. 提取关键帧:每 N 秒提取一帧
  2. 分段处理:每段 5-10 分钟
  3. 先摘要后详细:先生成整体摘要,再深入分析
  4. 音频分离:单独处理音频转录
# 视频关键帧提取示例
import cv2

def extract_keyframes(video_path, interval_seconds=10):
    """每隔 N 秒提取一帧"""
    cap = cv2.VideoCapture(video_path)
    fps = cap.get(cv2.CAP_PROP_FPS)
    interval_frames = int(fps * interval_seconds)
    
    frames = []
    frame_count = 0
    
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        
        if frame_count % interval_frames == 0:
            frames.append(frame)
        frame_count += 1
    
    cap.release()
    return frames

Q: 多模态请求太慢?

优化方法效果
压缩图像减少传输时间
使用 URL避免 Base64 编码开销
并行请求多图像并行处理
预处理提前准备数据

多模态应用场景

1. 智能文档处理

async def process_document(pdf_path):
    """智能文档处理流程"""
    # 1. 读取 PDF
    with open(pdf_path, "rb") as f:
        pdf_b64 = base64.b64encode(f.read()).decode()
    
    # 2. 提取结构化信息
    response = await client.messages.create(
        model="claude-sonnet-4-20250514",
        messages=[{
            "role": "user",
            "content": [
                {"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": pdf_b64}},
                {"type": "text", "text": """
                    分析这份文档,提取以下信息(JSON 格式):
                    - title: 文档标题
                    - date: 日期
                    - summary: 摘要(100字内)
                    - key_points: 关键要点(列表)
                    - tables: 表格数据(如有)
                """}
            ]
        }]
    )
    
    return response.content[0].text

2. 商品图像分析

def analyze_product_image(image_path):
    """电商商品图像分析"""
    b64 = prepare_image(image_path)
    
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{
            "role": "user",
            "content": [
                {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{b64}"}},
                {"type": "text", "text": """
                    分析这张商品图片,提供:
                    1. 商品类别
                    2. 主要特征(颜色、材质、风格)
                    3. 适合的使用场景
                    4. 建议的标签(用于搜索)
                    5. 图片质量评估
                """}
            ]
        }]
    )
    
    return response.choices[0].message.content

3. 会议记录处理

async def process_meeting_recording(audio_path):
    """会议录音处理"""
    # 1. 语音转文字
    with open(audio_path, "rb") as f:
        transcript = client.audio.transcriptions.create(
            model="whisper-1",
            file=f,
            response_format="verbose_json"
        )
    
    # 2. 生成会议纪要
    summary = client.chat.completions.create(
        model="gpt-4o",
        messages=[{
            "role": "user",
            "content": f"""
                根据以下会议转录,生成会议纪要:
                
                {transcript.text}
                
                请包含:
                1. 会议主题
                2. 参会人员(如能识别)
                3. 讨论要点
                4. 决议事项
                5. 待办事项(Action Items)
            """
        }]
    )
    
    return {
        "transcript": transcript.text,
        "summary": summary.choices[0].message.content
    }

相关文档