Инфраструктура и ЦОД

Отказоустойчивый инференс LLM: Как спроектировать два и более узлов

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

Две replicas ещё не означают, что LLM-сервис отказоустойчив.

После потери одного worker оставшиеся могут продолжать отвечать, но при этом:

  • резко увеличить TTFT;

  • накопить очередь;

  • повысить inter-token latency;

  • перегрузить KV cache;

  • начать отклонять новые requests;

  • потерять часть уже идущих generations.

Поэтому отказоустойчивость нельзя доказывать количеством серверов или наличием load balancer.

Практическая последовательность выглядит так:

Главный вопрос:

Сохранит ли сервис требуемый уровень обслуживания после конкретного отказа, если protected load останется прежним?

Почему две replicas ещё не означают HA

1
Почему две replicas ещё не означают HA

Представим два одинаковых inference workers.

В нормальном режиме каждый обслуживает часть трафика. После отказа одного worker весь protected load должен перейти на оставшийся pool.

Но surviving workers должны не просто продолжить отвечать. Они должны выдержать нагрузку с согласованными:

  • TTFT;

  • inter-token latency;

  • end-to-end latency;

  • error rate;

  • rejection policy.

Поэтому:

replication — элемент HA-архитектуры, а не доказательство её работоспособности.

HA подтверждается в degraded topology.

Сначала определите protected load

Перед расчётом GPU reserve нужно зафиксировать нагрузку, которую система обязана обслуживать после отказа.

Полезно различать:

Normal load

Типичный production traffic.

Normal peak

Ожидаемая максимальная нагрузка в штатном режиме.

Protected load

Нагрузка, которую сервис обязан сохранить после предусмотренного failure.

Protected load не обязан совпадать с абсолютным theoretical peak.

Например, архитектура может предусматривать controlled rejection низкоприоритетных запросов, но сохранять обслуживание критичного traffic.

Затем зафиксируйте SLO

Фраза:

сервис должен работать после отказа

слишком неопределённа.

Нужно договориться, что считается приемлемой работой.

Например:

  • p95 TTFT;

  • p95 inter-token latency;

  • p95 end-to-end latency;

  • success/error rate;

  • допустимый rejection rate;

  • ограничения на queue;

  • recovery objective.

Универсальных значений здесь нет.

Но одинаковое определение SLO должно использоваться и для healthy baseline, и для failed topology.

Назовите конкретный failure domain

Нельзя проектировать защиту от абстрактного «сбоя».

Нужно определить, что именно система должна пережить.

Например:

Process или engine failure

Один serving process перестаёт выполнять inference.

GPU failure

Недоступен accelerator или engine, работающий на нём.

Worker failure

Теряется конкретная serving replica.

Node failure

Недоступен целый сервер вместе со всеми размещёнными на нём workers.

Network-path failure

Worker формально работает, но перестаёт быть доступен через рабочий request path.

Planned drain

Узел выводится из эксплуатации контролируемо.

Эти сценарии различаются по последствиям и требуют отдельных тестов.

Почему два сервера могут не быть двумя независимыми failure domains

Даже два физических узла могут зависеть от общего:

  • switch;

  • gateway;

  • power path;

  • control-plane component;

  • upstream service.

Поэтому количество серверов само по себе не показывает уровень fault isolation.

Healthy capacity — только baseline

До fault injection нужно снять стабильный baseline.

Полезно сохранить:

Метрика

Healthy

Offered load

Throughput

p95 TTFT

p95 ITL

p95 E2E latency

Queue

Errors

Rejections

KV-cache usage

Но healthy peak — только отправная точка.

Главный показатель HA появляется после удаления защищаемого ресурса.

Главная метрика — degraded capacity

Обозначим:

Cdegraded — измеренная sustainable capacity failed topology при заданном request mix и SLO.

Lprotected — protected load.

Главный architecture gate:

Cdegraded ≥ Lprotected

При этом capacity нельзя выражать одной случайной цифрой req/s или tokens/s.

Она имеет смысл только вместе с:

  • request-length distribution;

  • concurrency;

  • streaming profile;

  • cache behaviour;

  • latency objective;

  • error/rejection policy.

