GPU и ускорители

CPU или GPU для embeddings и reranker в корпоративном RAG

~15 минут14 сентября 2026 г.

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: короткий ответ

1
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

2
Как рассчитать нагрузку 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

3
Как честно сравнить 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».