Платформа для моделирования физических процессов с учётом неопределённости. Если коротко — решаем 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)
# Для разработки — pytest, ruff, mypy, hypothesis, pip-audit
pip install -e ".[dev]"
# Полный набор — JAX, PyTorch, NumPyro, визуализация, PETSc
pip install -e ".[all]"
# Только gRPC + OpenTelemetry
pip install -e ".[api]"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 testGradient check — отдельная тема. GradientChecker сравнивает adjoint-градиент с конечными разностями и complex-step. Если relative error > 1% — что-то не так с сопряжённым методом, не игнорируй.
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 (.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)
- Форкни репо
- Ветка от main:
git checkout -b feature/название - Пиши код, прогоняй
ruff check python/ && pytest python/tests -m "not slow" - Коммить, пушь, открывай PR
- Pre-commit хуки проверят форматирование, секреты, большие файлы автоматически
Стиль: ruff format python/. Типы: mypy --strict. Без этого PR не мержим.