GPU не является обязательной ни для embeddings, ни для reranker. Но и правило «embeddings оставляем на CPU, reranker переносим на GPU» универсально неверно.
Для корпоративного RAG нужно отдельно рассчитать три нагрузки:
document embedding
→ batch throughput / окно индексации
query embedding → peak QPS / p95 / queue
reranker → QPS × candidates / длина пар / p95
После этого exact model и production-relevant inputs тестируют на подходящей CPU- и GPU-конфигурации. Выбирают не максимальную производительность, а минимальную архитектуру, которая проходит throughput, latency и retrieval-quality SLA.
Рабочий процесс:
разделить retrieval pipeline
↓
посчитать demand каждой стадии
↓
задать SLA
↓
зафиксировать model / runtime / inputs
↓
benchmark CPU
↓
benchmark GPU
↓
проверить queue
↓
проверить retrieval quality
↓
выбрать minimum accepted configuration
CPU или GPU: короткий ответ

CPU — полноценный inference target для embedding и reranking models, а не только запасной вариант. Hugging Face Text Embeddings Inference официально поддерживает CPU и GPU deployments, включая отдельные CPU images. Sentence Transformers поддерживает PyTorch, ONNX и OpenVINO; для CPU доступны оптимизированные и quantized paths.
Но:
model runs on CPU
не означает:
CPU meets production SLA
GPU становится обоснованным кандидатом, если после оптимизации CPU:
не укладывается в окно индексации
или:
не выдерживает peak QPS
или:
очередь растёт
→ p95/p99 выходит за SLA
или reranker не справляется с требуемым потоком query-passage pairs.
Embeddings и reranker — разные workloads
Embedding/bi-encoder кодирует тексты независимо:
query → embedding
document → embedding
Reranker обычно работает как cross-encoder: получает пару query + passage и вычисляет score именно для этой пары.
Поэтому Cross Encoder требует вычисления для каждой оцениваемой пары и обычно применяется к top-k результатов первого retrieval stage, а не ко всему корпусу.
Типичный online pipeline:
query
↓
query embedding
↓
vector / hybrid search
↓
top-N candidates
↓
query × passage reranking
↓
top-K context
↓
LLM
Отсюда разные единицы нагрузки:
embedding
→ texts / tokens to encode
и:
reranker
→ query-passage pairs to score
Поэтому фразы:
«у нас 30 RAG-запросов в секунду»
недостаточно для sizing reranker.
Document embedding и query embedding тоже нужно считать отдельно
Даже одна embedding model работает в двух принципиально разных режимах.
Document embedding
documents
↓
extraction
↓
chunking
↓
embedding batches
↓
vectors
↓
index
Типичная цель:
переиндексировать весь corpus не более чем за X часов.
Это throughput-oriented workload.
Query embedding
request
↓
query embedding
↓
search
Здесь нужны:
peak QPS
concurrency
p50
p95
p99
queue time
То есть одна и та же модель может требовать одного hardware для bulk indexing и совершенно другого sizing для online service.
Размер корпуса в GB не определяет embedding compute
Запись:
corpus = 1 TB
не говорит, нужна CPU или GPU.
Терабайт PDF-сканов и терабайт извлечённого текста после preprocessing могут дать совершенно разное число chunks и tokens.
Для compute sizing нужны:
number of chunks
+
tokens per chunk
+
total embedding tokens
+
change rate
Правильная цепочка:
source data
↓
extraction / OCR
↓
chunking
↓
token distribution
↓
embedding workload
а не:
GB документов
↓
GPU model
Как посчитать требуемую скорость индексации
Для первого sizing достаточно двух метрик.
Chunks/s
Required_chunks_per_second =
N_chunks / T_index_budget
Tokens/s
Required_tokens_per_second =
N_total_embedding_tokens / T_index_budget
Обе нужны одновременно.
Предположим, полный index содержит:
5 000 000 chunks
и должен перестраиваться максимум за:
8 часов
Бюджет:
8 × 3600 = 28 800 s
Требование:
5 000 000 / 28 800
≈ 173,6 chunks/s
Теперь учебно предположим среднюю длину 400 tokens/chunk.
Общий объём:
5 000 000 × 400
=
2 000 000 000 tokens
Требуемая скорость:
2 000 000 000 / 28 800
≈ 69 444 tokens/s
Это не benchmark CPU или GPU.
Это demand:
нужно ≥173,6 chunks/s
и примерно ≥69 444 tokens/s
Теперь уже можно проверить, какая конфигурация его выполняет.
Почему chunks/s недостаточно
Два корпуса:
A:
1000 chunks × 100 tokens
и:
B:
1000 chunks × 1000 tokens
имеют одинаковое число chunks, но существенно различаются по объёму transformer inference.
Поэтому при тестировании фиксируют:
chunks/s
tokens/s
tokens p50
tokens p95
tokens max
а не только «документов в секунду».
Частота обновлений иногда важнее полного размера
Сравним:
Corpus A
20 млн chunks
full rebuild раз в месяц
и:
Corpus B
2 млн chunks
continuous updates
В первом случае нужен высокий periodic batch throughput.
Во втором может быть важнее:
incremental update latency
Поэтому sizing intake должен содержать:
corpus size
change rate
incremental batch
full rebuild frequency
update SLA
Для online embedding нужен latency SLA
Максимальный batch throughput из offline test нельзя использовать как прогноз online performance.
Запрос проходит:
arrival
↓
queue
↓
batch formation
↓
inference
↓
response
Поэтому acceptance разумно формулировать так:
PASS
⇔
sustainable QPS >= peak required QPS
AND
p95/p99 <= latency budget
AND
queue remains bounded
Hugging Face TEI отдельно управляет maximum concurrent requests, maximum batch tokens и количеством requests в batch. Документация прямо описывает max-batch-tokens как критический параметр использования hardware, а ограничение concurrency — как механизм backpressure, предотвращающий слишком длительное ожидание запросов.
Отсюда:
maximum embeddings/s
≠
production p95
Batch нужно описывать не только количеством inputs
Запись:
batch = 32
не определяет реальную нагрузку.
Это может быть:
32 × 20 tokens
=
640 tokens
или:
32 × 1000 tokens
=
32 000 tokens
TEI использует token-based dynamic batching и отдельно задаёт ограничение общего потенциального числа tokens в batch.
Поэтому benchmark record должен включать:
batch inputs
batch tokens
tokens p50
tokens p95
tokens max
Exact model важнее слова «embedding»
Нельзя считать все embedding models одинаковой нагрузкой.
Hardware comparison начинается с:
model ID
revision
tokenizer
runtime
precision
quantization
а уже затем с CPU/GPU.
Некорректный тест:
CPU
→ small embedding model
GPU
→ much larger model
и вывод:
GPU быстрее или медленнее CPU.
В таком сравнении изменились сразу несколько переменных.
Sequence length — обязательная часть benchmark
Максимальная длина, заявленная моделью, не является production recommendation.
Нужно разделять:
model maximum sequence ≠ runtime/profile maximum ≠ actual production inputs
Для benchmark сохраняют:
tokens p50
tokens p95
tokens max
truncated requests
Это особенно важно для reranker, поскольку его input содержит одновременно query и passage.
Sentence Transformers отдельно предупреждает, что padding до большого model_max_length может существенно ухудшать performance; representative input shapes нужно учитывать и при оптимизации runtime.
Как рассчитать нагрузку reranker

