Перейти к основному содержимому

Чтобы получить чистую Markdown-версию этой страницы, добавьте .md к этому URL. Полный индекс документации доступен по адресу https://docs.nvidia.com/dynamo/llms.txt. Полное содержимое, включая API reference и примеры SDK, доступно по адресу https://docs.nvidia.com/dynamo/llms-full.txt.

Тестирование

В этом документе описана инфраструктура тестирования для проверки механизмов отказоустойчивости Dynamo. Фреймворк тестирования поддерживает отмену запросов, миграцию, HA для etcd и сценарии инъекции аппаратных сбоев.

Обзор

Набор тестов отказоустойчивости Dynamo находится в tests/fault_tolerance/ и включает:

Категория тестовРасположениеНазначение
Отменаcancellation/Отмена запроса во время выполнения
Миграцияmigration/Миграция запроса при отказе workers
HA etcdetcd_ha/Переключение и восстановление etcd
Аппаратныеhardware/Инъекция сбоев GPU и сети
Развертываниеdeploy/Сквозное тестирование развертывания

Структура каталога тестов

tests/fault_tolerance/
├── cancellation/
│ ├── test_vllm.py
│ ├── test_trtllm.py
│ ├── test_sglang.py
│ └── utils.py
├── migration/
│ ├── test_vllm.py
│ ├── test_trtllm.py
│ ├── test_sglang.py
│ └── utils.py
├── etcd_ha/
│ ├── test_vllm.py
│ ├── test_trtllm.py
│ ├── test_sglang.py
│ └── utils.py
├── hardware/
│ └── fault_injection_service/
│ ├── api_service/
│ └── agents/
├── deploy/
│ ├── test_deployment.py
│ ├── scenarios.py
│ ├── base_checker.py
│ └── ...
└── client.py

Тесты отмены запросов

Проверяют, что выполняющиеся запросы можно корректно отменять.

Запуск тестов отмены

# Run all cancellation tests
pytest tests/fault_tolerance/cancellation/ -v

# Run for specific backend
pytest tests/fault_tolerance/cancellation/test_vllm.py -v

Утилиты для тестов отмены

Модуль cancellation/utils.py предоставляет:

CancellableRequest

Потокобезопасную отмену запроса через управление TCP-сокетом:

from tests.fault_tolerance.cancellation.utils import CancellableRequest

request = CancellableRequest()

# Send request in separate thread
thread = Thread(target=send_request, args=(request,))
thread.start()

# Cancel after some time
time.sleep(1)
request.cancel() # Closes underlying socket

send_completion_request / send_chat_completion_request

Отправляют отменяемые completion-запросы:

from tests.fault_tolerance.cancellation.utils import (
send_completion_request,
send_chat_completion_request
)

# Non-streaming
response = send_completion_request(
base_url="http://localhost:8000",
model="Qwen/Qwen3-0.6B",
prompt="Hello, world!",
max_tokens=100
)

# Streaming with cancellation
responses = send_chat_completion_request(
base_url="http://localhost:8000",
model="Qwen/Qwen3-0.6B",
messages=[{"role": "user", "content": "Hello!"}],
stream=True,
cancellable_request=request
)

poll_for_pattern

Ожидает определенные шаблоны в логах:

from tests.fault_tolerance.cancellation.utils import poll_for_pattern

# Wait for cancellation confirmation
found = poll_for_pattern(
log_file="/var/log/dynamo/worker.log",
pattern="Request cancelled",
timeout=30,
interval=0.5
)

Тесты миграции

Проверяют, что запросы мигрируют на исправные workers при возникновении сбоев.

Запуск тестов миграции

# Run all migration tests
pytest tests/fault_tolerance/migration/ -v

# Run for specific backend
pytest tests/fault_tolerance/migration/test_vllm.py -v

Утилиты для тестов миграции

Модуль migration/utils.py предоставляет:

  • Обертку Frontend с настраиваемыми request planes
  • Создание длительных запросов для сценариев миграции
  • Отключение health check для контролируемого тестирования

Пример теста миграции

def test_migration_on_worker_failure():
# Start deployment with 2 workers
deployment = start_deployment(workers=2)

# Send long-running request
request_thread = spawn_long_request(max_tokens=1000)

# Kill one worker mid-generation
kill_worker(deployment.workers[0])

# Verify request completes on remaining worker
response = request_thread.join()
assert response.status_code == 200
assert len(response.tokens) > 0

Тесты HA для etcd

Проверяют поведение системы во время сбоев etcd и восстановления.

Запуск тестов HA для etcd

pytest tests/fault_tolerance/etcd_ha/ -v

Сценарии тестирования

  • Переключение лидера: отказывает узел-лидер etcd, кластер выбирает нового лидера
  • Сетевое разделение: узел etcd становится недоступен
  • Восстановление: система восстанавливается после повторного появления etcd

Инъекция аппаратных сбоев

Сервис инъекции сбоев позволяет тестировать систему при имитированных аппаратных отказах.

Сервис инъекции сбоев

Этот сервис FastAPI, расположенный в tests/fault_tolerance/hardware/fault_injection_service/, управляет инъекцией сбоев:

# Start the fault injection service
cd tests/fault_tolerance/hardware/fault_injection_service
python -m api_service.main

Поддерживаемые типы сбоев

Сбои GPU

Тип сбояОписание
XID_ERRORИмитирует ошибку GPU XID (разные коды)
THROTTLEТепловой троттлинг GPU
MEMORY_PRESSUREИсчерпание памяти GPU
OVERHEATПерегрев GPU
COMPUTE_OVERLOADПерегрузка вычислений GPU

Сетевые сбои

