当前位置: 首页 > news >正文

基于EmbeddingGemma-300m的语义搜索系统开发实战

基于EmbeddingGemma-300m的语义搜索系统开发实战

1. 引言

想象一下,你正在开发一个电商平台,用户输入"适合夏天穿的轻薄透气运动鞋",传统的关键词搜索可能只能匹配到包含这些词汇的商品,但无法理解"轻薄透气"的实际含义。而语义搜索却能理解用户的真实意图,找到那些材质透气、设计轻便的运动鞋,即使用户的查询语句和商品描述用词完全不同。

这就是语义搜索的魅力所在。今天我们要介绍的EmbeddingGemma-300m,是Google推出的轻量级嵌入模型,虽然只有3亿参数,但在语义理解方面的表现却相当出色。更重要的是,它足够轻量,可以在普通笔记本电脑上流畅运行,让中小团队也能轻松构建高质量的语义搜索系统。

本文将手把手带你搭建一个完整的语义搜索系统,从数据准备到查询处理,再到结果优化,每个环节都会提供可运行的代码示例。无论你是想要改进现有搜索功能,还是从零开始构建智能搜索,这篇文章都能给你实用的指导。

2. 环境准备与模型部署

2.1 安装必要依赖

首先确保你的Python环境是3.8或更高版本,然后安装所需的包:

pip install ollama numpy pandas sentence-transformers scikit-learn

2.2 部署EmbeddingGemma模型

EmbeddingGemma通过Ollama来部署非常简单:

# 拉取模型 ollama pull embeddinggemma:300m # 验证模型是否可用 ollama list

如果看到embeddinggemma:300m在列表中,说明模型已经准备就绪。

2.3 基础嵌入生成测试

让我们先测试一下模型的基本功能:

import ollama # 生成文本嵌入 response = ollama.embed( model='embeddinggemma:300m', input='为什么天空是蓝色的?' ) print(f'嵌入向量维度: {len(response.embeddings)}') print(f'前10个维度值: {response.embeddings[:10]}')

这段代码会输出一个768维的向量,这就是模型对输入文本的数学表示。语义搜索的核心就是比较这些向量的相似度。

3. 构建语义搜索系统

3.1 数据准备与预处理

假设我们有一个商品数据集,包含商品标题和描述:

import pandas as pd # 示例商品数据 products = [ {"id": 1, "title": "夏季透气运动鞋", "description": "网面设计,轻盈透气,适合跑步和日常穿着"}, {"id": 2, "title": "冬季保暖登山靴", "description": "加厚内衬,防滑鞋底,适合户外登山活动"}, {"id": 3, "title": "休闲帆布鞋", "description": "经典款式,舒适百搭,适合日常休闲场合"}, {"id": 4, "title": "专业篮球鞋", "description": "高帮设计,缓震科技,适合篮球运动"}, {"id": 5, "title": "轻便健步鞋", "description": "超轻材质,弹性鞋底,适合中老年人健步走"} ] df = pd.DataFrame(products)

3.2 批量生成嵌入向量

为了提高效率,我们可以批量处理文本生成嵌入:

def generate_embeddings_batch(texts, batch_size=32): """批量生成文本嵌入""" all_embeddings = [] for i in range(0, len(texts), batch_size): batch_texts = texts[i:i+batch_size] try: response = ollama.embed( model='embeddinggemma:300m', input=batch_texts ) all_embeddings.extend(response.embeddings) except Exception as e: print(f"处理批次 {i//batch_size + 1} 时出错: {e}") # 如果批量失败,尝试逐个处理 for text in batch_texts: try: response = ollama.embed( model='embeddinggemma:300m', input=text ) all_embeddings.append(response.embeddings[0]) except Exception as e2: print(f"处理文本失败: {text[:50]}...") all_embeddings.append([0]*768) # 填充零向量 return all_embeddings # 为所有商品生成嵌入 product_texts = [f"{row['title']} {row['description']}" for _, row in df.iterrows()] df['embedding'] = generate_embeddings_batch(product_texts) print("嵌入生成完成,前3个商品的嵌入维度:", [len(emb) for emb in df['embedding'][:3]])

