Настройка кэширования инференса LLM
Кэширование LLM-ответов снижает latency и затраты на GPU. Два уровня: semantic cache (похожие запросы дают одинаковый ответ) и KV-cache (prefix sharing на уровне внутри модели).
Semantic Caching
Точное совпадение запросов редко. Semantic cache находит семантически похожие запросы и возвращает сохранённый ответ без инференса:
from sentence_transformers import SentenceTransformer
import numpy as np
import redis
import json
class SemanticCache:
def __init__(self, similarity_threshold: float = 0.92):
self.encoder = SentenceTransformer("paraphrase-multilingual-mpnet-base-v2")
self.redis = redis.Redis(host="localhost", port=6379, db=1)
self.threshold = similarity_threshold
# Для поиска похожих — Qdrant или pgvector
from qdrant_client import QdrantClient
self.vector_db = QdrantClient("localhost", port=6333)
def get(self, prompt: str, system_prompt: str = "") -> str | None:
cache_key = self._make_key(prompt, system_prompt)
# 1. Точное совпадение (дешево)
exact = self.redis.get(cache_key)
if exact:
return json.loads(exact)["response"]
# 2. Семантическое совпадение (через vector search)
embedding = self.encoder.encode(prompt)
results = self.vector_db.search(
collection_name="llm_cache",
query_vector=embedding.tolist(),
limit=1,
score_threshold=self.threshold
)
if results:
cached_response = json.loads(results[0].payload["response"])
# Обновляем TTL найденной записи
self.redis.expire(results[0].id, 3600)
return cached_response
return None
def set(self, prompt: str, response: str, system_prompt: str = "", ttl: int = 3600):
embedding = self.encoder.encode(prompt)
cache_id = self._make_key(prompt, system_prompt)
# Сохраняем в vector DB
self.vector_db.upsert(
collection_name="llm_cache",
points=[{
"id": abs(hash(cache_id)) % (2**31),
"vector": embedding.tolist(),
"payload": {"prompt": prompt, "response": json.dumps(response), "system_prompt": system_prompt}
}]
)
# Сохраняем в Redis для точного lookup
self.redis.setex(cache_id, ttl, json.dumps({"response": response}))
def _make_key(self, prompt: str, system_prompt: str) -> str:
import hashlib
return hashlib.sha256(f"{system_prompt}||{prompt}".encode()).hexdigest()
GPTCache — готовое решение
GPTCache — специализированная библиотека для LLM-кэширования с поддержкой разных векторных хранилищ:
from gptcache import cache
from gptcache.adapter import openai as cached_openai
from gptcache.embedding import Onnx
from gptcache.manager import CacheBase, VectorBase, get_data_manager
from gptcache.similarity_evaluation.distance import SearchDistanceEvaluation
# Настройка кэша
embedding_model = Onnx()
data_manager = get_data_manager(
CacheBase("sqlite"),
VectorBase("qdrant", host="localhost", port=6333, dimension=512)
)
cache.init(
embedding_func=embedding_model.to_embeddings,
data_manager=data_manager,
similarity_evaluation=SearchDistanceEvaluation(max_distance=0.3),
cache_enable_func=lambda *args, **kwargs: True
)
# Использование — прозрачная замена openai клиента
response = cached_openai.ChatCompletion.create(
model="gpt-4o",
messages=[{"role": "user", "content": "What is Python?"}]
)
Prefix KV-Cache в vLLM
vLLM автоматически кэширует KV значения для общих префиксов (system prompts):
# vLLM автоматически использует prefix caching
# Важно: system prompt должен быть одинаковым для разных запросов
# При запуске включаем prefix caching
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3-8b-instruct \
--enable-prefix-caching \ # явное включение
--max-model-len 8192
# Метрика эффективности кэша
# vllm:cache_config_info{...} -> num_gpu_blocks
# vllm:gpu_cache_usage_perc -> процент занятых блоков кэша
Prefix cache hit rate 60–80% типичен при одинаковом system prompt для всех запросов.
Когда не кэшировать
- Персонализированные ответы (разные для каждого пользователя)
- Запросы с текущим временем/датой
- Финансовые данные (курсы, цены) — устаревают быстро
- Генерация кода (незначительные вариации prompt → разный код)
- temperature > 0.8 — стохастические ответы
Кэширование наиболее эффективно для FAQ-ботов, RAG с фиксированными документами, классификационных задач.
Метрики кэширования
Ключевые KPI: cache hit rate (цель > 30% для FAQ, < 5% для creative), latency reduction (p99 latency с кэшем vs без), cost savings (% запросов, не отправленных на инференс), staleness rate (% кэшированных ответов, ставших неактуальными).