Тип сбояОписание
FRONTEND_WORKERРазделение между frontend и workers
WORKER_NATSРазделение между workers и NATS
WORKER_WORKERРазделение между workers
CUSTOMПользовательское сетевое разделение

API инъекции сбоев

Инъекция сбоя GPU

curl -X POST http://localhost:8080/api/v1/faults/gpu/inject \
-H "Content-Type: application/json" \
-d '{
"target_pod": "vllm-worker-0",
"fault_type": "XID_ERROR",
"severity": "HIGH"
}'

Поддерживаемые коды XID: 43, 48, 74, 79, 94, 95, 119, 120

Инъекция сетевого разделения

curl -X POST http://localhost:8080/api/v1/faults/network/inject \
-H "Content-Type: application/json" \
-d '{
"partition_type": "FRONTEND_WORKER",
"duration_seconds": 30
}'

Восстановление после сбоя

curl -X POST http://localhost:8080/api/v1/faults/{fault_id}/recover

Список активных сбоев

curl http://localhost:8080/api/v1/faults

Агент инъекции сбоев GPU

Инжектор сбоев GPU запускается как DaemonSet на worker-узлах:

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: gpu-fault-injector
spec:
selector:
matchLabels:
app: gpu-fault-injector
template:
spec:
containers:
- name: agent
image: dynamo/gpu-fault-injector:latest
securityContext:
privileged: true
volumeMounts:
- name: dev
mountPath: /dev

Агент внедряет поддельные сообщения XID через /dev/kmsg, чтобы запустить обнаружение NVSentinel.

Фреймворк тестирования развертывания

Каталог deploy/ содержит фреймворк для сквозного тестирования.

Фазы тестирования

Тесты проходят три фазы:

ФазаОписание
STANDARDБазовая производительность в нормальных условиях
OVERFLOWПоведение системы во время сбоя/перегрузки
RECOVERYВосстановление системы после устранения сбоя

Конфигурация сценариев

Определяйте тестовые сценарии в scenarios.py:

from tests.fault_tolerance.deploy.scenarios import Scenario, Load, Failure

scenario = Scenario(
name="worker_failure_migration",
backend="vllm",
load=Load(
clients=10,
requests_per_client=100,
max_tokens=256
),
failure=Failure(
type="pod_kill",
target="vllm-worker-0",
trigger_after_requests=50
)
)

Запуск тестов развертывания

# Run all deployment tests
pytest tests/fault_tolerance/deploy/test_deployment.py -v

# Run specific scenario
pytest tests/fault_tolerance/deploy/test_deployment.py::test_worker_failure -v

Проверяющие валидаторы

Фреймворк включает подключаемые валидаторы:

from tests.fault_tolerance.deploy.base_checker import BaseChecker, ValidationContext

class MigrationChecker(BaseChecker):
def check(self, context: ValidationContext) -> bool:
# Verify migrations occurred
migrations = context.metrics.get("migrations_total", 0)
return migrations > 0

Разбор результатов

Разбирайте результаты тестов для анализа:

from tests.fault_tolerance.deploy.parse_results import process_overflow_recovery_test

results = process_overflow_recovery_test(log_dir="/path/to/logs")
print(f"Success rate: {results['success_rate']}")
print(f"P99 latency: {results['p99_latency_ms']}ms")

Утилиты клиента

Модуль client.py предоставляет общую клиентскую функциональность:

Многопоточная генерация нагрузки

from tests.fault_tolerance.client import client

# Generate load with multiple clients
results = client(
base_url="http://localhost:8000",
num_clients=10,
requests_per_client=100,
model="Qwen/Qwen3-0.6B",
max_tokens=256,
log_dir="/tmp/test_logs"
)

Параметры запроса

ПараметрОписание
base_urlURL frontend
num_clientsКоличество одновременных клиентов
requests_per_clientЗапросов на клиента
modelИмя модели
max_tokensМаксимальное число токенов на запрос
log_dirКаталог для логов клиента
endpointcompletions or chat/completions

Запуск полного набора тестов

Предварительные требования

  1. Kubernetes-кластер с GPU-узлами
  2. Развертывание Dynamo
  3. Кластер etcd (для тестов HA)
  4. Сервис инъекции сбоев (для аппаратных тестов)

Настройка окружения

export KUBECONFIG=/path/to/kubeconfig
export DYNAMO_NAMESPACE=dynamo-test
export FRONTEND_URL=http://localhost:8000

Запуск всех тестов

# Install test dependencies
pip install pytest pytest-asyncio

# Run all fault tolerance tests
pytest tests/fault_tolerance/ -v --tb=short

# Run with specific markers
pytest tests/fault_tolerance/ -v -m "not slow"

Маркеры тестов

МаркерОписание
slowДолгие тесты (> 5 минут)
gpuТребует GPU-ресурсы
k8sТребует Kubernetes-кластер
etcd_haТребует многонодовый etcd

Лучшие практики

1. Изолируйте тестовые окружения

Запускайте тесты отказоустойчивости в выделенных namespaces:

kubectl create namespace dynamo-fault-test

2. Очищайте окружение после тестов

Убедитесь, что сбои восстановлены:

# List and recover all active faults
curl http://localhost:8080/api/v1/faults | jq -r '.[].id' | \
xargs -I {} curl -X POST http://localhost:8080/api/v1/faults/{}/recover

3. Собирайте логи

Сохраняйте логи для отладки:

pytest tests/fault_tolerance/ -v \
--log-dir=/tmp/fault_test_logs \
--capture=no

4. Следите за системой во время тестов

Наблюдайте за состоянием системы во время тестов:

# Terminal 1: Watch pods
watch kubectl get pods -n dynamo-test

# Terminal 2: Watch metrics
watch 'curl -s localhost:8000/metrics | grep -E "(migration|rejection)"'

Связанная документация