From e7e713e9000c8c5ad89ba7a69e9018fd88b8566f Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 10 Jan 2024 17:12:54 -0800 Subject: [PATCH] Fix Python 3.11 dataclass field default_factory defaults (#2746) --- nerfstudio/configs/experiment_config.py | 15 ++++------ .../data/datamanagers/base_datamanager.py | 4 +-- .../datamanagers/full_images_datamanager.py | 4 +-- nerfstudio/models/base_surface_model.py | 16 ++-------- nerfstudio/models/gaussian_splatting.py | 30 +++++++++---------- nerfstudio/pipelines/base_pipeline.py | 16 ++++------ tests/plugins/test_registry.py | 9 +++--- 7 files changed, 36 insertions(+), 58 deletions(-) diff --git a/nerfstudio/configs/experiment_config.py b/nerfstudio/configs/experiment_config.py index cd431dca2..c93530fc1 100644 --- a/nerfstudio/configs/experiment_config.py +++ b/nerfstudio/configs/experiment_config.py @@ -23,12 +23,7 @@ from typing import Any, Dict, Literal, Optional import yaml -from nerfstudio.configs.base_config import ( - InstantiateConfig, - LoggingConfig, - MachineConfig, - ViewerConfig, -) +from nerfstudio.configs.base_config import InstantiateConfig, LoggingConfig, MachineConfig, ViewerConfig from nerfstudio.configs.config_utils import to_immutable_dict from nerfstudio.engine.optimizers import OptimizerConfig from nerfstudio.engine.schedulers import SchedulerConfig @@ -51,13 +46,13 @@ class ExperimentConfig(InstantiateConfig): """Project name.""" timestamp: str = "{timestamp}" """Experiment timestamp.""" - machine: MachineConfig = field(default_factory=lambda: MachineConfig()) + machine: MachineConfig = field(default_factory=MachineConfig) """Machine configuration""" - logging: LoggingConfig = field(default_factory=lambda: LoggingConfig()) + logging: LoggingConfig = field(default_factory=LoggingConfig) """Logging configuration""" - viewer: ViewerConfig = field(default_factory=lambda: ViewerConfig()) + viewer: ViewerConfig = field(default_factory=ViewerConfig) """Viewer configuration""" - pipeline: VanillaPipelineConfig = field(default_factory=lambda: VanillaPipelineConfig()) + pipeline: VanillaPipelineConfig = field(default_factory=VanillaPipelineConfig) """Pipeline configuration""" optimizers: Dict[str, Any] = to_immutable_dict( { diff --git a/nerfstudio/data/datamanagers/base_datamanager.py b/nerfstudio/data/datamanagers/base_datamanager.py index 67180bea6..322a1e861 100644 --- a/nerfstudio/data/datamanagers/base_datamanager.py +++ b/nerfstudio/data/datamanagers/base_datamanager.py @@ -316,7 +316,7 @@ class VanillaDataManagerConfig(DataManagerConfig): _target: Type = field(default_factory=lambda: VanillaDataManager) """Target class to instantiate.""" - dataparser: AnnotatedDataParserUnion = field(default_factory=lambda: BlenderDataParserConfig()) + dataparser: AnnotatedDataParserUnion = field(default_factory=BlenderDataParserConfig) """Specifies the dataparser used to unpack the data.""" train_num_rays_per_batch: int = 1024 """Number of rays per batch to use per training iteration.""" @@ -344,7 +344,7 @@ class VanillaDataManagerConfig(DataManagerConfig): """Size of patch to sample from. If > 1, patch-based sampling will be used.""" camera_optimizer: Optional[CameraOptimizerConfig] = field(default=None) """Deprecated, has been moved to the model config.""" - pixel_sampler: PixelSamplerConfig = field(default_factory=lambda: PixelSamplerConfig()) + pixel_sampler: PixelSamplerConfig = field(default_factory=PixelSamplerConfig) """Specifies the pixel sampler used to sample pixels from images.""" def __post_init__(self): diff --git a/nerfstudio/data/datamanagers/full_images_datamanager.py b/nerfstudio/data/datamanagers/full_images_datamanager.py index 1533b3245..bfc720d12 100644 --- a/nerfstudio/data/datamanagers/full_images_datamanager.py +++ b/nerfstudio/data/datamanagers/full_images_datamanager.py @@ -22,6 +22,7 @@ paradigm from __future__ import annotations import random +from copy import deepcopy from dataclasses import dataclass, field from functools import cached_property from pathlib import Path @@ -30,7 +31,6 @@ from typing import Dict, ForwardRef, Generic, List, Literal, Optional, Tuple, Ty import cv2 import numpy as np import torch -from copy import deepcopy from torch.nn import Parameter from tqdm import tqdm @@ -47,7 +47,7 @@ from nerfstudio.utils.rich_utils import CONSOLE @dataclass class FullImageDatamanagerConfig(DataManagerConfig): _target: Type = field(default_factory=lambda: FullImageDatamanager) - dataparser: AnnotatedDataParserUnion = NerfstudioDataParserConfig() + dataparser: AnnotatedDataParserUnion = field(default_factory=NerfstudioDataParserConfig) camera_res_scale_factor: float = 1.0 """The scale factor for scaling spatial data such as images, mask, semantics along with relevant information about camera intrinsics diff --git a/nerfstudio/models/base_surface_model.py b/nerfstudio/models/base_surface_model.py index 97bde9d9f..885e08e29 100644 --- a/nerfstudio/models/base_surface_model.py +++ b/nerfstudio/models/base_surface_model.py @@ -36,19 +36,9 @@ from nerfstudio.field_components.spatial_distortions import SceneContraction from nerfstudio.fields.nerfacto_field import NerfactoField from nerfstudio.fields.sdf_field import SDFFieldConfig from nerfstudio.fields.vanilla_nerf_field import NeRFField -from nerfstudio.model_components.losses import ( - L1Loss, - MSELoss, - ScaleAndShiftInvariantLoss, - monosdf_normal_loss, -) +from nerfstudio.model_components.losses import L1Loss, MSELoss, ScaleAndShiftInvariantLoss, monosdf_normal_loss from nerfstudio.model_components.ray_samplers import LinearDisparitySampler -from nerfstudio.model_components.renderers import ( - AccumulationRenderer, - DepthRenderer, - RGBRenderer, - SemanticRenderer, -) +from nerfstudio.model_components.renderers import AccumulationRenderer, DepthRenderer, RGBRenderer, SemanticRenderer from nerfstudio.model_components.scene_colliders import AABBBoxCollider, NearFarCollider from nerfstudio.models.base_model import Model, ModelConfig from nerfstudio.utils import colormaps @@ -79,7 +69,7 @@ class SurfaceModelConfig(ModelConfig): """Monocular normal consistency loss multiplier.""" mono_depth_loss_mult: float = 0.0 """Monocular depth consistency loss multiplier.""" - sdf_field: SDFFieldConfig = field(default_factory=lambda: SDFFieldConfig()) + sdf_field: SDFFieldConfig = field(default_factory=SDFFieldConfig) """Config for SDF Field""" background_model: Literal["grid", "mlp", "none"] = "mlp" """background models""" diff --git a/nerfstudio/models/gaussian_splatting.py b/nerfstudio/models/gaussian_splatting.py index e5f560772..7edc06491 100644 --- a/nerfstudio/models/gaussian_splatting.py +++ b/nerfstudio/models/gaussian_splatting.py @@ -19,35 +19,33 @@ NeRF implementation that combines many recent advancements. from __future__ import annotations +import math from dataclasses import dataclass, field from typing import Dict, List, Optional, Tuple, Type, Union -from nerfstudio.data.scene_box import OrientedBox +import numpy as np import torch +import torchvision.transforms.functional as TF +from gsplat._torch_impl import quat_to_rotmat +from gsplat.compute_cumulative_intersects import compute_cumulative_intersects +from gsplat.project_gaussians import ProjectGaussians +from gsplat.rasterize import RasterizeGaussians +from gsplat.sh import SphericalHarmonics, num_sh_bases +from pytorch_msssim import SSIM +from sklearn.neighbors import NearestNeighbors from torch.nn import Parameter from torchmetrics.image import PeakSignalNoiseRatio from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity -import torchvision.transforms.functional as TF +from nerfstudio.cameras.camera_optimizers import CameraOptimizer, CameraOptimizerConfig from nerfstudio.cameras.cameras import Cameras -from gsplat._torch_impl import quat_to_rotmat +from nerfstudio.data.scene_box import OrientedBox from nerfstudio.engine.callbacks import TrainingCallback, TrainingCallbackAttributes, TrainingCallbackLocation from nerfstudio.engine.optimizers import Optimizers -from nerfstudio.models.base_model import Model, ModelConfig -import math -import numpy as np -from sklearn.neighbors import NearestNeighbors -from nerfstudio.cameras.camera_optimizers import CameraOptimizer, CameraOptimizerConfig - -from gsplat.rasterize import RasterizeGaussians -from gsplat.project_gaussians import ProjectGaussians -from gsplat.sh import SphericalHarmonics, num_sh_bases - -from gsplat.compute_cumulative_intersects import compute_cumulative_intersects -from pytorch_msssim import SSIM # need following import for background color override from nerfstudio.model_components import renderers +from nerfstudio.models.base_model import Model, ModelConfig from nerfstudio.utils.rich_utils import CONSOLE @@ -149,7 +147,7 @@ class GaussianSplattingModelConfig(ModelConfig): """stop splitting at this step""" sh_degree: int = 3 """maximum degree of spherical harmonics to use""" - camera_optimizer: CameraOptimizerConfig = CameraOptimizerConfig(mode="off") + camera_optimizer: CameraOptimizerConfig = field(default_factory=CameraOptimizerConfig) """camera optimizer config""" use_scale_regularization: bool = False """If enabled, a scale regularization introduced in PhysGauss (https://xpandora.github.io/PhysGaussian/) is used for reducing huge spikey gaussians.""" diff --git a/nerfstudio/pipelines/base_pipeline.py b/nerfstudio/pipelines/base_pipeline.py index b75adc6ad..a746a81ab 100644 --- a/nerfstudio/pipelines/base_pipeline.py +++ b/nerfstudio/pipelines/base_pipeline.py @@ -32,14 +32,10 @@ from torch.cuda.amp.grad_scaler import GradScaler from torch.nn import Parameter from torch.nn.parallel import DistributedDataParallel as DDP -from nerfstudio.configs import base_config as cfg -from nerfstudio.data.datamanagers.base_datamanager import ( - DataManager, - DataManagerConfig, - VanillaDataManager, -) -from nerfstudio.data.datamanagers.parallel_datamanager import ParallelDataManager +from nerfstudio.configs.base_config import InstantiateConfig +from nerfstudio.data.datamanagers.base_datamanager import DataManager, DataManagerConfig, VanillaDataManager from nerfstudio.data.datamanagers.full_images_datamanager import FullImageDatamanager +from nerfstudio.data.datamanagers.parallel_datamanager import ParallelDataManager from nerfstudio.engine.callbacks import TrainingCallback, TrainingCallbackAttributes from nerfstudio.models.base_model import Model, ModelConfig from nerfstudio.utils import profiler @@ -213,14 +209,14 @@ class Pipeline(nn.Module): @dataclass -class VanillaPipelineConfig(cfg.InstantiateConfig): +class VanillaPipelineConfig(InstantiateConfig): """Configuration for pipeline instantiation""" _target: Type = field(default_factory=lambda: VanillaPipeline) """target class to instantiate""" - datamanager: DataManagerConfig = field(default_factory=lambda: DataManagerConfig()) + datamanager: DataManagerConfig = field(default_factory=DataManagerConfig) """specifies the datamanager config""" - model: ModelConfig = field(default_factory=lambda: ModelConfig()) + model: ModelConfig = field(default_factory=ModelConfig) """specifies the model config""" diff --git a/tests/plugins/test_registry.py b/tests/plugins/test_registry.py index 7263a79c0..c17d88e15 100644 --- a/tests/plugins/test_registry.py +++ b/tests/plugins/test_registry.py @@ -3,14 +3,13 @@ Tests for the nerfstudio.plugins.registry module. """ import os import sys -from dataclasses import dataclass +from dataclasses import dataclass, field from nerfstudio.engine.trainer import TrainerConfig from nerfstudio.pipelines.base_pipeline import VanillaPipelineConfig -from nerfstudio.plugins import registry +from nerfstudio.plugins import registry, registry_dataparser +from nerfstudio.plugins.registry_dataparser import DataParserConfig, DataParserSpecification, discover_dataparsers from nerfstudio.plugins.types import MethodSpecification -from nerfstudio.plugins import registry_dataparser -from nerfstudio.plugins.registry_dataparser import DataParserSpecification, discover_dataparsers, DataParserConfig if sys.version_info < (3, 10): import importlib_metadata @@ -100,7 +99,7 @@ def test_discover_methods_from_environment_variable_instance(): @dataclass class TestDataparserConfigClass(DataParserSpecification): - config: DataParserConfig = DataParserConfig() + config: DataParserConfig = field(default_factory=DataParserConfig) description: str = "Test description"