3.3 构建向量索引

为了快速搜索,我们需要构建一个向量索引:

import numpy as np from sklearn.metrics.pairwise import cosine_similarity class VectorIndex: def __init__(self): self.vectors = [] self.metadata = [] def add_item(self, vector, metadata): self.vectors.append(vector) self.metadata.append(metadata) def search(self, query_vector, top_k=5): """搜索最相似的项目""" if not self.vectors: return [] # 计算余弦相似度 similarities = cosine_similarity([query_vector], self.vectors)[0] # 获取最相似的项目 indices = np.argsort(similarities)[::-1][:top_k] results = [] for idx in indices: results.append({ 'metadata': self.metadata[idx], 'similarity': float(similarities[idx]) }) return results # 构建索引 index = VectorIndex() for _, row in df.iterrows(): index.add_item(row['embedding'], { 'id': row['id'], 'title': row['title'], 'description': row['description'] })

4. 实现搜索功能

4.1 基本搜索实现

现在让我们实现完整的搜索流程:

def semantic_search(query, top_k=5): """语义搜索函数""" # 生成查询嵌入 try: response = ollama.embed( model='embeddinggemma:300m', input=query ) query_embedding = response.embeddings[0] except Exception as e: print(f"生成查询嵌入失败: {e}") return [] # 执行搜索 results = index.search(query_embedding, top_k) return results # 测试搜索 test_query = "想要一双透气轻便的运动鞋" results = semantic_search(test_query) print(f"查询: '{test_query}'") print("搜索结果:") for i, result in enumerate(results): print(f"{i+1}. {result['metadata']['title']} (相似度: {result['similarity']:.3f})") print(f" 描述: {result['metadata']['description']}")

4.2 高级搜索功能

为了提升搜索体验,我们可以添加一些高级功能:

def advanced_semantic_search(query, filters=None, min_similarity=0.3, top_k=10): """带过滤的高级语义搜索""" if filters is None: filters = {} # 生成查询嵌入 try: response = ollama.embed( model='embeddinggemma:300m', input=query ) query_embedding = response.embeddings[0] except Exception as e: print(f"生成查询嵌入失败: {e}") return [] # 执行搜索 raw_results = index.search(query_embedding, top_k * 2) # 获取更多结果用于过滤 # 应用过滤器 filtered_results = [] for result in raw_results: if result['similarity'] < min_similarity: continue # 这里可以添加更多过滤逻辑 # 例如按类别、价格范围等过滤 filtered_results.append(result) if len(filtered_results) >= top_k: break return filtered_results[:top_k]

5. 性能优化与实践建议

5.1 批量处理优化

对于大量数据,批量处理可以显著提升效率:

def optimize_batch_processing(texts, optimal_batch_size=16): """优化批量处理参数""" # EmbeddingGemma-300m在批量大小为16时通常表现最佳 embeddings = [] for i in range(0, len(texts), optimal_batch_size): batch = texts[i:i+optimal_batch_size] try: response = ollama.embed( model='embeddinggemma:300m', input=batch ) embeddings.extend(response.embeddings) except Exception as e: print(f"批量处理失败,尝试减小批量大小: {e}") # 失败时尝试单个处理 for text in batch: try: response = ollama.embed( model='embeddinggemma:300m', input=text ) embeddings.append(response.embeddings[0]) except Exception as e2: print(f"处理单个文本失败: {text[:50]}...") embeddings.append([0]*768) return embeddings

5.2 缓存机制

实现简单的缓存来避免重复计算:

