Spaces:
Runtime error
Runtime error
# | |
# Copyright (C) 2023, Inria | |
# GRAPHDECO research group, https://team.inria.fr/graphdeco | |
# All rights reserved. | |
# | |
# This software is free for non-commercial, research and evaluation use | |
# under the terms of the LICENSE.md file. | |
# | |
# For inquiries contact george.drettakis@inria.fr | |
# | |
import random | |
import imageio | |
import os | |
import torch | |
import torch.nn as nn | |
from random import randint | |
from utils.loss_utils import l1_loss, ssim, tv_loss | |
from gaussian_renderer import render, network_gui | |
import sys | |
from scene import Scene, GaussianModel | |
from utils.general_utils import safe_state | |
import uuid | |
from tqdm import tqdm | |
from utils.image_utils import psnr | |
from argparse import ArgumentParser, Namespace | |
from arguments import ModelParams, PipelineParams, OptimizationParams, GenerateCamParams, GuidanceParams | |
import math | |
import yaml | |
from torchvision.utils import save_image | |
import torchvision.transforms as T | |
try: | |
from torch.utils.tensorboard import SummaryWriter | |
TENSORBOARD_FOUND = True | |
except ImportError: | |
TENSORBOARD_FOUND = False | |
sys.path.append('/root/yangxin/codebase/3D_Playground/GSDF') | |
def adjust_text_embeddings(embeddings, azimuth, guidance_opt): | |
#TODO: add prenerg functions | |
text_z_list = [] | |
weights_list = [] | |
K = 0 | |
#for b in range(azimuth): | |
text_z_, weights_ = get_pos_neg_text_embeddings(embeddings, azimuth, guidance_opt) | |
K = max(K, weights_.shape[0]) | |
text_z_list.append(text_z_) | |
weights_list.append(weights_) | |
# Interleave text_embeddings from different dirs to form a batch | |
text_embeddings = [] | |
for i in range(K): | |
for text_z in text_z_list: | |
# if uneven length, pad with the first embedding | |
text_embeddings.append(text_z[i] if i < len(text_z) else text_z[0]) | |
text_embeddings = torch.stack(text_embeddings, dim=0) # [B * K, 77, 768] | |
# Interleave weights from different dirs to form a batch | |
weights = [] | |
for i in range(K): | |
for weights_ in weights_list: | |
weights.append(weights_[i] if i < len(weights_) else torch.zeros_like(weights_[0])) | |
weights = torch.stack(weights, dim=0) # [B * K] | |
return text_embeddings, weights | |
def get_pos_neg_text_embeddings(embeddings, azimuth_val, opt): | |
if azimuth_val >= -90 and azimuth_val < 90: | |
if azimuth_val >= 0: | |
r = 1 - azimuth_val / 90 | |
else: | |
r = 1 + azimuth_val / 90 | |
start_z = embeddings['front'] | |
end_z = embeddings['side'] | |
# if random.random() < 0.3: | |
# r = r + random.gauss(0, 0.08) | |
pos_z = r * start_z + (1 - r) * end_z | |
text_z = torch.cat([pos_z, embeddings['front'], embeddings['side']], dim=0) | |
if r > 0.8: | |
front_neg_w = 0.0 | |
else: | |
front_neg_w = math.exp(-r * opt.front_decay_factor) * opt.negative_w | |
if r < 0.2: | |
side_neg_w = 0.0 | |
else: | |
side_neg_w = math.exp(-(1-r) * opt.side_decay_factor) * opt.negative_w | |
weights = torch.tensor([1.0, front_neg_w, side_neg_w]) | |
else: | |
if azimuth_val >= 0: | |
r = 1 - (azimuth_val - 90) / 90 | |
else: | |
r = 1 + (azimuth_val + 90) / 90 | |
start_z = embeddings['side'] | |
end_z = embeddings['back'] | |
# if random.random() < 0.3: | |
# r = r + random.gauss(0, 0.08) | |
pos_z = r * start_z + (1 - r) * end_z | |
text_z = torch.cat([pos_z, embeddings['side'], embeddings['front']], dim=0) | |
front_neg_w = opt.negative_w | |
if r > 0.8: | |
side_neg_w = 0.0 | |
else: | |
side_neg_w = math.exp(-r * opt.side_decay_factor) * opt.negative_w / 2 | |
weights = torch.tensor([1.0, side_neg_w, front_neg_w]) | |
return text_z, weights.to(text_z.device) | |
def prepare_embeddings(guidance_opt, guidance): | |
embeddings = {} | |
# text embeddings (stable-diffusion) and (IF) | |
embeddings['default'] = guidance.get_text_embeds([guidance_opt.text]) | |
embeddings['uncond'] = guidance.get_text_embeds([guidance_opt.negative]) | |
for d in ['front', 'side', 'back']: | |
embeddings[d] = guidance.get_text_embeds([f"{guidance_opt.text}, {d} view"]) | |
embeddings['inverse_text'] = guidance.get_text_embeds(guidance_opt.inverse_text) | |
return embeddings | |
def guidance_setup(guidance_opt): | |
if guidance_opt.guidance=="SD": | |
from guidance.sd_utils import StableDiffusion | |
guidance = StableDiffusion(guidance_opt.g_device, guidance_opt.fp16, guidance_opt.vram_O, | |
guidance_opt.t_range, guidance_opt.max_t_range, | |
num_train_timesteps=guidance_opt.num_train_timesteps, | |
ddim_inv=guidance_opt.ddim_inv, | |
textual_inversion_path = guidance_opt.textual_inversion_path, | |
LoRA_path = guidance_opt.LoRA_path, | |
guidance_opt=guidance_opt) | |
else: | |
raise ValueError(f'{guidance_opt.guidance} not supported.') | |
if guidance is not None: | |
for p in guidance.parameters(): | |
p.requires_grad = False | |
embeddings = prepare_embeddings(guidance_opt, guidance) | |
return guidance, embeddings | |
def training(dataset, opt, pipe, gcams, guidance_opt, testing_iterations, saving_iterations, checkpoint_iterations, checkpoint, debug_from, save_video): | |
first_iter = 0 | |
tb_writer = prepare_output_and_logger(dataset) | |
gaussians = GaussianModel(dataset.sh_degree) | |
scene = Scene(dataset, gcams, gaussians) | |
gaussians.training_setup(opt) | |
if checkpoint: | |
(model_params, first_iter) = torch.load(checkpoint) | |
gaussians.restore(model_params, opt) | |
bg_color = [1, 1, 1] if dataset._white_background else [0, 0, 0] | |
background = torch.tensor(bg_color, dtype=torch.float32, device=dataset.data_device) | |
iter_start = torch.cuda.Event(enable_timing = True) | |
iter_end = torch.cuda.Event(enable_timing = True) | |
# | |
save_folder = os.path.join(dataset._model_path,"train_process/") | |
if not os.path.exists(save_folder): | |
os.makedirs(save_folder) # makedirs | |
print('train_process is in :', save_folder) | |
#controlnet | |
use_control_net = False | |
#set up pretrain diffusion models and text_embedings | |
guidance, embeddings = guidance_setup(guidance_opt) | |
viewpoint_stack = None | |
viewpoint_stack_around = None | |
ema_loss_for_log = 0.0 | |
progress_bar = tqdm(range(first_iter, opt.iterations), desc="Training progress") | |
first_iter += 1 | |
if opt.save_process: | |
save_folder_proc = os.path.join(scene.args._model_path,"process_videos/") | |
if not os.path.exists(save_folder_proc): | |
os.makedirs(save_folder_proc) # makedirs | |
process_view_points = scene.getCircleVideoCameras(batch_size=opt.pro_frames_num,render45=opt.pro_render_45).copy() | |
save_process_iter = opt.iterations // len(process_view_points) | |
pro_img_frames = [] | |
for iteration in range(first_iter, opt.iterations + 1): | |
#TODO: DEBUG NETWORK_GUI | |
if network_gui.conn == None: | |
network_gui.try_connect() | |
while network_gui.conn != None: | |
try: | |
net_image_bytes = None | |
custom_cam, do_training, pipe.convert_SHs_python, pipe.compute_cov3D_python, keep_alive, scaling_modifer = network_gui.receive() | |
if custom_cam != None: | |
net_image = render(custom_cam, gaussians, pipe, background, scaling_modifer)["render"] | |
net_image_bytes = memoryview((torch.clamp(net_image, min=0, max=1.0) * 255).byte().permute(1, 2, 0).contiguous().cpu().numpy()) | |
network_gui.send(net_image_bytes, guidance_opt.text) | |
if do_training and ((iteration < int(opt.iterations)) or not keep_alive): | |
break | |
except Exception as e: | |
network_gui.conn = None | |
iter_start.record() | |
gaussians.update_learning_rate(iteration) | |
gaussians.update_feature_learning_rate(iteration) | |
gaussians.update_rotation_learning_rate(iteration) | |
gaussians.update_scaling_learning_rate(iteration) | |
# Every 500 its we increase the levels of SH up to a maximum degree | |
if iteration % 500 == 0: | |
gaussians.oneupSHdegree() | |
# progressively relaxing view range | |
if not opt.use_progressive: | |
if iteration >= opt.progressive_view_iter and iteration % opt.scale_up_cameras_iter == 0: | |
scene.pose_args.fovy_range[0] = max(scene.pose_args.max_fovy_range[0], scene.pose_args.fovy_range[0] * opt.fovy_scale_up_factor[0]) | |
scene.pose_args.fovy_range[1] = min(scene.pose_args.max_fovy_range[1], scene.pose_args.fovy_range[1] * opt.fovy_scale_up_factor[1]) | |
scene.pose_args.radius_range[1] = max(scene.pose_args.max_radius_range[1], scene.pose_args.radius_range[1] * opt.scale_up_factor) | |
scene.pose_args.radius_range[0] = max(scene.pose_args.max_radius_range[0], scene.pose_args.radius_range[0] * opt.scale_up_factor) | |
scene.pose_args.theta_range[1] = min(scene.pose_args.max_theta_range[1], scene.pose_args.theta_range[1] * opt.phi_scale_up_factor) | |
scene.pose_args.theta_range[0] = max(scene.pose_args.max_theta_range[0], scene.pose_args.theta_range[0] * 1/opt.phi_scale_up_factor) | |
# opt.reset_resnet_iter = max(500, opt.reset_resnet_iter // 1.25) | |
scene.pose_args.phi_range[0] = max(scene.pose_args.max_phi_range[0] , scene.pose_args.phi_range[0] * opt.phi_scale_up_factor) | |
scene.pose_args.phi_range[1] = min(scene.pose_args.max_phi_range[1], scene.pose_args.phi_range[1] * opt.phi_scale_up_factor) | |
print('scale up theta_range to:', scene.pose_args.theta_range) | |
print('scale up radius_range to:', scene.pose_args.radius_range) | |
print('scale up phi_range to:', scene.pose_args.phi_range) | |
print('scale up fovy_range to:', scene.pose_args.fovy_range) | |
# Pick a random Camera | |
if not viewpoint_stack: | |
viewpoint_stack = scene.getRandTrainCameras().copy() | |
C_batch_size = guidance_opt.C_batch_size | |
viewpoint_cams = [] | |
images = [] | |
text_z_ = [] | |
weights_ = [] | |
depths = [] | |
alphas = [] | |
scales = [] | |
text_z_inverse =torch.cat([embeddings['uncond'],embeddings['inverse_text']], dim=0) | |
for i in range(C_batch_size): | |
try: | |
viewpoint_cam = viewpoint_stack.pop(randint(0, len(viewpoint_stack)-1)) | |
except: | |
viewpoint_stack = scene.getRandTrainCameras().copy() | |
viewpoint_cam = viewpoint_stack.pop(randint(0, len(viewpoint_stack)-1)) | |
#pred text_z | |
azimuth = viewpoint_cam.delta_azimuth | |
text_z = [embeddings['uncond']] | |
if guidance_opt.perpneg: | |
text_z_comp, weights = adjust_text_embeddings(embeddings, azimuth, guidance_opt) | |
text_z.append(text_z_comp) | |
weights_.append(weights) | |
else: | |
if azimuth >= -90 and azimuth < 90: | |
if azimuth >= 0: | |
r = 1 - azimuth / 90 | |
else: | |
r = 1 + azimuth / 90 | |
start_z = embeddings['front'] | |
end_z = embeddings['side'] | |
else: | |
if azimuth >= 0: | |
r = 1 - (azimuth - 90) / 90 | |
else: | |
r = 1 + (azimuth + 90) / 90 | |
start_z = embeddings['side'] | |
end_z = embeddings['back'] | |
text_z.append(r * start_z + (1 - r) * end_z) | |
text_z = torch.cat(text_z, dim=0) | |
text_z_.append(text_z) | |
# Render | |
if (iteration - 1) == debug_from: | |
pipe.debug = True | |
render_pkg = render(viewpoint_cam, gaussians, pipe, background, | |
sh_deg_aug_ratio = dataset.sh_deg_aug_ratio, | |
bg_aug_ratio = dataset.bg_aug_ratio, | |
shs_aug_ratio = dataset.shs_aug_ratio, | |
scale_aug_ratio = dataset.scale_aug_ratio) | |
image, viewspace_point_tensor, visibility_filter, radii = render_pkg["render"], render_pkg["viewspace_points"], render_pkg["visibility_filter"], render_pkg["radii"] | |
depth, alpha = render_pkg["depth"], render_pkg["alpha"] | |
scales.append(render_pkg["scales"]) | |
images.append(image) | |
depths.append(depth) | |
alphas.append(alpha) | |
viewpoint_cams.append(viewpoint_cams) | |
images = torch.stack(images, dim=0) | |
depths = torch.stack(depths, dim=0) | |
alphas = torch.stack(alphas, dim=0) | |
# Loss | |
warm_up_rate = 1. - min(iteration/opt.warmup_iter,1.) | |
guidance_scale = guidance_opt.guidance_scale | |
_aslatent = False | |
if iteration < opt.geo_iter or random.random()< opt.as_latent_ratio: | |
_aslatent=True | |
if iteration > opt.use_control_net_iter and (random.random() < guidance_opt.controlnet_ratio): | |
use_control_net = True | |
if guidance_opt.perpneg: | |
loss = guidance.train_step_perpneg(torch.stack(text_z_, dim=1), images, | |
pred_depth=depths, pred_alpha=alphas, | |
grad_scale=guidance_opt.lambda_guidance, | |
use_control_net = use_control_net ,save_folder = save_folder, iteration = iteration, warm_up_rate=warm_up_rate, | |
weights = torch.stack(weights_, dim=1), resolution=(gcams.image_h, gcams.image_w), | |
guidance_opt=guidance_opt,as_latent=_aslatent, embedding_inverse = text_z_inverse) | |
else: | |
loss = guidance.train_step(torch.stack(text_z_, dim=1), images, | |
pred_depth=depths, pred_alpha=alphas, | |
grad_scale=guidance_opt.lambda_guidance, | |
use_control_net = use_control_net ,save_folder = save_folder, iteration = iteration, warm_up_rate=warm_up_rate, | |
resolution=(gcams.image_h, gcams.image_w), | |
guidance_opt=guidance_opt,as_latent=_aslatent, embedding_inverse = text_z_inverse) | |
#raise ValueError(f'original version not supported.') | |
scales = torch.stack(scales, dim=0) | |
loss_scale = torch.mean(scales,dim=-1).mean() | |
loss_tv = tv_loss(images) + tv_loss(depths) | |
# loss_bin = torch.mean(torch.min(alphas - 0.0001, 1 - alphas)) | |
loss = loss + opt.lambda_tv * loss_tv + opt.lambda_scale * loss_scale #opt.lambda_tv * loss_tv + opt.lambda_bin * loss_bin + opt.lambda_scale * loss_scale + | |
loss.backward() | |
iter_end.record() | |
with torch.no_grad(): | |
# Progress bar | |
ema_loss_for_log = 0.4 * loss.item() + 0.6 * ema_loss_for_log | |
if opt.save_process: | |
if iteration % save_process_iter == 0 and len(process_view_points) > 0: | |
viewpoint_cam_p = process_view_points.pop(0) | |
render_p = render(viewpoint_cam_p, gaussians, pipe, background, test=True) | |
img_p = torch.clamp(render_p["render"], 0.0, 1.0) | |
img_p = img_p.detach().cpu().permute(1,2,0).numpy() | |
img_p = (img_p * 255).round().astype('uint8') | |
pro_img_frames.append(img_p) | |
if iteration % 10 == 0: | |
progress_bar.set_postfix({"Loss": f"{ema_loss_for_log:.{7}f}"}) | |
progress_bar.update(10) | |
if iteration == opt.iterations: | |
progress_bar.close() | |
# Log and save | |
training_report(tb_writer, iteration, iter_start.elapsed_time(iter_end), testing_iterations, scene, render, (pipe, background)) | |
if (iteration in testing_iterations): | |
if save_video: | |
video_path = video_inference(iteration, scene, render, (pipe, background)) | |
if (iteration in saving_iterations): | |
print("\n[ITER {}] Saving Gaussians".format(iteration)) | |
scene.save(iteration) | |
# Densification | |
if iteration < opt.densify_until_iter: | |
# Keep track of max radii in image-space for pruning | |
gaussians.max_radii2D[visibility_filter] = torch.max(gaussians.max_radii2D[visibility_filter], radii[visibility_filter]) | |
gaussians.add_densification_stats(viewspace_point_tensor, visibility_filter) | |
if iteration > opt.densify_from_iter and iteration % opt.densification_interval == 0: | |
size_threshold = 20 if iteration > opt.opacity_reset_interval else None | |
gaussians.densify_and_prune(opt.densify_grad_threshold, 0.005, scene.cameras_extent, size_threshold) | |
if iteration % opt.opacity_reset_interval == 0: #or (dataset._white_background and iteration == opt.densify_from_iter) | |
gaussians.reset_opacity() | |
# Optimizer step | |
if iteration < opt.iterations: | |
gaussians.optimizer.step() | |
gaussians.optimizer.zero_grad(set_to_none = True) | |
if (iteration in checkpoint_iterations): | |
print("\n[ITER {}] Saving Checkpoint".format(iteration)) | |
torch.save((gaussians.capture(), iteration), scene._model_path + "/chkpnt" + str(iteration) + ".pth") | |
if opt.save_process: | |
imageio.mimwrite(os.path.join(save_folder_proc, "video_rgb.mp4"), pro_img_frames, fps=30, quality=8) | |
return video_path, os.path.join(save_folder_proc, "video_rgb.mp4") | |
def prepare_output_and_logger(args): | |
if not args._model_path: | |
if os.getenv('OAR_JOB_ID'): | |
unique_str=os.getenv('OAR_JOB_ID') | |
else: | |
unique_str = str(uuid.uuid4()) | |
args._model_path = os.path.join("./output/", args.workspace) | |
# Set up output folder | |
print("Output folder: {}".format(args._model_path)) | |
os.makedirs(args._model_path, exist_ok = True) | |
# copy configs | |
if args.opt_path is not None: | |
os.system(' '.join(['cp', args.opt_path, os.path.join(args._model_path, 'config.yaml')])) | |
with open(os.path.join(args._model_path, "cfg_args"), 'w') as cfg_log_f: | |
cfg_log_f.write(str(Namespace(**vars(args)))) | |
# Create Tensorboard writer | |
tb_writer = None | |
if TENSORBOARD_FOUND: | |
tb_writer = SummaryWriter(args._model_path) | |
else: | |
print("Tensorboard not available: not logging progress") | |
return tb_writer | |
def training_report(tb_writer, iteration, elapsed, testing_iterations, scene : Scene, renderFunc, renderArgs): | |
if tb_writer: | |
tb_writer.add_scalar('iter_time', elapsed, iteration) | |
# Report test and samples of training set | |
if iteration in testing_iterations: | |
save_folder = os.path.join(scene.args._model_path,"test_six_views/{}_iteration".format(iteration)) | |
if not os.path.exists(save_folder): | |
os.makedirs(save_folder) # makedirs 创建文件时如果路径不存在会创建这个路径 | |
print('test views is in :', save_folder) | |
torch.cuda.empty_cache() | |
config = ({'name': 'test', 'cameras' : scene.getTestCameras()}) | |
if config['cameras'] and len(config['cameras']) > 0: | |
for idx, viewpoint in enumerate(config['cameras']): | |
render_out = renderFunc(viewpoint, scene.gaussians, *renderArgs, test=True) | |
rgb, depth = render_out["render"],render_out["depth"] | |
if depth is not None: | |
depth_norm = depth/depth.max() | |
save_image(depth_norm,os.path.join(save_folder,"render_depth_{}.png".format(viewpoint.uid))) | |
image = torch.clamp(rgb, 0.0, 1.0) | |
save_image(image,os.path.join(save_folder,"render_view_{}.png".format(viewpoint.uid))) | |
if tb_writer: | |
tb_writer.add_images(config['name'] + "_view_{}/render".format(viewpoint.uid), image[None], global_step=iteration) | |
print("\n[ITER {}] Eval Done!".format(iteration)) | |
if tb_writer: | |
tb_writer.add_histogram("scene/opacity_histogram", scene.gaussians.get_opacity, iteration) | |
tb_writer.add_scalar('total_points', scene.gaussians.get_xyz.shape[0], iteration) | |
torch.cuda.empty_cache() | |
def video_inference(iteration, scene : Scene, renderFunc, renderArgs): | |
sharp = T.RandomAdjustSharpness(3, p=1.0) | |
save_folder = os.path.join(scene.args._model_path,"videos/{}_iteration".format(iteration)) | |
if not os.path.exists(save_folder): | |
os.makedirs(save_folder) # makedirs | |
print('videos is in :', save_folder) | |
torch.cuda.empty_cache() | |
config = ({'name': 'test', 'cameras' : scene.getCircleVideoCameras()}) | |
if config['cameras'] and len(config['cameras']) > 0: | |
img_frames = [] | |
depth_frames = [] | |
print("Generating Video using", len(config['cameras']), "different view points") | |
for idx, viewpoint in enumerate(config['cameras']): | |
render_out = renderFunc(viewpoint, scene.gaussians, *renderArgs, test=True) | |
rgb,depth = render_out["render"],render_out["depth"] | |
if depth is not None: | |
depth_norm = depth/depth.max() | |
depths = torch.clamp(depth_norm, 0.0, 1.0) | |
depths = depths.detach().cpu().permute(1,2,0).numpy() | |
depths = (depths * 255).round().astype('uint8') | |
depth_frames.append(depths) | |
image = torch.clamp(rgb, 0.0, 1.0) | |
image = image.detach().cpu().permute(1,2,0).numpy() | |
image = (image * 255).round().astype('uint8') | |
img_frames.append(image) | |
#save_image(image,os.path.join(save_folder,"lora_view_{}.jpg".format(viewpoint.uid))) | |
# Img to Numpy | |
imageio.mimwrite(os.path.join(save_folder, "video_rgb_{}.mp4".format(iteration)), img_frames, fps=30, quality=8) | |
if len(depth_frames) > 0: | |
imageio.mimwrite(os.path.join(save_folder, "video_depth_{}.mp4".format(iteration)), depth_frames, fps=30, quality=8) | |
print("\n[ITER {}] Video Save Done!".format(iteration)) | |
torch.cuda.empty_cache() | |
return os.path.join(save_folder, "video_rgb_{}.mp4".format(iteration)) | |
def args_parser(default_opt=None): | |
# Set up command line argument parser | |
parser = ArgumentParser(description="Training script parameters") | |
parser.add_argument('--opt', type=str, default=default_opt) | |
parser.add_argument('--ip', type=str, default="127.0.0.1") | |
parser.add_argument('--port', type=int, default=6009) | |
parser.add_argument('--debug_from', type=int, default=-1) | |
parser.add_argument('--seed', type=int, default=0) | |
parser.add_argument('--detect_anomaly', action='store_true', default=False) | |
parser.add_argument("--test_ratio", type=int, default=5) # [2500,5000,7500,10000,12000] | |
parser.add_argument("--save_ratio", type=int, default=2) # [10000,12000] | |
parser.add_argument("--save_video", type=bool, default=False) | |
parser.add_argument("--quiet", action="store_true") | |
parser.add_argument("--checkpoint_iterations", nargs="+", type=int, default=[]) | |
parser.add_argument("--start_checkpoint", type=str, default = None) | |
parser.add_argument("--cuda", type=str, default='0') | |
lp = ModelParams(parser) | |
op = OptimizationParams(parser) | |
pp = PipelineParams(parser) | |
gcp = GenerateCamParams(parser) | |
gp = GuidanceParams(parser) | |
args = parser.parse_args(sys.argv[1:]) | |
os.environ["CUDA_VISIBLE_DEVICES"] = args.cuda | |
if args.opt is not None: | |
with open(args.opt) as f: | |
opts = yaml.load(f, Loader=yaml.FullLoader) | |
lp.load_yaml(opts.get('ModelParams', None)) | |
op.load_yaml(opts.get('OptimizationParams', None)) | |
pp.load_yaml(opts.get('PipelineParams', None)) | |
gcp.load_yaml(opts.get('GenerateCamParams', None)) | |
gp.load_yaml(opts.get('GuidanceParams', None)) | |
lp.opt_path = args.opt | |
args.port = opts['port'] | |
args.save_video = opts.get('save_video', True) | |
args.seed = opts.get('seed', 0) | |
args.device = opts.get('device', 'cuda') | |
# override device | |
gp.g_device = args.device | |
lp.data_device = args.device | |
gcp.device = args.device | |
return args, lp, op, pp, gcp, gp | |
def start_training(args, lp, op, pp, gcp, gp): | |
# save iterations | |
test_iter = [1] + [k * op.iterations // args.test_ratio for k in range(1, args.test_ratio)] + [op.iterations] | |
args.test_iterations = test_iter | |
save_iter = [k * op.iterations // args.save_ratio for k in range(1, args.save_ratio)] + [op.iterations] | |
args.save_iterations = save_iter | |
print('Test iter:', args.test_iterations) | |
print('Save iter:', args.save_iterations) | |
print("Optimizing " + lp._model_path) | |
# Initialize system state (RNG) | |
safe_state(args.quiet, seed=args.seed) | |
# Start GUI server, configure and run training | |
network_gui.init(args.ip, args.port) | |
torch.autograd.set_detect_anomaly(args.detect_anomaly) | |
video_path, pro_video_path = training(lp, op, pp, gcp, gp, args.test_iterations, args.save_iterations, args.checkpoint_iterations, args.start_checkpoint, args.debug_from, args.save_video) | |
# All done | |
print("\nTraining complete.") | |
return video_path, pro_video_path | |
if __name__ == "__main__": | |
args, lp, op, pp, gcp, gp = args_parser() | |
start_training(args, lp, op, pp, gcp, gp) | |