Почему потерю capacity нельзя считать по числу workers

Если из четырёх workers потерян один, нельзя автоматически утверждать:

осталось 75% производительности.

После отказа меняются:

  • batching;

  • request distribution;

  • queue;

  • KV-cache pressure;

  • cache locality;

  • per-worker concurrency.

Поэтому арифметическое деление можно использовать как предварительную гипотезу.

Headroom и failover reserve — разные вещи

Normal headroom может расходоваться на:

  • traffic spikes;

  • длинные prompts;

  • cache misses;

  • deployment;

  • неравномерность нагрузки.

Failover reserve — это capacity, которая должна остаться после конкретного failure.

Если один и тот же запас одновременно считать и operational headroom, и HA reserve, реальная система может оказаться перегруженной именно во время аварии.

Warm capacity и cold replacement

Есть два принципиально разных ресурса.

Ready capacity

Worker уже:

  • запущен;

  • загрузил модель;

  • инициализировал engine;

  • готов принимать production traffic.

Эта capacity доступна сразу после failure.

Cold replacement

Worker создаётся после отказа.

Ему ещё нужно:

  • получить GPU;

  • запустить process;

  • загрузить model;

  • выполнить initialization;

  • стать ready.

Поэтому:

Startup, readiness и liveness — разные состояния

Эти понятия полезны независимо от конкретного orchestrator.

Startup

Закончила ли replica initialization.

Readiness

Можно ли отправлять ей новые requests.

Liveness

Нужно ли считать process неисправным и перезапускать.

Для HA особенно важна граница:

readiness управляет eligibility нового traffic, но сама по себе не восстанавливает queued или in-flight requests.

Planned drain и abrupt failure нужно тестировать отдельно

При planned maintenance можно:

  1. прекратить admission новых requests;

  2. оставить worker живым;

  3. дождаться завершения in-flight work;

  4. вывести его из эксплуатации.

При crash такой graceful phase может отсутствовать.

Поэтому:

planned drain ≠ abrupt failure.

Оба сценария нужны в qualification.

Что происходит с новым request

Если inference ещё не начался, request обычно проще направить на другой healthy worker.

Но нужно проверить:

  • когда failed endpoint перестаёт считаться eligible;

  • сколько времени новый traffic ещё может попадать на него;

  • как работает retry/reroute.

Поэтому failure detection и traffic removal измеряются отдельно.

Что происходит с queued request

Queued request уже находится внутри serving stack.

Его судьба зависит от:

  • места расположения queue;

  • ownership;

  • upstream retry;

  • конкретной serving architecture.

Поэтому нельзя универсально обещать:

queued request автоматически перейдёт на другой worker.

Эта policy должна быть определена заранее.

Что происходит во время prefill

Во время prefill worker уже выполняет существенный compute и формирует request-specific state.

При отказе возможны разные сценарии:

  • повтор prefill;

  • migration;

  • возврат ошибки.

Что именно произойдёт, зависит от serving stack.

Что происходит во время decode

Во время decode существуют:

  • KV state;

  • generated-token history;

  • возможно, уже переданная клиенту часть ответа.

Поэтому такой request нельзя считать обычным stateless HTTP-вызовом.

Load balancer сам по себе не умеет продолжить generation.

Streaming response требует отдельной policy

Если клиент уже получил часть output, полный retry может:

  • повторить часть ответа;

  • дать отличающееся продолжение;

  • создать duplicate downstream actions.

Поэтому для streaming заранее нужно определить:

  • request должен завершиться ошибкой;

  • можно ли его retry;

  • поддерживается ли migration;

  • требуется ли reconciliation на application side.

Универсально безопасного retry нет.

Почему KV cache усложняет failover

Две replicas могут иметь одинаковую модель, но разную стоимость обработки конкретного prompt.

На одном worker может находиться полезный prefix cache.

На другом — нет.

После reroute cache locality может ухудшиться в зависимости от serving architecture, и новый worker выполнит дополнительный prefill compute.

