AI 多模态
AI 不只会说话,还能看图片、听声音、理解视频——掌握多模态工具与技术。
在很长一段时间里,AI 都是单感官的。
文字 AI 只能处理文本,比如让 ChatGPT 写文章。
-
图像 AI 只能处理图片,比如让 Midjourney 画图。
-
音频 AI 只能处理声音,比如让 Whisper 转录语音。
但现实世界是多模态的——我们看书时会看到插图,看电影时有画面和声音,与人交流时要观察表情和语气。
多模态 AI 就是能同时理解和生成多种类型内容的 AI,这就像给 AI 配上了眼睛、耳朵和嘴巴,让它能用更接近人类的方式与世界互动。
一个实用的例子:你给 AI 一张购物小票的照片,它能识别上面的文字(OCR)、理解购买了什么商品、帮你整理成表格,还能用语音读给你听。这就是典型的多模态任务。
什么是多模态 AI
先搞清楚几个基础概念。
单模态 vs 多模态
模态(Modality)指的是信息的表现形式。
文字、图片、音频、视频,这些都是不同的模态。
| 类型 | 说明 | 典型产品 |
|---|---|---|
| 单模态 AI | 只能处理一种模态 | 早期的 GPT-3(只有文字)、Stable Diffusion(只有图像) |
| 多模态 AI | 能同时处理多种模态 | GPT-4o、Claude 3、Gemini |
多模态 AI 的核心突破是:它能把不同模态的信息转换成同一种语言来理解。
比如,看到一张"猫"的图片,它能把图片转换成向量(一组数字);看到"猫"这个字,也能转换成向量。这两个向量在数学空间里是接近的,因为它们代表同一个概念。
多模态的核心挑战
多模态听起来简单,实际做起来很难。
第一个挑战是"对齐"——如何让图片里的"猫"和文字里的"猫"在模型看来是同一个东西?
-
第二个挑战是"融合"——当同时看到一张图和一段文字时,如何把它们的信息结合起来?
-
第三个挑战是"生成"——如何根据文字描述生成图片,或者根据图片生成文字说明?
-
好在这些问题正在被逐步解决。2024 年之后的主流大模型,几乎都是多模态的。
图像理解(Vision)
图像理解就是让 AI看懂图片——描述内容、识别文字、分析图表、发现细节。
主流大模型都支持图片输入了。
使用方式通常有两种:
一种是直接上传图片文件,比如在 ChatGPT 网页版里点击图片图标上传。
-
另一种是用 Base64 编码把图片嵌在 API 请求里,适合程序调用。
| 模型 | 图片输入方式 | 支持的图片格式 |
|---|---|---|
| GPT | URL、Base64、直接上传 | JPG、PNG、WEBP、GIF |
| Claude | Base64、直接上传 | JPG、PNG、WEBP、GIF |
| Gemini | 直接上传、Google Drive | JPG、PNG、WEBP |
常见的视觉任务包括:
图像描述——这张图里有什么?
-
OCR——把图片里的文字提取出来。
-
图表分析——这个柱状图在说什么?
-
细节发现——帮我检查这张设计稿有没有问题。
实战:用 Python 调用 GPT-4o Vision API
我们来看一个完整的例子——用 API 分析一张图片。
实例
# 文件:runoob_vision_demo.py
# 功能:使用 GPT-4o Vision API 分析图片
# ============================================
import base64
import requests
import os
# 配置 API 密钥(请替换为你的真实密钥)
# 获取地址:https://platform.openai.com/api-keys
OPENAI_API_KEY = "sk-your-api-key-here"
OPENAI_API_URL = "https://api.openai.com/v1/chat/completions"
def encode_image_to_base64(image_path: str) -> str:
"""
将本地图片文件编码为 Base64 字符串
这是 API 要求的传输格式
"""
with open(image_path, "rb") as image_file:
# 读取二进制文件内容,用 Base64 编码
base64_data = base64.b64encode(image_file.read()).decode("utf-8")
return base64_data
def analyze_image_with_gpt4o(
image_path: str,
prompt: str = "请详细描述这张图片的内容",
model: str = "gpt-4o"
) -> str:
"""
使用 GPT-4o Vision API 分析图片
参数说明:
image_path: 本地图片文件路径(如 "runoob_test.jpg")
prompt: 你想问的问题或想让 AI 做的任务
model: 使用的模型名称(默认 gpt-4o)
返回:
AI 的分析结果文本
"""
# 步骤 1:将图片编码为 Base64
base64_image = encode_image_to_base64(image_path)
# 步骤 2:构建请求头
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
# 步骤 3:构建请求体
# 注意:图片内容通过 image_url 字段传递,格式为 "data:image/jpeg;base64,..."
payload = {
"model": model,
"messages": [
{
"role": "user",
"content": [
# 第一个部分是文本提示
{"type": "text", "text": prompt},
# 第二个部分是图片
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{base64_image}"
}
}
]
}
],
"max_tokens": 1000 # 控制输出长度,防止费用过高
}
# 步骤 4:发送 API 请求
print(f"正在分析图片:{image_path} ...")
response = requests.post(OPENAI_API_URL, headers=headers, json=payload)
# 步骤 5:处理响应
if response.status_code == 200:
result = response.json()
# 提取 AI 的回答
answer = result["choices"][0]["message"]["content"]
return answer
else:
# 出错时打印详细信息
error_msg = f"请求失败:{response.status_code} - {response.text}"
print(error_msg)
return error_msg
def extract_text_from_image(image_path: str) -> str:
"""
专门用于 OCR:提取图片中的文字
"""
prompt = """
请提取这张图片中的所有文字内容。
要求:
1. 准确还原文字,不要遗漏
2. 保持原有的段落和格式
3. 如果有表格,请用表格形式输出
4. 如果图片中没有文字,请说明
这是 RUNOOB 教程的 OCR 测试。
"""
return analyze_image_with_gpt4o(image_path, prompt)
def analyze_chart(image_path: str) -> str:
"""
专门用于图表分析
"""
prompt = """
请分析这张图表。
请回答以下问题:
1. 这是什么类型的图表(柱状图、折线图、饼图等)?
2. 图表的标题和坐标轴含义是什么?
3. 图表传达的主要信息是什么?
4. 有什么值得注意的趋势或异常?
这是 RUNOOB 教程的图表分析测试。
"""
return analyze_image_with_gpt4o(image_path, prompt)
# ============================================
# 主程序:演示不同的视觉分析任务
# ============================================
if __name__ == "__main__":
# 假设我们有一张测试图片(你需要准备一张真实的图片)
# 可以是:商品照片、截图、文档照片、图表等
test_image = "runoob_test_image.jpg"
# 检查图片是否存在
if not os.path.exists(test_image):
print(f"提示:请先准备一张图片,命名为 {test_image} 放在当前目录")
print("或者修改代码中的图片路径")
else:
# 任务 1:通用图像描述
print("\n" + "="*50)
print("任务 1:图像描述")
print("="*50)
result1 = analyze_image_with_gpt4o(
test_image,
"请详细描述这张图片,包括主体、背景、颜色、构图等"
)
print(result1)
# 任务 2:OCR 文字提取
print("\n" + "="*50)
print("任务 2:OCR 文字提取")
print("="*50)
result2 = extract_text_from_image(test_image)
print(result2)
# 任务 3:图表分析(如果图片是图表)
print("\n" + "="*50)
print("任务 3:图表分析")
print("="*50)
result3 = analyze_chart(test_image)
print(result3)
print("\n" + "="*50)
print("RUNOOB 教程演示完成!")
print("="*50)
运行这个程序前,你需要:
-
1. 安装依赖:
pip install requests -
2. 准备一张测试图片,命名为
runoob_test_image.jpg -
3. 把 API 密钥换成你自己的
费用提示:GPT-4o Vision 按图片尺寸计费。一张 1024x1024 的图片大约需要 0.00765 美元。小图片更便宜。调试时建议用低分辨率图,正式使用再上高清。
文生图(Text-to-Image)
文生图就是让 AI 根据文字描述生成图片,这是另一个非常成熟的多模态应用领域。
扩散模型原理简介
今天的文生图工具,基本都用扩散模型(Diffusion Model)技术。
简单理解它的工作原理:
训练阶段:给模型看一张清晰的图片,然后一点一点往上面加噪点,直到变成全是雪花的乱图。模型学习的是如何把乱图一步步变清晰。
-
生成阶段:给模型一张随机噪点图,让它根据文字提示,一步步去噪,最后生成一张符合描述的清晰图片。
这个过程通常需要 20-50 步,所以生成一张图需要几秒钟。
Midjourney 进阶使用技巧
Midjourney 是目前最流行的文生图工具之一,通过 Discord 使用。
一个高质量的提示词(Prompt)通常包含这些元素:
-
主体描述——"一只戴着帽子的猫"
-
风格——"宫崎骏风格"、"油画"、"3D 渲染"
-
光影——"自然光"、"电影光"、"赛博朋克霓虹灯"
-
构图——"特写"、"广角"、"俯视"
-
画质——"8K"、"超高细节"、"摄影级"
| 参数 | 说明 | 示例 |
|---|---|---|
| --ar | 设置宽高比 | --ar 16:9(视频)、--ar 3:4(手机) |
| --v | 指定模型版本 | --v 6.0(最新版本) |
| --s | 风格化程度(0-1000) | --s 750(艺术感强) |
| --q | 渲染质量(0.25-2) | --q 2(更高质量,更慢) |
| --iw | 参考图权重 | --iw 1.5(更像参考图) |
Stable Diffusion 本地部署
如果你想要完全的控制权,可以在本地运行 Stable Diffusion: https://github.com/compvis/stable-diffusion。
最常用的工具是 Automatic1111 的 WebUI。
步骤大致是:
-
1. 安装 Python 3.10
-
2. 下载 Stable Diffusion WebUI
-
3. 下载模型文件(.safetensors 格式)
-
4. 运行 webui.bat(Windows)或 webui.sh(Mac/Linux)
本地部署的优势是:生成不花钱、没有内容限制、可以用 LoRA 微调风格、可以用 ControlNet 精确控制构图。
劣势是:需要一张显存至少 6GB 的显卡,设置比较麻烦。
实战:调用 DALL·E 3 API 生成图片
如果你想要简单的 API 方式生成图片,DALL·E 3 是个好选择。
实例
# 文件:runoob_dalle3_demo.py
# 功能:使用 DALL·E 3 API 生成图片
# ============================================
import requests
import os
from datetime import datetime
# 配置 API 密钥(请替换为你的真实密钥)
OPENAI_API_KEY = "sk-your-api-key-here"
DALLE3_API_URL = "https://api.openai.com/v1/images/generations"
def generate_image_with_dalle3(
prompt: str,
size: str = "1024x1024",
quality: str = "standard",
style: str = "vivid",
save_dir: str = "runoob_generated_images"
) -> dict:
"""
使用 DALL·E 3 API 生成图片
参数说明:
prompt: 文字描述,越详细越好
size: 图片尺寸
可选:1024x1024、1024x1792(竖版)、1792x1024(横版)
quality: 图片质量
可选:standard(标准)、hd(高清,更贵)
style: 风格
可选:vivid(生动,更有艺术感)、natural(自然,更真实)
save_dir: 图片保存目录
返回:
包含图片 URL 和保存路径的字典
"""
# 步骤 1:准备请求头
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
# 步骤 2:准备请求体
payload = {
"model": "dall-e-3",
"prompt": prompt,
"n": 1, # DALL·E 3 每次只能生成 1 张
"size": size,
"quality": quality,
"style": style
}
# 步骤 3:发送请求
print(f"正在生成图片,提示词:{prompt[:50]}...")
response = requests.post(DALLE3_API_URL, headers=headers, json=payload)
# 步骤 4:处理响应
if response.status_code == 200:
result = response.json()
image_url = result["data"][0]["url"]
revised_prompt = result["data"][0].get("revised_prompt", prompt)
print(f"DALL·E 3 自动优化后的提示词:{revised_prompt}")
# 步骤 5:下载并保存图片
if not os.path.exists(save_dir):
os.makedirs(save_dir)
# 用时间戳生成文件名
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"runoob_dalle3_{timestamp}.png"
filepath = os.path.join(save_dir, filename)
# 下载图片
image_response = requests.get(image_url)
if image_response.status_code == 200:
with open(filepath, "wb") as f:
f.write(image_response.content)
print(f"图片已保存到:{filepath}")
return {
"image_url": image_url,
"filepath": filepath,
"revised_prompt": revised_prompt
}
else:
error_msg = f"请求失败:{response.status_code} - {response.text}"
print(error_msg)
return {"error": error_msg}
def generate_runoob_logo_demo():
"""演示:生成 RUNOOB 风格的 Logo"""
prompt = """
A cute and friendly robot mascot for RUNOOB tutorial website.
Blue and green color scheme, modern flat design, white background.
The robot looks helpful and intelligent, with big friendly eyes.
Simple, clean, suitable for a tech education brand.
"""
# 中文提示词也可以,DALL·E 3 支持多语言
prompt = """
为 RUNOOB 教程网站设计一个可爱友好的机器人吉祥物。
蓝绿色调,现代扁平化设计,白色背景。
机器人看起来乐于助人且聪明,有大大的友好眼睛。
简洁干净,适合科技教育品牌。
"""
return generate_image_with_dalle3(
prompt=prompt,
size="1024x1024",
quality="hd",
style="vivid"
)
def generate_book_cover_demo():
"""演示:生成书籍封面"""
prompt = """
Book cover design for "AI Tutorial for Beginners".
Modern minimalist style, deep blue and purple gradient background.
The title text is elegant and readable.
Subtle tech elements: floating geometric shapes, faint circuit patterns.
Professional, trustworthy, suitable for a programming book.
"""
return generate_image_with_dalle3(
prompt=prompt,
size="1024x1792", # 竖版
quality="hd",
style="natural"
)
def generate_banner_demo():
"""演示:生成横幅广告图"""
prompt = """
Web banner design for a coding tutorial website (RUNOOB).
16:9 wide format. Modern gradient background from teal to blue.
Clean layout with space for text.
Abstract tech elements: floating code snippets, subtle grid lines.
Professional and inviting.
"""
return generate_image_with_dalle3(
prompt=prompt,
size="1792x1024", # 横版
quality="standard",
style="vivid"
)
# ============================================
# 主程序:演示不同的生成任务
# ============================================
if __name__ == "__main__":
print("="*60)
print("RUNOOB DALL·E 3 图片生成演示")
print("="*60)
# 任务 1:生成 Logo
print("\n[任务 1] 生成 Logo ...")
result1 = generate_runoob_logo_demo()
# 任务 2:生成书籍封面
print("\n[任务 2] 生成书籍封面 ...")
result2 = generate_book_cover_demo()
# 任务 3:生成横幅
print("\n[任务 3] 生成横幅 ...")
result3 = generate_banner_demo()
print("\n" + "="*60)
print("所有任务完成!查看 runoob_generated_images 目录")
print("="*60)
DALL·E 3 的特点是:理解能力强、不会崩坏手和脸、文字生成效果好。
但它也有限制:每次只能生成 1 张、不能精确控制风格、无法像 Stable Diffusion 那样微调。
版权提示:目前的共识是,使用 AI 生成的图片,提示词撰写者拥有使用权,但不拥有版权(因为版权局要求人类创作)。用于商业用途时,建议确认工具的使用条款。
视频 AI
视频 AI 分为两类:视频生成和视频理解。
相比图片,视频的技术难度更大——因为视频是"时间+空间"的组合,要保证每一帧连贯、动作自然。
AI 视频生成工具对比
2024 年是 AI 视频元年,多家公司推出了视频生成产品。
| 工具 | 出品方 | 特点 | 典型时长 |
|---|---|---|---|
| Sora | OpenAI | 画面细节、空间场景理解行业顶尖,物理逻辑真实,暂未全面开放公测 | 最长60秒 |
| Runway Gen-4 | Runway | 全能创作平台,文/图生视频、AI后期剪辑、运动笔刷、VFX特效一体化,海外专业创作者首选 | 10–20秒 |
| Kling(可灵AI) | 快手 | 中文提示词适配优秀,人物动作流畅、跨镜头角色稳定,国内性价比高,支持多段叙事拼接 | 5–30秒,单段最高2分钟 |
| Pika | Pika Labs | 二次元、影视插画风格表现力极强,角色形象统一,支持视频风格重绘、扩帧 | 5–10秒 |
| Veo | 电影级光影与运镜,长镜头叙事稳定,物理渲染自然,尚未公开发布 | 60秒以上 | |
| 即梦AI(Seedance) | 字节跳动 | 深度打通剪映/抖音生态,中文语义精准,音画口型同步,支持脚本自动分镜 | 5–15秒,多段拼接成片 |
| 通义万相Video | 阿里达摩院 | 开源基础模型,多主体交互稳定,支持画面文字生成,可本地部署推理 | 2–15秒 |
| 海螺AI(Hailuo) | MiniMax稀宇 | 轻量化极速生成,适合海报转动态短视频、社媒快闪素材,动漫风格表现突出 | 4–10秒 |
| Luma Dream Machine | Luma AI | 物理动力学模拟顶尖,水、火、布料、爆炸等特效画面真实,电影级运镜 | 5–12秒 |
| 智影 | 腾讯 | 偏向AI剪辑+数字人视频,海量短视频模板,字幕、配音、抠像一站式,商用门槛低 | 不限时长,AI生成片段5–15秒 |
| 海艺AI | 海艺科技 | 支持4K/60fps高帧率输出,多图联动生视频,配套完整成片工作台,限时免费额度充足 | 单段最长30秒 |
AI 视频还在早期阶段:
-
优点是:创意快、成本低、能实现实拍很难的效果。
-
缺点是:时长有限、细节容易崩坏、物理逻辑有时不对(比如物体乱穿、手指数错)。
-
适合的场景:概念演示、短视频素材、电商广告、游戏动画。
-
不适合的场景:需要精确控制的长片、严肃新闻、法律证据。
视频理解与摘要
除了生成视频,AI 还能看懂视频。
视频理解的常见任务:
-
视频摘要——"这个视频在讲什么?用 3 句话总结。"
-
内容检索——"找到视频里有人骑自行车的片段。"
-
问答——"视频里第三个人说了什么?"
技术路线通常是:把视频抽帧(比如每秒抽 1 帧),然后用视觉模型一帧一帧看,最后把信息整合起来。
未来趋势
视频 AI 的发展方向很明确:
-
更长——从 10 秒到 1 分钟,再到 10 分钟。
-
更可控——能用故事板精确控制每一个镜头。
-
更一致——同一个角色在不同镜头里保持一致。
-
更实用——从看起来很酷到能解决实际问题。
-
可以期待:几年后,可能每个人都能用 AI 做出像电影一样的视频作品。
音频与语音 AI
音频 AI 主要包括:语音转文字(ASR)、文字转语音(TTS)、音乐生成。
这是一个已经相当成熟的领域。
语音转文字(Whisper API)
Whisper 是 OpenAI 开源的语音识别模型,效果非常好,支持 99 种语言。
实例
# 文件:runoob_whisper_demo.py
# 功能:使用 Whisper API 转写语音
# ============================================
import requests
import os
# 配置 API 密钥
OPENAI_API_KEY = "sk-your-api-key-here"
WHISPER_API_URL = "https://api.openai.com/v1/audio/transcriptions"
def transcribe_audio_with_whisper(
audio_path: str,
language: str = "zh", # zh=中文, en=英文, 留空则自动识别
prompt: str = "", # 可选:提供一些术语提示,提高准确率
temperature: float = 0.0
) -> dict:
"""
使用 Whisper API 转写音频文件
参数说明:
audio_path: 音频文件路径(支持 mp3、wav、m4a 等)
language: 语言代码(可选,不指定则自动识别)
常见代码:zh(中文)、en(英文)、ja(日文)
prompt: 提示词(可选,把可能出现的专业词、人名写在这里)
temperature: 采样温度(0.0 最确定,1.0 更多样)
返回:
包含转写文本的字典
"""
# 步骤 1:检查文件是否存在
if not os.path.exists(audio_path):
return {"error": f"文件不存在:{audio_path}"}
# 步骤 2:准备请求头
headers = {
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
# 步骤 3:准备请求体(注意:音频要用 multipart/form-data 格式)
files = {
"file": open(audio_path, "rb")
}
data = {
"model": "whisper-1",
"temperature": temperature
}
if language:
data["language"] = language
if prompt:
data["prompt"] = prompt
# 步骤 4:发送请求
print(f"正在转写音频:{audio_path} ...")
response = requests.post(WHISPER_API_URL, headers=headers, files=files, data=data)
# 步骤 5:关闭文件
files["file"].close()
# 步骤 6:处理响应
if response.status_code == 200:
result = response.json()
text = result["text"]
print(f"转写完成,共 {len(text)} 字")
return {
"text": text,
"language": language
}
else:
error_msg = f"请求失败:{response.status_code} - {response.text}"
print(error_msg)
return {"error": error_msg}
def transcribe_with_timestamps(audio_path: str) -> dict:
"""
带时间戳的转写(使用 verbose_json 格式)
"""
headers = {
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
files = {"file": open(audio_path, "rb")}
data = {
"model": "whisper-1",
"response_format": "verbose_json", # 返回详细信息,包括时间戳
"timestamp_granularities": ["segment", "word"] # 支持段级和词级时间戳
}
response = requests.post(WHISPER_API_URL, headers=headers, files=files, data=data)
files["file"].close()
if response.status_code == 200:
result = response.json()
return result
else:
return {"error": response.text}
def translate_audio_to_english(audio_path: str) -> dict:
"""
将任意语言的音频翻译成英文文本
"""
headers = {
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
files = {"file": open(audio_path, "rb")}
data = {
"model": "whisper-1",
"task": "translate" # 特别指定:翻译任务
}
response = requests.post("https://api.openai.com/v1/audio/translations",
headers=headers, files=files, data=data)
files["file"].close()
if response.status_code == 200:
return response.json()
else:
return {"error": response.text}
def runoob_meeting_minutes_demo(audio_path: str) -> str:
"""
实战:生成会议纪要
步骤 1:用 Whisper 转写录音
步骤 2:用 GPT-4o 整理成纪要
"""
# 先转写
print("第一步:转写会议录音...")
transcribe_result = transcribe_audio_with_whisper(
audio_path,
language="zh",
prompt="这是一次 RUNOOB 技术团队的会议,讨论产品开发、进度、技术方案等"
)
if "error" in transcribe_result:
return transcribe_result["error"]
transcript = transcribe_result["text"]
# 再整理(这里简化了,实际项目中可以调用 GPT-4o API)
print("第二步:整理会议纪要...")
# 这里为了演示,直接返回转写文本
# 实际项目中,你可以把 transcript 发给 GPT-4o,让它整理
return transcript
# ============================================
# 主程序
# ============================================
if __name__ == "__main__":
# 准备一个测试音频文件
test_audio = "runoob_test_audio.mp3"
if not os.path.exists(test_audio):
print(f"提示:请准备一个音频文件,命名为 {test_audio}")
print("或者用手机录一段语音,保存为 mp3 格式")
else:
# 任务 1:简单转写
print("\n" + "="*50)
print("任务 1:简单转写")
print("="*50)
result1 = transcribe_audio_with_whisper(test_audio, language="zh")
if "text" in result1:
print("转写结果:")
print(result1["text"])
# 任务 2:带时间戳的转写
print("\n" + "="*50)
print("任务 2:带时间戳的转写")
print("="*50)
result2 = transcribe_with_timestamps(test_audio)
if "segments" in result2:
print("段落信息:")
for seg in result2["segments"][:3]: # 只打印前 3 段
start = round(seg["start"], 2)
end = round(seg["end"], 2)
text = seg["text"]
print(f"[{start}-{end}] {text}")
print("\n" + "="*50)
print("RUNOOB Whisper 演示完成!")
print("="*50)
Whisper 的优势是:多语言支持好、对口音不挑剔、能自动加标点。
典型应用场景:会议录音转写、视频字幕生成、播客文字稿、语音日记。
文字转语音(TTS)
文字转语音就是让 AI"读"文章。
OpenAI 也提供了 TTS API,支持多种声音风格。
其他 TTS 工具:ElevenLabs(最像真人)、Azure TTS(商业级)、Edge TTS(免费)、Coqui(开源)。
音乐生成(Suno、Udio)
音乐生成也取得了突破。
Suno 和 Udio 是两个代表产品——你输入歌词和风格描述,它们就能生成一首完整的歌,有人声、有伴奏。
能力边界:
-
可以做:生成背景音乐、写歌 Demo、快速尝试风格。
-
不太能做:完全复制某首歌、精确控制音符、专业级后期。
-
版权方面:不同工具的条款不同,用于商业前请确认。
多模态模型架构简介
了解一点原理,能帮你更好地使用工具。
CLIP:图文对齐的基石
CLIP(Contrastive Language-Image Pre-training)是 OpenAI 2021 年发表的模型。
它的思路很简单:同时看图片和文字,学会把它们对应起来。
训练时,给模型一批图片+描述对,让它学会:
-
1. 把图片转换成向量
-
2. 把文字转换成向量
-
3. 让配对的图文向量尽量接近,不配对的尽量远离
CLIP 的意义在于:它证明了"跨模态理解"是可行的。
后来的 Stable Diffusion、GPT-4o 等,都受到了 CLIP 的启发。
LLaVA:开源多模态 LLM
LLaVA(Large Language and Vision Assistant)是一个开源的多模态模型。
它的架构很清晰:
-
一个视觉编码器(比如 ViT)——负责看图片
-
一个大语言模型(比如 LLaMA)——负责说话
-
一个投影层——把图片向量转换成语言模型能理解的格式
训练分两步:
-
第一步:预训练对齐——让视觉编码器和语言模型说同一种语言
-
第二步:指令微调——用图片-问题-答案的数据训练,让它学会按指令回答
LLaVA 是学习多模态技术的好起点——代码开源、架构清晰、效果不错。
实战:构建图片分析工具
我们把前面的知识整合起来,做一个实用的图片分析工具。
实例
# 文件:runoob_image_analyzer.py
# 功能:一个完整的多模态图片分析工具
# ============================================
import base64
import requests
import os
import json
from datetime import datetime
from typing import Optional, Dict, Any
class RunoobImageAnalyzer:
"""
RUNOOB 图片分析器——一个封装好的多模态工具类
"""
def __init__(self, api_key: str, base_url: str = "https://api.openai.com/v1"):
"""
初始化分析器
参数:
api_key: OpenAI API 密钥
base_url: API 地址(可配置代理)
"""
self.api_key = api_key
self.base_url = base_url
self.headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
def _encode_image(self, image_path: str) -> str:
"""将图片编码为 Base64"""
with open(image_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
def _call_vision_api(
self,
image_path: str,
prompt: str,
model: str = "gpt-4o",
max_tokens: int = 2000
) -> Optional[str]:
"""内部方法:调用视觉 API"""
base64_image = self._encode_image(image_path)
payload = {
"model": model,
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{
"type": "image_url",
"image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}
}
]
}
],
"max_tokens": max_tokens
}
url = f"{self.base_url}/chat/completions"
response = requests.post(url, headers=self.headers, json=payload)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
print(f"API 错误:{response.status_code} - {response.text}")
return None
def describe(self, image_path: str) -> Optional[str]:
"""详细描述图片内容"""
prompt = """
请详细描述这张图片,包括:
1. 主体内容(有什么人/物)
2. 背景环境
3. 颜色和光线
4. 整体氛围
用中文回答,结构清晰。
"""
return self._call_vision_api(image_path, prompt)
def extract_text(self, image_path: str) -> Optional[str]:
"""提取图片中的所有文字(OCR)"""
prompt = """
请提取这张图片中的所有文字内容。
要求:
1. 准确还原,不要遗漏
2. 保持原有的段落结构
3. 如果是表格,请用 Markdown 表格格式输出
4. 如果没有文字,请明确说明"图片中没有可识别的文字"
"""
return self._call_vision_api(image_path, prompt)
def analyze_ui(self, image_path: str) -> Optional[str]:
"""分析 UI 设计稿(截图)"""
prompt = """
请分析这张 UI 设计稿:
1. 这是什么类型的界面(APP、网页、小程序等)?
2. 界面的主要功能模块有哪些?
3. 设计风格如何(配色、布局、字体)?
4. 有什么可改进的地方?
用中文回答,分点列出。
"""
return self._call_vision_api(image_path, prompt)
def analyze_product(self, image_path: str) -> Optional[str]:
"""分析商品图片,生成电商文案"""
prompt = """
请分析这张商品图片,生成一段电商文案。
文案应包括:
1. 商品名称和类型
2. 外观特点(颜色、材质、设计)
3. 一个吸引人的简短推荐语(30-50字)
用中文回答,语气友好积极。
"""
return self._call_vision_api(image_path, prompt)
def classify(self, image_path: str, categories: list = None) -> Optional[str]:
"""对图片进行分类"""
if categories is None:
categories = [
"人物照片", "风景照片", "美食照片", "产品照片",
"设计稿/截图", "文档/表格", "图表/数据可视化", "其他"
]
cat_list = "、".join(categories)
prompt = f"""
请判断这张图片属于哪个类别。
可选类别:{cat_list}
请只返回最匹配的一个类别名称,不要其他文字。
"""
return self._call_vision_api(image_path, prompt)
def full_analysis(self, image_path: str, output_dir: str = "runoob_analysis") -> Dict[str, Any]:
"""
完整分析:生成一份详细的分析报告
返回一个字典,包含所有分析结果
"""
print(f"开始分析图片:{image_path}")
# 先分类
print("[1/5] 分类中...")
category = self.classify(image_path) or "未知"
# 描述
print("[2/5] 描述中...")
description = self.describe(image_path) or ""
# 提取文字
print("[3/5] OCR 中...")
text = self.extract_text(image_path) or ""
# 根据类别做专项分析
print("[4/5] 专项分析中...")
special_analysis = ""
if "设计" in category or "截图" in category:
special_analysis = self.analyze_ui(image_path) or ""
elif "产品" in category or "商品" in category:
special_analysis = self.analyze_product(image_path) or ""
# 保存报告
print("[5/5] 生成报告中...")
if not os.path.exists(output_dir):
os.makedirs(output_dir)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
report = {
"image_file": os.path.basename(image_path),
"analysis_time": datetime.now().isoformat(),
"category": category,
"description": description,
"extracted_text": text,
"special_analysis": special_analysis
}
# 保存 JSON
json_path = os.path.join(output_dir, f"report_{timestamp}.json")
with open(json_path, "w", encoding="utf-8") as f:
json.dump(report, f, ensure_ascii=False, indent=2)
# 保存可读文本
txt_path = os.path.join(output_dir, f"report_{timestamp}.txt")
with open(txt_path, "w", encoding="utf-8") as f:
f.write("="*60 + "\n")
f.write("RUNOOB 图片分析报告\n")
f.write("="*60 + "\n\n")
f.write(f"图片:{report['image_file']}\n")
f.write(f"时间:{report['analysis_time']}\n")
f.write(f"分类:{report['category']}\n\n")
f.write("-"*60 + "\n")
f.write("图片描述:\n")
f.write("-"*60 + "\n")
f.write(report["description"] + "\n\n")
f.write("-"*60 + "\n")
f.write("提取文字:\n")
f.write("-"*60 + "\n")
f.write(report["extracted_text"] + "\n\n")
if report["special_analysis"]:
f.write("-"*60 + "\n")
f.write("专项分析:\n")
f.write("-"*60 + "\n")
f.write(report["special_analysis"] + "\n")
print(f"分析完成!报告已保存到:{output_dir}")
return report
# ============================================
# 使用示例
# ============================================
def main():
# 配置你的 API Key
api_key = "sk-your-api-key-here"
# 创建分析器
analyzer = RunoobImageAnalyzer(api_key)
# 要分析的图片路径
image_path = "runoob_test_image.jpg"
if not os.path.exists(image_path):
print(f"请先准备图片:{image_path}")
return
# 方式 1:单独使用某个功能
print("\n方式 1:单独使用 OCR 功能")
print("-"*40)
text = analyzer.extract_text(image_path)
if text:
print("提取的文字:")
print(text)
# 方式 2:完整分析
print("\n方式 2:完整分析")
print("-"*40)
report = analyzer.full_analysis(image_path)
print(f"分类结果:{report['category']}")
print(f"报告已保存")
if __name__ == "__main__":
main()
这个工具封装了常用的图片分析功能,可以直接在项目中使用。
你可以根据需求扩展:
添加更多分析场景(比如医学影像、工业检测、教育题目分析)
-
加一个简单的 Web 界面(用 Flask 或 Gradio)
-
支持批量处理文件夹里的图片
-
把结果存入数据库
