Что такое Tensor Parallelism

Tensor Parallelism (TP) — техника распределения вычислений между несколькими GPU внутри одного узла. Каждый слой модели делится на части (шарды), которые обрабатываются параллельно на разных GPU; на границах шардов результатами обмениваются через all-reduce.

Два эффекта сразу:

  1. Влезает больше: 27B модель в AWQ (INT4) — ~14GB весов. Одна 24GB-карта её почти не держит вместе с KV-cache; две — с запасом.
  2. Быстрее: каждый forward pass делится между картами, decode-токен считается быстрее.

Как устроено разрезание

Для линейных слоёв (Y = X · W) vLLM применяет классическую схему:

  • Column parallelism: матрица весов W разрезается по столбцам — каждая GPU хранит свой блок и считает часть выходных активаций.
  • Row parallelism: следующая матрица разрезается по строкам — каждая GPU считает частичный скалярный результат, который суммируется all-reduce’ом.

Пара column+row на каждый линейный слой даёт 2 all-reduce на слой (после column-части и после row-части). Именно эти all-reduce — главная цена TP: на каждом токене каждая GPU обменивается с остальными промежуточными активациями.

TP-градусы

  • TP=1: одна GPU, нет параллелизма, нет коммуникации.
  • TP=2: модель делится между 2 GPU.
  • TP=4: 4 GPU.
  • TP=8: 8 GPU (полный NVLink-домен H100/B200).

Когда использовать: таблица по размеру модели

Размер моделиЖелезоРекомендуемый TP
7B (FP16)1× A100 / 1× 4090TP=1
13B (FP16)1× A100 80GB / 2× 4090TP=1–2
27B (AWQ)2× RTX 3090TP=2
34B (FP16)4× A100 80GBTP=2–4
70B (FP16)8× A100 80GB / 4× H100TP=4–8
70B (AWQ)4× RTX 3090/4090TP=2–4
175B+8× H100+TP=8 (+ pipeline между узлами)

Правило: TP подбирается так, чтобы веса + KV-cache влезли в суммарную VRAM с запасом ~10–15% под runtime.

Критичный вопрос для consumer-железа: что, если NVLink нет?

Пропускная способность связи определяет, сколько выигрыш TP съедает на коммуникации:

СвязьПропускная способностьТипичный случай
PCIe 4.0 x16~32 GB/s (bidir ~64)2× RTX 3090/4090 без моста
NVLink (3090)~112 GB/s2× 3090 с мостом
NVLink (H100)~900 GB/s (NVSwitch)8× H100

Для decode-токена объём all-reduce данных пропорционален скрытому размеру модели. Для 27B (hidden ~5120) это десятки килобайт на обход — даже по PCIe 4.0 доля коммуникации в общем времени decode остаётся небольшой, потому что decode memory-bound: GPU упирается в чтение весов, а не в обмен.

Именно поэтому 27B на 2×RTX 3090 по PCIe 4.0 работает: мы замерили 100 tok/s decode без NVLink-мостов. Компромисс появляется на больших моделях (70B+), где объём обмена растёт и PCIe уже заметно съедает scaling.

Настройка в vLLM

vllm serve Qwen3.8-27B-AWQ-MTP --tensor-parallel-size 2
  • --tensor-parallel-size N — число GPU на один инстанс.
  • GPU выбираются через CUDA_VISIBLE_DEVICES (или vLLM берёт первые N).
  • TP работает только внутри одного узла; между узлами — pipeline parallelism (--pipeline-parallel-size), но у него другой профиль задержек.

Ограничения

  • Коммуникация: TP требует быстрой связи между GPU. NVLink предпочтительнее; PCIe допустим для моделей до ~30B, дальше выигрыш падает.
  • Нелинейный scaling: удвоение TP не удваивает throughput. На 2×3090 (PCIe) мы получаем ~1.8x против одной карты, а не 2x — часть ушла на all-reduce.
  • Latency: при TP > 1 каждый токен требует синхронизации, поэтому TTFT и TPOT немного растут против идеала.
  • Целостность инстанса: все GPU инстанса живут и умирают вместе. Crash одной карты = падение всего инстанса. Поэтому в production мы держим несколько реплик (у нас 3×(2×3090)), а не один большой TP=6 — отказ одной реплики не останавливает сервис.

Что мы видели в референс-деплое

Наша конфигурация: 2×RTX 3090, TP=2, PCIe 4.0, без NVLink-мостов. Qwen3.8-27B-AWQ-MTP: 100 tok/s decode, 256K контекст, 46/48GB VRAM.

Почему не TP=4 (4 карты в одном инстансе)? Три причины:

  1. Отказоустойчивость: 2 инстанса по 2 карты отказоустойчивее 1 инстанса на 4 картах.
  2. PCIe-домен: 4 карты в одной материнской плате часто сидят на разных PCIe-корнях с общим пропускным профилем — scaling хуже, чем 2+2.
  3. Экономика: 3 реплики × 2×3090 = 6 GPU дают 3×100 tok/s суммарно с балансировщиком, и потеря одной реплики не роняет сервис.

Полный разбор — в части 1, части 3 и части 5 серии «Наш опыт», а цифры — в бенчмарке Qwen на 2×3090.

TP против Pipeline Parallelism

Не путайте TP с pipeline parallelism (PP):

  • TP делит один слой между GPU (each GPU хранит часть весов слоя). Требует быстрой связи (all-reduce на каждом токене). Используется внутри узла.
  • PP делит слои между GPU (each GPU хранит целый слой или группу слоёв). Данные идут «конвейером» от первого слоя к последнему. Менее требователен к пропускной способности, но имеет bubble (простои между стадиями). Используется между узлами.

Для consumer-железа (2×3090 в одном узле) — только TP. PP имеет смысл, когда модель не влезает даже в суммарную VRAM одного узла и нужно раскидать слои по нескольким машинам. В нашем случае 27B AWQ влезает в 2×3090, поэтому PP не нужен.

Вывод

TP — стандартный способ запустить модель больше одной карты. Для consumer-железа (2×3090/4090) TP=2 по PCIe 4.0 — рабочий режим для моделей до ~30B: коммуникация дорогая, но decode memory-bound, поэтому она не убивает результат. Для больших моделей и production-кластеров смотрите на NVLink-домены и на то, что реплики отказоустойчивее одного большого TP.

Смежные материалы: Continuous Batching, AWQ, A100 vs RTX 4090.

← Continuous Batching AWQ →