import hashlib import json from functools import lru_cache class EmbeddingCache: def __init__(self, max_size=1000): self.cache = {} self.max_size = max_size def get_key(self, text): """生成缓存键""" return hashlib.md5(text.encode()).hexdigest() def get(self, text): """获取缓存值""" key = self.get_key(text) return self.cache.get(key) def set(self, text, embedding): """设置缓存值""" if len(self.cache) >= self.max_size: # 简单的LRU策略:移除最早的一个项目 self.cache.pop(next(iter(self.cache))) key = self.get_key(text) self.cache[key] = embedding # 使用缓存的搜索函数 cache = EmbeddingCache() def cached_semantic_search(query, top_k=5): """带缓存的语义搜索""" # 检查查询缓存 cached_embedding = cache.get(query) if cached_embedding is not None: print("使用缓存嵌入") query_embedding = cached_embedding else: # 生成新嵌入 try: response = ollama.embed( model='embeddinggemma:300m', input=query ) query_embedding = response.embeddings[0] cache.set(query, query_embedding) # 缓存结果 except Exception as e: print(f"生成查询嵌入失败: {e}") return [] return index.search(query_embedding, top_k)

5.3 实时索引更新

对于需要频繁更新的场景:

class DynamicVectorIndex(VectorIndex): def __init__(self, update_threshold=100): super().__init__() self.update_counter = 0 self.update_threshold = update_threshold self.vector_matrix = None def add_item(self, vector, metadata): super().add_item(vector, metadata) self.update_counter += 1 # 定期优化索引结构 if self.update_counter % self.update_threshold == 0: self.optimize_index() def optimize_index(self): """优化索引性能""" if self.vectors: self.vector_matrix = np.array(self.vectors) def search(self, query_vector, top_k=5): """重写搜索方法以提高性能""" if not self.vectors: return [] if self.vector_matrix is None: self.optimize_index() # 使用矩阵运算提高计算效率 query_vector = np.array(query_vector).reshape(1, -1) similarities = cosine_similarity(query_vector, self.vector_matrix)[0] indices = np.argsort(similarities)[::-1][:top_k] results = [] for idx in indices: results.append({ 'metadata': self.metadata[idx], 'similarity': float(similarities[idx]) }) return results

6. 实际应用场景

6.1 电商商品搜索

# 模拟电商搜索场景 def ecommerce_search_example(): queries = [ "适合跑步的轻便鞋子", "冬季户外防滑靴子", "日常休闲穿的舒适鞋", "打篮球用的专业运动鞋" ] for query in queries: print(f"\n 搜索: {query}") results = semantic_search(query, top_k=3) for i, result in enumerate(results): print(f" {i+1}. {result['metadata']['title']} " f"(相似度: {result['similarity']:.3f})") print("-" * 50) # 运行示例 ecommerce_search_example()

6.2 内容检索系统

# 构建内容检索系统 class ContentRetrievalSystem: def __init__(self): self.index = DynamicVectorIndex() self.content_map = {} def add_content(self, content_id, text, metadata=None): """添加内容到检索系统""" if metadata is None: metadata = {} # 生成嵌入 response = ollama.embed( model='embeddinggemma:300m', input=text ) embedding = response.embeddings[0] # 存储到索引 self.index.add_item(embedding, { 'content_id': content_id, 'text': text, **metadata }) self.content_map[content_id] = { 'text': text, 'metadata': metadata } def search_content(self, query, top_k=5): """搜索相关内容""" results = semantic_search(query, top_k) return results def get_related_content(self, content_id, top_k=3): """获取相关内容""" if content_id not in self.content_map: return [] # 使用自身内容作为查询 text = self.content_map[content_id]['text'] return self.search_content(text, top_k)

7. 总结

通过本文的实践,我们完整地构建了一个基于EmbeddingGemma-300m的语义搜索系统。从环境部署、数据预处理,到索引构建和搜索实现,每个环节都提供了可运行的代码示例。

