BGE-Reranker-v2-m3缓存策略Redis加速重复查询教程1. 为什么需要缓存加速在实际的RAG系统应用中用户经常会提出相同或相似的查询请求。每次都对相同的查询-文档对进行重新计算不仅浪费计算资源还会增加响应延迟。特别是对于BGE-Reranker-v2-m3这样的深度模型虽然精度很高但推理速度相对较慢。通过引入Redis缓存我们可以将已经计算过的查询-文档对得分结果存储起来当相同的查询再次出现时直接从缓存中获取结果大幅提升系统响应速度。实测表明使用缓存后重复查询的响应时间可以从几百毫秒降低到几毫秒。2. 环境准备与Redis部署2.1 安装Redis服务首先需要在系统中安装Redis服务器# Ubuntu/Debian系统 sudo apt update sudo apt install redis-server # CentOS/RHEL系统 sudo yum install epel-release sudo yum install redis # 启动Redis服务 sudo systemctl start redis sudo systemctl enable redis2.2 安装Python Redis客户端在Python环境中安装redis-py库pip install redis2.3 验证Redis连接测试Redis服务是否正常运行import redis # 创建Redis连接 r redis.Redis(hostlocalhost, port6379, db0) # 测试连接 try: response r.ping() print(Redis连接成功) except redis.ConnectionError: print(无法连接到Redis服务器)3. 实现缓存装饰器我们可以创建一个通用的缓存装饰器方便地为任何函数添加缓存功能import redis import json import hashlib import functools class RedisCache: def __init__(self, hostlocalhost, port6379, db0, expire_time3600): self.redis_client redis.Redis(hosthost, portport, dbdb) self.expire_time expire_time # 缓存过期时间秒 def generate_key(self, func_name, *args, **kwargs): 生成唯一的缓存键 key_parts [func_name] # 处理位置参数 for arg in args: if isinstance(arg, (str, int, float, bool)): key_parts.append(str(arg)) else: # 对于复杂对象使用JSON序列化 key_parts.append(json.dumps(arg, sort_keysTrue)) # 处理关键字参数 for k, v in sorted(kwargs.items()): key_parts.append(f{k}:{json.dumps(v, sort_keysTrue)}) # 使用SHA256生成固定长度的键 key_string :.join(key_parts) return hashlib.sha256(key_string.encode()).hexdigest() def __call__(self, func): functools.wraps(func) def wrapper(*args, **kwargs): # 生成缓存键 cache_key self.generate_key(func.__name__, *args, **kwargs) # 尝试从缓存获取结果 cached_result self.redis_client.get(cache_key) if cached_result is not None: print(f缓存命中: {cache_key}) return json.loads(cached_result) # 缓存未命中执行原函数 print(f缓存未命中执行计算: {cache_key}) result func(*args, **kwargs) # 将结果存入缓存 self.redis_client.setex(cache_key, self.expire_time, json.dumps(result)) return result return wrapper # 创建全局缓存实例 reranker_cache RedisCache(expire_time86400) # 24小时过期4. 集成BGE-Reranker缓存功能现在我们将缓存功能集成到BGE-Reranker的推理过程中from FlagEmbedding import FlagReranker import numpy as np # 初始化reranker模型 reranker FlagReranker(BAAI/bge-reranker-v2-m3, use_fp16True) reranker_cache def cached_rerank_score(query, document): 带缓存的reranker打分函数 return reranker.compute_score([query, document]) reranker_cache def cached_batch_rerank(query, documents): 带缓存的批量reranker打分函数 pairs [[query, doc] for doc in documents] return reranker.compute_score(pairs) def get_rerank_scores_with_cache(query, documents, batch_size32): 智能批量处理函数自动处理大批量文档 all_scores [] for i in range(0, len(documents), batch_size): batch_docs documents[i:ibatch_size] # 检查缓存中已有的结果 cached_scores [] need_compute_docs [] need_compute_indices [] for j, doc in enumerate(batch_docs): cache_key reranker_cache.generate_key(cached_rerank_score, query, doc) cached_result reranker_cache.redis_client.get(cache_key) if cached_result is not None: cached_scores.append(json.loads(cached_result)) else: need_compute_docs.append(doc) need_compute_indices.append(j) # 计算需要重新计算的部分 if need_compute_docs: new_scores reranker.compute_score([[query, doc] for doc in need_compute_docs]) # 缓存新计算的结果 for idx, doc, score in zip(need_compute_indices, need_compute_docs, new_scores): cache_key reranker_cache.generate_key(cached_rerank_score, query, doc) reranker_cache.redis_client.setex( cache_key, reranker_cache.expire_time, json.dumps(float(score)) ) # 合并结果 batch_results [0] * len(batch_docs) for idx, score in zip(need_compute_indices, new_scores): batch_results[idx] float(score) for j in range(len(batch_docs)): if j not in need_compute_indices: cache_key reranker_cache.generate_key(cached_rerank_score, query, batch_docs[j]) cached_result reranker_cache.redis_client.get(cache_key) batch_results[j] json.loads(cached_result) all_scores.extend(batch_results) return all_scores5. 完整的使用示例下面是一个完整的示例展示如何使用带缓存的rerankerimport time # 示例文档库 documents [ 机器学习是人工智能的一个分支专注于开发能够从数据中学习的算法, 深度学习是机器学习的一个子领域使用多层神经网络处理复杂模式识别任务, 自然语言处理是人工智能领域专注于让计算机理解、解释和生成人类语言, 计算机视觉使计算机能够从图像和视频中提取信息并做出决策, 强化学习是一种机器学习方法智能体通过与环境交互学习最优行为策略 ] # 测试查询 queries [ 什么是机器学习, 深度学习与机器学习的关系, 什么是机器学习, # 重复查询应该命中缓存 自然语言处理的应用领域 ] def benchmark_performance(): print(性能测试开始...) print( * 50) for i, query in enumerate(queries): start_time time.time() # 使用带缓存的reranker scores get_rerank_scores_with_cache(query, documents) # 排序文档 scored_docs list(zip(documents, scores)) scored_docs.sort(keylambda x: x[1], reverseTrue) end_time time.time() response_time (end_time - start_time) * 1000 # 毫秒 print(f查询 {i1}: {query}) print(f响应时间: {response_time:.2f}ms) print(Top 3 结果:) for j, (doc, score) in enumerate(scored_docs[:3]): print(f {j1}. [得分: {score:.4f}] {doc[:60]}...) print(- * 50) if __name__ __main__: # 预热缓存第一次查询 print(预热缓存...) get_rerank_scores_with_cache(queries[0], documents) # 运行性能测试 benchmark_performance() # 显示缓存统计 cache_info reranker_cache.redis_client.info(memory) print(fRedis内存使用: {cache_info[used_memory_human]})6. 高级缓存策略6.1 基于相似度的缓存对于相似的查询我们可以使用语义相似度来扩展缓存命中率from sentence_transformers import SentenceTransformer import numpy as np # 初始化句子编码模型 embedding_model SentenceTransformer(all-MiniLM-L6-v2) def find_similar_cached_query(query, threshold0.8): 查找语义相似的缓存查询 # 获取所有缓存键 cache_keys reranker_cache.redis_client.keys(*) query_embedding embedding_model.encode([query])[0] similar_queries [] for key in cache_keys: if key.decode().startswith(cached_rerank_score): # 从缓存键中提取原始查询需要调整键生成逻辑 # 这里简化处理实际需要更复杂的键解析逻辑 pass return similar_queries def semantic_cache_rerank(query, documents): 基于语义相似度的缓存查询 # 首先尝试精确匹配 exact_key reranker_cache.generate_key(cached_rerank_score, query, documents[0]) if reranker_cache.redis_client.get(exact_key): return get_rerank_scores_with_cache(query, documents) # 查找相似查询 similar_queries find_similar_cached_query(query) if similar_queries: # 使用最相似查询的缓存结果 most_similar similar_queries[0] # 这里可以根据业务需求调整策略 pass # 没有相似缓存正常计算 return get_rerank_scores_with_cache(query, documents)6.2 缓存清理与维护def manage_reranker_cache(): 缓存管理函数 # 获取所有reranker相关的缓存键 reranker_keys [] for key in reranker_cache.redis_client.scan_iter(*cached_rerank_score*): reranker_keys.append(key) print(f当前缓存数量: {len(reranker_keys)}) # 清理过期缓存Redis自动处理 # 手动清理特定模式的缓存 def clear_pattern(pattern): keys list(reranker_cache.redis_client.scan_iter(pattern)) if keys: reranker_cache.redis_client.delete(*keys) print(f已清理 {len(keys)} 个匹配 {pattern} 的缓存) return len(reranker_keys) # 定期清理缓存 import schedule import time def job(): print(执行缓存清理任务...) manage_reranker_cache() # 每天凌晨执行清理 schedule.every().day.at(03:00).do(job) # 在后台线程运行调度器 def run_scheduler(): while True: schedule.run_pending() time.sleep(60) # 启动调度器线程 import threading scheduler_thread threading.Thread(targetrun_scheduler, daemonTrue) scheduler_thread.start()7. 实际应用建议7.1 缓存键设计优化为了提高缓存效率可以优化缓存键的生成策略def optimized_cache_key(query, document): 优化的缓存键生成函数 # 对长文本进行摘要处理 def summarize_text(text, max_words50): words text.split() if len(words) max_words: return text return .join(words[:max_words]) ... # 使用摘要后的文本生成键 summarized_query summarize_text(query) summarized_doc summarize_text(document) return reranker_cache.generate_key( cached_rerank_score, summarized_query, summarized_doc )7.2 分布式缓存部署对于生产环境建议使用Redis集群from redis.cluster import RedisCluster class DistributedRedisCache(RedisCache): def __init__(self, startup_nodes, expire_time3600): self.redis_client RedisCluster( startup_nodesstartup_nodes, decode_responsesFalse ) self.expire_time expire_time # 配置Redis集群节点 startup_nodes [ {host: redis-node1, port: 6379}, {host: redis-node2, port: 6379}, {host: redis-node3, port: 6379} ] distributed_cache DistributedRedisCache(startup_nodes)7.3 监控与告警实现缓存系统的监控def monitor_cache_performance(): 监控缓存性能 info reranker_cache.redis_client.info() metrics { hit_rate: calculate_hit_rate(), memory_usage: info[used_memory_human], key_count: info[db0][keys] if db0 in info else 0, evicted_keys: info[evicted_keys] if evicted_keys in info else 0 } # 检查是否需要告警 if metrics[hit_rate] 0.6: # 命中率低于60% send_alert(f缓存命中率过低: {metrics[hit_rate]:.2%}) if metrics[memory_usage] 1GB: # 内存使用超过1GB send_alert(f缓存内存使用过高: {metrics[memory_usage]}) return metrics def calculate_hit_rate(): 计算缓存命中率 # 需要在实际代码中统计命中次数和总请求数 # 这里使用简化实现 return 0.8 # 示例值8. 总结通过为BGE-Reranker-v2-m3实现Redis缓存策略我们显著提升了重复查询的响应速度降低了系统负载。关键要点包括缓存装饰器设计创建通用的Redis缓存装饰器可轻松应用于任何函数智能批量处理实现混合缓存策略同时利用已有缓存和批量计算高级缓存策略支持基于语义相似度的缓存扩展和分布式部署系统监控提供缓存性能监控和自动维护功能在实际部署时建议根据具体业务需求调整缓存过期时间、内存限制和清理策略。对于高并发场景考虑使用Redis集群来提高可用性和扩展性。这种缓存策略不仅适用于BGE-Reranker也可以推广到其他类似的AI模型推理场景中为构建高性能的AI应用提供重要支撑。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
BGE-Reranker-v2-m3缓存策略:Redis加速重复查询教程
BGE-Reranker-v2-m3缓存策略Redis加速重复查询教程1. 为什么需要缓存加速在实际的RAG系统应用中用户经常会提出相同或相似的查询请求。每次都对相同的查询-文档对进行重新计算不仅浪费计算资源还会增加响应延迟。特别是对于BGE-Reranker-v2-m3这样的深度模型虽然精度很高但推理速度相对较慢。通过引入Redis缓存我们可以将已经计算过的查询-文档对得分结果存储起来当相同的查询再次出现时直接从缓存中获取结果大幅提升系统响应速度。实测表明使用缓存后重复查询的响应时间可以从几百毫秒降低到几毫秒。2. 环境准备与Redis部署2.1 安装Redis服务首先需要在系统中安装Redis服务器# Ubuntu/Debian系统 sudo apt update sudo apt install redis-server # CentOS/RHEL系统 sudo yum install epel-release sudo yum install redis # 启动Redis服务 sudo systemctl start redis sudo systemctl enable redis2.2 安装Python Redis客户端在Python环境中安装redis-py库pip install redis2.3 验证Redis连接测试Redis服务是否正常运行import redis # 创建Redis连接 r redis.Redis(hostlocalhost, port6379, db0) # 测试连接 try: response r.ping() print(Redis连接成功) except redis.ConnectionError: print(无法连接到Redis服务器)3. 实现缓存装饰器我们可以创建一个通用的缓存装饰器方便地为任何函数添加缓存功能import redis import json import hashlib import functools class RedisCache: def __init__(self, hostlocalhost, port6379, db0, expire_time3600): self.redis_client redis.Redis(hosthost, portport, dbdb) self.expire_time expire_time # 缓存过期时间秒 def generate_key(self, func_name, *args, **kwargs): 生成唯一的缓存键 key_parts [func_name] # 处理位置参数 for arg in args: if isinstance(arg, (str, int, float, bool)): key_parts.append(str(arg)) else: # 对于复杂对象使用JSON序列化 key_parts.append(json.dumps(arg, sort_keysTrue)) # 处理关键字参数 for k, v in sorted(kwargs.items()): key_parts.append(f{k}:{json.dumps(v, sort_keysTrue)}) # 使用SHA256生成固定长度的键 key_string :.join(key_parts) return hashlib.sha256(key_string.encode()).hexdigest() def __call__(self, func): functools.wraps(func) def wrapper(*args, **kwargs): # 生成缓存键 cache_key self.generate_key(func.__name__, *args, **kwargs) # 尝试从缓存获取结果 cached_result self.redis_client.get(cache_key) if cached_result is not None: print(f缓存命中: {cache_key}) return json.loads(cached_result) # 缓存未命中执行原函数 print(f缓存未命中执行计算: {cache_key}) result func(*args, **kwargs) # 将结果存入缓存 self.redis_client.setex(cache_key, self.expire_time, json.dumps(result)) return result return wrapper # 创建全局缓存实例 reranker_cache RedisCache(expire_time86400) # 24小时过期4. 集成BGE-Reranker缓存功能现在我们将缓存功能集成到BGE-Reranker的推理过程中from FlagEmbedding import FlagReranker import numpy as np # 初始化reranker模型 reranker FlagReranker(BAAI/bge-reranker-v2-m3, use_fp16True) reranker_cache def cached_rerank_score(query, document): 带缓存的reranker打分函数 return reranker.compute_score([query, document]) reranker_cache def cached_batch_rerank(query, documents): 带缓存的批量reranker打分函数 pairs [[query, doc] for doc in documents] return reranker.compute_score(pairs) def get_rerank_scores_with_cache(query, documents, batch_size32): 智能批量处理函数自动处理大批量文档 all_scores [] for i in range(0, len(documents), batch_size): batch_docs documents[i:ibatch_size] # 检查缓存中已有的结果 cached_scores [] need_compute_docs [] need_compute_indices [] for j, doc in enumerate(batch_docs): cache_key reranker_cache.generate_key(cached_rerank_score, query, doc) cached_result reranker_cache.redis_client.get(cache_key) if cached_result is not None: cached_scores.append(json.loads(cached_result)) else: need_compute_docs.append(doc) need_compute_indices.append(j) # 计算需要重新计算的部分 if need_compute_docs: new_scores reranker.compute_score([[query, doc] for doc in need_compute_docs]) # 缓存新计算的结果 for idx, doc, score in zip(need_compute_indices, need_compute_docs, new_scores): cache_key reranker_cache.generate_key(cached_rerank_score, query, doc) reranker_cache.redis_client.setex( cache_key, reranker_cache.expire_time, json.dumps(float(score)) ) # 合并结果 batch_results [0] * len(batch_docs) for idx, score in zip(need_compute_indices, new_scores): batch_results[idx] float(score) for j in range(len(batch_docs)): if j not in need_compute_indices: cache_key reranker_cache.generate_key(cached_rerank_score, query, batch_docs[j]) cached_result reranker_cache.redis_client.get(cache_key) batch_results[j] json.loads(cached_result) all_scores.extend(batch_results) return all_scores5. 完整的使用示例下面是一个完整的示例展示如何使用带缓存的rerankerimport time # 示例文档库 documents [ 机器学习是人工智能的一个分支专注于开发能够从数据中学习的算法, 深度学习是机器学习的一个子领域使用多层神经网络处理复杂模式识别任务, 自然语言处理是人工智能领域专注于让计算机理解、解释和生成人类语言, 计算机视觉使计算机能够从图像和视频中提取信息并做出决策, 强化学习是一种机器学习方法智能体通过与环境交互学习最优行为策略 ] # 测试查询 queries [ 什么是机器学习, 深度学习与机器学习的关系, 什么是机器学习, # 重复查询应该命中缓存 自然语言处理的应用领域 ] def benchmark_performance(): print(性能测试开始...) print( * 50) for i, query in enumerate(queries): start_time time.time() # 使用带缓存的reranker scores get_rerank_scores_with_cache(query, documents) # 排序文档 scored_docs list(zip(documents, scores)) scored_docs.sort(keylambda x: x[1], reverseTrue) end_time time.time() response_time (end_time - start_time) * 1000 # 毫秒 print(f查询 {i1}: {query}) print(f响应时间: {response_time:.2f}ms) print(Top 3 结果:) for j, (doc, score) in enumerate(scored_docs[:3]): print(f {j1}. [得分: {score:.4f}] {doc[:60]}...) print(- * 50) if __name__ __main__: # 预热缓存第一次查询 print(预热缓存...) get_rerank_scores_with_cache(queries[0], documents) # 运行性能测试 benchmark_performance() # 显示缓存统计 cache_info reranker_cache.redis_client.info(memory) print(fRedis内存使用: {cache_info[used_memory_human]})6. 高级缓存策略6.1 基于相似度的缓存对于相似的查询我们可以使用语义相似度来扩展缓存命中率from sentence_transformers import SentenceTransformer import numpy as np # 初始化句子编码模型 embedding_model SentenceTransformer(all-MiniLM-L6-v2) def find_similar_cached_query(query, threshold0.8): 查找语义相似的缓存查询 # 获取所有缓存键 cache_keys reranker_cache.redis_client.keys(*) query_embedding embedding_model.encode([query])[0] similar_queries [] for key in cache_keys: if key.decode().startswith(cached_rerank_score): # 从缓存键中提取原始查询需要调整键生成逻辑 # 这里简化处理实际需要更复杂的键解析逻辑 pass return similar_queries def semantic_cache_rerank(query, documents): 基于语义相似度的缓存查询 # 首先尝试精确匹配 exact_key reranker_cache.generate_key(cached_rerank_score, query, documents[0]) if reranker_cache.redis_client.get(exact_key): return get_rerank_scores_with_cache(query, documents) # 查找相似查询 similar_queries find_similar_cached_query(query) if similar_queries: # 使用最相似查询的缓存结果 most_similar similar_queries[0] # 这里可以根据业务需求调整策略 pass # 没有相似缓存正常计算 return get_rerank_scores_with_cache(query, documents)6.2 缓存清理与维护def manage_reranker_cache(): 缓存管理函数 # 获取所有reranker相关的缓存键 reranker_keys [] for key in reranker_cache.redis_client.scan_iter(*cached_rerank_score*): reranker_keys.append(key) print(f当前缓存数量: {len(reranker_keys)}) # 清理过期缓存Redis自动处理 # 手动清理特定模式的缓存 def clear_pattern(pattern): keys list(reranker_cache.redis_client.scan_iter(pattern)) if keys: reranker_cache.redis_client.delete(*keys) print(f已清理 {len(keys)} 个匹配 {pattern} 的缓存) return len(reranker_keys) # 定期清理缓存 import schedule import time def job(): print(执行缓存清理任务...) manage_reranker_cache() # 每天凌晨执行清理 schedule.every().day.at(03:00).do(job) # 在后台线程运行调度器 def run_scheduler(): while True: schedule.run_pending() time.sleep(60) # 启动调度器线程 import threading scheduler_thread threading.Thread(targetrun_scheduler, daemonTrue) scheduler_thread.start()7. 实际应用建议7.1 缓存键设计优化为了提高缓存效率可以优化缓存键的生成策略def optimized_cache_key(query, document): 优化的缓存键生成函数 # 对长文本进行摘要处理 def summarize_text(text, max_words50): words text.split() if len(words) max_words: return text return .join(words[:max_words]) ... # 使用摘要后的文本生成键 summarized_query summarize_text(query) summarized_doc summarize_text(document) return reranker_cache.generate_key( cached_rerank_score, summarized_query, summarized_doc )7.2 分布式缓存部署对于生产环境建议使用Redis集群from redis.cluster import RedisCluster class DistributedRedisCache(RedisCache): def __init__(self, startup_nodes, expire_time3600): self.redis_client RedisCluster( startup_nodesstartup_nodes, decode_responsesFalse ) self.expire_time expire_time # 配置Redis集群节点 startup_nodes [ {host: redis-node1, port: 6379}, {host: redis-node2, port: 6379}, {host: redis-node3, port: 6379} ] distributed_cache DistributedRedisCache(startup_nodes)7.3 监控与告警实现缓存系统的监控def monitor_cache_performance(): 监控缓存性能 info reranker_cache.redis_client.info() metrics { hit_rate: calculate_hit_rate(), memory_usage: info[used_memory_human], key_count: info[db0][keys] if db0 in info else 0, evicted_keys: info[evicted_keys] if evicted_keys in info else 0 } # 检查是否需要告警 if metrics[hit_rate] 0.6: # 命中率低于60% send_alert(f缓存命中率过低: {metrics[hit_rate]:.2%}) if metrics[memory_usage] 1GB: # 内存使用超过1GB send_alert(f缓存内存使用过高: {metrics[memory_usage]}) return metrics def calculate_hit_rate(): 计算缓存命中率 # 需要在实际代码中统计命中次数和总请求数 # 这里使用简化实现 return 0.8 # 示例值8. 总结通过为BGE-Reranker-v2-m3实现Redis缓存策略我们显著提升了重复查询的响应速度降低了系统负载。关键要点包括缓存装饰器设计创建通用的Redis缓存装饰器可轻松应用于任何函数智能批量处理实现混合缓存策略同时利用已有缓存和批量计算高级缓存策略支持基于语义相似度的缓存扩展和分布式部署系统监控提供缓存性能监控和自动维护功能在实际部署时建议根据具体业务需求调整缓存过期时间、内存限制和清理策略。对于高并发场景考虑使用Redis集群来提高可用性和扩展性。这种缓存策略不仅适用于BGE-Reranker也可以推广到其他类似的AI模型推理场景中为构建高性能的AI应用提供重要支撑。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。