p-doom/crowd-code-dataset-0.2 huggingface dataset:
[tab] slurm/jobs/alfred/helmholtz_cluster/jafar_og_reproduction/og_coinrun_dynamics_reproduction.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --gres=gpu:1
#SBATCH --time=3-00:00:00
#SBATCH --cpus-per-task=8
#SBATCH --partition=gpu_p
#SBATCH --reservation=haicu_stefan
#SBATCH --qos=gpu_long
#SBATCH --output=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/dynamics/%x_%j.log
#SBATCH --error=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/dynamics/%x_%j.log
#SBATCH --job-name=train_dynamics_coinrun_og_reproduction

# Log the sbatch script
cat $0

source .venv/bin/activate

job_name=$SLURM_JOB_NAME
slurm_job_id=$SLURM_JOB_ID

tags="coinrun_og dynanmics 10m_dataset helmholtz_reproduction dyn_repro"

npy_records_dir="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/data/coinrun_episodes/coinrun_episodes"

tokenizer_ckpt_dir="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/checkpoints/coinrun/tokenizer/train_tokenizer_coinrun_og_reproduction_28246778/tokenizer_1756303195_110000"
lam_ckpt_dir="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/checkpoints/coinrun/lam/train_lam_coinrun_og_reproduction_28246647/lam_1756303037_200000"
CHECKPOINT_DIR="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/checkpoints/coinrun/dynamics/${job_name}/${slurm_job_id}"
mkdir -p $CHECKPOINT_DIR

env | grep SLURM

srun python train_dynamics.py \
    --ckpt_dir $CHECKPOINT_DIR \
    --tokenizer_checkpoint="${tokenizer_ckpt_dir}" \
    --lam_checkpoint="${lam_ckpt_dir}" \
    --log_image_interval=1000 \
    --log \
    --name="${job_name}_${slurm_job_id}" \
    --tags ${tags} \
    --entity instant-uv \
    --project jafar \
    --data_dir $npy_records_dir
[tab] slurm/jobs/mihir/horeka/jafar_og_reproduction/og_coinrun_dynamics_reproduction.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --gres=gpu:1
#SBATCH --time=3-00:00:00
#SBATCH --cpus-per-task=8
#SBATCH --partition=gpu_p
#SBATCH --reservation=haicu_stefan
#SBATCH --qos=gpu_long
#SBATCH --output=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/dynamics/%x_%j.log
#SBATCH --error=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/dynamics/%x_%j.log
#SBATCH --job-name=train_dynamics_coinrun_og_reproduction

# Log the sbatch script
cat $0

source .venv/bin/activate

job_name=$SLURM_JOB_NAME
slurm_job_id=$SLURM_JOB_ID

tags="coinrun_og dynanmics 10m_dataset helmholtz_reproduction dyn_repro"

npy_records_dir="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/data/coinrun_episodes/coinrun_episodes"

tokenizer_ckpt_dir="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/checkpoints/coinrun/tokenizer/train_tokenizer_coinrun_og_reproduction_28246778/tokenizer_1756303195_110000"
lam_ckpt_dir="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/checkpoints/coinrun/lam/train_lam_coinrun_og_reproduction_28246647/lam_1756303037_200000"
CHECKPOINT_DIR="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/checkpoints/coinrun/dynamics/${job_name}/${slurm_job_id}"
mkdir -p $CHECKPOINT_DIR

env | grep SLURM

srun python train_dynamics.py \
    --ckpt_dir $CHECKPOINT_DIR \
    --tokenizer_checkpoint="${tokenizer_ckpt_dir}" \
    --lam_checkpoint="${lam_ckpt_dir}" \
    --log_image_interval=1000 \
    --log \
    --name="${job_name}_${slurm_job_id}" \
    --tags ${tags} \
    --entity instant-uv \
    --project jafar \
    --data_dir $npy_records_dir
