Webベースの水理・水文解析プラットフォームを独自に作る構想を立てる
はじめに
水文・河川分野の解析では、雨量、流量、水位、地形、河道、氾濫、土砂、ダム操作、人口・建物など、扱うデータが多くなります。
解析ソフトも一つでは済みません。多数のアプリを組み合わせる事により結果を得ることができます。
例えば、雨量を整理して流出解析を行い、その流量を河川解析へ渡し、さらに氾濫解析や被害評価へつなげる場合、実務では次のような作業が発生します。
- 雨量データを解析用に加工する
- 流出解析結果をCSVへ出力する
- 河川解析用の境界条件へ変換する
- 氾濫解析結果をGISへ読み込む
- ケースごとに入力ファイルを複製する
- どのデータ版、モデル版、パラメータで計算したのかを後から確認する
- 別の担当者へ引き継ぐために、データと計算条件を整理し直す
このあたりを個別のツールでつないでいくと、解析そのものよりもデータ管理やケース管理に時間を取られるようになります。
そこで、個々の解析ソフトを単独で作るのではなく、Project Workspaceと共通データ基盤を中心に、複数の解析アプリケーションを追加できるWebベースの解析プラットフォームを作ることを考えます。
既存の水文・河川解析ソフトウェア群の構成は参考にしますが、特定製品の互換環境を作ることが目的ではありません。
目標は、日本国内の水文・河川データや実務の進め方に合わせて拡張できる、独自の解析基盤です。そして、最終的には、データの取得から、報告書作成までを行う基盤を作成する事です。
1. まず決めたい全体像
最初に考えている構成は次のようなものです。
ポイントは、解析エンジンを中心にしないことです。
システム全体の中心に置くのは、
Project Workspace
+
共通データ基盤
です。
解析アプリケーションは、その上でデータを利用し、結果を戻す側と考えます。
2. Projectは「フォルダー」ではなくWorkspaceにする
このプラットフォームでは、Projectを単なる保存先にはしません。
Projectは、
一つの河川・流域・検討業務について、データ、モデル、シナリオ、計算履歴、整備状況をまとめて管理するWorkspace
とします。
例えば、Projectを開いたときに最初に見たいのは、ファイル一覧よりも現在の作業状況です。
解析対象河川
====================================================
概要 | データ | モデル | シナリオ | Run | 履歴
データ整備状況
----------------------------------------------------
流域界 登録済み
河川中心線 登録済み
観測所 12地点
雨量 登録済み
水位 一部不足
流量 登録済み
DEM 5m
河道断面 未登録
粗度 未登録
解析準備状況
----------------------------------------------------
Rainfall Studio READY
Runoff Studio READY
River Studio NOT READY
Flood Studio NOT READY
最近のRun
----------------------------------------------------
run-0027 SUCCEEDED
run-0026 FAILED
run-0025 SUCCEEDED
この画面をProject Workspaceの入口にします。
3. Projectで管理するもの
Project配下では、少なくとも次の情報をまとめます。
Project
│
├── ProjectSetting
│
├── ProjectDataset
│ ├── 流域
│ ├── 河川
│ ├── 観測所
│ ├── 雨量
│ ├── 水位
│ ├── 流量
│ └── DEM
│
├── ProjectModel
│ ├── Runoff Model
│ ├── River Model
│ └── Flood Model
│
├── Scenario
│
├── Run
│
├── ProjectReadiness
│
├── ProjectSnapshot
│
└── ProjectActivity
ここで、ProjectDatasetとDatasetは同じものではありません。
Projectには「このProjectでどのデータを使用するか」を関連付けます。
データ本体はData Hub側で管理します。
4. ProjectとData Hubは役割を分ける
Project WorkspaceとData Hubを混ぜると、後で責務が分かりにくくなります。
役割は次のように分けます。
| 機能 | 役割 |
|---|---|
| Project Workspace | このProjectで何を使うか、何が不足しているかを管理 |
| Data Hub | データそのものを登録・検索・更新・版管理する |
| Model | 解析モデルとモデル版を管理 |
| Scenario | 解析条件の組み合わせを管理 |
| Run | 実際の計算実行と履歴を管理 |
| Experiment | 複数Runの比較や実験を管理 |
| Workflow | 複数解析をつないで実行する |
関係は次のようになります。
Project Workspaceは、
「何を使っているか」
を管理します。
Data Hubは、
「データそのもの」
を管理します。
5. DatasetはProjectごとに物理コピーしない
同じDEMや観測データを複数Projectで利用することがあります。
そのため、
Project A ─┐
Project B ─┼── DatasetVersion DEM-r003
Project C ─┘
という参照構造にします。
データモデルとしては、例えば次のようにします。
Projectをコピーしても、10GBのDEMを複製する必要はありません。
6. Projectコピーを最初から考えておく
解析では、現況ケースを基に改修案や計画案を作ることが多くあります。
例えば、
解析対象河川_現況
│
├── Clone → 解析対象河川_改修案A
│
└── Clone → 解析対象河川_改修案B
という使い方です。
Projectコピー時には、何を引き継ぐか選べるようにします。
Projectをコピー
コピー元
解析対象河川_現況
新しいProject
解析対象河川_改修案A
コピー対象
☑ Project設定
☑ Dataset参照
☑ Model参照
☑ Scenario
☐ Run履歴
☐ 計算結果
通常は、Run履歴や計算結果まではコピーしません。
7. Project削除はアーカイブを基本にする
ProjectにRunや計算結果が残るようになると、簡単なDELETEは危険です。
そのため通常操作では、
ACTIVE
↓
ARCHIVED
とします。
アーカイブしたProjectは復元できます。
完全削除が必要な場合は、
ARCHIVED
↓
DELETE_REQUESTED
↓
PURGED
のように段階を分けます。
Projectを削除した結果、過去のRunが再現できなくなることは避けます。
8. Project Snapshotを用意する
Projectは時間とともに変化します。
例えば、
DEM r001 → r002
Rainfall r004 → r005
Model r002 → r003
Scenario r001 → r002
と更新されます。
そこで、Projectのある時点の状態を固定できるProjectSnapshotを持たせます。
ProjectSnapshot
snapshot-20260810-001
Datasets
rainfall r005
dem r003
river r002
Models
runoff r004
river r002
Scenario
current-condition-r002
Runを実行するときには、このSnapshotに近い情報を固定します。
これによって、
「この計算を実行したときに、どのデータとモデルを使っていたか」
を後から確認できます。
9. 解析準備状況を自動判定する
Project画面では、各解析アプリケーションが実行可能か確認できるようにします。
判定は手入力だけにせず、必要データのルールから求めます。
例えばRunoff Studioなら、
application: runoff
required:
- watershed
- rainfall
recommended:
- observed_discharge
- evapotranspiration
River Studioなら、
application: river
required:
- river_network
- cross_sections
- roughness
- upstream_discharge
- downstream_boundary
Flood Studioなら、
application: flood
required:
- dem
- roughness
- boundary_condition
recommended:
- landuse
- levee
- buildings
Project Workspaceでは、この定義を基に、
Runoff Studio READY
River Studio 2項目不足
Flood Studio 3項目不足
と表示します。
10. ポータル型のWebアプリケーションにする
利用者は最初に統合ポータルへアクセスします。
単なるリンク集にはしません。
どの画面へ移動しても、
Project
Scenario
対象期間
使用Dataset
使用Model
最新Run
などを共有します。
11. 共通データ基盤がシステムの中心
解析アプリケーション同士を直接結合しないようにします。
例えば、流出解析で計算した流量は、CSVを介してRiver Studioへ渡すのではなく、共通データ基盤へ登録します。
こうしておくと、解析エンジンを交換しても次の解析への接続を保ちやすくなります。
12. データと解析モデルを分離する
例えばDEMはFlood Studio専用にはしません。
DEM
├── 流出解析
├── 河川解析
├── 氾濫解析
├── 土砂移動解析
└── 土石流解析
雨量も同様です。
Rainfall
├── 雨量解析
├── 流出解析
├── 土石流解析
└── リスク評価
共通データ基盤へ一度登録し、Project側で利用する版を指定します。
13. 日本向けの共通データモデルを作る
独自基盤なので、日本国内の水文・河川データを扱いやすい構造にできます。
例えば観測所です。
station_id
name
provider
provider_station_id
river_system
river_name
watershed_id
longitude
latitude
crs
elevation
vertical_datum
valid_from
valid_to
雨量時系列なら、
series_id
station_id
timestamp
period_start
period_end
value
unit
quality
revision
source
dataset_version
とします。
水位では、観測値と高さ基準を分けます。
station_id
timestamp
gauge_level_m
gauge_zero_elevation_m
vertical_datum
elevation_m
quality
revision
単純な、
timestamp,value
だけではなく、
- どの地点か
- 何の物理量か
- どの単位か
- どの期間の値か
- 観測か計算か
- 品質はどうか
- 何版か
- 出典は何か
を追跡できるようにします。
14. 保存形式を一つに統一しない
独自データ基盤だからといって、一つの専用ファイル形式を作る必要はありません。
データの特性ごとに使い分けます。
| データ | 主な保存方式 |
|---|---|
| Project・Model・Scenario・Run | PostgreSQL |
| 観測所・河川・流域 | PostGIS |
| 最新観測値 | PostgreSQL |
| 長期間の時系列 | Parquet |
| ベクターGIS | GeoParquet |
| GIS検索・集計 | DuckDB Spatial |
| DEM | COG |
| 時系列格子 | Zarr |
| 元データ | MinIO |
| 計算結果原本 | MinIO |
| Web地図 | PMTiles / MVT |
| 外部ソフト受け渡し | Adapterごとの形式 |
共通データモデルと保存形式は分けて考えます。
15. Data Hub
Data Hubでは、データそのものを管理します。
主な機能は、
- データ登録
- データ検索
- データ確認
- DatasetVersion管理
- 品質管理
- 出典管理
- GIS表示
- 時系列表示
- Projectへの割り当て
です。
例えば観測所を開くと、
観測所
○○雨量観測所
提供元
○○県
データ
10分雨量
期間
2000/01/01 ~ 2026/08/09
品質
CHECKED
DatasetVersion
rainfall-r005
利用Project
解析対象河川
○○川検討業務
といった情報を確認できるようにします。
地図はOpenLayers、時系列グラフはPlotlyなどを利用します。
16. Rainfall Studio
雨量データを確認・加工するアプリケーションです。
対象候補は、
- 観測雨量
- レーダ雨量
- 解析雨量
- 予測雨量
- 累積雨量
- 実効雨量
- IDW補間
- 流域平均雨量
- メッシュ平均雨量
などです。
Rainfall Studioで作成したデータも、DatasetまたはRun Artifactとして共通基盤へ戻します。
17. Runoff Studio
降雨流出解析を行います。
雨量
↓
流域
↓
パラメータ
↓
流出モデル
↓
流量
モデルは一種類に固定せず、Engineとして追加できる構造にします。
Tank Model
SCS-CN
Kinematic Wave
XGBoost
LSTM
NeuralHydrology
Differentiable Model
共通インターフェースのイメージは次のようになります。
from __future__ import annotations
from typing import Protocol
class RunoffEngine(Protocol):
"""降雨流出Engineが実装する共通インターフェース。
Web UIやFastAPIから解析式を直接呼ばないようにし、
Worker側から共通の呼び出し方で解析Engineを扱うことを目的とする。
Tank Model、LSTM、GPU実装などに変更しても、
PortalやRun管理側へ解析固有の実装を持ち込まない構成にする。
"""
def prepare(
self,
project_snapshot,
scenario,
parameters: dict[str, float],
) -> None:
"""解析入力を準備する。
Parameters
----------
project_snapshot:
Run開始時に固定したDatasetVersionやModelVersionを含むSnapshot。
scenario:
対象期間や初期条件などをまとめた解析Scenario。
parameters:
Engineへ渡すモデルパラメータ。
"""
...
def run(self):
"""解析本体を実行し、Engine固有の計算結果を返す。"""
...
def collect_results(self):
"""共通データ基盤へ保存可能な形で計算結果を整理して返す。"""
...
18. River Studio
River Studioでは、河道内の1次元解析を扱います。
上流流量
下流水位
河道断面
粗度
構造物
↓
1D河川計算
↓
水位
流量
流速
Runoff Studioの結果は、共通データ基盤に保存されたRun Resultを境界条件として利用します。
19. Flood Studio
2次元氾濫解析を担当します。
入力候補は、
DEM
土地利用
粗度
河川水位
河川流量
降雨
堤防
構造物
です。
出力は、
最大浸水深
最大流速
到達時間
浸水継続時間
などです。
大きな格子結果はCOGやZarrへ保存し、WebではOpenLayersから表示します。
20. Sediment / Debris Flow Studio
土砂移動や土石流も、同じプラットフォーム上の解析アプリとして追加します。
DEM
雨量
流量
粒径
河床条件
土砂量
↓
解析Engine
↓
流動深
流速
侵食量
堆積量
到達範囲
Python、Fortran、C++、GPU、MPIといったEngine実装の違いは、PortalやProject管理から切り離します。
21. Reservoir Studio
ダム、調節池、ゲート、ポンプなどの施設操作を扱います。
流入量
貯水位
放流規則
ゲート操作
↓
施設操作モデル
↓
放流量
貯水位
Workflow上では、RunoffとRiverの間に入るケースもあります。
22. Impact Studio
解析結果と社会データを組み合わせて、影響を整理します。
例えば、
浸水深
人口
建物
道路
重要施設
から、
浸水人口
浸水建物数
建物被害
道路影響
重要施設影響
などを集計します。
e-Stat、PLATEAU、国土数値情報などもData Hub経由で利用できる構成を考えます。
23. Workflow Studio
各解析が揃ってきた段階で、複数解析を連続実行できるようにします。
WorkflowはYAMLやJSONでも定義できるようにします。
workflow:
name: flood_analysis
steps:
- id: runoff
engine: runoff
model: runoff-r003
- id: river
engine: river_1d
model: river-r002
inputs:
upstream_discharge: runoff.discharge
- id: flood
engine: flood_2d
model: flood-r004
inputs:
boundary: river.water_level
- id: impact
engine: damage
inputs:
water_depth: flood.max_depth
ProjectやScenarioを変えても、同じWorkflow定義を再利用できる形を目指します。
24. 解析処理はWorkerで実行する
解析処理をFastAPIのHTTPリクエスト内で直接実行しません。
数秒の解析でも、数時間かかる解析でも、Runとして同じ流れで扱います。
25. Runを共通概念にする
すべての解析はRunとして管理します。
QUEUED
↓
PREPARING
↓
RUNNING
↓
POSTPROCESSING
↓
SUCCEEDED
異常終了は、
FAILED
とします。
Runには最低でも次を保存します。
run_id
project_id
project_snapshot_id
scenario_id
engine
engine_version
model_version
input_dataset_versions
parameters
started_at
finished_at
status
progress
logs
artifacts
これによって、計算結果と入力条件を追跡できます。
26. Experiment & Calibration Studio
解析モデルを増やすと、「計算できる」だけでは足りなくなります。
例えば、
- パラメータを変えた結果を比較したい
- NSEやRMSEを一覧で比較したい
- 計算時間を比較したい
- CPU版とGPU版を比べたい
- 最良パラメータを正式なModelVersionとして保存したい
といった作業が必要になります。
そこで、
Experiment Tracking
└─ MLflow
Calibration / Optimization
└─ Optuna
を拡張機能として接続します。
MLflowやOptunaをHydro Platform本体の必須機能にはしません。
27. MLflowは実験履歴の比較に使う
MLflowには、
Parameters
Metrics
Artifacts
Tags
を記録します。
例えば、
Parameters
k1
k2
mesh_size
dt
roughness
Metrics
NSE
KGE
RMSE
MAE
Bias
computation_time
Artifacts
hydrograph.png
comparison.csv
parameters.json
run.log
Tags
project_id
scenario_id
hydro_run_id
model_version
dataset_version
といった情報です。
Hydro PlatformのRunとMLflowのRunは同一視しません。
Hydro Platform Run
run-20260810-0001
│
└── mlflow_run_id
という関連付けにします。
28. MLflow連携コードの考え方
解析Engineから直接MLflowを呼ばず、Worker側のAdapterで記録します。
サンプルのPythonコード全文を表示する
from __future__ import annotations
from pathlib import Path
from typing import Mapping
import mlflow
class ExperimentTracker:
"""解析結果をMLflowへ記録するためのAdapter。
Hydro Platform本体のRun管理とMLflow固有処理を分離する。
Engine側にはMLflowへの依存を持たせず、
Workerが解析結果を受け取った後で実験情報を記録する。
"""
def __init__(
self,
tracking_uri: str,
experiment_name: str,
) -> None:
"""MLflow Tracking ServerとExperimentを設定する。
Parameters
----------
tracking_uri:
MLflow Tracking Serverの接続先URL。
experiment_name:
MLflow上で使用するExperiment名。
"""
mlflow.set_tracking_uri(tracking_uri)
mlflow.set_experiment(experiment_name)
def log_analysis(
self,
*,
run_name: str,
parameters: Mapping[str, float | int | str],
metrics: Mapping[str, float],
tags: Mapping[str, str],
artifacts: list[Path],
) -> str:
"""解析条件、指標、成果物を1つのMLflow Runとして登録する。
Parameters
----------
run_name:
MLflow画面上で識別するRun名。
parameters:
モデル係数、時間刻み、メッシュサイズなどの実験条件。
metrics:
NSE、KGE、RMSE、計算時間などの比較指標。
tags:
Hydro Platform側のProject ID、Run ID、ModelVersionなど。
artifacts:
グラフ、CSV、ログなど、保存したい成果物。
Returns
-------
str
MLflow Run ID。
"""
with mlflow.start_run(run_name=run_name) as active_run:
# 比較対象となる解析条件を登録する。
mlflow.log_params(dict(parameters))
# 各評価指標を個別に登録し、MLflow UI上で比較できるようにする。
for metric_name, metric_value in metrics.items():
mlflow.log_metric(metric_name, float(metric_value))
# Hydro Platform側のIDをTagへ残し、相互参照できるようにする。
mlflow.set_tags(dict(tags))
# Artifactは存在するものだけ登録する。
# グラフ生成に失敗した場合でもRun全体を失敗扱いにしないため。
for artifact_path in artifacts:
if artifact_path.exists():
mlflow.log_artifact(str(artifact_path))
return active_run.info.run_id
29. Optunaはパラメータ同定に使う
例えば流出モデルなら、
という流れになります。
目的関数には、
NSE
KGE
RMSE
ピーク流量誤差
ピーク時刻誤差
総流出量誤差
などを利用できます。
最良パラメータは一時値で終わらせず、
OptimizationStudy
↓
Best Trial
↓
CalibrationResult
↓
ModelVersion
として保存します。
30. Optuna連携コードの考え方
Optunaも解析Engineと分離します。
サンプルのPythonコード全文を表示する
from __future__ import annotations
from dataclasses import dataclass
import numpy as np
import optuna
@dataclass(frozen=True)
class CalibrationData:
"""パラメータ同定に使用する観測データ。
Attributes
----------
rainfall:
対象期間の雨量時系列。
observed_discharge:
評価対象となる観測流量。
"""
rainfall: np.ndarray
observed_discharge: np.ndarray
def calculate_nse(
observed: np.ndarray,
simulated: np.ndarray,
) -> float:
"""Nash-Sutcliffe Efficiencyを計算する。
欠測処理や品質判定は、この関数の中ではなく、
Data HubまたはCalibration前処理で済ませておく。
Parameters
----------
observed:
観測流量。
simulated:
同じ時刻に対応する計算流量。
Returns
-------
float
NSE。
"""
if observed.shape != simulated.shape:
raise ValueError("observedとsimulatedのshapeが一致していません。")
denominator = np.sum((observed - np.mean(observed)) ** 2)
# 観測値の分散が0の場合はNSEを定義できない。
if denominator == 0:
raise ValueError("観測値の分散が0のためNSEを計算できません。")
numerator = np.sum((observed - simulated) ** 2)
return float(1.0 - numerator / denominator)
def create_objective(calibration_data: CalibrationData, runoff_engine):
"""Optunaへ渡す目的関数を生成する。
Optuna固有のTrial管理はこの層で扱い、
Runoff Engine側にはOptunaへの依存を持たせない。
"""
def objective(trial: optuna.Trial) -> float:
"""1 Trial分のパラメータ候補を評価する。"""
# 探索範囲は最終的にはModel定義側へ持たせる。
k1 = trial.suggest_float("k1", 0.01, 1.00)
k2 = trial.suggest_float("k2", 0.001, 0.50)
result = runoff_engine.run(
rainfall=calibration_data.rainfall,
parameters={
"k1": k1,
"k2": k2,
},
)
return calculate_nse(
observed=calibration_data.observed_discharge,
simulated=result.discharge,
)
return objective
31. 外部解析ソフトとの接続
独自Engineだけに限定しません。
Common Data Platform
↓
External Adapter
↓
External Model
↓
Result Adapter
↓
Common Data Platform
という形で外部ソフトを接続します。
共通インターフェースの例です。
class ExternalModelAdapter:
"""外部解析ソフトとHydro Platformを接続するための共通Adapter。"""
def prepare_input(self, run_context):
"""共通データを外部モデル用入力へ変換する。"""
...
def execute(self, run_context):
"""外部モデルの計算を実行する。"""
...
def collect_results(self, run_context):
"""外部モデルが出力した結果ファイルを取得する。"""
...
def convert_results(self, run_context):
"""外部形式の結果を共通データモデルへ変換する。"""
...
この仕組みなら、
外部水文モデル
外部河川モデル
SWMM
Fortran Solver
C++ Solver
GPU Solver
などを同じ枠組みで接続できます。
特定形式が必要な場合は、その形式用のExport / Import Adapterを追加します。
32. Docker Composeを基本環境にする
Web/API/DB/WorkerはDocker Composeで動かします。
標準環境は、
Ubuntu 24.04
Docker Engine
Docker Compose
を想定します。
Windows環境ではWSL2やDocker Desktopを利用できます。
GPU解析はGPU Workerとして分離します。
33. MLflow / Optunaを追加したDocker構成
解析支援機能を追加する段階では次のように拡張します。
MLflowやOptunaは、最初から必須コンテナにはしません。
必要なStepで追加します。
34. フロントエンド
初期段階では一つのWebフロントエンドとしてまとめます。
候補は、
Vite
TypeScript
React
OpenLayers
Plotly
です。
frontend/
└── src/
├── app/
│
├── modules/
│ ├── portal/
│ ├── project_workspace/
│ ├── data_hub/
│ ├── rainfall/
│ ├── runoff/
│ ├── river/
│ ├── flood/
│ ├── debris_flow/
│ ├── experiment/
│ ├── impact/
│ └── workflow/
│
├── components/
│ ├── map/
│ ├── chart/
│ ├── table/
│ └── forms/
│
└── api/
最初からマイクロフロントエンドには分割しません。
35. バックエンド
FastAPIを中心にしたモジュラーモノリスから始めます。
backend/
└── app/
├── core/
│
├── modules/
│ ├── projects/
│ ├── project_datasets/
│ ├── readiness/
│ ├── snapshots/
│ ├── activities/
│ ├── datasets/
│ ├── models/
│ ├── scenarios/
│ ├── runs/
│ ├── experiments/
│ ├── optimizations/
│ ├── workflows/
│ └── artifacts/
│
├── api/
└── main.py
必要になった機能だけ、後からサービス分割します。
36. リポジトリ構成案
当初は一つのリポジトリで管理します。
リポジトリの全文を表示する
hydro_platform/
│
├── apps/
│ ├── portal_web/
│ └── core_api/
│
├── modules/
│ ├── project_workspace/
│ ├── data_hub/
│ ├── rainfall/
│ ├── runoff/
│ ├── river/
│ ├── flood/
│ ├── sediment/
│ ├── debris_flow/
│ ├── reservoir/
│ ├── experiment/
│ ├── impact/
│ └── workflow/
│
├── engines/
│ ├── rainfall/
│ ├── runoff/
│ ├── river/
│ ├── flood/
│ ├── sediment/
│ ├── debris_flow/
│ ├── reservoir/
│ └── damage/
│
├── workers/
│ ├── common/
│ ├── analysis_worker/
│ ├── gpu_worker/
│ └── external_model_worker/
│
├── data_platform/
│ ├── catalog/
│ ├── timeseries/
│ ├── spatial/
│ ├── grid/
│ ├── quality/
│ ├── versioning/
│ └── storage/
│
├── adapters/
│ ├── jma/
│ ├── mlit/
│ ├── gsi/
│ ├── estat/
│ ├── csv/
│ └── external_models/
│
├── packages/
│ ├── common_models/
│ ├── common_gis/
│ ├── common_timeseries/
│ ├── common_units/
│ ├── common_logging/
│ └── common_validation/
│
├── schemas/
│ ├── projects/
│ ├── datasets/
│ ├── models/
│ ├── scenarios/
│ ├── runs/
│ ├── experiments/
│ └── workflows/
│
├── deploy/
│ ├── docker/
│ ├── nginx/
│ └── scripts/
│
├── tests/
│ ├── unit/
│ ├── integration/
│ └── reference_cases/
│
├── docker-compose.yml
├── .env.example
└── README.md
37. 開発ステップ
Project管理はStep 0とStep 1の時点から中心に置きます。
Step 0:共通基盤・Project Workspace基本設計
最初に実装対象と責務を確定します。
対象は、
Project
ProjectSetting
ProjectDataset
ProjectModel
ProjectReadiness
ProjectSnapshot
ProjectActivity
Dataset
DatasetVersion
Feature
Series
Model
ModelVersion
Scenario
Run
Artifact
Workflow
Experiment
OptimizationStudy
Trial
CalibrationResult
です。
さらに、
時刻
単位
品質
欠測
座標系
高さ基準
版管理
出典
を決めます。
Step 0では、これらをすべて実装する必要はありません。
関係と責務を先に決めることが目的です。
Step 1:開発基盤・Portal・Project Workspace
Docker Composeによる開発基盤とProject Workspaceを作ります。
Vite + React + TypeScript
FastAPI
PostgreSQL / PostGIS
MinIO
Redis
Nginx
Docker Compose
Project管理としては、
Project Dashboard
Project作成
Project編集
Projectコピー
Archive
Restore
Project Activity
Dataset一覧枠
Readiness表示枠
Snapshot一覧枠
まで作ります。
この時点では実データ登録は最小限にします。
Step 2:Data Hub
ここで実データ管理を本格的に実装します。
最初の対象は、
流域界
観測所
10分雨量
水位
流量
DEM
です。
CSV登録
GIS登録
DatasetVersion
品質情報
出典情報
時系列検索
OpenLayers表示
Plotly表示
Projectへの割当
まで実装します。
Data Hubでデータを登録すると、Project WorkspaceのReadinessが更新されるところまでつなげます。
Step 3:Model / Scenario / Run管理
次に計算管理基盤を作ります。
Model
ModelVersion
Scenario
Run
Artifact
ProjectSnapshot
を実装します。
Runの状態は、
QUEUED
↓
PREPARING
↓
RUNNING
↓
POSTPROCESSING
↓
SUCCEEDED / FAILED
とします。
Step 4:Runoff Studio
最初の解析アプリケーションです。
初期版は簡易2段タンクモデル程度から始めます。
ここで、
Project
↓
Dataset
↓
Scenario
↓
Run
↓
Queue
↓
Worker
↓
Engine
↓
Result
の最初の解析処理の流れを完成させます。
Step 5:Experiment Tracking / MLflow
Runoff Studioが動いた段階で、実験比較を追加します。
Parameters
Metrics
Artifacts
Tags
を記録します。
最初は、
NSE
RMSE
MAE
計算時間
程度から始めます。
Step 6:Calibration / Optuna
流出モデルのパラメータ同定を追加します。
観測雨量
観測流量
↓
Optuna
↓
パラメータ候補
↓
Runoff Engine
↓
評価指標
↓
次のTrial
Best TrialはModelVersionへ登録します。
Step 7:River Studio
1D河川解析を追加します。
Runoff Studioの結果を共通データ基盤経由で境界条件に利用します。
Step 8:Flood Studio
2D氾濫解析を追加します。
結果はCOG / Zarrへ保存し、OpenLayersで表示します。
Step 9:Workflow Studio
Runoff → River → Floodなどの連続計算を実装します。
Step 10:Reservoir / Sediment / Debris Flow
専門解析を追加します。
必要に応じてGPU WorkerやMPI Workerへ分けます。
Step 11:Impact Studio
人口、建物、道路、重要施設などと解析結果を組み合わせて影響評価を行います。
Step 12:外部モデル連携
External Adapterを使って外部解析ソフトを接続します。
最初はファイル交換から始めます。
Step 13:リアルタイム化
観測データ自動取得
予測雨量取得
自動Run
結果更新
通知
へ進めます。
Step 14:GPU / MPI / 分散計算
最後に計算資源管理を拡張します。
複数Worker
GPU Worker
MPI
複数サーバ
クラウド
ジョブ優先度
計算資源管理
最初からKubernetesは前提にしません。
38. 開発ステップ全体
39. 最初のプロトタイプはどこまで作るか
プロトタイプは2段階に分けて作成します。
第1段階
Step 0
Step 1
Step 2
Step 3
Step 4
第2段階
Step 5
Step 6
第1段階で、
第1段階
Projectを作る
↓
必要データが表示される
↓
Data Hubで雨量や流域を登録する
↓
ProjectのReadinessが更新される
↓
Scenarioを作る
↓
Runoff StudioでRunを開始する
↓
Workerで解析する
↓
流量を共通データ基盤へ保存する
↓
Webで結果を確認する
までを完成させます。
第2段階で、
第2段階
実験を残す
比較する
パラメータを同定する
Best TrialをModelVersionとして保存する
ところまで進めます。
40. 最初から作り込みすぎない
初期段階では、次のものは後回しにします。
Kubernetes
大規模認証基盤
複数組織向けマルチテナント
全国規模データ
複雑な権限管理
完全リアルタイム運用
大規模分散計算
外部モデルの完全自動制御
まずは、
一つのProjectで、データ整備状況を確認し、必要データを登録し、一つの解析を実行して結果をWebで確認できる
ところまでを優先します。
41. この構成の利点
Projectの状態が分かる
「何が揃っていて、何が不足しているか」をProjectトップで確認できます。
データを再利用できる
同じDEMや雨量DatasetVersionを複数Projectで利用できます。
Projectを安全に複製できる
現況から改修案を作る場合も、大容量データを物理コピーせずにProjectを作れます。
解析モデルを交換できる
PortalやRun管理を変えずに、Engineだけを差し替えやすくなります。
実験履歴を残せる
MLflowを使ってパラメータや評価指標を比較できます。
パラメータ同定を組み込める
Optunaで探索し、Best Trialを正式なModelVersionへ戻せます。
外部ソフトも接続できる
Adapterを追加することで、既存解析ソフトや独自Solverを利用できます。
WebとDockerで環境を揃えやすい
利用者側の入口をブラウザへ寄せ、サーバ側の実行環境をコンテナで揃えられます。
42. おわりに
今回考えているのは、単独の流出解析ソフトや河川解析ソフトではありません。
目標は、
Project Workspaceと共通データ基盤を中心に、水文・河川・氾濫・土砂・被害評価などの解析アプリケーションを追加していけるWebベースの解析プラットフォーム
です。
全体を簡単に表すと、
全体構成
Portal
↓
Project Workspace
↓
Data / Model / Scenario / Run
↓
Common Data Platform
↓
Analysis Engine
↓
Result
↓
Project Workspace
となります。
特に最初の段階では、解析式を増やすことより、
Project
ProjectDataset
DatasetVersion
ModelVersion
Scenario
Run
Snapshot
Readiness
の関係をきちんと決めることが重要です。
この構想を基準にして、次はStep 0を設計し、どこまでをStep 0で確定し、どこからをStep 1で実装するかを整理してから実装へ進めます。
全体を通して、何かご意見などあれば、是非コメントなどいただければと考えています。