Это способно увеличить:

  • TTFT;

  • queue time;

  • GPU load.

Поэтому после failure latency нужно измерять заново.

Cache-aware routing не является HA

KV-aware или load-aware routing помогает выбрать подходящий healthy worker.

Но не заменяет:

  • reserve capacity;

  • failure detection;

  • request recovery;

  • replacement;

  • degraded benchmark.

Routing — только один слой HA architecture.

Можно ли продолжить generation на другом worker

Некоторые современные serving stacks поддерживают request migration.

В таком случае active generation может быть продолжена на другом worker.

Но это implementation-specific capability.

Она может:

  • быть выключена;

  • иметь ограничения по request type;

  • зависеть от sequence length;

  • требовать отдельной настройки.

Поэтому нельзя исходить из предположения:

любой LLM request автоматически продолжится на другом GPU.

Migration не означает автоматически перенос готового KV state

Request migration не следует приравнивать к бесплатному переносу всего GPU-resident state.

Конкретный recovery path зависит от serving stack и topology.

После миграции могут появиться:

  • recompute;

  • дополнительный prefill;

  • queue delay;

  • временное ухудшение ITL.

Поэтому migration нужно оценивать не только бинарно:

request завершился / не завершился.

Нужна также latency penalty.

Что измерять при migration

Полезно фиксировать:

  • success/failure;

  • interruption duration;

  • изменение ITL;

  • дополнительную queue delay;

  • incomplete output;

  • duplicated output;

  • recompute/cache effects.

Для streaming главным критерием является фактическое поведение, которое видит клиент.

Что делать, если degraded pool перегружен

После потери worker оставшиеся replicas могут приблизиться к saturation.

Если продолжать принимать весь новый traffic:

  • queue растёт;

  • TTFT ухудшается;

  • timeouts порождают retries;

  • retries дополнительно увеличивают нагрузку.

Это может привести к cascading overload.

Поэтому serving architecture может использовать load shedding — controlled rejection части новых requests.

Load shedding не заменяет failover reserve

Controlled rejection может защитить surviving workers.

Но если SLO требует обслуживать весь protected load, rejection этого traffic означает:

Capacity PASS не пройден.

Load shedding — safety/degradation mechanism, а не способ превратить недостаточную capacity в достаточную.

Поэтому rejection policy должна быть частью SLO заранее.

Availability не равно сохранению SLO

2
Availability не равно сохранению SLO

Сервис может формально продолжать отвечать, но:

  • TTFT вырос в несколько раз;

  • queue постоянно увеличивается;

  • часть requests отклоняется;

  • streaming connections обрываются.

Такой сервис жив.

Но HA qualification он может не пройти.

Главный критерий:

Что измерять во время failure

Минимальный набор:

Метрика

Зачем

Offered protected load

Убедиться, что тест не стал легче

Successful requests

Фактически обслуженная нагрузка

Errors

Failure impact

Rejections

Overload policy

Throughput

Degraded capacity

p95 TTFT

Delay до первого token

p95 ITL

Responsiveness generation

p95 E2E latency

Полная задержка

Queue

Saturation

KV-cache usage

Pressure surviving pool

Failed in-flight requests

Request continuity

Migrated/retried requests

Recovery behaviour

Failure detection time

Это интервал:

от фактического failure до момента, когда serving/control path определил проблему.

Но это ещё не означает, что новый traffic полностью перестал попадать на failed endpoint.

Traffic removal time

Отдельная метрика:

когда failed endpoint фактически перестал получать новые requests.

Detection и traffic removal могут происходить не одновременно.

Request recovery time

Если stack поддерживает migration или другой recovery mechanism, отдельно измеряется время до:

  • продолжения request;

  • либо его terminal failure.

Это особенно важно для streaming.

Degraded-service interval

После reroute cluster всё ещё работает с уменьшенным ready pool.

Этот период продолжается до возвращения replacement capacity.

И именно здесь нужно проверять:

  • TTFT;

  • ITL;

  • queue;

  • errors;

  • rejections.

Replacement readiness

Recovery timeline может выглядеть так:

failure

→ replacement requested

→ GPU/resource allocated

