Skip to content

Repository files navigation

PDTX — Вероятностные Цифровые Двойники

Платформа для моделирования физических процессов с учётом неопределённости. Если коротко — решаем PDE, крутим байесовский вывод, ассимилируем данные в реальном времени. Всё это на Python (вычислительное ядро) и Java (микросервисная обвязка для прода).

Проект собран так, чтобы один человек мог запустить эксперимент за 5 минут, а команда — задеплоить в Kubernetes за полчаса. Без магии, без скрытых зависимостей, без «у меня на машине работает».


Архитектура

Четыре сервиса, каждый делает одно дело и делает его нормально:

                    ┌─────────────────────────────────────────────────────────┐
                    │                     Gateway (HTTP :8080)                 │
                    │           REST-прокси, rate limiter, валидация           │
                    └───────────────────────────┬───────────────────────────┘
                                                 │ gRPC
         ┌──────────────────────────────────────┼──────────────────────────────────────┐
         │                                      │                                       │
         ▼                                      ▼                                       ▼
┌─────────────────┐                 ┌─────────────────┐                    ┌─────────────────┐
│   Orchestrator   │                 │    Ingestion    │                    │  Python Core     │
│   (очередь задач)│◄────────────────│  (Kafka → gRPC) │◄───────────────────│  (gRPC :50051)   │
└────────┬─────────┘                 └────────┬────────┘                    └────────┬─────────┘
         │                                     │                                      │
         ▼                                     ▼                                      │
┌─────────────────┐                 ┌─────────────────┐                              │
│     Kafka       │                 │   Prometheus     │                              │
│   (KRaft mode)  │                 │   + Jaeger       │                              │
└─────────────────┘                 └─────────────────┘                              │
                                                                                      │
         ┌────────────────────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│  Python: pdtx_core | pdtx_pde | pdtx_solvers | pdtx_inference | pdtx_assimilation    │
│         pdtx_data | pdtx_viz | pdtx_surrogates | pdtx_adjoint | pdtx_api              │
└─────────────────────────────────────────────────────────────────────────────────────┘

Gateway принимает HTTP, валидирует через DTO, проксирует в Python Core по gRPC. Ingestion тянет наблюдения из Kafka и пушит в ассимиляцию. Orchestrator управляет очередью задач. Всё общение между сервисами — protobuf, бинарный, типизированный. JSON только на входе в Gateway.


Быстрый старт

git clone <repo-url>
cd Python-java
pip install -e ".[dev]"

# Обратная задача диффузии — восстанавливаем коэффициент теплопроводности
python scripts/run_uc1.py

# Ассимиляция Lorenz-96 через ансамблевый фильтр Калмана
python scripts/run_uc3_lorenz.py

# Проверка порядка сходимости на точном решении
python scripts/run_convergence_test.py

Если хочется сразу весь стек — cd docker && docker compose up -d. Поднимутся Python Core, Gateway, Kafka, Prometheus, Jaeger.


Структура проекта

Python-java/
├── python/                 # Вычислительное ядро
│   ├── pdtx_core/          # Сетки, поля, операторы, модели, observability, сессии
│   ├── pdtx_pde/           # PDE-модели: диффузия, Lorenz-96, manufactured solutions
│   ├── pdtx_solvers/       # Временные интеграторы, сборка матриц жёсткости
│   ├── pdtx_inference/     # MAP (L-BFGS, Adam, Gauss-Newton), MCMC (NUTS, HMC, pCN), VI
│   ├── pdtx_assimilation/  # EnKF, ETKF, LETKF, SMC — ансамблевые фильтры
│   ├── pdtx_adjoint/       # Сопряжённый солвер + gradient check (FD, complex-step)
│   ├── pdtx_data/          # Синтетические данные, паттерны пропусков, I/O (Zarr, HDF5)
│   ├── pdtx_viz/           # Графики сходимости, визуализация полей
│   ├── pdtx_surrogates/    # POD, FNO, ROM — когда полная модель слишком жирная
│   ├── pdtx_exp/           # CLI runner, трекер экспериментов, отчёты
│   └── pdtx_api/           # gRPC-сервер, конвертеры proto <-> Python, OpenAPI
├── java/                   # Микросервисная обвязка
│   ├── gateway-service/    # REST API, DTO, rate limiter
│   ├── ingestion-service/  # Kafka consumer, gRPC forwarder с retry
│   ├── orchestrator-service/ # Очередь задач, приоритизация
│   └── java-sdk/           # Клиентская библиотека, exception mapper
├── proto/                  # Protobuf-схемы (5 файлов: common, simulation, inference, assimilation, experiment)
├── docker/                 # Dockerfile.python, Dockerfile.java, Compose, OTEL collector
├── deploy/                 # Helm-чарты (staging/prod values), SLO, HPA, ServiceMonitor
├── scripts/                # Скрипты экспериментов UC-1..UC-5
├── configs/                # YAML-конфиги (сетка, PDE, метод, солвер)
├── docs/                   # ADR, troubleshooting
└── .github/workflows/      # CI (lint, test, security) + CD (build, staging, prod)

Установка

Python (3.10+)

# Для разработки — pytest, ruff, mypy, hypothesis, pip-audit
pip install -e ".[dev]"