[tab] slurm/jobs/mihir/horeka/jafar_og_reproduction/og_coinrun_lam_reproduction.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=3-00:00:00
#SBATCH --cpus-per-task=8
#SBATCH --partition=gpu_p
#SBATCH --reservation=haicu_stefan
#SBATCH --qos=gpu_long
#SBATCH --gres=gpu:1
#SBATCH --output=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/lam/%x_%j.log
#SBATCH --error=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/lam/%x_%j.log
#SBATCH --job-name=train_lam_coinrun_og_reproduction

# Log the sbatch script
cat $0

source .venv/bin/activate

job_name=$SLURM_JOB_NAME
slurm_job_id=$SLURM_JOB_ID

tags="coinrun_og reproduction 10k_dataset lam helmholtz_reproduction"

npy_records_dir="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/data/coinrun_episodes/coinrun_episodes"

CHECKPOINT_DIR="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/checkpoints/coinrun/lam/${job_name}_${slurm_job_id}"
mkdir -p $CHECKPOINT_DIR

env | grep SLURM

srun python train_lam.py \
    --ckpt_dir $CHECKPOINT_DIR \
    --log_image_interval=1000 \
    --log \
    --name="${job_name}_${slurm_job_id}" \
    --tags $tags \
    --entity instant-uv \
    --project jafar \
    --data_dir $npy_records_dir
[tab] slurm/jobs/mihir/horeka/lam/train_lam_minecraft_8node-darkness-filter-base.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=8
#SBATCH --ntasks-per-node=4
#SBATCH --time=48:00:00
#SBATCH --partition=accelerated
#SBATCH --cpus-per-task=5
#SBATCH --gres=gpu:4
#SBATCH --output=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/lam/%x_%j.log
#SBATCH --error=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/lam/%x_%j.log
#SBATCH --job-name=train_lam_minecraft_8node_darkness_filter_37M
#SBATCH --requeue
#SBATCH --signal=b:usr1@300 # 5 min before timeout

# --- signal trap to requeue job before timeout ---
requeue_job() {
    echo "[$(date)] caught sigusr1 (timeout warning), requeueing slurm job $SLURM_JOB_ID..."
    scontrol requeue $SLURM_JOB_ID
    exit 0
}

trap requeue_job sigusr1

# set checkpoint flag based on restart count
restart_count=$(scontrol show job $SLURM_JOB_ID | grep -o 'Restarts=[0-9]*' | cut -d'=' -f2)

if [ $restart_count -eq 0 ]; then
    restore_ckpt_flag="--no-restore-ckpt"
else
    restore_ckpt_flag="--restore-ckpt"
fi

# Log the sbatch script
cat $0

module unload mpi/openmpi/5.0
module unload devel/cuda/12.4
source .venv/bin/activate

array_records_dir=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/data_new/open_ai_minecraft_arrayrecords_chunked

job_name=$SLURM_JOB_NAME
# slurm_job_id=$SLURM_JOB_ID
slurm_job_id=3454953

CHECKPOINT_DIR=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/checkpoints/mihir/lam/$job_name/$slurm_job_id
mkdir -p $CHECKPOINT_DIR

env | grep SLURM

srun python train_lam.py \
    --save_ckpt \
    --restore_ckpt \
    --wandb_id $slurm_job_id \
    --ckpt_dir $CHECKPOINT_DIR \
    --batch_size=160 \
    --init_lr=0 \
    --max_lr=1e-4 \
    --darkness_threshold=50 \
    --log_image_interval=1000 \
    --log \
    --log_checkpoint_interval=1000 \
    --name=lam-minecraft-8-node-darkness-filter-37M-$slurm_job_id \
    --tags lam minecraft 8-node darkness-filter 37M \
    --entity instant-uv \
    --project jafar \
    --num_latents=100 \
    --data_dir $array_records_dir &

child_pid=$!

wait $child_pid
[content] slurm/jobs/mihir/horeka/jafar_og_reproduction/og_coinrun_lam_reproduction.sbatch (shellscript)
#SBATCH --output=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/lam/%x_%j.log
#SBATCH --error=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/lam/%x_%j.log
[tab] slurm/jobs/mihir/horeka/jafar_og_reproduction/og_coinrun_tokenizer_repoduction.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=3-00:00:00
#SBATCH --cpus-per-task=8
#SBATCH --partition=gpu_p
#SBATCH --reservation=haicu_stefan
#SBATCH --qos=gpu_long
#SBATCH --gres=gpu:1
#SBATCH --output=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/tokenizer/%x_%j.log
#SBATCH --error=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/tokenizer/%x_%j.log
#SBATCH --job-name=train_tokenizer_coinrun_og_reproduction

# Log the sbatch script
cat $0

source .venv/bin/activate

job_name=$SLURM_JOB_NAME
slurm_job_id=$SLURM_JOB_ID

tags="coinrun_og reproduction 10k_dataset tokenizer helmholtz_reproduction"

npy_records_dir="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/data/coinrun_episodes/coinrun_episodes"

CHECKPOINT_DIR="/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/checkpoints/coinrun/tokenizer/${job_name}_${slurm_job_id}"
mkdir -p $CHECKPOINT_DIR

env | grep SLURM

srun python train_tokenizer.py \
    --ckpt_dir $CHECKPOINT_DIR \
    --log_image_interval=1000 \
    --log \
    --name="${job_name}_${slurm_job_id}" \
    --tags $tags \
    --entity instant-uv \
    --project jafar \
    --data_dir $npy_records_dir
[content] slurm/jobs/mihir/horeka/jafar_og_reproduction/og_coinrun_tokenizer_repoduction.sbatch (shellscript)

npy_records_dir="/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/data_coinrun/coinrun_episodes_10m"

CHECKPOINT_DIR="/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/checkpoints/mihir/jafar_og_reproduction/lam/$job_name/$slurm_job_id"
[tab] slurm/jobs/mihir/horeka/jafar_og_reproduction/generate_dataset.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=2:00:00
#SBATCH --partition=cpu_p
#SBATCH --qos=cpu_short
#SBATCH --cpus-per-task=8
#SBATCH --output=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/generate_dataset/%x_%j.log
#SBATCH --error=/lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/logs/coinrun/generate_dataset/%x_%j.log
#SBATCH --job-name=generate_coinrun_dataset


# Log the sbatch script
cat $0
source .venv/bin/activate

python generate_dataset.py --num_episodes 10000 --output_dir /lustre/groups/haicu/workspace/alfred.nguyen/jafar_worksapce/data/coinrun_episodes_10k
[tab] slurm/jobs/mihir/horeka/jafar_og_reproduction/generate_dataset_10m.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=12:00:00
#SBATCH --partition=cpuonly
#SBATCH --cpus-per-task=8
#SBATCH --output=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --error=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --job-name=generate_coinrun_dataset_10m


# Log the sbatch script
cat $0
source .venv/bin/activate

python generate_dataset.py \
    --num_episodes 10000 \
    --output_dir /hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/data_coinrun/coinrun_episodes_10m \
    --min_episode_length 1000
[content] slurm/jobs/mihir/horeka/jafar_og_reproduction/generate_dataset.sbatch (shellscript)
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=12:00:00
#SBATCH --partition=cpuonly
#SBATCH --cpus-per-task=8
#SBATCH --output=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --error=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --job-name=generate_coinrun_dataset_10m
[tab] generate_dataset.py (python)
"""
Generates a dataset of random-action CoinRun episodes.
Episodes are saved individually as memory-mapped files for efficient loading.
"""

from dataclasses import dataclass
from pathlib import Path

from gym3 import types_np
import numpy as np
from procgen import ProcgenGym3Env
import tyro


@dataclass
class Args:
    num_episodes: int = 10000
    output_dir: str = "data/coinrun_episodes"
    min_episode_length: int = 50


args = tyro.cli(Args)
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)

# --- Generate episodes ---
i = 0
metadata = []
while i < args.num_episodes:
    seed = np.random.randint(0, 10000)
    env = ProcgenGym3Env(num=1, env_name="coinrun", start_level=seed)
    dataseq = []

    # --- Run episode ---
    for j in range(1000):
        action = types_np.sample(env.ac_space, bshape=(env.num,))
        env.act(action)
        rew, obs, first = env.observe()
        dataseq.append(obs["rgb"])
        if first:
            break

    # --- Save episode ---
    if len(dataseq) >= args.min_episode_length:
        episode_data = np.concatenate(dataseq, axis=0)
        episode_path = output_dir / f"episode_{i}.npy"
        np.save(episode_path, episode_data.astype(np.uint8))
        metadata.append({"path": str(episode_path), "length": len(dataseq)})
        print(f"Episode {i} completed, length: {len(dataseq)}")
        i += 1
    else:
        print(f"Episode too short ({len(dataseq)}), resampling...")

# --- Save metadata ---
np.save(output_dir / "metadata.npy", metadata)
print(f"Dataset generated with {len(metadata)} valid episodes")
[tab] slurm/dev/mihir/horeka/generate_dataset_10m.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=12:00:00
#SBATCH --partition=cpuonly
#SBATCH --cpus-per-task=8
#SBATCH --output=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --error=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --job-name=generate_coinrun_dataset_10m


# Log the sbatch script
cat $0
source .venv/bin/activate

python generate_dataset.py \
    --num_episodes 10000 \
    --output_dir /hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/data_coinrun/coinrun_episodes_10m \
    --min_episode_length 1000
[tab] slurm/dev/mihir/horeka/generate_dataset_10m.sh (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=12:00:00
#SBATCH --partition=cpuonly
#SBATCH --cpus-per-task=8
#SBATCH --output=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --error=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --job-name=generate_coinrun_dataset_10m


# Log the sbatch script
cat $0
source .venv/bin/activate

python generate_dataset.py \
    --num_episodes 10000 \
    --output_dir /hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/data_coinrun/coinrun_episodes_10m \
    --min_episode_length 1000
[content] input_pipeline/preprocess/npy_to_arrayrecords.py (python)
import numpy as np
import os
import tyro
import multiprocessing as mp
from dataclasses import dataclass
import json
import pickle
from array_record.python.array_record_module import ArrayRecordWriter


@dataclass
class Args:
    input_path: str = "data/minecraft_npy"
    output_path: str = "data/minecraft_arrayrecords"

def preprocess_video(
    idx, in_filename, output_path
):
    print(f"Processing video {idx}, Filename: {in_filename}")
    try:
        frames = np.load(in_filename)
        n_frames = frames.shape[0]

        output_path = os.path.join(
            output_path,
            os.path.splitext(os.path.basename(in_filename))[0] + ".array_record",
        )

        writer = ArrayRecordWriter(str(output_path), "group_size:1")

        print(f"Saving video {idx} to {output_path}")
        record = {"raw_video": frames.tobytes(), "sequence_length": n_frames}
        writer.write(pickle.dumps(record))
        writer.close()

        return in_filename, n_frames
    except Exception as e:
        print(f"Error processing video {idx} ({in_filename}): {e}")
        return in_filename, 0


def main():
    args = tyro.cli(Args)

    os.makedirs(args.output_path, exist_ok=True)
    print(f"Output path: {args.output_path}")

    num_processes = mp.cpu_count()
    print(f"Number of processes: {num_processes}")

    print("Converting npy to array_record files...")
    pool_args = [
        (
            idx,
            os.path.join(args.input_path, in_filename),
            args.output_path,
        )
        for idx, in_filename in enumerate(os.listdir(args.input_path))
        if in_filename.endswith(".npy")
    ]

    results = []
    with mp.Pool(processes=num_processes) as pool:
        for result in pool.starmap(preprocess_video, pool_args):
            results.append(result)
    print("Done converting npy to array_record files")

    # count the number of failed videos
    failed_videos = [result for result in results if result[1] == 0]
    short_episodes = [result for result in results if result[1] < 1600]
    print(f"Number of failed videos: {len(failed_videos)}")
    print(f"Number of short episodes: {len(short_episodes)}")
    print(
        f"Number of successful videos: {len(results) - len(failed_videos) - len(short_episodes)}"
    )
    print(f"Number of total videos: {len(results)}")

    with open(os.path.join(args.output_path, "meta_data.json"), "w") as f:
        json.dump(results, f)


if __name__ == "__main__":
    main()
[tab] generate_dataset.py (python)
"""
Generates a dataset of random-action CoinRun episodes.
Episodes are saved individually as memory-mapped files for efficient loading.
"""

from dataclasses import dataclass
from pathlib import Path

from gym3 import types_np
import numpy as np
from procgen import ProcgenGym3Env
import tyro


@dataclass
class Args:
    num_episodes: int = 10000
    output_dir: str = "data/coinrun_episodes"
    min_episode_length: int = 50


args = tyro.cli(Args)
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)