→ process started

→ model loaded

→ engine initialized

→ ready

→ production traffic поступает на worker

Последний пункт тоже важен.

Формальная readiness ещё должна реализоваться в реальном routing.

Full-capacity recovery

Тест нельзя заканчивать, когда число replicas снова стало исходным.

Нужно проверить:

  • все нужные workers действительно ready;

  • router использует их;

  • queue вернулась к нормальному состоянию;

  • healthy latency envelope восстановлен.

Только после этого capacity можно считать восстановленной.

Почему autoscaling не заменяет HA

Autoscaling отвечает:

сколько replicas нужно добавить или убрать при изменении demand?

High availability отвечает:

какая capacity остаётся сразу после потери защищаемого ресурса?

До момента, когда новые workers станут ready, сервис опирается только на уже доступный degraded pool.

Поэтому:

Почему load balancer не доказывает HA

Load balancer распределяет traffic.

Для полноценного HA дополнительно нужны:

  • endpoint eligibility;

  • failure detection;

  • degraded capacity;

  • request-fate policy;

  • overload policy;

  • replacement/recovery.

Наличие балансировщика само по себе не подтверждает отказоустойчивость.

Inference HA Worksheet

Перед проектированием двух и более inference nodes полезно заполнить одну карточку.

Service objective

Параметр

Значение

Protected load

Input token distribution

Output token distribution

Streaming share

Repeated-prefix profile

TTFT target

ITL target

E2E target

Error policy

Rejection policy

Topology

Параметр

Значение

Nodes

Workers

GPU/worker

Serving engine/version

Routing

KV-cache policy

Ready reserve

Failure Budget

Параметр

Значение

Named failure

Resources lost

Shared dependencies

Remaining ready workers

Healthy vs degraded

Метрика

Healthy

Failed topology

Offered protected load

Throughput

p95 TTFT

p95 ITL

p95 E2E

Queue

Errors

Rejections

KV usage

Failed in-flight requests

Recovery

Метрика

Значение

Failure detection

Traffic removal

Request recovery

Degraded interval

Replacement started

Replacement ready

Full capacity restored

Request Fate Matrix

Для каждого этапа request заранее определите ожидаемый outcome.

Request state

Policy

До routing

Routed, inference не начат

Queue

Prefill

Decode

Streaming

Completed

Возможные policies:

  • reroute;

  • retry;

  • migrate;

  • recompute;

  • fail.

Как провести HA qualification

3
Как провести HA qualification

1. Зафиксировать serving configuration

Сохранить:

  • model/version;

  • precision/quantization;

  • engine/version;

  • GPU topology;

  • parallelism;

  • routing;

  • cache configuration.

2. Зафиксировать production-like request mix

Нужны:

  • input-token distribution;

  • output-token distribution;

  • concurrency или arrival profile;

  • streaming share;

  • repeated prefixes;

  • используемые API features.

3. Определить protected load

Именно этот offered load должен сохраняться во время fault test.

Не произвольный theoretical peak, если он не входит в HA objective.

4. Зафиксировать SLO

Определить:

  • TTFT;

  • ITL;

  • E2E latency;

  • errors;

  • rejection policy.

5. Назвать failure domain

Например:

  • worker;

  • GPU;

  • node.

6. Снять healthy baseline

На representative steady-state protected load.

7. Провести planned drain

Проверить:

  • остановку нового admission;

  • behaviour in-flight requests;

  • фактическое исключение worker из нового traffic.

8. Провести abrupt failure

Отдельно от graceful drain.

9. Измерить failure detection

Когда проблема стала известна serving/control layer.

10. Измерить traffic removal

Когда новые requests перестали попадать на unusable endpoint.

11. Зафиксировать Request Fate

Особенно:

  • queued;

  • prefill;

  • decode;

  • streaming.

12. Не уменьшать protected offered load

Иначе тест не измеряет degraded capacity.

13. Измерить degraded SLO

Сохранить:

  • throughput;

  • TTFT;

  • ITL;

  • E2E;

  • queue;

  • errors;

  • rejections.

14. Проверить KV/cache effect

Посмотреть, изменились ли:

  • cache locality;

  • prefill load;

  • KV pressure.

15. Проверить overload policy

Что произойдёт, если degraded pool достигнет saturation?

16. Измерить replacement readiness

До момента, когда worker реально готов обслуживать production requests.

17. Проверить full recovery

Убедиться, что:

  • capacity восстановлена;

  • routing использует replacement;

  • healthy SLO снова достигнут.

Когда архитектура проходит HA qualification

Failure-Domain PASS

Тест удаляет именно тот resource или domain, отказ которого должна выдерживать архитектура.

Routing PASS

Новый traffic перестаёт идти на unusable endpoint.

Request-Fate PASS

Queued и in-flight requests ведут себя согласно заранее принятой policy.

Capacity PASS

Cdegraded ≥ Lprotected

при одинаковом workload definition и SLO.

Latency PASS

Degraded:

  • TTFT;

  • ITL;

  • E2E latency

остаются в согласованном envelope.

Overload PASS

При выходе за protected envelope система деградирует предсказуемо, а не уходит в cascading overload.

Recovery PASS

Replacement capacity становится реально usable в требуемый interval.

Maintenance PASS

Planned drain проходит без неприемлемого service disruption.

Когда проблема может быть не в количестве replicas

Симптом

Что проверить

Новый traffic всё ещё идёт на dead worker

detection / routing

Process жив, но inference не выполняется

readiness / engine health

TTFT резко вырос после failure

queue / cache locality / prefill

Throughput почти тот же, latency хуже

saturation

Queue продолжает расти

недостаточная degraded capacity

KV usage резко вырос

pressure surviving workers

Streaming обрывается

migration / retry policy

Retry создаёт duplicate output

client/application semantics

Migration работает не для всех requests

stack/API limitations

Planned drain обрывает long generations

drain window

Replacement process есть, но traffic не получает

readiness / routing

Worker долго становится ready

model loading / initialization

Autoscaling помогает позже нужного

insufficient immediate capacity

Rejections растут

load shedding / insufficient reserve

Healthy metrics хорошие, degraded SLO нарушен

failover reserve

Какие данные нужны для проектирования отказоустойчивого LLM-инференса

Перед выбором hardware topology полезно собрать:

Блок

Данные

Model

version, precision/quantization

Engine

serving stack/version

Request profile

input/output distributions

Traffic

normal/peak/protected

SLO

TTFT, ITL, E2E, error/rejection

Topology

workers, nodes, GPU

Routing

eligibility/load/cache policy

Failure

required failure domains

Request state

queue/prefill/decode/streaming

Healthy baseline

throughput/latency/queue

Degraded test

те же metrics после failure

Recovery

detect/remove/ready/full recovery

После этого вопрос:

Сколько серверов нужно для отказоустойчивого LLM-инференса?

можно заменить технически проверяемым требованием:

После этого можно переходить к подбору production-систем для LLM-инференса.

Главное

Отказоустойчивость LLM-инференса определяется не количеством replicas.

Сначала нужно зафиксировать:

production request mix → protected load → SLO → failure domain.

Затем снять:

healthy baseline.

После этого провести controlled failure и сохранить тот же protected offered load.

Проверить:

detection → routing → request fate → degraded capacity → TTFT/ITL/queue/errors → replacement readiness → full recovery.

При этом:

Replicas ≠ HA.

Readiness ≠ request recovery.

Load balancer ≠ HA proof.

Healthy capacity ≠ degraded capacity.

Headroom ≠ failover reserve.

KV-aware routing ≠ failover capacity.

Migration ≠ универсальная возможность любого serving stack.

Load shedding ≠ достаточный резерв.

Replacement started ≠ replacement ready.

Autoscaling ≠ immediate failover capacity.

Traffic rerouted ≠ HA test completed.

Финальное доказательство HA — fault-injection test, в котором после реального отказа оставшийся ready pool продолжает обслуживать заранее определённый protected load в требуемом service envelope, behaviour in-flight requests соответствует принятой policy, а затем действительно восстанавливается normal service capacity.