# Полный набор — JAX, PyTorch, NumPyro, визуализация, PETSc
pip install -e ".[all]"

# Только gRPC + OpenTelemetry
pip install -e ".[api]"

Java (JDK 17+)

cd java
chmod +x gradlew
./gradlew build    # сборка + тесты

Эксперименты

Каждый use case — законченный эксперимент: конфиг -> данные -> метод -> метрики -> артефакты.

Скрипт Что делает
scripts/run_uc1.py Обратная задача диффузии: по разреженным температурным сенсорам восстанавливаем коэффициент теплопроводности κ через MAP-оценку (L-BFGS + adjoint для градиентов)
scripts/run_uc3_lorenz.py Ассимиляция данных Lorenz-96: EnKF с 40 переменными, частичные наблюдения, инфляция и локализация
scripts/run_convergence_test.py Проверка порядка сходимости дискретизации на manufactured solution — если не O(h^2), значит баг

Конфиги лежат в configs/, запускаются через CLI:

pdtx run --config configs/uc1_diffusion.yaml

Можно менять сетку, параметры PDE, метод вывода, солвер — всё через YAML без правки кода.


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

Coverage gate на 80% — ниже CI падает, без разговоров.

# Быстрые тесты (без slow-маркера)
pytest python/tests -v -m "not slow"

# С HTML-отчётом по покрытию
pytest python/tests -v --cov-report=html

# Только интеграционные
pytest python/tests -v -m slow

# Java
cd java && ./gradlew test

Gradient check — отдельная тема. GradientChecker сравнивает adjoint-градиент с конечными разностями и complex-step. Если relative error > 1% — что-то не так с сопряжённым методом, не игнорируй.


Docker-деплой

cd docker
docker compose up -d

Что поднимется:

Сервис Порт Назначение
python-core 50051 (gRPC), 8080 (health) Вычислительное ядро, все солверы
gateway 8080 REST API, rate limiter, DTO-валидация
kafka 9092 Брокер (KRaft, без Zookeeper)
ingestion - Kafka -> Python gRPC мост
orchestrator - Очередь задач
prometheus 9090 Метрики
otel-collector 4317 Сбор трейсов (OTLP)
jaeger 16686 UI для distributed tracing

Все контейнеры от non-root пользователя, с healthcheck, multi-stage сборка.


Сценарии использования

UC Задача Метод Что внутри
UC-1 Обратная диффузия MAP (L-BFGS + adjoint) Восстановление κ из 10 сенсоров. Prior gaussian, noise model — диагональная R. Gradient check для верификации adjoint
UC-2 2D адвекция-диффузия MAP / VI Точечный источник, оценка коэффициентов переноса и диффузии. 2D structured mesh
UC-3 Lorenz-96 EnKF / ETKF / LETKF 40 переменных, 20 наблюдаемых. Инфляция 1.02, Gaspari-Cohn локализация. Метрики: RMSE, spread-skill
UC-4 Полный байесовский вывод MCMC (NUTS, HMC, pCN) / VI Когда MAP-точка не устраивает — хочется posterior целиком. Diagnostics: ESS, R-hat, trace plots
UC-5 Суррогатное ускорение POD / FNO Полная модель слишком дорогая для MCMC — строим ROM и гоняем вывод на нём

Стек

Слой Что используем Зачем
Ядро NumPy, SciPy Линалг, sparse-солверы, оптимизация. Работает везде, зависимостей минимум
Данные Xarray, Zarr, PyArrow Многомерные поля, ленивая загрузка, колоночный формат
Конфигурация Pydantic, Hydra, OmegaConf Валидация конфигов на уровне типов, композиция YAML
Визуализация Matplotlib, PyVista 1D/2D графики, 3D рендер полей
API gRPC, protobuf Типизированный бинарный RPC между Python и Java
Observability OpenTelemetry, Prometheus, Jaeger Трейсинг, метрики, structured logging с correlation ID
Опционально JAX, PyTorch, NumPyro, PETSc, CuPy GPU-ускорение, autograd, параллельные PDE-солверы
Java Gradle, Javalin, Kafka client, gRPC REST-gateway, event-driven ingestion, SDK
Инфра Docker, Helm, K8s Контейнеризация, деплой, автоскейлинг

CI/CD

CI (.github/workflows/ci.yml):

  • Ruff lint + format check
  • Mypy strict на pdtx_core + pdtx_solvers
  • pytest на матрице Python 3.10 / 3.11 / 3.12 с coverage gate 80%
  • Интеграционные тесты + convergence test
  • pip-audit (уязвимости ломают пайплайн)
  • Java: gradlew build (компиляция + JUnit)

CD (.github/workflows/cd.yml):

  • Push в main -> Docker build -> GHCR -> staging (Helm + --atomic)
  • Release tag -> production (с ручным approve через GitHub environment)
  • Smoke test после деплоя (curl /health)

Контрибьютинг

  1. Форкни репо
  2. Ветка от main: git checkout -b feature/название
  3. Пиши код, прогоняй ruff check python/ && pytest python/tests -m "not slow"
  4. Коммить, пушь, открывай PR
  5. Pre-commit хуки проверят форматирование, секреты, большие файлы автоматически

Стиль: ruff format python/. Типы: mypy --strict. Без этого PR не мержим.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages