Run full causal Geometry Forcing RE10K evaluation at 12 slots and CFG1
Browse filesExtend the tested causal evaluator to eight workers and 300-frame loops with separate worker records. The full launcher evaluates one monitor preflight, then all100fixedscenes with common scoring and aggregation. Teacher-history diagnostics are optional. Sampling code, released weights, environment and required cache paths are unchanged.
- README.md +8 -6
- deployment/evaluate_geometry_forcing_8h200.sh +14 -23
- deployment/geometry_causal_controls.py +17 -9
README.md
CHANGED
|
@@ -18,7 +18,7 @@ Four independent model workspaces and conda environments for the existing Minecr
|
|
| 18 |
| DecMem public Wan reference | `DecMem/` | `/proj/cvl/users/x_fahkh2/envs/decmem-eval` | Minecraft: 600 observed + 500 generated frames |
|
| 19 |
| Matrix-Game 2.0 | `Matrix-Game/Matrix-Game-2/` | `/proj/cvl/users/x_fahkh2/envs/matrix-game2-eval` | Minecraft: 600 observed + 500 generated frames |
|
| 20 |
| LIVE | `LIVE/` | `/proj/cvl/users/x_fahkh2/envs/live-eval` | RE10K: 100 observed + 300 generated frames |
|
| 21 |
-
| Geometry Forcing | `GeometryForcing/` | `/proj/cvl/users/x_fahkh2/envs/geometry-forcing-eval` | RE10K: causal
|
| 22 |
|
| 23 |
The Berzelius checkout location is `/proj/cvl/users/x_fahkh2/worldmem-baseline-evals`. Submit jobs from Berzelius Hopper. First, `deployment/setup_environment_berzelius.sh` creates all four environments under `/proj/cvl/users/x_fahkh2/envs/`, builds required CUDA extensions, downloads checkpoints, validates data, and caches metric weights. It installs the official pinned Miniforge 24.7.1-2 manager under `/proj/cvl/users/x_fahkh2/envs/baseline-miniforge3` and restricts conda environment creation to the `conda-forge` channel. It uses that manager by its absolute path, without a Miniforge module or shell-profile changes. It uses the dedicated `berzelius-hopper-cpu` partition, 14 CPU cores, no GPUs, and an eight-hour limit. It runs no model inference. Setup logs are written under `slurm_logs/`, and records under `artifacts/environment_setup_JOBID/`. All setup, smoke and full evaluation jobs set both `TMPDIR` and `TRITON_CACHE_DIR` to `/proj/cvl/users/x_fahkh2/worldmem-baseline-evals/cache/`, as required by the project.
|
| 24 |
|
|
@@ -29,11 +29,11 @@ After setup completes successfully, each method has its own smoke job and full e
|
|
| 29 |
| DecMem | `deployment/smoke_decmem_1h200.sh` | `deployment/evaluate_decmem_8h200.sh` |
|
| 30 |
| Matrix-Game 2.0 | `deployment/smoke_matrix_game2_1h200.sh` | `deployment/evaluate_matrix_game2_8h200.sh` |
|
| 31 |
| LIVE | `deployment/smoke_live_1h200.sh` | `deployment/evaluate_live_8h200.sh` |
|
| 32 |
-
| Geometry Forcing (
|
| 33 |
|
| 34 |
-
|
| 35 |
|
| 36 |
-
|
| 37 |
|
| 38 |
The full launchers partition cases without duplication, score each case, and aggregate all requested outputs. Minecraft evaluates 300 cases with seeds 42 and 43 in sequential array elements; RE10K evaluates the fixed final100 scope with seed 0. Each GPU job requests 14 CPU cores per H200 and leaves memory allocation to Slurm. Each model has a separate submitted job. No script submits other jobs automatically.
|
| 39 |
|
|
@@ -41,8 +41,10 @@ Expected existing dataset locations are `/proj/cvl/users/x_fahkh2/WorldMem_Repro
|
|
| 41 |
|
| 42 |
**Protocol details.** Minecraft observes source frames `[100,700)` and scores `[700,1200)` at 360×640, against the fixed Oasis-VAE reference cache. DecMem uses actions and poses with UniPC20/CFG5; Matrix uses calibrated action conditioning and its native three-step sampler. Temporal padding duplicates only observed frames, and the scored suffix contains exactly 500 frames. Matrix's incoming-to-outgoing action conversion is documented in its method manifest.
|
| 43 |
|
| 44 |
-
RE10K follows `G0…G199,G199…G0`, including the repeated turnaround, with 100 observed and 300 generated frames at 256×256. LIVE uses its 18-step sampler with the requested 12-frame window. Geometry Forcing
|
| 45 |
|
| 46 |
-
**
|
|
|
|
|
|
|
| 47 |
|
| 48 |
Upstream revisions are recorded in `upstream_sources.json`. Sources retain their original licenses and notices, described in [THIRD_PARTY.md](THIRD_PARTY.md). In particular, the frozen WorldMem reference is covered by S-Lab License 1.0 and is not covered by the other projects' permissive licenses.
|
|
|
|
| 18 |
| DecMem public Wan reference | `DecMem/` | `/proj/cvl/users/x_fahkh2/envs/decmem-eval` | Minecraft: 600 observed + 500 generated frames |
|
| 19 |
| Matrix-Game 2.0 | `Matrix-Game/Matrix-Game-2/` | `/proj/cvl/users/x_fahkh2/envs/matrix-game2-eval` | Minecraft: 600 observed + 500 generated frames |
|
| 20 |
| LIVE | `LIVE/` | `/proj/cvl/users/x_fahkh2/envs/live-eval` | RE10K: 100 observed + 300 generated frames |
|
| 21 |
+
| Geometry Forcing | `GeometryForcing/` | `/proj/cvl/users/x_fahkh2/envs/geometry-forcing-eval` | RE10K: causal 12-slot/CFG1 evaluation; native interpolation is an offline control |
|
| 22 |
|
| 23 |
The Berzelius checkout location is `/proj/cvl/users/x_fahkh2/worldmem-baseline-evals`. Submit jobs from Berzelius Hopper. First, `deployment/setup_environment_berzelius.sh` creates all four environments under `/proj/cvl/users/x_fahkh2/envs/`, builds required CUDA extensions, downloads checkpoints, validates data, and caches metric weights. It installs the official pinned Miniforge 24.7.1-2 manager under `/proj/cvl/users/x_fahkh2/envs/baseline-miniforge3` and restricts conda environment creation to the `conda-forge` channel. It uses that manager by its absolute path, without a Miniforge module or shell-profile changes. It uses the dedicated `berzelius-hopper-cpu` partition, 14 CPU cores, no GPUs, and an eight-hour limit. It runs no model inference. Setup logs are written under `slurm_logs/`, and records under `artifacts/environment_setup_JOBID/`. All setup, smoke and full evaluation jobs set both `TMPDIR` and `TRITON_CACHE_DIR` to `/proj/cvl/users/x_fahkh2/worldmem-baseline-evals/cache/`, as required by the project.
|
| 24 |
|
|
|
|
| 29 |
| DecMem | `deployment/smoke_decmem_1h200.sh` | `deployment/evaluate_decmem_8h200.sh` |
|
| 30 |
| Matrix-Game 2.0 | `deployment/smoke_matrix_game2_1h200.sh` | `deployment/evaluate_matrix_game2_8h200.sh` |
|
| 31 |
| LIVE | `deployment/smoke_live_1h200.sh` | `deployment/evaluate_live_8h200.sh` |
|
| 32 |
+
| Geometry Forcing (causal, 12 slots, CFG1) | `deployment/geometry_causal_controls_1h200.sh` | `deployment/evaluate_geometry_forcing_8h200.sh` |
|
| 33 |
|
| 34 |
+
The completed strictly autoregressive diagnostics used `deployment/geometry_causal_controls_1h200.sh`: 8 slots/guidance 4, 12 slots/guidance 4, and 12 slots/guidance 1 on two monitor scenes with 32 future frames. Its optional fourth task replaces generated history with ground-truth history while retaining the same noise masks; this task is diagnostic only. The autoregressive tasks use past RGB and poses through the current target; unused model slots contain noise and copies of the current camera. The full launcher uses the selected 12-slot/guidance-1 setting without waiting for the fourth task.
|
| 35 |
|
| 36 |
+
The full causal GF job includes its own 300-frame preflight. Standalone LIVE and Minecraft smoke jobs each generate and score one real-data case and check aggregation: LIVE generates 104 frames, DecMem 20, and Matrix 24. The separate native GF offline smoke generates 300 frames using keyframes and interpolation. Smoke and causal-diagnostic logs are under the checkout's `slurm_logs/`; full logs are under each method workspace's `slurm_logs/`. Results are under each method workspace's `outputs/`.
|
| 37 |
|
| 38 |
The full launchers partition cases without duplication, score each case, and aggregate all requested outputs. Minecraft evaluates 300 cases with seeds 42 and 43 in sequential array elements; RE10K evaluates the fixed final100 scope with seed 0. Each GPU job requests 14 CPU cores per H200 and leaves memory allocation to Slurm. Each model has a separate submitted job. No script submits other jobs automatically.
|
| 39 |
|
|
|
|
| 41 |
|
| 42 |
**Protocol details.** Minecraft observes source frames `[100,700)` and scores `[700,1200)` at 360×640, against the fixed Oasis-VAE reference cache. DecMem uses actions and poses with UniPC20/CFG5; Matrix uses calibrated action conditioning and its native three-step sampler. Temporal padding duplicates only observed frames, and the scored suffix contains exactly 500 frames. Matrix's incoming-to-outgoing action conversion is documented in its method manifest.
|
| 43 |
|
| 44 |
+
RE10K follows `G0…G199,G199…G0`, including the repeated turnaround, with 100 observed and 300 generated frames at 256×256. LIVE uses its 18-step sampler with the requested 12-frame window. The Geometry Forcing offline control consumes the last observed image (timeline 99), predicts 19 sparse keyframes over timeline 99–399, and interpolates the other frames with its native 16-slot backbone. Its prediction guidance is 4 with stabilization 0.02; interpolation guidance is 1.5. Short camera batches repeat the final camera to fill unused model slots. This offline workflow is not the causal evaluation described below. Scene seeds follow `1_000_003 * metadata_index + 7`. The common RGB targets, AlexNet LPIPS, mean frame PSNR, SSIM and pooled FID are retained; these are not the paper's exact metric implementation. Archived offline GF outputs use the `geometry-forcing_native_re10k_` prefix.
|
| 45 |
|
| 46 |
+
**Geometry Forcing full causal evaluation.** The full launcher now runs the tested causal evaluator at 12 active slots (11 past frames plus one target), guidance 1, DDIM50, eta 0 and stabilization 0.02. It first generates and scores one complete 300-frame monitor loop, then automatically evaluates final100 on eight H200 workers and aggregates all 30,000 frames. The teacher-history diagnostic is optional and does not gate this run. Outputs use `geometry-forcing_ar12_cfg1_re10k_100cases_seed0_job<JOB>`; logs are in `GeometryForcing/slurm_logs/`. The native workflow described above remains available only through `deployment/smoke_geometry_forcing_1h200.sh` as an offline control.
|
| 47 |
+
|
| 48 |
+
**Validation status.** Causal tasks 85128_0/1/2 completed two monitor scenes with 32 frames each. CFG1 avoided CFG4's noise collapse but still showed blur and motion lag; its full-horizon quality is not established. These monitor scenes are disjoint from final100, and the full run freezes the chosen CFG1 setting. Native smoke 85127 completed 300 frames but uses future keyframes during interpolation. Context budgets and method differences are recorded in `deployment/context_budget_audit.json`.
|
| 49 |
|
| 50 |
Upstream revisions are recorded in `upstream_sources.json`. Sources retain their original licenses and notices, described in [THIRD_PARTY.md](THIRD_PARTY.md). In particular, the frozen WorldMem reference is covered by S-Lab License 1.0 and is not covered by the other projects' permissive licenses.
|
deployment/evaluate_geometry_forcing_8h200.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
#!/usr/bin/env bash
|
| 2 |
-
#SBATCH --job-name=geometry-forcing-re10k-
|
| 3 |
#SBATCH --nodes=1
|
| 4 |
#SBATCH --ntasks-per-node=8
|
| 5 |
#SBATCH --cpus-per-task=14
|
|
@@ -19,12 +19,11 @@ ENV_ROOT=/proj/cvl/users/x_fahkh2/envs
|
|
| 19 |
REPO=$ROOT/GeometryForcing
|
| 20 |
PYTHON=$ENV_ROOT/geometry-forcing-eval/bin/python
|
| 21 |
METRIC_PYTHON=$ENV_ROOT/geometry-forcing-eval/bin/python
|
| 22 |
-
WORLD_MEM_ROOT=$ROOT/references/worldmem
|
| 23 |
DATA_ROOT=/proj/cvl/users/x_fahkh2/WorldMem_Repro/datasets/re10k_dfot/real-estate-10k
|
| 24 |
MANIFEST=$ROOT/deployment/manifests/re10k_real_trajectory_h100_f399_scopes_v1.csv
|
| 25 |
SEED=0
|
| 26 |
JOB=$SLURM_JOB_ID
|
| 27 |
-
RUN=geometry-
|
| 28 |
OUTPUT=$REPO/outputs/$RUN
|
| 29 |
PREFLIGHT_OUTPUT=$REPO/outputs/${RUN}_preflight
|
| 30 |
|
|
@@ -46,21 +45,17 @@ cd "$REPO"
|
|
| 46 |
|
| 47 |
"$PYTHON" "$ROOT/deployment/verify_node.py" --output "$OUTPUT"
|
| 48 |
cp "$0" "$OUTPUT/launcher.sh"
|
|
|
|
| 49 |
|
| 50 |
-
#
|
| 51 |
srun --exclusive --exact --nodes=1 --ntasks=1 --gpus-per-task=1 --cpus-per-task=14 --cpu-bind=cores \
|
| 52 |
-
"$PYTHON" "$ROOT/
|
| 53 |
-
--
|
| 54 |
-
--workspace-root "$ROOT" \
|
| 55 |
-
--metric-python "$METRIC_PYTHON" \
|
| 56 |
-
--worldmem-root "$WORLD_MEM_ROOT" \
|
| 57 |
-
--manifest "$MANIFEST" \
|
| 58 |
--data-root "$DATA_ROOT" \
|
| 59 |
--output "$PREFLIGHT_OUTPUT" \
|
| 60 |
-
--scope
|
| 61 |
-
--seed "$SEED" \
|
| 62 |
--limit 1 \
|
| 63 |
-
--
|
| 64 |
--rank 0 \
|
| 65 |
--world-size 1
|
| 66 |
|
|
@@ -69,24 +64,19 @@ srun --exclusive --exact --nodes=1 --ntasks=1 --gpus-per-task=1 --cpus-per-task=
|
|
| 69 |
--output "$PREFLIGHT_OUTPUT" \
|
| 70 |
--manifest "$MANIFEST" \
|
| 71 |
--dataset re10k \
|
| 72 |
-
--scope
|
| 73 |
--seed "$SEED" \
|
| 74 |
--expected-frames 300 \
|
| 75 |
--limit 1
|
| 76 |
|
| 77 |
srun --ntasks=8 --gpus-per-task=1 --cpus-per-task=14 --cpu-bind=cores --kill-on-bad-exit=1 \
|
| 78 |
-
"$PYTHON" "$ROOT/
|
| 79 |
-
--
|
| 80 |
-
--workspace-root "$ROOT" \
|
| 81 |
-
--metric-python "$METRIC_PYTHON" \
|
| 82 |
-
--worldmem-root "$WORLD_MEM_ROOT" \
|
| 83 |
-
--manifest "$MANIFEST" \
|
| 84 |
--data-root "$DATA_ROOT" \
|
| 85 |
--output "$OUTPUT" \
|
| 86 |
--scope final100 \
|
| 87 |
-
--seed "$SEED" \
|
| 88 |
--limit 100 \
|
| 89 |
-
--
|
| 90 |
--world-size 8
|
| 91 |
|
| 92 |
srun --exclusive --exact --nodes=1 --ntasks=1 --gpus-per-task=1 --cpus-per-task=14 \
|
|
@@ -95,4 +85,5 @@ srun --exclusive --exact --nodes=1 --ntasks=1 --gpus-per-task=1 --cpus-per-task=
|
|
| 95 |
--manifest "$MANIFEST" \
|
| 96 |
--dataset re10k \
|
| 97 |
--scope final100 \
|
| 98 |
-
--seed "$SEED"
|
|
|
|
|
|
| 1 |
#!/usr/bin/env bash
|
| 2 |
+
#SBATCH --job-name=geometry-forcing-re10k-ar12-cfg1-full
|
| 3 |
#SBATCH --nodes=1
|
| 4 |
#SBATCH --ntasks-per-node=8
|
| 5 |
#SBATCH --cpus-per-task=14
|
|
|
|
| 19 |
REPO=$ROOT/GeometryForcing
|
| 20 |
PYTHON=$ENV_ROOT/geometry-forcing-eval/bin/python
|
| 21 |
METRIC_PYTHON=$ENV_ROOT/geometry-forcing-eval/bin/python
|
|
|
|
| 22 |
DATA_ROOT=/proj/cvl/users/x_fahkh2/WorldMem_Repro/datasets/re10k_dfot/real-estate-10k
|
| 23 |
MANIFEST=$ROOT/deployment/manifests/re10k_real_trajectory_h100_f399_scopes_v1.csv
|
| 24 |
SEED=0
|
| 25 |
JOB=$SLURM_JOB_ID
|
| 26 |
+
RUN=geometry-forcing_ar12_cfg1_re10k_100cases_seed${SEED}_job${JOB}
|
| 27 |
OUTPUT=$REPO/outputs/$RUN
|
| 28 |
PREFLIGHT_OUTPUT=$REPO/outputs/${RUN}_preflight
|
| 29 |
|
|
|
|
| 45 |
|
| 46 |
"$PYTHON" "$ROOT/deployment/verify_node.py" --output "$OUTPUT"
|
| 47 |
cp "$0" "$OUTPUT/launcher.sh"
|
| 48 |
+
cp "$ROOT/deployment/geometry_causal_controls.py" "$OUTPUT/probe.py"
|
| 49 |
|
| 50 |
+
# Check generation and scoring across the complete loop, then continue automatically.
|
| 51 |
srun --exclusive --exact --nodes=1 --ntasks=1 --gpus-per-task=1 --cpus-per-task=14 --cpu-bind=cores \
|
| 52 |
+
"$PYTHON" "$ROOT/deployment/geometry_causal_controls.py" \
|
| 53 |
+
--mode ar12_cfg1 \
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
--data-root "$DATA_ROOT" \
|
| 55 |
--output "$PREFLIGHT_OUTPUT" \
|
| 56 |
+
--scope monitor8 \
|
|
|
|
| 57 |
--limit 1 \
|
| 58 |
+
--frames 300 \
|
| 59 |
--rank 0 \
|
| 60 |
--world-size 1
|
| 61 |
|
|
|
|
| 64 |
--output "$PREFLIGHT_OUTPUT" \
|
| 65 |
--manifest "$MANIFEST" \
|
| 66 |
--dataset re10k \
|
| 67 |
+
--scope monitor8 \
|
| 68 |
--seed "$SEED" \
|
| 69 |
--expected-frames 300 \
|
| 70 |
--limit 1
|
| 71 |
|
| 72 |
srun --ntasks=8 --gpus-per-task=1 --cpus-per-task=14 --cpu-bind=cores --kill-on-bad-exit=1 \
|
| 73 |
+
"$PYTHON" "$ROOT/deployment/geometry_causal_controls.py" \
|
| 74 |
+
--mode ar12_cfg1 \
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
--data-root "$DATA_ROOT" \
|
| 76 |
--output "$OUTPUT" \
|
| 77 |
--scope final100 \
|
|
|
|
| 78 |
--limit 100 \
|
| 79 |
+
--frames 300 \
|
| 80 |
--world-size 8
|
| 81 |
|
| 82 |
srun --exclusive --exact --nodes=1 --ntasks=1 --gpus-per-task=1 --cpus-per-task=14 \
|
|
|
|
| 85 |
--manifest "$MANIFEST" \
|
| 86 |
--dataset re10k \
|
| 87 |
--scope final100 \
|
| 88 |
+
--seed "$SEED" \
|
| 89 |
+
--expected-frames 300
|
deployment/geometry_causal_controls.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
"""
|
| 2 |
import argparse
|
| 3 |
import json
|
| 4 |
import os
|
|
@@ -54,12 +54,18 @@ def main():
|
|
| 54 |
parser.add_argument('--mode', choices=MODES, required=True)
|
| 55 |
parser.add_argument('--data-root', type=Path, required=True)
|
| 56 |
parser.add_argument('--output', type=Path, required=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
parser.add_argument('--dry-run', action='store_true')
|
| 58 |
args = parser.parse_args()
|
| 59 |
window, scale, teacher = MODES[args.mode]
|
| 60 |
manifest_path = ROOT / 'deployment/manifests/re10k_real_trajectory_h100_f399_scopes_v1.csv'
|
| 61 |
-
rows = select_cases(manifest_path,
|
| 62 |
-
manifest = {'mode': args.mode, 'diagnostic_only':
|
|
|
|
| 63 |
'workflow': 'one target at a time; no keyframes or interpolation', 'active_slots': window,
|
| 64 |
'past_rgb_frames': window-1, 'physical_slots': 16, 'noise_padding_slots': 16-window,
|
| 65 |
'camera_policy': 'past and current target only; current camera repeated in noise-padding slots',
|
|
@@ -70,7 +76,7 @@ def main():
|
|
| 70 |
'weights': 'released state_dict; unchanged; no EMA substitution', 'parameters': 458818051,
|
| 71 |
'trainable_parameters': 0, 'batch_size': 1, 'optimizer': None, 'lr': None, 'lora': None,
|
| 72 |
'activation_checkpointing': False, 'precision': 'fp16 autocast; fp32 weights/cameras',
|
| 73 |
-
'scored_timeline': [100,
|
| 74 |
'torch': torch.__version__, 'initial_noise_shape': [1, 16, 3, 256, 256], 'target_noise_slot': window-1,
|
| 75 |
'rng_note': 'same case seeds; AR8 and AR12 have different target noise slots',
|
| 76 |
'cases': [{'scene': r['scene_id'], 'seed': case_seed(r, 0)} for r in rows]}
|
|
@@ -80,7 +86,8 @@ def main():
|
|
| 80 |
args.output = args.output.resolve()
|
| 81 |
args.data_root = args.data_root.resolve()
|
| 82 |
args.output.mkdir(parents=True, exist_ok=True)
|
| 83 |
-
|
|
|
|
| 84 |
os.chdir(ROOT / 'GeometryForcing')
|
| 85 |
from evaluation.worldmem_adapter import GeometryForcingAdapter
|
| 86 |
from algorithms.dfot.history_guidance import HistoryGuidance
|
|
@@ -89,20 +96,21 @@ def main():
|
|
| 89 |
manifest['checkpoint'] = adapter.provenance['checkpoint']
|
| 90 |
manifest['loaded_tensors'] = adapter.provenance['loaded_backbone_tensors']
|
| 91 |
manifest['actual_parameters'] = adapter.provenance['parameters']
|
| 92 |
-
|
| 93 |
for row in rows:
|
| 94 |
case = load_re10k_case(row, args.data_root)
|
| 95 |
seed = case_seed(row, 0)
|
| 96 |
start = time.monotonic()
|
| 97 |
-
prediction, sampler_states, global_states = generate(adapter.model, case, window, guidance, teacher, seed)
|
| 98 |
-
directory = save_case(args.output, row, prediction, {**manifest, 'seed': seed, 'generated_frames':
|
| 99 |
'history_frames': 100, 'source_indices': case['source_indices'].tolist(), 'generation_seconds': time.monotonic()-start})
|
| 100 |
np.savez_compressed(directory / 'rng_states.npz', sampler=sampler_states.numpy(), global_rng=global_states.numpy())
|
| 101 |
del prediction, case
|
| 102 |
torch.cuda.empty_cache()
|
| 103 |
subprocess.run([sys.executable, str(ROOT / 'shared/score_case.py'), '--case-dir', str(directory),
|
| 104 |
'--dataset', 're10k', '--data-root', str(args.data_root), '--worldmem-root', str(ROOT / 'references/worldmem')], check=True)
|
| 105 |
-
|
|
|
|
| 106 |
print('CAUSAL_CONTROL_COMPLETE', flush=True)
|
| 107 |
|
| 108 |
if __name__ == '__main__':
|
|
|
|
| 1 |
+
"""Causal GF evaluation and diagnostics; teacher history is diagnostic only."""
|
| 2 |
import argparse
|
| 3 |
import json
|
| 4 |
import os
|
|
|
|
| 54 |
parser.add_argument('--mode', choices=MODES, required=True)
|
| 55 |
parser.add_argument('--data-root', type=Path, required=True)
|
| 56 |
parser.add_argument('--output', type=Path, required=True)
|
| 57 |
+
parser.add_argument('--scope', choices=['monitor8', 'final100'], default='monitor8')
|
| 58 |
+
parser.add_argument('--limit', type=int, default=2)
|
| 59 |
+
parser.add_argument('--frames', type=int, default=32)
|
| 60 |
+
parser.add_argument('--rank', type=int, default=int(os.environ.get('SLURM_PROCID', 0)))
|
| 61 |
+
parser.add_argument('--world-size', type=int, default=int(os.environ.get('SLURM_NTASKS', 1)))
|
| 62 |
parser.add_argument('--dry-run', action='store_true')
|
| 63 |
args = parser.parse_args()
|
| 64 |
window, scale, teacher = MODES[args.mode]
|
| 65 |
manifest_path = ROOT / 'deployment/manifests/re10k_real_trajectory_h100_f399_scopes_v1.csv'
|
| 66 |
+
rows = select_cases(manifest_path, args.scope, args.rank, args.world_size, args.limit)
|
| 67 |
+
manifest = {'mode': args.mode, 'diagnostic_only': teacher or args.scope != 'final100' or args.frames != 300,
|
| 68 |
+
'teacher_history': teacher, 'scope': args.scope, 'rank': args.rank, 'world_size': args.world_size,
|
| 69 |
'workflow': 'one target at a time; no keyframes or interpolation', 'active_slots': window,
|
| 70 |
'past_rgb_frames': window-1, 'physical_slots': 16, 'noise_padding_slots': 16-window,
|
| 71 |
'camera_policy': 'past and current target only; current camera repeated in noise-padding slots',
|
|
|
|
| 76 |
'weights': 'released state_dict; unchanged; no EMA substitution', 'parameters': 458818051,
|
| 77 |
'trainable_parameters': 0, 'batch_size': 1, 'optimizer': None, 'lr': None, 'lora': None,
|
| 78 |
'activation_checkpointing': False, 'precision': 'fp16 autocast; fp32 weights/cameras',
|
| 79 |
+
'scored_timeline': [100, 100+args.frames], 'master_seed': 0, 'full_loop_evaluation': args.frames == 300,
|
| 80 |
'torch': torch.__version__, 'initial_noise_shape': [1, 16, 3, 256, 256], 'target_noise_slot': window-1,
|
| 81 |
'rng_note': 'same case seeds; AR8 and AR12 have different target noise slots',
|
| 82 |
'cases': [{'scene': r['scene_id'], 'seed': case_seed(r, 0)} for r in rows]}
|
|
|
|
| 86 |
args.output = args.output.resolve()
|
| 87 |
args.data_root = args.data_root.resolve()
|
| 88 |
args.output.mkdir(parents=True, exist_ok=True)
|
| 89 |
+
manifest_file = args.output / ('manifest.json' if args.world_size == 1 else f'manifest_rank{args.rank}.json')
|
| 90 |
+
manifest_file.write_text(json.dumps(manifest, indent=2))
|
| 91 |
os.chdir(ROOT / 'GeometryForcing')
|
| 92 |
from evaluation.worldmem_adapter import GeometryForcingAdapter
|
| 93 |
from algorithms.dfot.history_guidance import HistoryGuidance
|
|
|
|
| 96 |
manifest['checkpoint'] = adapter.provenance['checkpoint']
|
| 97 |
manifest['loaded_tensors'] = adapter.provenance['loaded_backbone_tensors']
|
| 98 |
manifest['actual_parameters'] = adapter.provenance['parameters']
|
| 99 |
+
manifest_file.write_text(json.dumps(manifest, indent=2))
|
| 100 |
for row in rows:
|
| 101 |
case = load_re10k_case(row, args.data_root)
|
| 102 |
seed = case_seed(row, 0)
|
| 103 |
start = time.monotonic()
|
| 104 |
+
prediction, sampler_states, global_states = generate(adapter.model, case, window, guidance, teacher, seed, args.frames)
|
| 105 |
+
directory = save_case(args.output, row, prediction, {**manifest, 'seed': seed, 'generated_frames': args.frames,
|
| 106 |
'history_frames': 100, 'source_indices': case['source_indices'].tolist(), 'generation_seconds': time.monotonic()-start})
|
| 107 |
np.savez_compressed(directory / 'rng_states.npz', sampler=sampler_states.numpy(), global_rng=global_states.numpy())
|
| 108 |
del prediction, case
|
| 109 |
torch.cuda.empty_cache()
|
| 110 |
subprocess.run([sys.executable, str(ROOT / 'shared/score_case.py'), '--case-dir', str(directory),
|
| 111 |
'--dataset', 're10k', '--data-root', str(args.data_root), '--worldmem-root', str(ROOT / 'references/worldmem')], check=True)
|
| 112 |
+
complete_file = args.output / ('complete.json' if args.world_size == 1 else f'worker_{args.rank:02d}_complete.json')
|
| 113 |
+
complete_file.write_text(json.dumps({'mode': args.mode, 'rank': args.rank, 'cases': len(rows), 'frames': args.frames}))
|
| 114 |
print('CAUSAL_CONTROL_COMPLETE', flush=True)
|
| 115 |
|
| 116 |
if __name__ == '__main__':
|