Downloads · 30 days
0
mrvictoru/energydecision-dt-v2-sdp
energydecision-dt-v2-sdp is a reinforcement learning model from mrvictoru. Use it for the reinforcement learning task on the model card, and read the license before you ship it in a product. It is set up for pytorch.
The shipped / preferred model of the energydecision benchmark. A standalone Decision Transformer distilled from an honest (non-clairvoyant), degradation-aware SDP-planning teacher — no solver in the control loop (the…
Downloads · 30 days
0
Access
Public
Updated Oct 22, 2026
Repo size
5.1 GB
Likes
1
Public
Click a slice to open those files.
.pt607 MB · 100%
From the Hugging Face model README
The shipped / preferred model of the energydecision benchmark. A standalone Decision Transformer distilled from an honest (non-clairvoyant), degradation-aware SDP-planning teacher — no solver in the control loop (the J_t(soc) prompt is precomputed) — that beats the PPO reference on all four identity surfaces and remains strong under the market-impact benchmark.
2026-09 update (physics-v2): this model was retrained on the corrected degradation/efficiency physics (round-trip efficiency 0.80, calendar aging, corrected rainflow C-rate units) and a wear-calibrated teacher (
--deg-calibration 0.12, aligning the planner's per-step wear with the environment's realized per-cycle wear). See Provenance below. It supersedes the earlieraemo_dt_sdp_jtsoc_fullcorpus.pt.
| File | Model | Status |
|---|---|---|
aemo_dt_sdp_jtsoc_v2cal.pt (+ .pt.meta.json) | Physics-v2 Stage C — J_t(soc) RTG, wear-calibrated SDP teacher (320 eps) | ✅ Shipped — use this one |
aemo_dt_sdp_jtsoc_fullcorpus.pt (+ .pt.meta.json) | Stage C v1 — J_t(soc) RTG, combined corpus (640 eps), pre-physics-fix | Historical (superseded; kept for the v1 comparison) |
(Removed 2026-09: the behaviour-cloning-era files aemo_dt_fcas_model.pt and aemo_dt_fcas_best_checkpoint.pt.)
aemo_dt_sdp_jtsoc_v2cal.pt, rtg_mode="auto")| Surface | This model | PPO | Ratio vs PPO | n |
|---|---|---|---|---|
| Standard 2024 (5 regions × 6 periods) | $16,501/ep | $4,303 | 3.84× | 30 |
| Dispatch-matched (SA1 full-year) | $33,791/ep | $18,818 | 1.80× | 12 |
| Expanded broad-2024 | $29,124/ep | $4,350 | 6.70× | 30 |
| 2025 OOD | $30,791/ep | $4,817 | 6.39× | 6 |
| Market impact (piecewise merit-order) | 9/9 cells beat PPO; fixed rtg0.0 fallback small 4.36× / hornsdale 4.70× / torrens 4.67× | — | passes | 9 |
All four identity surfaces beat PPO with paired-difference 95% CIs excluding zero. Methodology, the physics fixes, and the full experiment ladder: report.md §8.2.10/§8.2.11 and docs/known_issues.md.
| Fix | Effect |
|---|---|
A3/A4 — rainflow inferred current was %SoC/hour instead of a C-rate (~100× too large, then clamped); reset() dropped the C-rate cap | corrected cycle-aging magnitude globally |
| A5 — planner degradation estimator always returned 0 (a 3-point rainflow sequence can never close a cycle) | planners are now wear-aware and state-dependent |
| A6 / B4 — the planner's per-step wear over-counted the env's per-closed-cycle wear by 8.4× on identical actions | added an explicit deg_calibration factor; the teacher corpus was regenerated with --deg-calibration 0.12 |
B1/B8 — impact-aware J_t(soc) dispatch-sign bug and a return_scale sidecar bug in the impact-eval runner | evaluation correctness (the previous "explicit j_t_soc collapses under impact" claim was an artifact) |
The model card's numbers above are from the corrected pipeline. Prior household and AEMO numbers produced before these fixes are historical.
| Parameter | Value |
|---|---|
| Blocks / hidden dim | 8 / 768 |
| Attention | GQA (12 Q / 6 KV), QK-Norm |
| RoPE | enabled (rope_max_position=630, max_timestep=2016) |
| FFN | SwiGLU, dropout 0.15 |
| Weight tying | Enabled |
| State / action dim | 18 / 9 (full_fcas) |
| Action head | Mixed (Tanh energy, Sigmoid FCAS) |
return_scale | 23,284.83 — auto-calibrated at training time (the p90(|J_t|)/10 heuristic), checkpoint-specific; must be applied at inference |
Note on
return_scale: 23,284.83 is the correct value to use at inference, but it does not reproduce exactly asp90(|J_t|)/10of the released corpus (recomputed ≈21,067). The checkpoint sidecar is authoritative; the discrepancy is documented in the paper's provenance appendix.
Action space: dim 0 energy dispatch in [-1, 1]; dims 1–8 FCAS bids in [0, 1] (RAISEREG, LOWERREG, RAISE6SEC, LOWER6SEC, RAISE60SEC, LOWER60SEC, RAISE5MIN, LOWER5MIN). State space: 18-dim normalized market observations (time features, RRP, demand, 8 FCAS prices, generation mix, SOC).
dt_trajectories_jtsoc_v2cal_conservative.parquet — 320 episodes, 3.13M rows, honest SDP teacher with wear calibration and per-episode J_t(soc) cost-to-go RTG. Hosted at mrvictoru/AEMO_simulated_trade_sdp.scripts/generate_sdp_dt_trajectories.py (--deg-calibration 0.12, --rtg-mode j_t_soc); method in report.md §4.3/§5.4.scripts/generate_soc_waypoint_targets.py in the GitHub repo. The shipped policy does not need this model at inference.import json
import torch
from huggingface_hub import hf_hub_download
from decision_transformer import DecisionTransformer
from decision import AEMOAgent
repo = "mrvictoru/energydecision-dt-v2-sdp"
ckpt = hf_hub_download(repo, "aemo_dt_sdp_jtsoc_v2cal.pt")
meta = json.loads(hf_hub_download(repo, "aemo_dt_sdp_jtsoc_v2cal.pt.meta.json"))
model_kwargs = dict(
state_dim=meta["model"]["state_dim"], act_dim=meta["model"]["act_dim"],
h_dim=meta["model"]["h_dim"], context_len=meta["model"]["context_len"],
n_block=8, n_heads=12, n_kv_heads=6, drop_p=0.15,
max_timestep=2016, rope_enabled=True, qk_norm=True, tie_weights=True,
action_head_mode="mixed",
)
model = DecisionTransformer(**model_kwargs)
model.load_from_checkpoint(ckpt) # raw state_dict
model.return_scale = meta["return_scale"] # 23284.83
model.eval()
agent = AEMOAgent(env, algorithm="dt", model=model, rtg_mode="auto")
rtg_mode="auto" resolves to state-dependent j_t_soc prompting on price-taking (identity) surfaces and a conservative constant-RTG fallback under a market-impact model.
DecisionTransformer model, AEMOAgent, and the AEMOBatteryTradingEnv live in the energydecision repo, not in this model repo.rtg_mode="j_t_soc" / "auto" on identity surfaces, the agent builds a J_t(soc) cost-to-go table from a seasonal price forecast, cached to data/aemo_sdp/seasonal_rrp_<REGION>.json. The five profiles are included in this repo under data/aemo_sdp/ — copy them to data/aemo_sdp/ in the repo checkout (otherwise the j_t_soc path has to rebuild them from raw AEMO parquets, which the simulation environment fetches separately). Building the table runs one backward-induction pass per episode (not per step); because it depends only on the seasonal forecast and the SOC grid, it can be precomputed or cached, after which each step is a constant-time lookup.rtg_mode="constant" (with a prompt value) needs no seasonal profile, but it is not the shipped setting and under-performs on identity surfaces.Research into offline RL / sequence modeling for energy markets; simulation of multi-market BESS dispatch in Australia's NEM; baseline for planner-distilled offline RL. Not intended for live trading without further validation (sim-to-real is open), risk management, and regulatory compliance.
@misc{energydecision-dt-v2-sdp,
title = {AEMO SDP-Teacher Decision Transformer (planner-distilled, physics-v2)},
author = {mrvictoru},
year = {2026},
url = {https://huggingface.co/mrvictoru/energydecision-dt-v2-sdp}
}