mirror of
https://github.com/nerfstudio-project/nerfstudio.git
synced 2026-11-11 02:24:38 +08:00
151 lines
5.2 KiB
Python
151 lines
5.2 KiB
Python
"""
|
|
run_benchmark.py
|
|
"""
|
|
import argparse
|
|
import json
|
|
import logging
|
|
import os
|
|
from datetime import datetime
|
|
from typing import Any, Dict, Tuple
|
|
|
|
import numpy as np
|
|
from hydra import compose, initialize
|
|
from omegaconf import DictConfig
|
|
|
|
from scripts.run_eval import run_inference_from_config
|
|
|
|
|
|
def _load_best_ckpt(hydra_dir: str, config: DictConfig) -> str:
|
|
"""helper function to update config with latest checkpoint in specified hydra_dir
|
|
|
|
Args:
|
|
hydra_dir (str): base directory for the specified run (where the model directories are stored)
|
|
config (DictConfig): configuration for the specified run.
|
|
|
|
Returns:
|
|
str: path to the most recent checkpoint sorted by timestamps and step number
|
|
"""
|
|
# get the most recent run in the model directory
|
|
latest_run = os.listdir(hydra_dir)
|
|
latest_run.sort()
|
|
latest_run = latest_run[-1]
|
|
# get the latest checkpoint name
|
|
model_dir = os.path.join(hydra_dir, latest_run, config.model_dir)
|
|
latest_ckpt = os.listdir(model_dir)
|
|
latest_ckpt.sort()
|
|
latest_ckpt = latest_ckpt[-1]
|
|
step = os.path.splitext(latest_ckpt)[0].split("-")[-1]
|
|
config.resume_train.load_dir = model_dir
|
|
config.resume_train.load_step = int(step)
|
|
return os.path.join(model_dir, latest_ckpt)
|
|
|
|
|
|
def _load_hydra_config(hydra_dir: str, benchmark_time=None, benchmark_date=None) -> Tuple[DictConfig, str]:
|
|
"""helper function to load the specified hydra config from the specified directory
|
|
|
|
Args:
|
|
hydra_dir (str): base directory for the specified run (where the flattened config.yaml is stored)
|
|
|
|
Returns:
|
|
DictConfig: returns the loaded hydra dictionary config
|
|
"""
|
|
if benchmark_time:
|
|
assert benchmark_date is not None
|
|
reformat_date = datetime.strptime(benchmark_date, "%m-%d-%Y").strftime("%Y-%m-%d")
|
|
basename = f"{reformat_date}_{benchmark_time}"
|
|
else:
|
|
basename = sorted(os.listdir(hydra_dir))[-1]
|
|
hydra_dir = f"{hydra_dir}/{basename}"
|
|
initialize(version_base="1.2", config_path=os.path.join("../../", hydra_dir, ".hydra/"))
|
|
config = compose("config.yaml")
|
|
return config, basename
|
|
|
|
|
|
def _calc_avg(stat_name: str, benchmark: Dict[str, Any]):
|
|
"""helper to calculate the average across all objects in dataset"""
|
|
stats = []
|
|
for _, object_stats in benchmark.items():
|
|
stats.append(object_stats[stat_name])
|
|
return np.mean(stats)
|
|
|
|
|
|
def main(args):
|
|
"""Main function."""
|
|
benchmarks = {}
|
|
# set up trainer, config, and checkpoint loading
|
|
hydra_dir = f"{args.hydra_base_dir}/blender_{args.item_name}_{args.benchmark_date}/{args.graph}/"
|
|
config, basename = _load_hydra_config(
|
|
hydra_dir, benchmark_time=args.benchmark_time, benchmark_date=args.benchmark_date
|
|
)
|
|
# config.data.dataloader_eval.image_indices = None
|
|
ckpt = _load_best_ckpt(hydra_dir, config.trainer)
|
|
|
|
# run evaluation
|
|
stats_dict = run_inference_from_config(config)
|
|
stats_dict["checkpoint"] = ckpt
|
|
benchmarks[args.item_name] = stats_dict
|
|
|
|
avg_rays_per_sec = _calc_avg("avg rays per sec", benchmarks)
|
|
avg_fps = _calc_avg("avg fps", benchmarks)
|
|
|
|
# output benchmark statistics to a json file
|
|
benchmark_info = {
|
|
"meta info": {"graph": args.graph, "benchmark_date": args.benchmark_date, "hydra": args.hydra_base_dir},
|
|
"avg rays per sec": avg_rays_per_sec,
|
|
"avg fps": avg_fps,
|
|
"results": benchmarks,
|
|
}
|
|
json_dir = os.path.join(args.hydra_base_dir, args.graph)
|
|
if not os.path.exists(json_dir):
|
|
os.makedirs(json_dir)
|
|
json_file = os.path.join(json_dir, f"{basename}_{args.item_name}.json")
|
|
|
|
# if benchmark file already exists, update the results dictionary by overriding existing info or appending.
|
|
if os.path.exists(json_file):
|
|
with open(json_file, "r", encoding="utf8") as f:
|
|
existing_data = json.load(f)
|
|
existing_benchmarks = existing_data["results"]
|
|
existing_benchmarks.update(benchmarks)
|
|
existing_data["results"] = existing_benchmarks
|
|
benchmark_info = existing_data
|
|
|
|
with open(json_file, "w", encoding="utf8") as f:
|
|
json.dump(benchmark_info, f, indent=2)
|
|
logging.info("saved benchmark results to %s", json_file)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"-g",
|
|
"--graph",
|
|
type=str,
|
|
required=True,
|
|
help="name of nerf graph to benchmark. Note: name without the 'graph_' prefix",
|
|
)
|
|
parser.add_argument(
|
|
"-d",
|
|
"--benchmark_date",
|
|
type=str,
|
|
required=True,
|
|
help="date of run to benchmark provided in '%%m-%%d-%%Y' format.",
|
|
)
|
|
parser.add_argument(
|
|
"-i",
|
|
"--item_name",
|
|
type=str,
|
|
required=True,
|
|
choices=["mic", "ficus", "chair", "hotdog", "materials", "drums", "ship", "lego"],
|
|
help="name of item in blender dataset to benchmark",
|
|
)
|
|
parser.add_argument(
|
|
"-t",
|
|
"--benchmark_time",
|
|
type=str,
|
|
default=None,
|
|
help="timestamp of the run to benchmark; if None, will default to running most recent timestamp",
|
|
)
|
|
parser.add_argument("-o", "--hydra_base_dir", type=str, default="outputs/", help="hydra base output path")
|
|
parsed_args = parser.parse_args()
|
|
main(parsed_args)
|