Elastic-forcing's picture
Add training and inference source code
2ea2835 verified
Raw History Blame Contribute Delete
4.03 kB
import argparse
import os
import torch.distributed as dist
from omegaconf import OmegaConf
from utils.config import load_config
from utils.optional_wandb import wandb
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--config_path", type=str, required=True)
parser.add_argument("--no_save", action="store_true")
parser.add_argument("--no_visualize", action="store_true")
parser.add_argument(
"--max_steps", "--training-updates",
type=int,
default=None,
help="Optional runtime override for training_updates (useful for smoke tests)",
)
parser.add_argument(
"--fresh-video-local-samples", "--distribution-samples-per-rank",
type=int,
default=None,
help=(
"Optional smoke-test override for the number of fresh videos "
"collected per rank and optimizer update."
),
)
parser.add_argument(
"--total-batch-size", "--distribution-batch-size",
type=int,
default=None,
help="Optional matching logical global-batch override.",
)
parser.add_argument(
"--eval-interval",
type=int,
default=None,
help="Optional runtime eval interval override; 0 disables eval.",
)
parser.add_argument("--logdir", type=str, default="", help="Path to the directory to save logs")
parser.add_argument("--wandb-save-dir", type=str, default="", help="Path to the directory to save wandb logs")
parser.add_argument("--disable-wandb", action="store_true")
parser.add_argument(
"--preflight-only",
action="store_true",
help="Build and validate the complete distributed trainer, then exit before updates.",
)
args = parser.parse_args()
config = load_config(args.config_path, "configs/default_config.yaml")
config.no_save = args.no_save
config.no_visualize = args.no_visualize
if args.max_steps is not None:
if args.max_steps <= 0:
parser.error("--max_steps must be positive")
config.max_steps = args.max_steps
if args.fresh_video_local_samples is not None:
if args.fresh_video_local_samples <= 0:
parser.error("--fresh-video-local-samples must be positive")
config.fresh_video_local_samples = args.fresh_video_local_samples
if args.total_batch_size is not None:
if args.total_batch_size <= 0:
parser.error("--total-batch-size must be positive")
config.total_batch_size = args.total_batch_size
if args.eval_interval is not None:
if args.eval_interval < 0:
parser.error("--eval-interval must be non-negative")
config.eval_interval = args.eval_interval
# get the filename of config_path
config_name = os.path.basename(args.config_path).split(".")[0]
config.config_name = config_name
# Preserve the exact YAML identity for strict offline-reference checks.
# Runtime-only smoke overrides remain separate and do not change the
# generator trajectory contract encoded by this file.
config.config_path = os.path.realpath(args.config_path)
config.logdir = args.logdir
config.wandb_save_dir = args.wandb_save_dir
config.disable_wandb = args.disable_wandb
if config.trainer != "score_distillation":
raise ValueError("This release uses the distribution matching trainer.")
from trainer.distribution_matching import DistributionMatchingTrainer
trainer = DistributionMatchingTrainer(config)
try:
if args.preflight_only:
if dist.is_available() and dist.is_initialized():
dist.barrier()
if not dist.is_initialized() or dist.get_rank() == 0:
print("Distributed trainer preflight complete; no update or checkpoint written.")
else:
trainer.train()
finally:
wandb.finish()
if dist.is_available() and dist.is_initialized():
dist.destroy_process_group()
if __name__ == "__main__":
main()