# --- Generate episodes ---
i = 0
metadata = []
while i < args.num_episodes:
    seed = np.random.randint(0, 10000)
    env = ProcgenGym3Env(num=1, env_name="coinrun", start_level=seed)
    dataseq = []

    # --- Run episode ---
    for j in range(1000):
        action = types_np.sample(env.ac_space, bshape=(env.num,))
        env.act(action)
        breakpoint()
        rew, obs, first = env.observe()
        dataseq.append(obs["rgb"])
        if first:
            break

    # --- Save episode ---
    if len(dataseq) >= args.min_episode_length:
        episode_data = np.concatenate(dataseq, axis=0)
        episode_path = output_dir / f"episode_{i}.npy"
        np.save(episode_path, episode_data.astype(np.uint8))
        metadata.append({"path": str(episode_path), "length": len(dataseq)})
        print(f"Episode {i} completed, length: {len(dataseq)}")
        i += 1
    else:
        print(f"Episode too short ({len(dataseq)}), resampling...")

# --- Save metadata ---
np.save(output_dir / "metadata.npy", metadata)
print(f"Dataset generated with {len(metadata)} valid episodes")
[content] generate_dataset.py (python)
*You seem to be using an outdated version of Cursor. Please upgrade to the latest version by [downloading Cursor again from our website](https://www.cursor.com/). All your settings will be preserved.*
[content] generate_dataset.py (python)
"""
Generates a dataset of random-action CoinRun episodes.
Episodes are saved individually as memory-mapped files for efficient loading.
"""

from dataclasses import dataclass
from pathlib import Path

from gym3 import types_np
import numpy as np
from procgen import ProcgenGym3Env
import tyro


@dataclass
class Args:
    num_episodes: int = 10000
    output_dir: str = "data/coinrun_episodes"
    min_episode_length: int = 50


args = tyro.cli(Args)
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)

# --- Generate episodes ---
i = 0
metadata = []
while i < args.num_episodes:
    seed = np.random.randint(0, 10000)
    env = ProcgenGym3Env(num=1, env_name="coinrun", start_level=seed)
    dataseq = []

    # --- Run episode ---
    for j in range(1000):
        action = types_np.sample(env.ac_space, bshape=(env.num,))
        env.act(action)
        breakpoint()
        rew, obs, first = env.observe()
        dataseq.append(obs["rgb"])
        if first:
            break

    # --- Save episode ---
    if len(dataseq) >= args.min_episode_length:
        episode_data = np.concatenate(dataseq, axis=0)
        episode_path = output_dir / f"episode_{i}.npy"
        np.save(episode_path, episode_data.astype(np.uint8))
        metadata.append({"path": str(episode_path), "length": len(dataseq)})
        print(f"Episode {i} completed, length: {len(dataseq)}")
        i += 1
    else:
        print(f"Episode too short ({len(dataseq)}), resampling...")

# --- Save metadata ---
np.save(output_dir / "metadata.npy", metadata)
print(f"Dataset generated with {len(metadata)} valid episodes")
[content] generate_dataset.py (python)
# --- Generate episodes ---
i = 0
metadata = []
while i < args.num_episodes:
    seed = np.random.randint(0, 10000)
    env = ProcgenGym3Env(num=1, env_name="coinrun", start_level=seed)
    dataseq = []

    # --- Run episode ---
    for j in range(1000):
        action = types_np.sample(env.ac_space, bshape=(env.num,))
        env.act(action)
        rew, obs, first = env.observe()
        dataseq.append(obs["rgb"])
        if first:
            break

    # --- Save episode ---
    if len(dataseq) >= args.min_episode_length:
        episode_data = np.concatenate(dataseq, axis=0)
        episode_path = output_dir / f"episode_{i}.array_record"  # <-- change extension

        # --- Save as ArrayRecord ---
        writer = ArrayRecordWriter(str(episode_path), "group_size:1")
        record = {"raw_video": episode_data.tobytes(), "sequence_length": len(dataseq)}
        writer.write(pickle.dumps(record))
        writer.close()

        metadata.append({"path": str(episode_path), "length": len(dataseq)})
        print(f"Episode {i} completed, length: {len(dataseq)}")
        i += 1
    else:
        print(f"Episode too short ({len(dataseq)}), resampling...")

