NextStatNextStat

Rust — справка API

Rust API организован как Cargo workspace с несколькими крейтами. Каждый крейт имеет чёткую ответственность в соответствии с принципами чистой архитектуры.

КрейтНазначение
ns-coreТипы и трейты (Model, FitResult, обработка ошибок)
ns-adАвтоматическое дифференцирование (Dual, Tape, Scalar trait)
ns-probРаспределения вероятностей и мат. функции (logpdf, cdf, трансформы)
ns-unbinnedPDF событийного уровня, normalizing flows, DCR-суррогаты
ns-computeБэкенды вычислений: SIMD, Apple Accelerate, CUDA, Metal
ns-rootНативный ROOT I/O (TH1, TTree, движок выражений)
ns-translateТрансляторы: pyhf JSON, HistFactory XML, HS3, TRExFitter, Arrow
ns-inferenceАлгоритмы вывода (MLE, NUTS, CLs, PK/NLME, churn, эконометрика)
ns-vizАртефакты визуализации (CLs, профили, ранжирование, pulls, gammas)
ns-cliCLI nextstat
ns-serverREST API nextstat-server (axum)
ns-wasmWebAssembly-привязки для браузерной песочницы
ns-zstdЧистый Rust Zstd-декодер (оптимизирован для ROOT)
ns-pyPython-привязки через PyO3/maturin

ns-core: типы и трейты

Определяет LogDensityModel (NLL + градиент + метаданные),FitResult (параметры, неопределённости, NLL, информация о сходимости, termination_reason, final_grad_norm, initial_nll, n_active_bounds) и типы ошибок.

ns-prob: распределения вероятностей

Переиспользуемые блоки вероятностей. Каждый модуль экспортирует logpdf/nll: normal, poisson, exponential, gamma, beta, weibull, student_t, bernoulli, binomial, neg_binomial. Также: стабильные мат. хелперы (log1pexp, sigmoid, softplus) и биективные трансформы (ParameterTransform).

ns-translate: загрузка моделей

use ns_translate::pyhf::{
    HistFactoryModel, HistoSysInterpCode,
    NormSysInterpCode, Workspace,
};

let json = std::fs::read_to_string("workspace.json")?;
let ws: Workspace = serde_json::from_str(&json)?;

// Интерполяция по умолчанию (NextStat "smooth"):
//   NormSys=Code4, HistoSys=Code4p.
// Для строгих значений HistFactory/pyhf используйте Code1/Code0:
let model = HistFactoryModel::from_workspace_with_settings(
    &ws,
    NormSysInterpCode::Code1,
    HistoSysInterpCode::Code0,
)?;

from_workspace() использует smooth-настройки NextStat по умолчанию (Code4/Code4p). Используйте from_workspace_with_settings() чтобы явно выбрать коды интерполяции. См. docs/pyhf-parity-contract.md для подробностей.

ns-inference: фиттинг

use ns_inference::mle::MaximumLikelihoodEstimator;

let mle = MaximumLikelihoodEstimator::new();
let result = mle.fit(&model)?;

println!("Параметры: {:?}", result.parameters);
println!("NLL: {}", result.nll);
println!("Неопределенности: {:?}", result.uncertainties);

GPU Flow Session (CUDA, feature-gated)

Оркестрирует оценку flow PDF + GPU NLL-редукцию для небиннированных моделей с нейронными PDF:

• GpuFlowSession — сессия: flow eval (CPU / CUDA EP) + GPU NLL-редукция
  ├ new(config)           — создать сессию, выделить GPU-буферы
  ├ nll(logp_flat, params) — NLL из предвычисленных logp_flat[n_procs × n_events]
  ├ nll_grad(params, eval_logp) — NLL + градиент (центральные конечные разности)
  └ compute_yields(params)      — вычисление yield из вектора параметров

