谷歌首個nana-banana多模態RAG實戰:徹底告別關鍵詞搜索,讓AI為電商游戲提效 原創 精華
最新的AI生圖模型已經能做到驚人的效果。給它一句話,它就能生成逼真的圖片。告訴它想怎么改,它就能精準編輯細節。速度還快得離譜。
但對企業來說,光有個生圖模型還不夠。
我之前碰到一個公司,他們想讓用戶上傳照片后,從素材庫選配飾和道具進行換裝。另一家電商平臺想給模特換裝、換發型、換配飾,實現一次拍攝,反復使用。
問題來了:這些公司都有海量的歷史素材。服裝、配飾、道具、背景,全是圖片文件。怎么快速找到想要的素材?傳統搜索根本不行。
他們真正需要的,是一套能理解圖片內容的智能檢索系統。輸入文字描述,就能找到對應的圖片素材。再配合AI生圖模型,才能實現真正的生產級應用。
這就是多模態RAG系統的價值所在。
企業生圖的真正痛點
快消品公司每年積累數萬張產品圖。游戲公司的素材庫里躺著幾十萬個道具模型。這些非結構化數據就像一座金山,卻無法高效利用。
傳統的文件名搜索?太原始了。手動打標簽?人力成本高得嚇人,還容易出錯。
現實中,設計師要找一個"金色復古懷表"的素材,可能要翻幾十個文件夾。產品經理想找"穿西裝的男模特"照片,得靠記憶和運氣。
更糟糕的是,即使找到了合適的素材,怎么和AI生圖模型無縫對接?怎么確保生成的圖片風格統一?怎么批量處理上千個SKU的產品圖?
這些問題,單靠一個AI模型解決不了。你需要一套完整的系統。
技術方案:向量化
解決方案其實不復雜。
核心是把圖片和文字都轉換成向量。同一個概念的圖片和文字,轉換后的向量很相似。比如"金色手表"這段文字的向量,和一張金表圖片的向量,在向量空間里距離很近。
向量化方案選擇
你有三種選擇,各有優劣:
方案一:CLIP本地部署(免費但需要GPU)
import clip
model, preprocess = clip.load("ViT-B/32") # 512維向量
# 或者用更強的模型
model, preprocess = clip.load("ViT-L/14") # 768維向量
方案二:OpenAI API(效果最好但按次收費)
from openai import OpenAI
client = OpenAI(api_key="your-key")
response = client.embeddings.create(
model="text-embedding-3-large",
input="金色手表"
)
方案三:國內大廠API(穩定且中文優化好)
# 阿里云 DashScope
from dashscope import MultiModalEmbedding
response = MultiModalEmbedding.call(
model='multimodal-embedding-one-peace-v1',
input=[{"image": "watch.jpg"}]
)
Milvus向量數據庫
不管用哪種向量化方案,存儲和檢索都用Milvus。它能在毫秒內從百萬個向量中找出最相似的。
工作流程:
- 把所有歷史圖片轉成向量,存到Milvus
- 用戶輸入文字描述時,同樣轉成向量
- Milvus找出最相似的圖片向量
- 返回對應的原始圖片
實戰:搭建以文搜圖系統
三種實現方式,你選一個合適的。
方式一:CLIP本地部署
環境準備
pip install pymilvus pillow matplotlib
pip install git+https://github.com/openai/CLIP.git
完整代碼
import clip
import torch
from PIL import Image
from pymilvus import MilvusClient
from glob import glob
# 初始化
client = MilvusClient(uri="http://localhost:19530")
device = "cuda"if torch.cuda.is_available() else"cpu"
model, preprocess = clip.load("ViT-B/32", device=device)
# 創建集合
collection_name = "product_images"
if client.has_collection(collection_name):
client.drop_collection(collection_name)
client.create_collection(
collection_name=collection_name,
dimension=512,
metric_type="COSINE"
)
# 圖片向量化
def encode_image(image_path):
image = preprocess(Image.open(image_path)).unsqueeze(0).to(device)
with torch.no_grad():
features = model.encode_image(image)
features /= features.norm(dim=-1, keepdim=True)
return features.squeeze().cpu().tolist()
# 批量處理
image_paths = glob("./images/*.jpg")
data = []
for path in image_paths:
vector = encode_image(path)
data.append({"vector": vector, "filepath": path})
client.insert(collection_name=collection_name, data=data)
# 搜索功能
def search_by_text(query, top_k=3):
text = clip.tokenize([query]).to(device)
with torch.no_grad():
text_features = model.encode_text(text)
text_features /= text_features.norm(dim=-1, keepdim=True)
results = client.search(
collection_name=collection_name,
data=[text_features.squeeze().cpu().tolist()],
limit=top_k,
output_fields=["filepath"]
)
return results[0]
方式二:OpenAI API
from openai import OpenAI
from pymilvus import MilvusClient
import base64
# 初始化
openai_client = OpenAI(api_key="your-key")
milvus_client = MilvusClient(uri="http://localhost:19530")
# 創建集合(注意維度不同)
collection_name = "product_images_openai"
milvus_client.create_collection(
collection_name=collection_name,
dimension=1536, # OpenAI的維度
metric_type="COSINE"
)
def encode_text_openai(text):
"""文本向量化"""
response = openai_client.embeddings.create(
model="text-embedding-3-large",
input=text,
dimensions=1536
)
return response.data[0].embedding
def encode_image_openai(image_path):
"""圖片先描述再向量化"""
with open(image_path, "rb") as f:
base64_image = base64.b64encode(f.read()).decode('utf-8')
# GPT-4V描述圖片
response = openai_client.chat.completions.create(
model="gpt-4-vision-preview",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image concisely"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}
]
}]
)
description = response.choices[0].message.content
return encode_text_openai(description)
# 批量處理(注意成本)
from glob import glob
image_paths = glob("./images/*.jpg")[:100] # 先處理100張試試
data = []
for path in image_paths:
print(f"Processing {path}...")
vector = encode_image_openai(path)
data.append({"vector": vector, "filepath": path})
milvus_client.insert(collection_name=collection_name, data=data)
方式三:混合方案
class HybridEmbedding:
"""智能選擇最合適的向量化方案"""
def __init__(self):
# CLIP用于批量處理
self.clip_model, self.preprocess = clip.load("ViT-B/32")
# OpenAI用于高質量需求
self.openai_client = OpenAI(api_key="your-key")
# Milvus連接
self.milvus = MilvusClient(uri="http://localhost:19530")
# 統一到1536維(通過填充或截斷)
self.dimension = 1536
def encode(self, content, mode="fast"):
"""根據模式選擇編碼方式"""
if mode == "fast":
# 用CLIP,成本低
if isinstance(content, str):
tokens = clip.tokenize([content])
features = self.clip_model.encode_text(tokens)
else: # 圖片路徑
image = self.preprocess(Image.open(content)).unsqueeze(0)
features = self.clip_model.encode_image(image)
# 歸一化并填充到1536維
features = features.squeeze().cpu().numpy()
features = features / np.linalg.norm(features)
padded = np.zeros(self.dimension)
padded[:len(features)] = features
return padded.tolist()
elif mode == "quality":
# 用OpenAI,效果好
response = self.openai_client.embeddings.create(
model="text-embedding-3-large",
input=content,
dimensions=self.dimension
)
return response.data[0].embedding
def smart_batch_process(self, items, budget=100):
"""智能批處理,控制成本"""
results = []
for i, item in enumerate(items):
if i < budget:
# 前100個用高質量
vector = self.encode(item, mode="quality")
else:
# 剩下的用快速模式
vector = self.encode(item, mode="fast")
results.append(vector)
return results
集成AI生圖模型實現自動化
找到素材只是第一步。接下來要把它和AI生圖模型打通。
這里用Gemini的圖像生成API做示范。你也可以換成Stable Diffusion、Midjourney或任何其他模型。
import google.generativeai as genai
from PIL import Image
# 配置API
genai.configure(api_key="your_api_key")
model = genai.GenerativeModel('gemini-2.0-flash-exp')
def generate_product_image(text_query, style_reference):
"""
先搜索相似素材,再生成新圖
"""
# 步驟1:從數據庫找參考圖
similar_images = search_by_text(text_query, top_k=1)
reference_path = similar_images[0]['entity']['filepath']
# 步驟2:加載參考圖
ref_image = Image.open(reference_path)
# 步驟3:生成新圖
prompt = f"{text_query}. Style should match the reference image."
response = model.generate_content([prompt, ref_image])
# 步驟4:保存結果
for part in response.candidates[0].content.parts:
if part.inline_data:
new_image = Image.open(BytesIO(part.inline_data.data))
new_image.save(f"generated_{text_query.replace(' ', '_')}.png")
return new_image
# 實際使用
generate_product_image(
"European male model wearing suit with gold watch",
style_reference="luxury_fashion"
)
這套流程的妙處在于:
- 自動匹配風格:從歷史素材找參考,保證視覺一致性
- 批量處理:寫個循環,一晚上能生成上千張產品圖
- 精準控制:通過調整prompt和參考圖,精確控制輸出效果
實際應用場景和效果展示
電商換裝場景
一家服裝品牌,原本每個季度要拍攝500套新品。現在只需拍攝50套基礎款,剩下的全靠AI生成。
# 批量換裝示例
base_models = ["model_001.jpg", "model_002.jpg"]
clothing_items = search_by_text("summer dress collection", top_k=50)
for model in base_models:
for item in clothing_items:
generate_outfit_combination(model, item)
游戲道具定制
某款卡牌游戲,玩家可以自定義角色裝備。系統從10萬個道具素材中實時檢索,然后生成獨一無二的角色形象。
玩家描述:"戴著火焰皇冠的精靈弓箭手" 系統操作:
- 檢索"火焰皇冠"素材
- 檢索"精靈弓箭手"基礎形象
- AI融合生成最終角色
產品展示自動化
一個3C品牌,新品發布需要大量場景圖。以前要搭建實景、請攝影師。現在:
products = ["smartphone_x1.jpg", "earbuds_pro.jpg", "smartwatch_v2.jpg"]
scenes = ["modern office", "outdoor adventure", "home living room"]
for product in products:
for scene in scenes:
prompt = f"Place {product} in {scene} setting"
generate_scene_image(prompt, product)
一天生成1000張場景圖。每張成本不到1元。
總結
向量化技術還在快速進化。Google的Gemini已經原生支持多模態。Meta的ImageBind能處理6種模態。但不管技術怎么變,核心邏輯不變:把非結構化數據變成向量,用向量相似度做檢索。
本文轉載自??AI 博物院?? 作者:longyunfeigu
