Skip to content

Commit

Permalink
Migrate from releases/2.0.0 (#3245)
Browse files Browse the repository at this point in the history
* Add unit tests for dataset and module

* Add unit tests for transfrom lib

* Reflect develop

* Add PTQ update docs for Action Classification

* Update action detection docs

* Add action intg test

* Add raise

* Modify export intg test

* Fix anomaly intg test

* Modify detection docs and remove unused initial detectors

* Update unit tests

* Remove unused recipes

* add auto setting cpu when infer IR

* quick fix of unit test

* fix pre-commit

* add warning

* Add flag for cache

* Fix test and add for flag

---------

Co-authored-by: kprokofi <kirill.prokofiev@intel.com>
Co-authored-by: Kang, Harim <harim.kang@intel.com>
  • Loading branch information
3 people authored Apr 2, 2024
1 parent 2a70b74 commit 7df78c1
Show file tree
Hide file tree
Showing 27 changed files with 651 additions and 321 deletions.
4 changes: 4 additions & 0 deletions src/otx/algo/action_classification/openvino_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,7 @@ def postprocess(self, outputs: dict[str, np.ndarray], meta: dict[str, Any]) -> n
"""Post-process."""
logits = next(iter(outputs.values())).squeeze()
return get_multiclass_predictions(logits)

def _change_layout(self, inputs: np.ndarray) -> np.ndarray:
"""Action classification task do not require layout change."""
return inputs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import functools

from mmaction.models import MODELS
from mmaction.models.recognizers.recognizer3d import Recognizer3D
from torch import nn

from otx.algo.action_classification.recognizers.recognizer import OTXRecognizer3D


@MODELS.register_module()
class MoViNetRecognizer(Recognizer3D):
class MoViNetRecognizer(OTXRecognizer3D):
"""MoViNet recognizer model framework for OTX compatibility."""

def __init__(self, **kwargs):
Expand Down
37 changes: 0 additions & 37 deletions src/otx/algo/detection/atss.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,40 +60,3 @@ def _export_parameters(self) -> dict[str, Any]:
def load_from_otx_v1_ckpt(self, state_dict: dict, add_prefix: str = "model.model.") -> dict:
"""Load the previous OTX ckpt according to OTX2.0."""
return OTXv1Helper.load_det_ckpt(state_dict, add_prefix)


class ATSSR50FPN(MMDetCompatibleModel):
"""ATSSR50FPN Model."""

def __init__(
self,
num_classes: int,
optimizer: OptimizerCallable = DefaultOptimizerCallable,
scheduler: LRSchedulerCallable | LRSchedulerListCallable = DefaultSchedulerCallable,
metric: MetricCallable = MeanAPCallable,
torch_compile: bool = False,
) -> None:
model_name = "atss_r50_fpn"
config = read_mmconfig(model_name=model_name)
super().__init__(
num_classes=num_classes,
config=config,
optimizer=optimizer,
scheduler=scheduler,
metric=metric,
torch_compile=torch_compile,
)
self.image_size = (1, 3, 800, 1333)
self.tile_image_size = self.image_size

@property
def _export_parameters(self) -> dict[str, Any]:
"""Parameters for an exporter."""
export_params = super()._export_parameters
export_params["deploy_cfg"] = "otx.algo.detection.mmdeploy.atss_r50_fpn"
export_params["input_size"] = self.image_size
export_params["resize_mode"] = "standard" # [TODO](@Eunwoo): need to revert it to fit_to_window after resolving
export_params["pad_value"] = 0
export_params["swap_rgb"] = False

return export_params
7 changes: 3 additions & 4 deletions src/otx/core/data/pre_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,18 @@ def pre_filtering(dataset: DmDataset, data_format: str, unannotated_items_ratio:
used_background_items = set()
msg = f"There are empty annotation items in train set, Of these, only {unannotated_items_ratio*100}% are used."
warnings.warn(msg, stacklevel=2)
dataset = DmDataset.filter(dataset, is_valid_annot, filter_annotations=True)
dataset = remove_unused_labels(dataset, data_format)
if unannotated_items_ratio > 0:
empty_items = [item.id for item in dataset if item.subset == "train" and len(item.annotations) == 0]
used_background_items = set(sample(empty_items, int(len(empty_items) * unannotated_items_ratio)))

dataset = DmDataset.filter(
return DmDataset.filter(
dataset,
lambda item: not (
item.subset == "train" and len(item.annotations) == 0 and item.id not in used_background_items
),
)
dataset = DmDataset.filter(dataset, is_valid_annot, filter_annotations=True)

return remove_unused_labels(dataset, data_format)


def is_valid_annot(item: DatasetItem, annotation: Annotation) -> bool: # noqa: ARG001
Expand Down
19 changes: 19 additions & 0 deletions src/otx/core/model/action_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,25 @@ def _customize_outputs(
labels=pred_labels,
)

def _convert_pred_entity_to_compute_metric(
self,
preds: ActionClsBatchPredEntity,
inputs: ActionClsBatchDataEntity,
) -> MetricInput:
pred = torch.tensor(preds.labels)
target = torch.tensor(inputs.labels)
return {
"preds": pred,
"target": target,
}

def transform_fn(self, data_batch: ActionClsBatchDataEntity) -> np.array:
"""Data transform function for PTQ."""
np_data = self._customize_inputs(data_batch)
vid = np_data["inputs"][0]
vid = self.model.preprocess(vid)[0][self.model.image_blob_name]
return self.model._change_layout(vid) # noqa: SLF001

@property
def model_adapter_parameters(self) -> dict:
"""Model parameters for export."""
Expand Down
17 changes: 9 additions & 8 deletions src/otx/core/model/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -791,13 +791,6 @@ def check_if_quantized(model: openvino.Model) -> bool:
msg = "Model is already optimized by PTQ"
raise RuntimeError(msg)

def transform_fn(data_batch: T_OTXBatchDataEntity) -> np.array:
np_data = self._customize_inputs(data_batch)
image = np_data["inputs"][0]
resized_image = self.model.resize(image, (self.model.w, self.model.h))
resized_image = self.model.input_transform(resized_image)
return self.model._change_layout(resized_image) # noqa: SLF001

train_dataset = data_module.train_dataloader()

ptq_config_from_ir = self._read_ptq_config_from_ir(ov_model)
Expand All @@ -807,7 +800,7 @@ def transform_fn(data_batch: T_OTXBatchDataEntity) -> np.array:
else:
ptq_config = ptq_config_from_ir

quantization_dataset = nncf.Dataset(train_dataset, transform_fn) # type: ignore[attr-defined]
quantization_dataset = nncf.Dataset(train_dataset, self.transform_fn) # type: ignore[attr-defined]

compressed_model = nncf.quantize( # type: ignore[attr-defined]
ov_model,
Expand All @@ -819,6 +812,14 @@ def transform_fn(data_batch: T_OTXBatchDataEntity) -> np.array:

return output_model_path

def transform_fn(self, data_batch: T_OTXBatchDataEntity) -> np.array:
"""Data transform function for PTQ."""
np_data = self._customize_inputs(data_batch)
image = np_data["inputs"][0]
resized_image = self.model.resize(image, (self.model.w, self.model.h))
resized_image = self.model.input_transform(resized_image)
return self.model._change_layout(resized_image) # noqa: SLF001

def _read_ptq_config_from_ir(self, ov_model: Model) -> dict[str, Any]:
"""Generates the PTQ (Post-Training Quantization) configuration from the meta data of the given OpenVINO model.
Expand Down
5 changes: 4 additions & 1 deletion src/otx/core/utils/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class TrainerArgumentsCache:

def __init__(self, **kwargs) -> None:
self._cached_args = {**kwargs}
self.is_trainer_args_identical = False

def update(self, **kwargs) -> None:
"""Replace cached arguments with arguments retrieved from the model."""
Expand All @@ -65,7 +66,9 @@ def requires_update(self, **kwargs) -> bool:
Returns:
bool: True if any of the cached arguments need to be updated, False otherwise.
"""
return any(key in self._cached_args and self._cached_args[key] != value for key, value in kwargs.items())
return not self.is_trainer_args_identical or any(
key in self._cached_args and self._cached_args[key] != value for key, value in kwargs.items()
)

@property
def args(self) -> dict[str, Any]:
Expand Down
8 changes: 8 additions & 0 deletions src/otx/engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ def test(
if is_ir_ckpt and not isinstance(model, OVModel):
datamodule = self._auto_configurator.update_ov_subset_pipeline(datamodule=datamodule, subset="test")
model = self._auto_configurator.get_ov_model(model_name=str(checkpoint), label_info=datamodule.label_info)
if self.device.accelerator != "cpu":
msg = "IR model supports inference only on CPU device. The device is changed automatic."
warn(msg, stacklevel=1)
self.device = DeviceType.cpu # type: ignore[assignment]

# NOTE, trainer.test takes only lightning based checkpoint.
# So, it can't take the OTX1.x checkpoint.
Expand Down Expand Up @@ -804,6 +808,7 @@ def work_dir(self) -> PathLike:
def work_dir(self, work_dir: PathLike) -> None:
self._work_dir = work_dir
self._cache.update(default_root_dir=work_dir)
self._cache.is_trainer_args_identical = False

@property
def device(self) -> DeviceConfig:
Expand All @@ -814,6 +819,7 @@ def device(self) -> DeviceConfig:
def device(self, device: DeviceType) -> None:
self._device = DeviceConfig(accelerator=device)
self._cache.update(accelerator=self._device.accelerator, devices=self._device.devices)
self._cache.is_trainer_args_identical = False

@property
def trainer(self) -> Trainer:
Expand All @@ -835,6 +841,8 @@ def _build_trainer(self, **kwargs) -> None:
self._cache.update(**kwargs)
kwargs = self._cache.args
self._trainer = Trainer(**kwargs)
self._cache.is_trainer_args_identical = True
self._trainer.task = self.task
self.work_dir = self._trainer.default_root_dir

@property
Expand Down
16 changes: 16 additions & 0 deletions src/otx/recipe/action/action_classification/openvino_model.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ overrides:
config:
image_color_channel: BGR
data_format: kinetics
train_subset:
batch_size: 8
num_workers: 2
transforms:
- class_path: otx.core.data.transform_libs.torchvision.DecodeVideo
init_args:
test_mode: False
- class_path: otx.core.data.transform_libs.torchvision.PackVideo
val_subset:
batch_size: 8
num_workers: 2
transforms:
- class_path: otx.core.data.transform_libs.torchvision.DecodeVideo
init_args:
test_mode: true
- class_path: otx.core.data.transform_libs.torchvision.PackVideo
test_subset:
batch_size: 8
num_workers: 2
Expand Down
88 changes: 0 additions & 88 deletions src/otx/recipe/detection/atss_r50_fpn.yaml

This file was deleted.

Loading

0 comments on commit 7df78c1

Please sign in to comment.