• GpuFlowSessionConfig — processes, n_events, n_params, gauss_constraints
• FlowProcessDesc     — base_yield, yield_param_idx, yield_is_scaled
use ns_inference::gpu_flow_session::{GpuFlowSession, GpuFlowSessionConfig, FlowProcessDesc};

let config = GpuFlowSessionConfig {
    processes: vec![
        FlowProcessDesc {
            process_index: 0,
            base_yield: 100.0,
            yield_param_idx: Some(0),
            yield_is_scaled: true,
        },
    ],
    n_events: 50_000,
    n_params: 1,
    gauss_constraints: vec![],
    constraint_const: 0.0,
};

let mut session = GpuFlowSession::new(config)?;
let nll = session.nll(&logp_flat, &params)?;

Модели волатильности (GARCH / Стохастическая волатильность)

Оценка волатильности финансовых временных рядов в ns_inference::timeseries::volatility:

• garch11_fit(y, config) → Garch11Fit — MLE гауссовой GARCH(1,1) (L-BFGS-B)
  ├ Garch11Params { mu, omega, alpha, beta }
  ├ Garch11Config { optimizer, alpha_beta_max, init, min_var }
  └ Garch11Fit   { params, log_likelihood, conditional_variance, optimization }

• sv_logchi2_fit(y, config) → SvLogChi2Fit — приближённая SV через log(χ²₁) + Kalman MLE
  ├ SvLogChi2Params { mu, phi, sigma }
  ├ SvLogChi2Config { optimizer, log_eps, init }
  └ SvLogChi2Fit   { params, log_likelihood, smoothed_h, smoothed_sigma, optimization }
use ns_inference::timeseries::volatility::{garch11_fit, Garch11Config};

let returns = vec![0.01, -0.02, 0.005, 0.03, -0.015];
let fit = garch11_fit(&returns, Garch11Config::default())?;
println!("omega={:.4} alpha={:.4} beta={:.4}",
    fit.params.omega, fit.params.alpha, fit.params.beta);

ns-root: ROOT I/O

use ns_root::RootFile;

let file = RootFile::open("data.root")?;
let tree = file.get_tree("events")?;

// Столбцовая выборка
let pt: Vec<f64> = file.branch_data(&tree, "pt")?;
let eta: Vec<f64> = file.branch_data(&tree, "eta")?;

// Компилируемые выражения
let expr = ns_root::CompiledExpr::compile(
    "pt > 25.0 && abs(eta) < 2.5"
)?;

ns-ad: автоматическое дифференцирование

Предоставляет автоматическое дифференцирование на основе двойных чисел и ленты, используемое внутри оптимизатора для вычисления градиентов.

ns-compute: абстракция бэкендов

Абстрагирует CPU (SIMD), Apple Accelerate (vDSP/vForce), CUDA и Metal бэкенды. Слой вывода выбирает лучший доступный бэкенд во время выполнения.

CudaFlowNllAccelerator (feature-gated)

GPU NLL-редукция из внешне вычисленных log-prob значений (flow PDF). Отделяет оценку PDF от редукции правдоподобия, позволяя использовать смешанные параметрические+flow модели.

• CudaFlowNllAccelerator
  ├ new(config: &FlowNllConfig)              — выделение GPU-буферов, загрузка PTX-ядра
  ├ nll(logp_flat, yields, params) → f64     — host-upload: logp вычислен на CPU, загружен на GPU
  ├ nll_device(d_logp_flat, yields, params)  — device-resident: CudaSlice<f64> от CUDA EP (zero-copy)
  └ is_available() → bool                    — проверка наличия CUDA

• FlowNllConfig — n_events, n_procs, n_params, gauss_constraints, constraint_const

ns-translate: Arrow / Parquet

Zero-copy колоночный обмен данными с экосистемой Arrow. Скрыт за feature-флагом arrow-io.

// Принять Arrow IPC → Workspace
use ns_translate::arrow::ingest::{from_arrow_ipc, ArrowIngestConfig};