# --- Save metadata ---
np.save(output_dir / "metadata.npy", metadata)
print(f"Dataset generated with {len(metadata)} valid episodes")
[tab] input_pipeline/preprocess/npy_to_array_records.py (python)
import numpy as np
import os
import tyro
import multiprocessing as mp
from dataclasses import dataclass
import json
import pickle
from array_record.python.array_record_module import ArrayRecordWriter


@dataclass
class Args:
    input_path: str = "data/minecraft_npy"
    output_path: str = "data/minecraft_arrayrecords"

def preprocess_video(
    idx, in_filename, output_path
):
    print(f"Processing video {idx}, Filename: {in_filename}")
    try:
        frames = np.load(in_filename)
        n_frames = frames.shape[0]

        output_path = os.path.join(
            output_path,
            os.path.splitext(os.path.basename(in_filename))[0] + ".array_record",
        )

        writer = ArrayRecordWriter(str(output_path), "group_size:1")

        print(f"Saving video {idx} to {output_path}")
        record = {"raw_video": frames.tobytes(), "sequence_length": n_frames}
        writer.write(pickle.dumps(record))
        writer.close()

        return in_filename, n_frames
    except Exception as e:
        print(f"Error processing video {idx} ({in_filename}): {e}")
        return in_filename, 0


def main():
    args = tyro.cli(Args)

    os.makedirs(args.output_path, exist_ok=True)
    print(f"Output path: {args.output_path}")

    num_processes = mp.cpu_count()
    print(f"Number of processes: {num_processes}")

    print("Converting npy to array_record files...")
    pool_args = [
        (
            idx,
            os.path.join(args.input_path, in_filename),
            args.output_path,
        )
        for idx, in_filename in enumerate(os.listdir(args.input_path))
        if in_filename.endswith(".npy")
    ]

    results = []
    with mp.Pool(processes=num_processes) as pool:
        for result in pool.starmap(preprocess_video, pool_args):
            results.append(result)
    print("Done converting npy to array_record files")

    # count the number of failed videos
    failed_videos = [result for result in results if result[1] == 0]
    short_episodes = [result for result in results if result[1] < 1600]
    print(f"Number of failed videos: {len(failed_videos)}")
    print(f"Number of short episodes: {len(short_episodes)}")
    print(
        f"Number of successful videos: {len(results) - len(failed_videos) - len(short_episodes)}"
    )
    print(f"Number of total videos: {len(results)}")

    with open(os.path.join(args.output_path, "meta_data.json"), "w") as f:
        json.dump(results, f)


if __name__ == "__main__":
    main()
[tab] generate_dataset.py (python)
"""
Generates a dataset of random-action CoinRun episodes.
Episodes are saved individually as memory-mapped files for efficient loading.
"""

from dataclasses import dataclass
from pathlib import Path

from gym3 import types_np
import numpy as np
from procgen import ProcgenGym3Env
import tyro
import pickle
import json
from array_record.python.array_record_module import ArrayRecordWriter 



@dataclass
class Args:
    num_episodes: int = 10000
    output_dir: str = "data/coinrun_episodes"
    min_episode_length: int = 50


args = tyro.cli(Args)
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)