EmbeddingGemma-300m虽然参数量不大,但在语义理解任务上的表现令人印象深刻。它的轻量级特性使得即使在资源有限的环境下也能流畅运行,这为中小型项目提供了很好的选择。在实际使用中,批量处理、缓存机制和索引优化这些技巧能显著提升系统性能。

语义搜索的真正价值在于它能理解用户的意图,而不仅仅是匹配关键词。这种能力在电商、内容平台、知识库等各种场景中都能大幅提升用户体验。不过也要注意,嵌入模型的效果很大程度上取决于训练数据和具体任务场景,在实际应用中可能需要进行适当的微调或参数优化。

建议先从简单的场景开始尝试,逐步优化和扩展功能。随着对模型特性的深入了解,你可以探索更多高级应用,比如多模态搜索、个性化推荐等方向。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

http://www.jsqmd.com/news/389551/

相关文章:

  • Janus-Pro-7B论文精读:解读统一多模态架构设计思想
  • 人工智能应用- 推荐算法:01. 什么是推荐算法
  • 实测才敢推 10个降AIGC软件测评:MBA降AI率必备工具推荐
  • 人工智能应用- 推荐算法:02.推荐算法的基本思想
  • translategemma-27b-it图文教程:Ollama安装与多语言翻译实战
  • 这次终于选对!10个AI论文平台测评:研究生毕业论文与科研写作必备工具推荐
  • ERNIE-4.5-0.3B-PT持续学习方案:灾难性遗忘应对策略
  • 2026必备!10个AI论文网站深度测评,自考毕业论文写作与格式规范全攻略
  • 2026年老工厂车间升级改造浙江标准化工厂布局/标准化工厂布局用户认可推荐企业 - 行业平台推荐
  • 互联网大厂Java面试实录:智慧城市场景下的核心技术与AI应用
  • 2026年比较好的洗衣机柜一体盆/异形洗衣机柜定制源头直供参考哪家便宜 - 行业平台推荐
  • 2026年口碑好的西安一体盆洗衣柜/整体阳台洗衣柜销售厂家推荐哪家好(真实参考) - 行业平台推荐
  • 2026年口碑好的防晒洗衣柜/西安洗衣柜畅销厂家采购指南如何选 - 行业平台推荐
  • 真的太省时间!继续教育专属的一键生成工具 —— 千笔写作工具
  • 2026年口碑好的石英石台面橱柜/厨房橱柜定做生产商实力参考哪家质量好(更新) - 行业平台推荐
  • DeepSeek写论文AI率99%怎么急救?3步降到安全线(实测有图)
  • 别再瞎找了!8个降AI率软件降AIGC网站:继续教育必备测评与推荐
  • 基于SpringBoot+协同过滤推荐算法+智能AI推荐的影院票务管理平台开题报告
  • 2026年评价高的双联齿轮滚齿机/行星齿轮滚齿机哪家强生产厂家实力参考 - 行业平台推荐
  • 写作小白救星!千笔AI,深得人心的降AIGC工具
  • 2026降AI工具第一梯队盘点:哪些值得花钱?哪些在割韭菜?
  • LeetCode401:二进制手表
  • ChatGPT、Claude、Gemini三大AI写的论文怎么降AI?一篇搞定所有主流模型
  • 科研党收藏!AI论文软件 千笔 VS 灵感ai,MBA写论文神器!
  • Qwen3-Embedding-4B实操教程:知识库语义聚类+自动标签生成工作流
  • 2026年靠谱的化工废水处理设备/电镀废水处理设备制造厂家选购指南怎么选(精选) - 行业平台推荐
  • 干货合集:10个AI论文网站测评!本科生毕业论文写作必备工具推荐
  • 知网AIGC检测3.0算法深度拆解:它到底怎么判定你是AI写的?
  • 5步搞定GTE文本向量部署:中文NLP开发必备
  • 2026年比较好的重庆特产独立小包装零食/重庆特产怪味胡豆老字号推荐公司 - 行业平台推荐