let config = ArrowIngestConfig { poi: "mu", .. };
let workspace = from_arrow_ipc(&ipc_bytes, &config)?;

// Экспортировать Model → Arrow IPC
use ns_translate::arrow::export::yields_to_ipc;
let ipc = yields_to_ipc(&model, Some(&params))?;

// Чтение/запись Parquet (Zstd)
use ns_translate::arrow::parquet::{from_parquet, write_parquet};
let workspace = from_parquet("histograms.parquet", &config)?;

Схема: channel (Utf8), sample (Utf8), yields (List<Float64>), опционально stat_error (List<Float64>).

ns-server: REST API

Самостоятельный REST API для общего GPU-вывода, построен на axum 0.8.

// Ключевые элементы
ns_server::state::AppState     // блокировка GPU, атомарные счетчики, кеш моделей
ns_server::pool::ModelPool     // LRU-кеш по SHA-256 workspace
ns_server::pool::ModelInfo     // метаданные кешированной модели (id, name, params, age)

// Эндпоинты: /v1/fit, /v1/ranking, /v1/batch/fit,
//           /v1/models, /v1/health

ns-unbinned: PDF событийного уровня

Параметрические PDF: GaussianPdf, CrystalBallPdf, DoubleCrystalBallPdf, ExponentialPdf, ChebyshevPdf, ArgusPdf, VoigtianPdf, SplinePdf. Непараметрические: HistogramPdf, KdePdf, MorphingHistogramPdf, ProductPdf. Нейронные (feature neural): FlowPdf, DcrSurrogate. Все реализуют трейт UnbinnedPdf.

ns-inference: дифференцируемый слой

Zero-copy интеграция с PyTorch для ML-воркфлоу:

• DifferentiableSession (CUDA)
  ├ nll_grad_signal(params, d_signal, d_grad_signal) — zero-copy градиент в PyTorch-тензор
  └ signal_n_bins(), n_params(), parameter_init()

• ProfiledDifferentiableSession (CUDA)
  ├ profiled_q0_and_grad(d_signal) → (f64, Vec<f64>) — q₀ + градиент (envelope theorem)
  └ profiled_qmu_and_grad(mu_test, d_signal) → (f64, Vec<f64>) — qμ исключения

• MetalProfiledDifferentiableSession (Metal, f32)
  ├ upload_signal(signal), profiled_q0_and_grad(), profiled_qmu_and_grad(mu_test)
  └ batch_profiled_qmu(mu_values) — множество значений mu с переиспользованием сессии

ns-viz: артефакты визуализации

Лёгкие JSON-сериализуемые артефакты без зависимостей. Все содержат schema_version.

ClsCurveArtifact         — Brazil band CLs кривые исключения
ProfileCurveArtifact     — −2Δln L профильные сканы
RankingArtifact          — влияние NP на POI
PullsArtifact            — pull/constraint графики для всех NP
CorrArtifact             — корреляционная (+ ковариационная) матрица
DistributionsArtifact    — стекированные pre/post-fit гистограммы с ratio-панелью
YieldsArtifact           — таблицы yield по каналам
GammasArtifact           — параметры staterror (Barlow-Beeston)
SeparationArtifact       — метрика S/B разделения по каналам
PieArtifact              — доли компонентов по сэмплам
UncertaintyBreakdownArtifact — группированная разбивка влияния NP

ns-zstd: чистый Rust Zstd-декодер

Форк ruzstd 0.8.2, оптимизированный для декомпрессии ROOT-файлов. Объединённый decode+execute (один проход), экспоненциальное копирование совпадений, статические таблицы Хаффмана. ~820 МБ/с медианная пропускная способность (2× оригинального ruzstd).

Сборка и тестирование

# Собрать весь workspace
cargo build --workspace

# Запустить все тесты
cargo test --workspace --all-features

# Форматирование и линт
cargo fmt --check
cargo clippy --workspace -- -D warnings

# Бенчмарки
cargo bench --workspace