# --- Generate episodes ---
i = 0
episode_metadata = []
while i < args.num_episodes:
    seed = np.random.randint(0, 10000)
    env = ProcgenGym3Env(num=1, env_name="coinrun", start_level=seed)
    observations_seq = []

    # --- Run episode ---
    for j in range(1000):
        env.act(types_np.sample(env.ac_space, bshape=(env.num,)))
        rew, obs, first = env.observe()
        observations_seq.append(obs["rgb"])
        if first:
            break

    # --- Save episode ---
    if len(observations_seq) >= args.min_episode_length:
        observations_data = np.concatenate(observations_seq, axis=0)
        episode_path = output_dir / f"episode_{i}.array_record"  

        # --- Save as ArrayRecord ---
        writer = ArrayRecordWriter(str(episode_path), "group_size:1")
        record = {"raw_video": observations_data.tobytes(), "sequence_length": len(observations_seq)}
        writer.write(pickle.dumps(record))
        writer.close()

        episode_metadata.append({"path": str(episode_path), "length": len(observations_seq)})
        print(f"Episode {i} completed, length: {len(observations_seq)}")
        i += 1
    else:
        print(f"Episode too short ({len(observations_seq)}), resampling...")

# --- Save metadata ---
metadata = {
    "env": "coinrun",
    "num_episodes": args.num_episodes,
    "avg_episode_len": np.mean([ep["length"] for ep in episode_metadata]),
    "episode_metadata": episode_metadata,
}
with open(output_dir / "meta_data.json", "w") as f:
    json.dump(metadata, f)

print(f"Dataset generated with {len(episode_metadata)} valid episodes")
[content] input_pipeline/preprocess/pngs_to_array_records.py (python)
    metadata = {
        "env": args.env_name,
        "total_videos": len(results),
        "num_successful_videos": len(results) - len(failed_videos) - len(short_episodes),
        "num_failed_videos": len(failed_videos),
        "num_short_videos": len(short_episodes),
        "avg_episode_len": np.mean([ep["length"] for ep in results]),
        "episode_metadata": results,
    }

    with open(os.path.join(args.output_path, "metadata.json"), "w") as f:
        json.dump(metadata, f)
[content] input_pipeline/preprocess/video_to_array_records.py (python)
    num_successful_videos = len(results) - len(failed_videos) - len(short_episodes)
    print(f"Number of failed videos: {len(failed_videos)}")
    print(f"Number of short episodes: {len(short_episodes)}")
    print(f"Number of successful videos: {num_successful_videos}")
[tab] generate_dataset.py (python)
"""
Generates a dataset of random-action CoinRun episodes.
Episodes are saved individually as memory-mapped files for efficient loading.
"""

from dataclasses import dataclass
from pathlib import Path

from gym3 import types_np
import numpy as np
from procgen import ProcgenGym3Env
import tyro
import pickle
import json
from array_record.python.array_record_module import ArrayRecordWriter 



@dataclass
class Args:
    num_episodes: int = 10000
    output_dir: str = "data/coinrun_episodes"
    min_episode_length: int = 50


args = tyro.cli(Args)
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)

# --- Generate episodes ---
i = 0
episode_metadata = []
while i < args.num_episodes:
    seed = np.random.randint(0, 10000)
    env = ProcgenGym3Env(num=1, env_name="coinrun", start_level=seed)
    observations_seq = []
    actions_seq = []

    # --- Run episode ---
    for j in range(1000):
        action = types_np.sample(env.ac_space, bshape=(env.num,))
        print(action)
        env.act(action)
        rew, obs, first = env.observe()
        observations_seq.append(obs["rgb"])
        actions_seq.append(action)
        if first:
            break

    # --- Save episode ---
    if len(observations_seq) >= args.min_episode_length:
        observations_data = np.concatenate(observations_seq, axis=0)
        action_data = np.concatenate(actions_seq, axis=0)
        episode_path = output_dir / f"episode_{i}.array_record"  

        # --- Save as ArrayRecord ---
        writer = ArrayRecordWriter(str(episode_path), "group_size:1")
        record = {"raw_video": observations_data.tobytes(), "actions": action_data, "sequence_length": len(observations_seq)}
        writer.write(pickle.dumps(record))
        writer.close()

        episode_metadata.append({"path": str(episode_path), "length": len(observations_seq)})
        print(f"Episode {i} completed, length: {len(observations_seq)}")
        i += 1
    else:
        print(f"Episode too short ({len(observations_seq)}), resampling...")