Основная арифметика:
Required_pairs_per_second =
Peak_query_rate × Candidates_per_query
Например:
peak QPS = 30
candidates/query = 40
Тогда:
30 × 40 = 1200 query-passage pairs/s
1200 pairs/s — offered workload, а не benchmark performance.
Нельзя сделать вывод, что любой reranker потребует ровно определённое число CPU cores или GPU.
Реальная производительность будет зависеть от:
model
pair length
padding
batching
concurrency
runtime
hardware
Но теперь требование сформулировано правильно:
конфигурация должна устойчиво обслуживать production workload порядка 1200 пар/с при заданном latency SLA.
Почему пользовательский QPS не равен нагрузке reranker
При тех же:
20 queries/s
получаем:
10 candidates → 200 pairs/s
50 candidates → 1000 pairs/s
100 candidates → 2000 pairs/s
Входной user traffic не изменился, а offered reranker load вырос в десять раз.
TopK одновременно влияет на качество и ресурсы
Candidate count — не только retrieval parameter.
candidates ↑
↓
pairs to rerank ↑
↓
reranker compute ↑
↓
queue / latency risk ↑
Но уменьшить TopK только ради экономии тоже нельзя:
TopK ↓
→
compute ↓
может сопровождаться:
retrieval quality ↓
Поэтому решение принимается совместно:
TopK
↓
quality
+
reranker workload
+
end-to-end latency
↓
combined acceptance
NVIDIA также рассматривает TopK как параметр, влияющий одновременно на retrieval accuracy, latency, throughput и стоимость своей reference architecture.
Но конкретные рекомендуемые значения NVIDIA нельзя переносить на любой корпоративный RAG: они относятся к их моделям, datasets и SLA.
CPU нужно тестировать с production-oriented backend
Сравнение:
default PyTorch CPU VS optimized GPU runtime
может описывать две конкретные конфигурации, но не является универсальным доказательством «CPU против GPU».
Sentence Transformers поддерживает ONNX и OpenVINO, в том числе ONNX Runtime CPU provider и int8 quantization. Документация показывает, что эффект оптимизации зависит от модели и длины текстов и прямо рекомендует benchmark на собственных данных.
Для CrossEncoder доступны аналогичные optimized execution paths.
Поэтому для закупочного решения сравнивают:
production-intended CPU stack
с:
production-intended GPU stack
а не искусственно слабую CPU-конфигурацию с настроенной GPU.
Когда CPU является достаточным вариантом
CPU остаётся рациональным выбором, если после настройки:
indexing window
PASS
peak QPS
PASS
p95 / p99
PASS
queue stable
retrieval quality
PASS
При этом нет универсального порога:
до N документов → CPU
или:
до X QPS → CPU
Он будет зависеть от model/runtime/input/hardware.
Когда GPU становится обоснованной
GPU имеет смысл рассматривать, когда конкретный CPU design не выполняет target.
Например:
Индексация
required:
full reindex <= 6 h
measured CPU:
11 h → FAIL
Если GPU-configuration выполняет:
<= 6 h → PASS
ускоритель имеет понятную инженерную функцию.
Online
CPU:
required throughput PASS
p50 PASS
p95 FAIL under peak load
queue grows
Если GPU сохраняет bounded queue и проходит p95:
GPU → candidate
GPU может понадобиться только во время indexing
Offline и online workloads не обязаны использовать одинаковое hardware.
Например:
full reindex
раз в неделю
↓
GPU batch service
↓
index updated
↓
GPU resource released
При этом online retrieval:
query embedding → CPU
search → selected VDB architecture
reranking → CPU
может успешно работать постоянно.
Получается:
INDEXING POOL
periodic
throughput-oriented
и отдельно:
ONLINE POOL
persistent
latency-oriented
Это важная архитектурная граница: GPU, необходимая для batch indexing, не обязана круглосуточно находиться в online retrieval service.
Возможен и обратный вариант: GPU только для reranker
Предположим, corpus небольшой и CPU быстро выполняет индексацию.
Query embedding также проходит SLA.
Но:
peak QPS
×
many candidates
×
long passages
↓
reranker CPU queue grows
↓
p95 FAIL
Если GPU при том же model/input profile проходит acceptance:
document embeddings → CPU
query embeddings → CPU
reranker → GPU
становится логичной архитектурой.
Поэтому вопрос:
Сколько GPU нужно для RAG?
нужно сначала заменить на:
Какой компонент не выполняет SLA и почему?
Низкая GPU utilization не означает, что GPU лишняя
Для latency-oriented сервиса headroom может быть намеренным.
Если:
average GPU utilization = low
но:
burst handled
queue stable
p95 PASS
p99 PASS
конфигурация может быть рассчитана корректно.
Так же и высокая utilization не означает автоматически undersizing.
Если при высокой загрузке:
throughput PASS
p95 PASS
queue stable
ресурс может использоваться эффективно.
Поэтому решение строится по набору:
throughput
+
p95/p99
+
queue
+
utilization
а не по одному percentage.
Queue time нужно видеть отдельно
При saturation может происходить:
inference time
почти не меняется
но:
queue
растёт
и вслед за ней:
end-to-end latency ↑
Поэтому желательно измерять отдельно:
queue time
processing time
request latency
Backpressure controls TEI существуют именно для управления подобными ситуациями.
Ускорение embedder не равно ускорению RAG
Рассмотрим учебный пример:
embedding = 20 ms
search = 80 ms
reranker = 300 ms
other = 50 ms
Условный retrieval path:
20 + 80 + 300 + 50 = 450 ms
Теперь embedding ускорен:
20 ms → 5 ms
Новый результат:
5 + 80 + 300 + 50 = 435 ms
Компонент стал быстрее в 4 раза, но end-to-end retrieval улучшился всего примерно на 3,3%.
Это учебные числа, а не benchmark.
Вывод:
Оптимизировать компонент нужно относительно его доли в critical path, а не ради максимального standalone throughput.
NVIDIA аналогично рекомендует независимо отслеживать latency компонентов retrieval pipeline и масштабировать тот, который приближается к заданному latency threshold.
Vendor sizing table нельзя использовать как универсальную
В актуальной NVIDIA Enterprise RAG reference architecture embedder, reranker, LLM и vector database получают разное количество CPU/GPU resources и масштабируются в разных пропорциях. Например, в конкретном baseline NVIDIA embedder получает fractional GPU, а reranker — отдельный GPU.
Из этого нельзя получить правило:
любой RAG
→ 0,5 GPU для embedder
→ 1 GPU для reranker
Потому что reference configuration фиксирует конкретные:
models
precision
runtime
hardware
query lengths
TopK
concurrency
latency target
Использовать её здесь правильно только для одного вывода:
Компоненты retrieval pipeline действительно нужно sizing'овать независимо.
Нельзя оптимизировать hardware ценой качества поиска
Предположим, меньшая модель на CPU значительно дешевле.
Если она не проходит relevance target, это не успешная инфраструктурная оптимизация.
Итоговый acceptance:
performance PASS
AND
quality PASS
Quality metric зависит от проекта:
Recall@K
nDCG@K
MRR
human relevance
business-specific score
Как честно сравнить CPU и GPU

