English translation is not available yet. Showing Russian content.
Как вы уменьшаете latency RAG-системы (время ответа)?
Краткий тезис
Latency RAG-системы складывается из трёх этапов: pre-retrieval (подготовка запроса), retrieval (поиск в векторной БД) и generation (генерация ответа LLM). Оптимизация каждого этапа даёт совокупный эффект. Ключевые методы: кэширование, настройка ANN индексов, уменьшение top-k, использование меньших LLM, streaming ответов и специализированные инференс-серверы (vLLM, TGI). Реальный результат: latency снижается с 5-10 секунд до 1-2 секунд.
1. Термин: Latency (латентность, задержка)
Что это Время от получения запроса пользователем до получения полного ответа.
Из чего складывается в RAG
Total Latency = T_pre_retrieval + T_retrieval + T_post_retrieval + T_generation
| Этап | Что происходит | Типичная latency |
|---|---|---|
| Pre-retrieval | Embedding запроса, query rewriting | 50-200 ms |
| Retrieval | Поиск в векторной БД, ANN, фильтрация | 10-100 ms |
| Post-retrieval | Reranking, сжатие контекста | 50-500 ms |
| Generation | LLM генерирует ответ (самый долгий) | 500-5000 ms |
Термин «P95 latency» 95-й перцентиль — 95% запросов выполняются быстрее этого времени. Важнее средней (average), потому что показывает "хвост" медленных запросов.
Термин «TTFT» (Time To First Token Время до первого токена. Пользователь видит, что система начала отвечать (важно для UX).
Термин «TPOT» (Time Per Output Token Время на генерацию одного токена после первого.
Часть 1: Pre-retrieval оптимизации
1.1 Кэширование частых запросов (кэш)
Что это Хранение результатов частых запросов в быстром хранилище (Redis, in-memory), чтобы не вычислять каждый раз заново.
Термин «Кэш» (Cache Временное хранилище с быстрым доступом. Redis — in-memory база данных с latency < 1ms.
Как работает
Запрос пользователя → Проверка кэша
│
┌────────┴────────┐
▼ ▼
Есть в кэше? Нет в кэше?
│ │
▼ ▼
Вернуть ответ Выполнить RAG
│ │
└────────┬────────┘
▼
Вернуть ответ
(и сохранить в кэш)
Пример ключа кэша
import hashlib
def get_cache_key(query: str, top_k: int, temperature: float) -> str:
content = f"{query}|{top_k}|{temperature}"
return hashlib.md5(content.encode()).hexdigest()
Термин «Cache hit ratio» Доля запросов, которые нашлись в кэше. Чем выше, тем лучше.
| Стратегия кэширования | Когда использовать | Пример |
|---|---|---|
| Точное совпадение (exact match | Запросы повторяются дословно | Чат-бот поддержки (100 пользователей спрашивают "как сменить пароль") |
| Семантический кэш | Запросы разные по формулировке, но одинаковые по смыслу | "как поменять пароль" и "смена пароля инструкция" |
| TTL (Time To Live | Данные устаревают | Новости, курсы валют (кэш на 5 минут) |
Результат Cache hit ratio 30-50% → уменьшение latency на 70-90% для закэшированных запросов.
Цифра С Redis latency retrieval падает с 100ms до 1ms.
1.2 Асинхронная индексация документов
Что это Индексация новых документов происходит в фоновом режиме, не блокируя поисковые запросы.
Проблема Если при загрузке нового документа ждать, пока он вставится в векторную БД — пользовательский запрос зависнет.
Решение
- Очередь задач (RabbitMQ, Kafka, Celery)
- Документ → очередь → фоновая индексация
- Поиск идёт по уже проиндексированным документам
Термин «Очередь задач» (Task queue Система, где задачи (индексация) складываются в очередь и обрабатываются воркерами. Kafka, RabbitMQ, Celery.
Цифра Latency поиска не увеличивается при загрузке новых документов (с 100ms → 100ms, а не 500ms).
Часть 2: Retrieval оптимизации
2.1 HNSW индексы (настройка параметров)
Термин «HNSW» (Hierarchical Navigable Small World ANN алгоритм для быстрого поиска векторов. Строит многослойный граф.
Ключевые параметры
| Параметр | Что делает | Значение по умолчанию | Влияние на latency |
|---|---|---|---|
| M (max connections) | Количество связей каждого узла в графе | 16 | Больше M → точнее, но медленнее и больше памяти |
| ef_construct | Размер динамического списка при построении индекса | 200 | Больше → точнее, но дольше строить индекс |
| ef_search | Размер динамического списка при поиске | 128 | Больше → точнее, но медленнее поиск |
Настройка для low latency
# Для скорости (жертвуем точностью)
M = 8 # меньше связей
ef_construct = 40 # быстрое построение
ef_search = 40 # быстрый поиск
# Для точности (жертвуем скоростью)
M = 32
ef_construct = 500
ef_search = 200
Trade-off Скорость ↔ Точность
| Настройка | Latency | Recall@10 | Память |
|---|---|---|---|
| Fast (M=8, ef=40) | 5 ms | 0.92 | 100 MB |
| Balanced (M=16, ef=128) | 15 ms | 0.97 | 200 MB |
| Accurate (M=32, ef=200) | 50 ms | 0.99 | 400 MB |
Цифра Уменьшение ef_search со 200 до 40 снижает latency с 50ms до 5ms (10x), но recall падает с 0.99 до 0.92 (приемлемо для многих задач).
2.2 Уменьшение количества чанков (top-k)
Что такое top-k Количество документов (чанков), которые retrieval возвращает в LLM.
Проблема Больше k → больше контекста → лучше ответ, но дольше генерация (LLM обрабатывает больше токенов).
Рекомендации
| k | Latency generation (Llama-3-8B, 500 токенов ответа) | Когда использовать |
|---|---|---|
| 3 | 800 ms | Очень быстрые сценарии (чат, поиск) |
| 5 | 1200 ms | Default (баланс качества и скорости |
| 10 | 2000 ms | Медицина, юриспруденция (нужна полнота) |
| 20 | 3500 ms | Аналитика, исследования |
Термин «Монотонный рост» Latency генерации растёт линейно с количеством токенов контекста. Двойной контекст → двойная latency.
Дополнительная оптимизация Не все top-k чанки одинаково важны. Можно передавать первые 3 чанка полностью, остальные — только суммаризации.
Цифра Уменьшение k с 20 до 5 снижает latency генерации с 3500ms до 1200ms (почти в 3 раза) с потерей качества 2-5%.
2.3 Quantization (квантование векторов)
Что такое квантование Уменьшение точности чисел (например, с 32-битных до 8-битных целых), чтобы экономить память и ускорять поиск.
Термин «FP32» (32-bit floating point Стандартная точность, 4 байта на число. 8. Как вы обрабатываете запросы, на которые нет ответа в документах|8]]. Как вы обрабатываете запросы, на которые нет ответа в документах|8]]. Как вы обрабатываете запросы, на которые нет ответа в документах|8]]-bit integer|Термин «INT8» (8-bit integer]] Целое число от -128 до 127, 1 байт.
| Тип | Размер (1 млн векторов 768d) | Latency поиска | Потеря точности (recall) |
|---|---|---|---|
| FP32 (full precision) | 3 GB | 50 ms | 0% (baseline) |
| FP16 (half precision) | 1.5 GB | 30 ms | 0.5-1% |
| INT8 (scalar quantization) | 0.75 GB | 15 ms | 2-5% |
| Binary quantization | 0.1 GB | 5 ms | 10-20% |
Пример квантования в Qdrant
from qdrant_client.http.models import ScalarQuantization, ScalarQuantizationConfig
client.create_collection(
collection_name="my_docs",
vectors_config=VectorParams(size=768, distance=Distance.COSINE),
quantization_config=ScalarQuantization(
scalar=ScalarQuantizationConfig(
type="int8", # или "int16"
quantile=0.99
)
)
)
Термин «PQ (Product Quantization)» Более продвинутое квантование, разбивает вектор на подвекторы и кодирует каждый. Сжатие в 8-32 раза.
Цифра INT8 quantization снижает память в 4 раза и ускоряет поиск в 3 раза (50ms → 15ms) при потере recall всего на 2-5%.
Часть 3: Post-retrieval оптимизации
3.1 LLM distillation (дистилляция модели)
Что такое дистилляция Обучение маленькой модели (студента) имитировать большую модель (учителя). Студент быстрее, но почти так же качественно.
Термин «Teacher-student distillation» Учитель (GPT-4, 70B) генерирует ответы на датасете. Студент (Llama-3-8B) учится предсказывать эти ответы.
| Модель | Latency (1 токен) | Качество (MMLU) | Размер |
|---|---|---|---|
| GPT-4 | 50-100 ms | 86% | ~1.7T params |
| Llama-3-70B | 20-30 ms | 82% | 70B |
| Llama-3-8B (distilled) | 5-10 ms | 75% | 8B |
| Phi-3-mini-3.8B | 2-5 ms | 68% | 3.8B |
Как выбрать модель под задачу
- Сложные рассуждения (юриспруденция, медицина) → 70B+
- Фактологические ответы (RAG) → 8B достаточно
- Классификация, извлечение → 3B достаточно
Цифра Замена Llama-3-70B на Llama-3-8B снижает latency генерации с 1200ms до 200ms (6x ускорение) при потере качества 5-10% на RAG-задачах.
3.2 Streaming ответов (потоковая передача)
Что это LLM возвращает токены по одному по мере генерации, а не ждёт полный ответ.
Термин «Streaming» (потоковая передача Использование Server-Sent Events (SSE) или WebSockets для отправки данных частями.
Как это меняет восприятие пользователя
Без streaming: (ждём 3 секунды) → ответ целиком
Со streaming: токен за токеном, через 200ms уже первый токен
Реализация с FastAPI
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
@app.post("/chat/stream")
async def chat_stream(request: Request):
async def generate():
async for token in llm.stream(request.query):
yield f"data: {token}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
Термин «TTFT» (Time To First Token Время до первого токена. Со streaming пользователь видит, что система начала отвечать, даже если полный ответ через 5 секунд.
Цифра При генерации 500 токенов (10 секунд без streaming) → streaming даёт TTFT 200ms, что психологически воспринимается как "быстрый ответ", хотя полный ответ всё ещё 10 секунд.
Часть 4: Архитектурные оптимизации
4.1 vLLM или TGI для инференса LLM
Термин «vLLM» Инференс-сервер с paged attention и continuous batching. Ускоряет LLM в 2-10x.
Термин «TGI» (Text Generation Inference Аналог от Hugging Face с похожими оптимизациями.
Сравнение
| Характеристика | vLLM | TGI | Стандартный Hugging Face |
|---|---|---|---|
| Continuous batching | ✅ Да | ✅ Да | ❌ Нет |
| Paged attention | ✅ Да | ❌ Нет | ❌ Нет |
| FlashAttention | ✅ Да | ✅ Да | ✅ Да |
| Throughput (токенов/сек | 1000-2000 | 800-1500 | 100-200 |
| Latency p95 | 50-200 ms | 70-250 ms | 500-2000 ms |
Термин «Continuous batching» Вместо ожидания самого медленного запроса в батче, батч динамически обновляется (завершившиеся удаляются, новые добавляются).
Термин «Paged attention» KV-кэш разбивается на страницы, как в операционной системе, уменьшая фрагментацию памяти.
Цифра Переход с Hugging Face pipeline на vLLM снижает latency генерации с 2000ms до 200ms (10x ускорение).
Запуск vLLM
pip install vllm
python -m vllm.entrypoints.api_server --model meta-llama/Llama-3-8B --tensor-parallel-size 2
4.2 Edge-вычисления для простых запросов
Что это Маршрутизация (routing) запросов: простые запросы обрабатываются маленькой моделью на edge (пользовательское устройство или ближайший сервер), сложные — большой моделью в облаке.
Термин «Edge computing» Вычисления на периферии (ближе к пользователю), а не в центральном облаке.
Классификатор запросов (router
# Маленькая модель (DistilBERT) классифицирует сложность
def classify_query(query: str) -> str:
if "сравните" in query or "проанализируйте" in query:
return "complex"
if len(query.split()) < 10:
return "simple"
# ... более сложная логика
return "medium"
if classify_query(query) == "simple":
model = "Phi-3-mini-3.8B" # latency 500ms
else:
model = "Llama-3-70B" # latency 2000ms
Цифра 70% запросов простые (как поменять пароль, сколько стоит, какой адрес) → они идут на edge-модель за 200ms вместо 2000ms. Средняя latency падает с 2000ms до 740ms (0.3×2000 + 0.7×200 = 600+140 = 740ms).
Полная оптимизация: итоговые цифры
| Этап | До оптимизации | После оптимизации | Метод |
|---|---|---|---|
| Pre-retrieval | 200 ms | 5 ms | Кэш (Redis) |
| Retrieval | 100 ms | 15 ms | HNSW (ef=40) + INT8 |
| Post-retrieval | 100 ms | 0 ms (убрали) | Отказ от reranking |
| Generation | 5000 ms | 500 ms | vLLM + меньшая модель (8B) |
| Total | 5400 ms | 520 ms | ~10x ускорение |
Реальный пример из практики «Я оптимизировал RAG для поддержки клиентов: кэширование частых запросов (500 запросов/час → cache hit 40%), замена 70B модели на 8B дистиллированную, vLLM вместо Hugging Face. Latency упала с 5.2 секунд до 1.2 секунд, качество осталось на уровне 92% faithfulness».
Пет-проект для закрепления
Задача Измерить и оптимизировать latency вашего RAG-пайплайна.
Инструменты Python, Qdrant, vLLM, Redis, Locust (нагрузочное тестирование)
Шаги
- Собрать базовый RAG (retrieval + Llama-3-70B через Hugging Face)
- Замерить baseline latency на 100 запросах (p50, p95)
- Применить оптимизации по очереди:
- После каждой оптимизации замерять latency и качество (faithfulness)
- Построить график trade-off скорость vs качество
Ожидаемый результат Вы получите реальные цифры для вашего домена и поймёте, какие оптимизации дают наибольший эффект.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 4 | Векторная БД (HNSW, quantization) |
| 5 | Оценка качества (чтобы убедиться, что оптимизации не убили качество) |
| 6 | Гибридный поиск (тоже влияет на latency) |
| 14 | Обрезка контекста (как уменьшить токены) |
| 61-80 | Production & MLOps (vLLM, TGI, мониторинг latency) |
| 201-220 | Inference optimization (глубоко про vLLM, paged attention, speculative decoding) |
7. Как вы уменьшаете latency RAG-системы (время ответа)|7. Как вы уменьшаете latency RAG-системы (время ответа)|7. Как вы уменьшаете latency RAG-системы (время ответа)|7 полностью разобран. Переходим к вопросу 8, когда будете готовы|Вопрос 7 полностью разобран. Переходим к вопросу 8, когда будете готовы]]
Навигация
- Предыдущий: 6
- Следующий: 8
- Индекс: 00. Индекс разборов