# --- Save metadata ---
metadata = {
    "env": "coinrun",
    "num_actions": env.ac_space.eltype.n,
    "num_episodes": args.num_episodes,
    "avg_episode_len": np.mean([ep["length"] for ep in episode_metadata]),
    "episode_metadata": episode_metadata,
}
with open(output_dir / "meta_data.json", "w") as f:
    json.dump(metadata, f)

print(f"Dataset generated with {len(episode_metadata)} valid episodes")
[tab] slurm/jobs/mihir/horeka/jafar_og_reproduction/generate_dataset_10m copy.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=12:00:00
#SBATCH --partition=cpuonly
#SBATCH --cpus-per-task=8
#SBATCH --output=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --error=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --job-name=generate_coinrun_dataset_10m


# Log the sbatch script
cat $0
source .venv/bin/activate

python generate_dataset.py \
    --num_episodes 10000 \
    --output_dir /hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/data_coinrun/coinrun_episodes_10m \
    --min_episode_length 1000
[tab] slurm/jobs/mihir/horeka/jafar_og_reproduction/generate_dataset_10m_gt_actions.sbatch (shellscript)
#!/usr/bin/env bash

#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --time=12:00:00
#SBATCH --partition=cpuonly
#SBATCH --cpus-per-task=8
#SBATCH --output=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --error=/hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/logs/logs_mihir/data_coinrun/%x_%j.log
#SBATCH --job-name=generate_coinrun_dataset_10m


# Log the sbatch script
cat $0
source .venv/bin/activate

python generate_dataset.py \
    --num_episodes 10000 \
    --output_dir /hkfs/work/workspace/scratch/tum_ind3695-jafa_ws_shared/data_coinrun/coinrun_episodes_10m \
    --min_episode_length 1000
[tab] generate_dataset.py (python)
"""
Generates a dataset of random-action CoinRun episodes.
Episodes are saved individually as memory-mapped files for efficient loading.
"""

from dataclasses import dataclass
from pathlib import Path

from gym3 import types_np
import numpy as np
from procgen import ProcgenGym3Env
import tyro
import pickle
import json
from array_record.python.array_record_module import ArrayRecordWriter 



@dataclass
class Args:
    num_episodes: int = 10000
    output_dir: str = "data/coinrun_episodes"
    min_episode_length: int = 50


args = tyro.cli(Args)
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)

# --- Generate episodes ---
i = 0
episode_metadata = []
while i < args.num_episodes:
    seed = np.random.randint(0, 10000)
    env = ProcgenGym3Env(num=1, env_name="coinrun", start_level=seed)
    observations_seq = []

    # --- Run episode ---
    for j in range(1000):
        env.act(types_np.sample(env.ac_space, bshape=(env.num,)))
        rew, obs, first = env.observe()
        observations_seq.append(obs["rgb"])
        if first:
            break

    # --- Save episode ---
    if len(observations_seq) >= args.min_episode_length:
        observations_data = np.concatenate(observations_seq, axis=0)
        episode_path = output_dir / f"episode_{i}.array_record"  

        # --- Save as ArrayRecord ---
        writer = ArrayRecordWriter(str(episode_path), "group_size:1")
        record = {"raw_video": observations_data.tobytes(), "sequence_length": len(observations_seq)}
        writer.write(pickle.dumps(record))
        writer.close()

        episode_metadata.append({"path": str(episode_path), "length": len(observations_seq)})
        print(f"Episode {i} completed, length: {len(observations_seq)}")
        i += 1
    else:
        print(f"Episode too short ({len(observations_seq)}), resampling...")

# --- Save metadata ---
metadata = {
    "env": "coinrun",
    "num_episodes": args.num_episodes,
    "avg_episode_len": np.mean([ep["length"] for ep in episode_metadata]),
    "episode_metadata": episode_metadata,
}
with open(output_dir / "metadata.json", "w") as f:
    json.dump(metadata, f)

print(f"Dataset generated with {len(episode_metadata)} valid episodes")