Если задача — именно hardware comparison, фиксируем:
same task
same model ID
same revision
same tokenizer
same input dataset
same input-length distribution
same truncation
same quality target
Отдельно записываются:
CPU runtime / backend / precision
GPU runtime / backend / precision
Если precision или backend различаются, это допустимо для сравнения двух production systems, но нужно так и написать.
Тогда вывод будет:
конфигурация A против конфигурации B,
а не:
любой CPU против любой GPU.
CPU/GPU Benchmark Protocol
MODEL
Task:
Model ID:
Revision:
Tokenizer:
Model max sequence:
Runtime:
Runtime version:
Backend:
Precision:
Quantization:
HARDWARE
CPU exact SKU:
Sockets:
Physical cores:
Threads:
RAM:
NUMA placement:
GPU exact SKU:
GPU count:
VRAM:
Driver:
CUDA/runtime:
DATASET
Production / synthetic:
Number of inputs:
Tokens p50:
Tokens p95:
Tokens max:
Truncated inputs:
BATCHING
Client batch:
Batch tokens:
Dynamic batching:
Concurrency:
TEST
Warmup:
Measured duration:
Requests:
Repeated runs:
METRICS
Inputs/s:
Tokens/s:
Pairs/s:
Queue time:
p50:
p95:
p99:
Errors / rejected requests:
CPU utilization:
GPU utilization:
Peak memory:
QUALITY
Recall@K:
nDCG@K:
Business relevance:
RESULT
CPU:
PASS / FAIL
GPU:
PASS / FAIL
Quality:
PASS / FAIL
Minimum accepted configuration:
Retrieval Compute Budget
Основной worksheet для проекта:
CORPUS
Documents:
Chunks:
Total embedding tokens:
Chunk tokens p50:
Chunk tokens p95:
Change rate:
INDEXING SLA
Incremental update frequency:
Full rebuild frequency:
Full rebuild time budget:
Required chunks/s:
Required tokens/s:
EMBEDDING MODEL
Model ID:
Revision:
Dimension:
Model max sequence:
Runtime max:
Precision:
Runtime:
INDEXING CPU
CPU:
Backend:
Batch inputs:
Batch tokens:
Chunks/s:
Tokens/s:
Full rebuild time:
PASS / FAIL:
INDEXING GPU
GPU:
Backend:
Batch inputs:
Batch tokens:
Chunks/s:
Tokens/s:
Full rebuild time:
PASS / FAIL:
ONLINE QUERY
Peak QPS:
Concurrency:
Query tokens p50:
Query tokens p95:
Embedding p95 budget:
ONLINE EMBEDDING CPU
Sustainable QPS:
p50:
p95:
p99:
Queue:
PASS / FAIL:
ONLINE EMBEDDING GPU
Sustainable QPS:
p50:
p95:
p99:
Queue:
PASS / FAIL:
RETRIEVAL
Vector DB:
TopN candidates:
Search p95:
RERANKER
Model:
Revision:
Candidates/query p50:
Candidates/query p95:
Pair tokens p50:
Pair tokens p95:
Required pairs/s:
Reranker p95 budget:
RERANK CPU
Pairs/s:
p50:
p95:
p99:
Queue:
PASS / FAIL:
RERANK GPU
Pairs/s:
p50:
p95:
p99:
Queue:
PASS / FAIL:
QUALITY
Recall@K:
nDCG@K:
Business metric:
PASS / FAIL:
END TO END
Retrieval p95 target:
Measured retrieval p95:
DECISION
Offline document embedding:
CPU / GPU / temporary accelerator
Online query embedding:
CPU / GPU
Reranker:
CPU / GPU
Minimum accepted architecture:
Вместо одного вопроса:
«Нужна ли GPU для RAG?»
получаются три независимо проверяемых решения.
Три возможных результата sizing
CPU выполняет весь retrieval workload
indexing SLA PASS
+
query embedding PASS
+
reranker PASS
+
queue stable
+
quality PASS
В этом случае отдельная GPU для embeddings/reranker может не требоваться.
GPU нужна только для indexing
CPU online
→ PASS
CPU full rebuild
→ FAIL
Тогда:
document embedding
→ temporary/shared GPU
query embedding
→ CPU
reranker
→ CPU
может быть достаточной архитектурой.
GPU нужна для online reranker
CPU indexing
→ PASS
CPU query embedding
→ PASS
CPU reranker under peak
→ p95 FAIL
→ queue grows
Если GPU benchmark проходит тот же SLA и quality target:
document embedding
→ CPU
query embedding
→ CPU
reranker
→ GPU
становится обоснованным решением.
Ни один из сценариев нельзя выбрать заранее только по размеру компании или корпуса.
Итоговый алгоритм
1. Зафиксировать embedding model
↓
2. Зафиксировать reranker
↓
3. Разделить offline и online workloads
↓
4. Посчитать chunks и tokens
↓
5. Задать indexing window
↓
6. Определить peak QPS
↓
7. Измерить candidates/query
↓
8. Посчитать offered pairs/s
↓
9. Задать latency budgets
↓
10. Benchmark production CPU stack
↓
11. Benchmark production GPU stack
↓
12. Проверить queue на peak load
↓
13. Проверить retrieval quality
↓
14. Проверить end-to-end retrieval SLA
↓
15. Выбрать minimum accepted architecture
Итогом может стать:
CPU для всех retrieval stages
или:
GPU только для batch indexing
или:
CPU query embedding
+
GPU reranker
или полностью GPU-oriented retrieval.
Что передать для расчёта поискового контура
Для sizing нужны:
embedding model + revision
reranker model + revision
число chunks
total tokens
input-length distribution
change rate
reindex window
peak QPS
concurrency
candidates/query
query/passage lengths
latency SLA
quality target
По ним можно построить CPU/GPU benchmark matrix и определить минимальную конфигурацию без правил вроде «от миллиона документов нужна GPU».
Получить консультацию
Оставьте заявку и наш менеджер свяжется с вами для консультации









