Spaces:
Runtime error
Runtime error
Build MBench leaderboard Space
Browse files- .gitignore +6 -0
- README.md +26 -6
- app.py +450 -0
- constants.py +71 -0
- requirements.txt +7 -0
- scripts/upload_seed_results.py +60 -0
- scripts/validate_submission.py +58 -0
- seed/results.csv +15 -0
.gitignore
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
| 2 |
+
*.pyc
|
| 3 |
+
.env
|
| 4 |
+
.venv/
|
| 5 |
+
mbench_leaderboard_submission/
|
| 6 |
+
membench_leaderboard_submission/
|
README.md
CHANGED
|
@@ -1,13 +1,33 @@
|
|
| 1 |
---
|
| 2 |
title: MBench Leaderboard
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version:
|
| 8 |
-
python_version:
|
| 9 |
app_file: app.py
|
| 10 |
pinned: false
|
|
|
|
| 11 |
---
|
| 12 |
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
title: MBench Leaderboard
|
| 3 |
+
emoji: 🏆
|
| 4 |
+
colorFrom: indigo
|
| 5 |
+
colorTo: purple
|
| 6 |
sdk: gradio
|
| 7 |
+
sdk_version: 4.36.1
|
| 8 |
+
python_version: 3.10
|
| 9 |
app_file: app.py
|
| 10 |
pinned: false
|
| 11 |
+
license: mit
|
| 12 |
---
|
| 13 |
|
| 14 |
+
# MBench Leaderboard
|
| 15 |
+
|
| 16 |
+
MBench is a benchmark for evaluating the memory capability of video world models. It focuses on whether a model can preserve a coherent world state across long-horizon video continuation and interaction.
|
| 17 |
+
|
| 18 |
+
The benchmark is organized around three core memory dimensions:
|
| 19 |
+
|
| 20 |
+
- **Entity Consistency:** persistent object and human identity, geometry, texture, and appearance.
|
| 21 |
+
- **Environment Consistency:** stable spatial layout, reprojection behavior, lighting, and style.
|
| 22 |
+
- **Causal Consistency:** reliable state evolution and interaction consequences over time.
|
| 23 |
+
|
| 24 |
+
MBench uses trigger-conditioned scoring: Trigger Coverage measures whether the model actually enters the intended memory challenge, Memory Reliability measures consistency after the challenge is triggered, and M-Score balances both with a harmonic mean.
|
| 25 |
+
|
| 26 |
+
The bundled seed leaderboard is transcribed from Table 2 of the MBench paper. Aggregate leaderboard columns are derived as unweighted averages over the reported sub-dimensions until official leaderboard totals are released.
|
| 27 |
+
|
| 28 |
+
## Links
|
| 29 |
+
|
| 30 |
+
- **Dataset:** `studyOverflow/TempMemoryData`
|
| 31 |
+
- **Leaderboard data repo:** `PeanutUp/membench_leaderboard_submission`
|
| 32 |
+
- **GitHub repo:** https://github.com/study-overflow/MBench
|
| 33 |
+
- **Project page:** https://peanutup.github.io/MBench-project/
|
app.py
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
import re
|
| 4 |
+
import shutil
|
| 5 |
+
import tempfile
|
| 6 |
+
import zipfile
|
| 7 |
+
from datetime import datetime, timezone
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
from typing import Any
|
| 10 |
+
|
| 11 |
+
import gradio as gr
|
| 12 |
+
import numpy as np
|
| 13 |
+
import pandas as pd
|
| 14 |
+
from huggingface_hub import HfApi, snapshot_download
|
| 15 |
+
|
| 16 |
+
from constants import (
|
| 17 |
+
ALL_COLUMNS,
|
| 18 |
+
LEADERBOARD_INTRO,
|
| 19 |
+
LEADERBOARD_REPO,
|
| 20 |
+
LOCAL_LEADERBOARD_DIR,
|
| 21 |
+
METRIC_COLUMNS,
|
| 22 |
+
MODEL_INFO_COLUMNS,
|
| 23 |
+
MODEL_TYPE_CHOICES,
|
| 24 |
+
RESULTS_CSV,
|
| 25 |
+
SUBMIT_INTRO,
|
| 26 |
+
)
|
| 27 |
+
from scripts.validate_submission import validate_submission_json
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
SPACE_ROOT = Path(__file__).resolve().parent
|
| 31 |
+
LOCAL_LEADERBOARD_PATH = Path(LOCAL_LEADERBOARD_DIR).resolve()
|
| 32 |
+
RESULTS_PATH = Path(RESULTS_CSV).resolve()
|
| 33 |
+
SEED_RESULTS_PATH = SPACE_ROOT / "seed" / "results.csv"
|
| 34 |
+
PENDING_DIR = LOCAL_LEADERBOARD_PATH / "submissions" / "pending"
|
| 35 |
+
VERIFIED_DIR = LOCAL_LEADERBOARD_PATH / "submissions" / "verified"
|
| 36 |
+
NUMERIC_COLUMNS = [
|
| 37 |
+
"Total M-Score",
|
| 38 |
+
"Entity Score",
|
| 39 |
+
"Environment Score",
|
| 40 |
+
"Causal Score",
|
| 41 |
+
*METRIC_COLUMNS,
|
| 42 |
+
]
|
| 43 |
+
UPLOAD_ALLOW_PATTERNS = ["results.csv", "submissions/**"]
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def empty_results() -> pd.DataFrame:
|
| 47 |
+
return pd.DataFrame(columns=ALL_COLUMNS)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def ensure_columns(df: pd.DataFrame) -> pd.DataFrame:
|
| 51 |
+
df = df.copy()
|
| 52 |
+
for column in ALL_COLUMNS:
|
| 53 |
+
if column not in df.columns:
|
| 54 |
+
df[column] = 0 if column in NUMERIC_COLUMNS or column == "Rank" else ""
|
| 55 |
+
return df[ALL_COLUMNS]
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def clean_numeric_columns(df: pd.DataFrame) -> pd.DataFrame:
|
| 59 |
+
df = df.copy()
|
| 60 |
+
for column in NUMERIC_COLUMNS:
|
| 61 |
+
df[column] = pd.to_numeric(df[column], errors="coerce").fillna(0.0)
|
| 62 |
+
return df
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def read_results_csv(path: Path) -> pd.DataFrame:
|
| 66 |
+
df = pd.read_csv(path)
|
| 67 |
+
return clean_numeric_columns(ensure_columns(df))
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def load_seed_results(reason: str) -> tuple[pd.DataFrame, str]:
|
| 71 |
+
if SEED_RESULTS_PATH.exists():
|
| 72 |
+
try:
|
| 73 |
+
df = read_results_csv(SEED_RESULTS_PATH)
|
| 74 |
+
return (
|
| 75 |
+
df,
|
| 76 |
+
f"{reason}\n\nUsing bundled seed results from Table 2 of the MBench paper.",
|
| 77 |
+
)
|
| 78 |
+
except Exception as exc:
|
| 79 |
+
return empty_results(), f"{reason}\n\nCould not read bundled seed results: {exc}"
|
| 80 |
+
return empty_results(), f"{reason}\n\nBundled seed results are missing."
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def load_remote_results() -> tuple[pd.DataFrame, str]:
|
| 84 |
+
try:
|
| 85 |
+
snapshot_download(
|
| 86 |
+
repo_id=LEADERBOARD_REPO,
|
| 87 |
+
repo_type="dataset",
|
| 88 |
+
local_dir=str(LOCAL_LEADERBOARD_PATH),
|
| 89 |
+
local_dir_use_symlinks=False,
|
| 90 |
+
)
|
| 91 |
+
except Exception as exc:
|
| 92 |
+
message = (
|
| 93 |
+
"Leaderboard data is not available yet. Please run "
|
| 94 |
+
"`python scripts/upload_seed_results.py` after setting `HF_TOKEN`."
|
| 95 |
+
f"\n\nDetails: {exc}"
|
| 96 |
+
)
|
| 97 |
+
return load_seed_results(message)
|
| 98 |
+
|
| 99 |
+
if not RESULTS_PATH.exists():
|
| 100 |
+
message = (
|
| 101 |
+
"`results.csv` was not found in the leaderboard data repo. Please run "
|
| 102 |
+
"`python scripts/upload_seed_results.py` to initialize it."
|
| 103 |
+
)
|
| 104 |
+
return load_seed_results(message)
|
| 105 |
+
|
| 106 |
+
try:
|
| 107 |
+
df = read_results_csv(RESULTS_PATH)
|
| 108 |
+
except Exception as exc:
|
| 109 |
+
return load_seed_results(f"Could not read `results.csv`: {exc}")
|
| 110 |
+
|
| 111 |
+
return df, f"Loaded results from `{LEADERBOARD_REPO}`."
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def prepare_leaderboard(
|
| 115 |
+
model_type: str,
|
| 116 |
+
selected_metrics: list[str] | None,
|
| 117 |
+
) -> tuple[pd.DataFrame, str]:
|
| 118 |
+
df, status = load_remote_results()
|
| 119 |
+
|
| 120 |
+
if model_type and model_type != "All" and not df.empty:
|
| 121 |
+
df = df[df["Model Type"] == model_type].copy()
|
| 122 |
+
|
| 123 |
+
if not df.empty:
|
| 124 |
+
df = df.sort_values(
|
| 125 |
+
by="Total M-Score",
|
| 126 |
+
ascending=False,
|
| 127 |
+
kind="mergesort",
|
| 128 |
+
).reset_index(drop=True)
|
| 129 |
+
df["Rank"] = np.arange(1, len(df) + 1)
|
| 130 |
+
|
| 131 |
+
metrics = [metric for metric in (selected_metrics or []) if metric in METRIC_COLUMNS]
|
| 132 |
+
columns = MODEL_INFO_COLUMNS + metrics
|
| 133 |
+
return df[columns], status
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
def sanitize_filename(value: str) -> str:
|
| 137 |
+
cleaned = re.sub(r"[^A-Za-z0-9_.-]+", "_", value.strip())
|
| 138 |
+
cleaned = cleaned.strip("._-")
|
| 139 |
+
return cleaned or "model"
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def get_uploaded_path(file_obj: Any) -> Path | None:
|
| 143 |
+
if file_obj is None:
|
| 144 |
+
return None
|
| 145 |
+
if isinstance(file_obj, (str, os.PathLike)):
|
| 146 |
+
return Path(file_obj)
|
| 147 |
+
if isinstance(file_obj, dict):
|
| 148 |
+
path = file_obj.get("path") or file_obj.get("name")
|
| 149 |
+
return Path(path) if path else None
|
| 150 |
+
name = getattr(file_obj, "name", None)
|
| 151 |
+
return Path(name) if name else None
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def safe_extract_zip(zip_path: Path, target_dir: Path) -> None:
|
| 155 |
+
target_root = target_dir.resolve()
|
| 156 |
+
with zipfile.ZipFile(zip_path, "r") as zip_ref:
|
| 157 |
+
for member in zip_ref.infolist():
|
| 158 |
+
member_path = (target_root / member.filename).resolve()
|
| 159 |
+
try:
|
| 160 |
+
member_path.relative_to(target_root)
|
| 161 |
+
except ValueError:
|
| 162 |
+
raise ValueError("ZIP contains an unsafe path.")
|
| 163 |
+
zip_ref.extractall(target_root)
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def read_first_json_from_zip(zip_path: Path) -> dict:
|
| 167 |
+
if not zipfile.is_zipfile(zip_path):
|
| 168 |
+
raise ValueError("Uploaded file must be a valid ZIP archive.")
|
| 169 |
+
|
| 170 |
+
with tempfile.TemporaryDirectory(prefix="mbench_submission_") as tmp_dir:
|
| 171 |
+
extract_dir = Path(tmp_dir)
|
| 172 |
+
safe_extract_zip(zip_path, extract_dir)
|
| 173 |
+
json_files = sorted(
|
| 174 |
+
path for path in extract_dir.rglob("*.json") if path.is_file()
|
| 175 |
+
)
|
| 176 |
+
if not json_files:
|
| 177 |
+
raise ValueError("No JSON file found inside the ZIP archive.")
|
| 178 |
+
|
| 179 |
+
with json_files[0].open("r", encoding="utf-8") as handle:
|
| 180 |
+
data = json.load(handle)
|
| 181 |
+
|
| 182 |
+
if not isinstance(data, dict):
|
| 183 |
+
raise ValueError("The first JSON file must contain a JSON object.")
|
| 184 |
+
return data
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
def require_text(value: str, label: str) -> str:
|
| 188 |
+
if value is None or not str(value).strip():
|
| 189 |
+
raise ValueError(f"{label} is required.")
|
| 190 |
+
return str(value).strip()
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
def ensure_submission_dirs() -> None:
|
| 194 |
+
PENDING_DIR.mkdir(parents=True, exist_ok=True)
|
| 195 |
+
VERIFIED_DIR.mkdir(parents=True, exist_ok=True)
|
| 196 |
+
(PENDING_DIR / ".gitkeep").touch(exist_ok=True)
|
| 197 |
+
(VERIFIED_DIR / ".gitkeep").touch(exist_ok=True)
|
| 198 |
+
|
| 199 |
+
|
| 200 |
+
def ensure_local_results_file() -> None:
|
| 201 |
+
if RESULTS_PATH.exists() or not SEED_RESULTS_PATH.exists():
|
| 202 |
+
return
|
| 203 |
+
RESULTS_PATH.parent.mkdir(parents=True, exist_ok=True)
|
| 204 |
+
shutil.copy2(SEED_RESULTS_PATH, RESULTS_PATH)
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
def save_pending_submission(
|
| 208 |
+
zip_path: Path,
|
| 209 |
+
result_json: dict,
|
| 210 |
+
model_name: str,
|
| 211 |
+
model_link: str,
|
| 212 |
+
team_name: str,
|
| 213 |
+
contact_email: str,
|
| 214 |
+
model_type: str,
|
| 215 |
+
accessibility: str,
|
| 216 |
+
) -> tuple[Path, Path]:
|
| 217 |
+
ensure_submission_dirs()
|
| 218 |
+
timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
|
| 219 |
+
safe_model_name = sanitize_filename(model_name)
|
| 220 |
+
stem = f"{timestamp}_{safe_model_name}"
|
| 221 |
+
|
| 222 |
+
payload = {
|
| 223 |
+
"submitted_at_utc": datetime.now(timezone.utc).isoformat(),
|
| 224 |
+
"status": "pending",
|
| 225 |
+
"model_name": model_name,
|
| 226 |
+
"model_link": model_link,
|
| 227 |
+
"team_name": team_name,
|
| 228 |
+
"contact_email": contact_email,
|
| 229 |
+
"model_type": model_type,
|
| 230 |
+
"accessibility": accessibility,
|
| 231 |
+
"result_json": result_json,
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
json_path = PENDING_DIR / f"{stem}.json"
|
| 235 |
+
raw_zip_path = PENDING_DIR / f"{stem}.zip"
|
| 236 |
+
json_path.write_text(
|
| 237 |
+
json.dumps(payload, indent=2, ensure_ascii=False),
|
| 238 |
+
encoding="utf-8",
|
| 239 |
+
)
|
| 240 |
+
shutil.copyfile(zip_path, raw_zip_path)
|
| 241 |
+
return json_path, raw_zip_path
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
def upload_local_leaderboard(token: str, model_name: str) -> None:
|
| 245 |
+
api = HfApi(token=token)
|
| 246 |
+
api.create_repo(repo_id=LEADERBOARD_REPO, repo_type="dataset", exist_ok=True)
|
| 247 |
+
ensure_local_results_file()
|
| 248 |
+
api.upload_folder(
|
| 249 |
+
folder_path=str(LOCAL_LEADERBOARD_PATH),
|
| 250 |
+
repo_id=LEADERBOARD_REPO,
|
| 251 |
+
repo_type="dataset",
|
| 252 |
+
allow_patterns=UPLOAD_ALLOW_PATTERNS,
|
| 253 |
+
commit_message=f"Add pending MBench submission for {model_name}",
|
| 254 |
+
)
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
def submit_result(
|
| 258 |
+
zip_file: Any,
|
| 259 |
+
model_name: str,
|
| 260 |
+
model_link: str,
|
| 261 |
+
team_name: str,
|
| 262 |
+
contact_email: str,
|
| 263 |
+
model_type: str,
|
| 264 |
+
accessibility: str,
|
| 265 |
+
) -> str:
|
| 266 |
+
token = os.environ.get("HF_TOKEN")
|
| 267 |
+
if not token:
|
| 268 |
+
return "HF_TOKEN is not set. Please add it in Space Settings -> Secrets."
|
| 269 |
+
|
| 270 |
+
try:
|
| 271 |
+
model_name = require_text(model_name, "Model name")
|
| 272 |
+
model_link = require_text(model_link, "Model link")
|
| 273 |
+
contact_email = require_text(contact_email, "Contact email")
|
| 274 |
+
team_name = str(team_name or "").strip()
|
| 275 |
+
accessibility = str(accessibility or "Unknown").strip()
|
| 276 |
+
|
| 277 |
+
if model_type not in MODEL_TYPE_CHOICES[1:]:
|
| 278 |
+
raise ValueError("Model type must be text-conditioned or action-conditioned.")
|
| 279 |
+
|
| 280 |
+
zip_path = get_uploaded_path(zip_file)
|
| 281 |
+
if zip_path is None or not zip_path.exists():
|
| 282 |
+
raise ValueError("Please upload a ZIP file.")
|
| 283 |
+
|
| 284 |
+
result_json = read_first_json_from_zip(zip_path)
|
| 285 |
+
ok, message = validate_submission_json(result_json)
|
| 286 |
+
if not ok:
|
| 287 |
+
raise ValueError(message)
|
| 288 |
+
|
| 289 |
+
# Refresh the local dataset checkout before adding the pending submission.
|
| 290 |
+
try:
|
| 291 |
+
snapshot_download(
|
| 292 |
+
repo_id=LEADERBOARD_REPO,
|
| 293 |
+
repo_type="dataset",
|
| 294 |
+
local_dir=str(LOCAL_LEADERBOARD_PATH),
|
| 295 |
+
token=token,
|
| 296 |
+
local_dir_use_symlinks=False,
|
| 297 |
+
)
|
| 298 |
+
except Exception:
|
| 299 |
+
ensure_submission_dirs()
|
| 300 |
+
|
| 301 |
+
ensure_local_results_file()
|
| 302 |
+
save_pending_submission(
|
| 303 |
+
zip_path=zip_path,
|
| 304 |
+
result_json=result_json,
|
| 305 |
+
model_name=model_name,
|
| 306 |
+
model_link=model_link,
|
| 307 |
+
team_name=team_name,
|
| 308 |
+
contact_email=contact_email,
|
| 309 |
+
model_type=model_type,
|
| 310 |
+
accessibility=accessibility,
|
| 311 |
+
)
|
| 312 |
+
upload_local_leaderboard(token, model_name)
|
| 313 |
+
except Exception as exc:
|
| 314 |
+
return f"Submission failed: {exc}"
|
| 315 |
+
|
| 316 |
+
return "Submission received. It is pending official verification."
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
def about_markdown() -> str:
|
| 320 |
+
return """
|
| 321 |
+
# About MBench
|
| 322 |
+
|
| 323 |
+
MBench evaluates whether video world models preserve memory over long-horizon generation and interaction.
|
| 324 |
+
|
| 325 |
+
**Entity Consistency** measures whether objects and humans keep stable identity, geometry, texture, and appearance after occlusion, exit/re-entry, or viewpoint changes.
|
| 326 |
+
|
| 327 |
+
**Environment Consistency** measures whether the world layout remains stable, including epipolar geometry, reprojection consistency, lighting, and style.
|
| 328 |
+
|
| 329 |
+
**Causal Consistency** measures whether earlier events continue to affect later frames through state progress, physical plausibility, and text/action interaction.
|
| 330 |
+
|
| 331 |
+
**Trigger Coverage** checks whether a generated video actually enters the intended memory challenge. **Memory Reliability** evaluates consistency only after that challenge is triggered. **M-Score** is the harmonic mean of Trigger Coverage and Memory Reliability.
|
| 332 |
+
|
| 333 |
+
Submitted results are not automatically verified. Official results will be added after MBench team review.
|
| 334 |
+
"""
|
| 335 |
+
|
| 336 |
+
|
| 337 |
+
def build_demo() -> gr.Blocks:
|
| 338 |
+
initial_df, initial_status = prepare_leaderboard("All", METRIC_COLUMNS)
|
| 339 |
+
|
| 340 |
+
css = """
|
| 341 |
+
.metric-panel textarea { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
| 342 |
+
footer { visibility: hidden; }
|
| 343 |
+
"""
|
| 344 |
+
|
| 345 |
+
with gr.Blocks(
|
| 346 |
+
title="MBench Leaderboard",
|
| 347 |
+
theme=gr.themes.Soft(primary_hue="indigo", secondary_hue="purple"),
|
| 348 |
+
css=css,
|
| 349 |
+
) as demo:
|
| 350 |
+
with gr.Tab("Leaderboard"):
|
| 351 |
+
gr.Markdown(LEADERBOARD_INTRO)
|
| 352 |
+
status = gr.Markdown(initial_status)
|
| 353 |
+
|
| 354 |
+
with gr.Row():
|
| 355 |
+
model_type_filter = gr.Radio(
|
| 356 |
+
choices=MODEL_TYPE_CHOICES,
|
| 357 |
+
value="All",
|
| 358 |
+
label="Model Type",
|
| 359 |
+
)
|
| 360 |
+
refresh_button = gr.Button("Refresh", variant="primary")
|
| 361 |
+
|
| 362 |
+
metric_selector = gr.CheckboxGroup(
|
| 363 |
+
choices=METRIC_COLUMNS,
|
| 364 |
+
value=METRIC_COLUMNS,
|
| 365 |
+
label="Metric Columns",
|
| 366 |
+
)
|
| 367 |
+
|
| 368 |
+
leaderboard_table = gr.Dataframe(
|
| 369 |
+
value=initial_df,
|
| 370 |
+
label="MBench Results",
|
| 371 |
+
interactive=False,
|
| 372 |
+
wrap=True,
|
| 373 |
+
height=520,
|
| 374 |
+
)
|
| 375 |
+
|
| 376 |
+
refresh_button.click(
|
| 377 |
+
fn=prepare_leaderboard,
|
| 378 |
+
inputs=[model_type_filter, metric_selector],
|
| 379 |
+
outputs=[leaderboard_table, status],
|
| 380 |
+
)
|
| 381 |
+
model_type_filter.change(
|
| 382 |
+
fn=prepare_leaderboard,
|
| 383 |
+
inputs=[model_type_filter, metric_selector],
|
| 384 |
+
outputs=[leaderboard_table, status],
|
| 385 |
+
)
|
| 386 |
+
metric_selector.change(
|
| 387 |
+
fn=prepare_leaderboard,
|
| 388 |
+
inputs=[model_type_filter, metric_selector],
|
| 389 |
+
outputs=[leaderboard_table, status],
|
| 390 |
+
)
|
| 391 |
+
|
| 392 |
+
with gr.Tab("Submit"):
|
| 393 |
+
gr.Markdown(SUBMIT_INTRO)
|
| 394 |
+
with gr.Row():
|
| 395 |
+
with gr.Column():
|
| 396 |
+
zip_input = gr.File(
|
| 397 |
+
label="Submission ZIP",
|
| 398 |
+
file_types=[".zip"],
|
| 399 |
+
type="filepath",
|
| 400 |
+
)
|
| 401 |
+
model_name_input = gr.Textbox(label="Model Name")
|
| 402 |
+
model_link_input = gr.Textbox(label="Model Link")
|
| 403 |
+
team_name_input = gr.Textbox(label="Team Name")
|
| 404 |
+
contact_email_input = gr.Textbox(label="Contact Email")
|
| 405 |
+
model_type_input = gr.Dropdown(
|
| 406 |
+
choices=MODEL_TYPE_CHOICES[1:],
|
| 407 |
+
value="text-conditioned",
|
| 408 |
+
label="Model Type",
|
| 409 |
+
)
|
| 410 |
+
accessibility_input = gr.Dropdown(
|
| 411 |
+
choices=[
|
| 412 |
+
"Open weights",
|
| 413 |
+
"API only",
|
| 414 |
+
"Closed",
|
| 415 |
+
"Research preview",
|
| 416 |
+
"Unknown",
|
| 417 |
+
],
|
| 418 |
+
value="Unknown",
|
| 419 |
+
label="Accessibility",
|
| 420 |
+
)
|
| 421 |
+
submit_button = gr.Button("Submit", variant="primary")
|
| 422 |
+
|
| 423 |
+
with gr.Column():
|
| 424 |
+
submit_status = gr.Markdown()
|
| 425 |
+
|
| 426 |
+
submit_button.click(
|
| 427 |
+
fn=submit_result,
|
| 428 |
+
inputs=[
|
| 429 |
+
zip_input,
|
| 430 |
+
model_name_input,
|
| 431 |
+
model_link_input,
|
| 432 |
+
team_name_input,
|
| 433 |
+
contact_email_input,
|
| 434 |
+
model_type_input,
|
| 435 |
+
accessibility_input,
|
| 436 |
+
],
|
| 437 |
+
outputs=submit_status,
|
| 438 |
+
)
|
| 439 |
+
|
| 440 |
+
with gr.Tab("About"):
|
| 441 |
+
gr.Markdown(about_markdown())
|
| 442 |
+
|
| 443 |
+
return demo
|
| 444 |
+
|
| 445 |
+
|
| 446 |
+
demo = build_demo()
|
| 447 |
+
|
| 448 |
+
|
| 449 |
+
if __name__ == "__main__":
|
| 450 |
+
demo.launch()
|
constants.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
BENCHMARK_DATASET_REPO = "studyOverflow/TempMemoryData"
|
| 2 |
+
LEADERBOARD_REPO = "PeanutUp/membench_leaderboard_submission"
|
| 3 |
+
LOCAL_LEADERBOARD_DIR = "./membench_leaderboard_submission"
|
| 4 |
+
RESULTS_CSV = "./membench_leaderboard_submission/results.csv"
|
| 5 |
+
|
| 6 |
+
MODEL_INFO_COLUMNS = [
|
| 7 |
+
"Rank",
|
| 8 |
+
"Model Name",
|
| 9 |
+
"Model Link",
|
| 10 |
+
"Model Type",
|
| 11 |
+
"Certification",
|
| 12 |
+
"Accessibility",
|
| 13 |
+
"Sampled by",
|
| 14 |
+
"Evaluated by",
|
| 15 |
+
"Date",
|
| 16 |
+
"Total M-Score",
|
| 17 |
+
"Entity Score",
|
| 18 |
+
"Environment Score",
|
| 19 |
+
"Causal Score",
|
| 20 |
+
]
|
| 21 |
+
|
| 22 |
+
METRIC_COLUMNS = [
|
| 23 |
+
"Object Geometry",
|
| 24 |
+
"Object Texture",
|
| 25 |
+
"Human Identity",
|
| 26 |
+
"Human Appearance",
|
| 27 |
+
"Epipolar Geometry",
|
| 28 |
+
"Reprojection Consistency",
|
| 29 |
+
"Lighting Consistency",
|
| 30 |
+
"Style Consistency",
|
| 31 |
+
"State Progress",
|
| 32 |
+
"Physical Plausibility",
|
| 33 |
+
"Text Interaction",
|
| 34 |
+
"Action Interaction",
|
| 35 |
+
"Trigger Coverage",
|
| 36 |
+
"Memory Reliability",
|
| 37 |
+
]
|
| 38 |
+
|
| 39 |
+
ALL_COLUMNS = MODEL_INFO_COLUMNS + METRIC_COLUMNS
|
| 40 |
+
|
| 41 |
+
MODEL_TYPE_CHOICES = [
|
| 42 |
+
"All",
|
| 43 |
+
"text-conditioned",
|
| 44 |
+
"action-conditioned",
|
| 45 |
+
]
|
| 46 |
+
|
| 47 |
+
LEADERBOARD_INTRO = """
|
| 48 |
+
# MBench Leaderboard
|
| 49 |
+
|
| 50 |
+
**MBench** evaluates memory capability in video world models: whether generated worlds keep entities, environments, and causal state coherent across long horizons and interaction.
|
| 51 |
+
|
| 52 |
+
- **Entity Consistency:** object geometry/texture and human identity/appearance.
|
| 53 |
+
- **Environment Consistency:** spatial consistency, reprojection, lighting, and style stability.
|
| 54 |
+
- **Causal Consistency:** state progress, physical plausibility, and text/action interaction consistency.
|
| 55 |
+
- **Trigger-Conditioned Scoring:** M-Score is the harmonic mean of Trigger Coverage and Memory Reliability, so models are rewarded only when they both trigger the memory challenge and remain consistent after it.
|
| 56 |
+
|
| 57 |
+
Seed leaderboard values are transcribed from Table 2 of the MBench paper. Aggregate columns are derived as unweighted averages over the reported sub-dimensions until official leaderboard totals are released.
|
| 58 |
+
|
| 59 |
+
Dataset: `studyOverflow/TempMemoryData`
|
| 60 |
+
Leaderboard data repo: `PeanutUp/membench_leaderboard_submission`
|
| 61 |
+
Project page: https://peanutup.github.io/MBench-project/
|
| 62 |
+
GitHub: https://github.com/study-overflow/MBench
|
| 63 |
+
"""
|
| 64 |
+
|
| 65 |
+
SUBMIT_INTRO = """
|
| 66 |
+
# Submit to MBench
|
| 67 |
+
|
| 68 |
+
Upload a ZIP file containing one JSON result file. Submissions are saved to `submissions/pending/` in the leaderboard data repo and are **not** added to the public leaderboard automatically.
|
| 69 |
+
|
| 70 |
+
Required JSON keys: `model_name`, `model_link`, `model_type`, and `total_m_score`.
|
| 71 |
+
"""
|
requirements.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio==4.36.1
|
| 2 |
+
pandas
|
| 3 |
+
numpy
|
| 4 |
+
huggingface_hub==0.23.4
|
| 5 |
+
fastapi==0.111.0
|
| 6 |
+
starlette==0.37.2
|
| 7 |
+
socksio
|
scripts/upload_seed_results.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import shutil
|
| 3 |
+
import sys
|
| 4 |
+
import tempfile
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
from huggingface_hub import HfApi
|
| 8 |
+
|
| 9 |
+
ROOT = Path(__file__).resolve().parents[1]
|
| 10 |
+
if str(ROOT) not in sys.path:
|
| 11 |
+
sys.path.insert(0, str(ROOT))
|
| 12 |
+
|
| 13 |
+
from constants import LEADERBOARD_REPO
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
REPO_TYPE = "dataset"
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def main() -> None:
|
| 20 |
+
token = os.environ.get("HF_TOKEN")
|
| 21 |
+
|
| 22 |
+
seed_results = ROOT / "seed" / "results.csv"
|
| 23 |
+
if not seed_results.exists():
|
| 24 |
+
raise FileNotFoundError(f"Seed file not found: {seed_results}")
|
| 25 |
+
|
| 26 |
+
api = HfApi(token=token)
|
| 27 |
+
try:
|
| 28 |
+
api.whoami(token=token)
|
| 29 |
+
except Exception as exc:
|
| 30 |
+
raise RuntimeError(
|
| 31 |
+
"HF_TOKEN is not set and no cached Hugging Face login was found. "
|
| 32 |
+
"Please run `export HF_TOKEN=...` or `hf auth login` first."
|
| 33 |
+
) from exc
|
| 34 |
+
|
| 35 |
+
api.create_repo(repo_id=LEADERBOARD_REPO, repo_type=REPO_TYPE, exist_ok=True)
|
| 36 |
+
|
| 37 |
+
with tempfile.TemporaryDirectory(prefix="mbench_seed_") as tmp_dir:
|
| 38 |
+
tmp_root = Path(tmp_dir)
|
| 39 |
+
shutil.copy2(seed_results, tmp_root / "results.csv")
|
| 40 |
+
|
| 41 |
+
pending_dir = tmp_root / "submissions" / "pending"
|
| 42 |
+
verified_dir = tmp_root / "submissions" / "verified"
|
| 43 |
+
pending_dir.mkdir(parents=True, exist_ok=True)
|
| 44 |
+
verified_dir.mkdir(parents=True, exist_ok=True)
|
| 45 |
+
(pending_dir / ".gitkeep").write_text("", encoding="utf-8")
|
| 46 |
+
(verified_dir / ".gitkeep").write_text("", encoding="utf-8")
|
| 47 |
+
|
| 48 |
+
api.upload_folder(
|
| 49 |
+
folder_path=str(tmp_root),
|
| 50 |
+
repo_id=LEADERBOARD_REPO,
|
| 51 |
+
repo_type=REPO_TYPE,
|
| 52 |
+
commit_message="Initialize MBench leaderboard seed results",
|
| 53 |
+
)
|
| 54 |
+
|
| 55 |
+
print(f"Uploaded seed results to {LEADERBOARD_REPO}: results.csv")
|
| 56 |
+
print("Created submissions/pending/.gitkeep and submissions/verified/.gitkeep")
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
if __name__ == "__main__":
|
| 60 |
+
main()
|
scripts/validate_submission.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import re
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from typing import Any
|
| 5 |
+
|
| 6 |
+
ROOT = Path(__file__).resolve().parents[1]
|
| 7 |
+
if str(ROOT) not in sys.path:
|
| 8 |
+
sys.path.insert(0, str(ROOT))
|
| 9 |
+
|
| 10 |
+
from constants import METRIC_COLUMNS
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
ALLOWED_MODEL_TYPES = {"text-conditioned", "action-conditioned"}
|
| 14 |
+
REQUIRED_KEYS = ["model_name", "model_link", "model_type", "total_m_score"]
|
| 15 |
+
SUMMARY_SCORE_FIELDS = [
|
| 16 |
+
"total_m_score",
|
| 17 |
+
"entity_score",
|
| 18 |
+
"environment_score",
|
| 19 |
+
"causal_score",
|
| 20 |
+
]
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def _normalize_key(key: str) -> str:
|
| 24 |
+
return re.sub(r"[^a-z0-9]+", "_", key.lower()).strip("_")
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def _is_present(value: Any) -> bool:
|
| 28 |
+
return value is not None and str(value).strip() != ""
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def validate_submission_json(data: dict) -> tuple[bool, str]:
|
| 32 |
+
if not isinstance(data, dict):
|
| 33 |
+
return False, "Submission JSON must be an object."
|
| 34 |
+
|
| 35 |
+
normalized = {_normalize_key(str(key)): value for key, value in data.items()}
|
| 36 |
+
|
| 37 |
+
for key in REQUIRED_KEYS:
|
| 38 |
+
if key not in normalized or not _is_present(normalized[key]):
|
| 39 |
+
return False, f"Missing required field: {key}"
|
| 40 |
+
|
| 41 |
+
model_type = str(normalized["model_type"]).strip()
|
| 42 |
+
if model_type not in ALLOWED_MODEL_TYPES:
|
| 43 |
+
return (
|
| 44 |
+
False,
|
| 45 |
+
"model_type must be either text-conditioned or action-conditioned.",
|
| 46 |
+
)
|
| 47 |
+
|
| 48 |
+
score_fields = set(SUMMARY_SCORE_FIELDS)
|
| 49 |
+
score_fields.update(_normalize_key(column) for column in METRIC_COLUMNS)
|
| 50 |
+
|
| 51 |
+
for key, value in normalized.items():
|
| 52 |
+
if key in score_fields and _is_present(value):
|
| 53 |
+
try:
|
| 54 |
+
float(value)
|
| 55 |
+
except (TypeError, ValueError):
|
| 56 |
+
return False, f"Score field {key} must be convertible to float."
|
| 57 |
+
|
| 58 |
+
return True, "Submission JSON is valid."
|
seed/results.csv
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Rank,Model Name,Model Link,Model Type,Certification,Accessibility,Sampled by,Evaluated by,Date,Total M-Score,Entity Score,Environment Score,Causal Score,Object Geometry,Object Texture,Human Identity,Human Appearance,Epipolar Geometry,Reprojection Consistency,Lighting Consistency,Style Consistency,State Progress,Physical Plausibility,Text Interaction,Action Interaction,Trigger Coverage,Memory Reliability
|
| 2 |
+
1,HY-WorldPlay,,action-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,67.25,58.67,81.69,55.53,47.12,68.54,52.46,66.58,83.86,68.17,82.67,92.04,0,0,25.38,85.69,0,0
|
| 3 |
+
2,Infinite-World,,action-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,56.59,41.88,71.13,56.95,35.70,61.88,23.08,46.85,74.04,61.51,62.63,86.34,0,0,27.53,86.37,0,0
|
| 4 |
+
3,Matrix-Game 3.0,,action-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,53.79,48.16,60.20,52.21,44.15,58.22,42.38,47.91,61.99,32.86,62.06,83.90,0,0,22.48,81.93,0,0
|
| 5 |
+
4,Self Forcing,,text-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,49.44,61.42,46.77,30.81,85.23,66.16,37.67,56.64,52.76,8.70,52.01,73.61,33.50,0,28.13,0,0,0
|
| 6 |
+
5,Yume-1.5,,action-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,46.67,42.23,50.57,47.76,60.96,49.99,17.41,40.57,51.86,24.55,51.21,74.65,0,0,33.32,62.20,0,0
|
| 7 |
+
6,LongLive,,text-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,45.28,55.88,36.10,42.45,75.29,55.83,34.89,57.49,31.11,2.38,43.58,67.32,54.22,0,30.69,0,0,0
|
| 8 |
+
7,MemFlow,,text-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,45.13,56.51,37.36,37.92,80.60,63.78,31.44,50.22,42.00,1.29,39.03,67.12,45.72,0,30.13,0,0,0
|
| 9 |
+
8,Skyreels V2,,text-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,38.16,40.10,35.13,40.34,63.54,40.94,14.62,41.31,33.43,2.49,31.08,73.54,51.92,0,28.77,0,0,0
|
| 10 |
+
9,LongCat-Video,,text-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,36.83,35.90,30.48,51.38,45.97,39.15,16.32,42.16,16.66,0.74,40.08,64.46,72.67,0,30.08,0,0,0
|
| 11 |
+
10,Helios,,text-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,34.73,42.86,26.80,34.32,71.72,49.60,20.28,29.85,14.37,2.47,27.20,63.16,41.11,0,27.53,0,0,0
|
| 12 |
+
11,Causal Forcing,,text-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,34.26,42.10,24.34,38.44,49.77,39.32,28.16,51.14,10.02,0.00,41.46,45.86,47.92,0,28.95,0,0,0
|
| 13 |
+
12,Lingbot-World,,action-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,34.12,30.71,30.81,47.54,33.20,44.54,11.57,33.53,22.12,7.57,40.06,53.50,0,0,31.76,63.32,0,0
|
| 14 |
+
13,Cosmos-Predict 2.5,,text-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,30.93,27.81,24.25,50.51,36.98,32.49,9.53,32.26,5.14,0.17,40.56,51.14,71.92,0,29.10,0,0,0
|
| 15 |
+
14,Matrix-Game 2.0,,action-conditioned,MBench Paper,TBD,MBench Team,MBench Team,2026-05-28,20.34,11.44,23.44,31.93,14.62,28.99,1.22,0.94,14.78,3.08,38.79,37.10,0,0,16.00,47.86,0,0
|