diff --git a/modelscope/metainfo.py b/modelscope/metainfo.py index 432f7dd8..8d6034e2 100644 --- a/modelscope/metainfo.py +++ b/modelscope/metainfo.py @@ -118,13 +118,6 @@ class Models(object): longshortnet = 'longshortnet' pedestrian_attribute_recognition = 'pedestrian-attribute-recognition' - # EasyCV models - yolox = 'YOLOX' - segformer = 'Segformer' - hand_2d_keypoints = 'HRNet-Hand2D-Keypoints' - image_object_detection_auto = 'image-object-detection-auto' - dino = 'DINO' - # nlp models bert = 'bert' palm = 'palm-v2' @@ -279,8 +272,6 @@ class Pipelines(object): tbs_detection = 'tbs-detection' object_detection = 'vit-object-detection' abnormal_object_detection = 'abnormal-object-detection' - easycv_detection = 'easycv-detection' - easycv_segmentation = 'easycv-segmentation' face_2d_keypoints = 'mobilenet_face-2d-keypoints_alignment' salient_detection = 'u2net-salient-detection' salient_boudary_detection = 'res2net-salient-detection' @@ -349,7 +340,6 @@ class Pipelines(object): video_single_object_tracking_procontext = 'procontext-vitb-video-single-object-tracking' video_multi_object_tracking = 'video-multi-object-tracking' image_panoptic_segmentation = 'image-panoptic-segmentation' - image_panoptic_segmentation_easycv = 'image-panoptic-segmentation-easycv' video_summarization = 'googlenet_pgl_video_summarization' language_guided_video_summarization = 'clip-it-video-summarization' image_semantic_segmentation = 'image-semantic-segmentation' @@ -914,7 +904,6 @@ class Trainers(CVTrainers, NLPTrainers, MultiModalTrainers, AudioTrainers): """ default = 'trainer' - easycv = 'easycv' tinynas_damoyolo = 'tinynas-damoyolo' @staticmethod @@ -936,8 +925,6 @@ class Trainers(CVTrainers, NLPTrainers, MultiModalTrainers, AudioTrainers): return Fields.multi_modal elif attribute_or_value == Trainers.default: return Trainers.default - elif attribute_or_value == Trainers.easycv: - return Trainers.easycv else: return 'unknown' @@ -1168,14 +1155,6 @@ class LR_Schedulers(object): class CustomDatasets(object): """ Names for different datasets. """ - ClsDataset = 'ClsDataset' - Face2dKeypointsDataset = 'FaceKeypointDataset' - HandCocoWholeBodyDataset = 'HandCocoWholeBodyDataset' - HumanWholeBodyKeypointDataset = 'WholeBodyCocoTopDownDataset' - SegDataset = 'SegDataset' - DetDataset = 'DetDataset' - DetImagesMixDataset = 'DetImagesMixDataset' - PanopticDataset = 'PanopticDataset' PairedDataset = 'PairedDataset' SiddDataset = 'SiddDataset' GoproDataset = 'GoproDataset' diff --git a/modelscope/models/cv/__init__.py b/modelscope/models/cv/__init__.py index 21487216..39acec69 100644 --- a/modelscope/models/cv/__init__.py +++ b/modelscope/models/cv/__init__.py @@ -4,9 +4,8 @@ from . import (action_recognition, animal_recognition, bad_image_detecting, body_2d_keypoints, body_3d_keypoints, cartoon, cmdssl_video_embedding, controllable_image_generation, - crowd_counting, face_2d_keypoints, face_detection, - face_generation, face_reconstruction, human_reconstruction, - human_wholebody_keypoint, image_classification, + crowd_counting, face_detection, face_generation, + face_reconstruction, human_reconstruction, image_classification, image_color_enhance, image_colorization, image_defrcn_fewshot, image_denoise, image_inpainting, image_instance_segmentation, image_matching, image_mvs_depth_estimation, diff --git a/modelscope/models/cv/easycv_base.py b/modelscope/models/cv/easycv_base.py deleted file mode 100644 index 7bc35e84..00000000 --- a/modelscope/models/cv/easycv_base.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.models.base import BaseModel -from easycv.utils.ms_utils import EasyCVMeta - -from modelscope.models.base import TorchModel - - -class EasyCVBaseModel(BaseModel, TorchModel): - """Base model for EasyCV.""" - - def __init__(self, model_dir=None, args=(), kwargs={}): - kwargs.pop(EasyCVMeta.ARCH, None) # pop useless keys - BaseModel.__init__(self) - TorchModel.__init__(self, model_dir=model_dir) - - def forward(self, img, mode='train', **kwargs): - if self.training: - losses = self.forward_train(img, **kwargs) - loss, log_vars = self._parse_losses(losses) - return dict(loss=loss, log_vars=log_vars) - else: - return self.forward_test(img, **kwargs) - - def __call__(self, *args, **kwargs): - return self.forward(*args, **kwargs) diff --git a/modelscope/models/cv/face_2d_keypoints/__init__.py b/modelscope/models/cv/face_2d_keypoints/__init__.py deleted file mode 100644 index 636ba0f4..00000000 --- a/modelscope/models/cv/face_2d_keypoints/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .face_2d_keypoints_align import Face2DKeypoints - -else: - _import_structure = {'face_2d_keypoints_align': ['Face2DKeypoints']} - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/models/cv/face_2d_keypoints/face_2d_keypoints_align.py b/modelscope/models/cv/face_2d_keypoints/face_2d_keypoints_align.py deleted file mode 100644 index 468662a0..00000000 --- a/modelscope/models/cv/face_2d_keypoints/face_2d_keypoints_align.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.models.face.face_keypoint import FaceKeypoint - -from modelscope.metainfo import Models -from modelscope.models.builder import MODELS -from modelscope.models.cv.easycv_base import EasyCVBaseModel -from modelscope.utils.constant import Tasks - - -@MODELS.register_module( - group_key=Tasks.face_2d_keypoints, module_name=Models.face_2d_keypoints) -class Face2DKeypoints(EasyCVBaseModel, FaceKeypoint): - - def __init__(self, model_dir=None, *args, **kwargs): - EasyCVBaseModel.__init__(self, model_dir, args, kwargs) - FaceKeypoint.__init__(self, *args, **kwargs) diff --git a/modelscope/models/cv/hand_2d_keypoints/__init__.py b/modelscope/models/cv/hand_2d_keypoints/__init__.py deleted file mode 100644 index 2b06f19a..00000000 --- a/modelscope/models/cv/hand_2d_keypoints/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .hand_2d_keypoints import Hand2dKeyPoints - -else: - _import_structure = {'hand_2d_keypoints': ['Hand2dKeyPoints']} - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/models/cv/hand_2d_keypoints/hand_2d_keypoints.py b/modelscope/models/cv/hand_2d_keypoints/hand_2d_keypoints.py deleted file mode 100644 index 15a97c30..00000000 --- a/modelscope/models/cv/hand_2d_keypoints/hand_2d_keypoints.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.models.pose import TopDown - -from modelscope.metainfo import Models -from modelscope.models.builder import MODELS -from modelscope.models.cv.easycv_base import EasyCVBaseModel -from modelscope.utils.constant import Tasks - - -@MODELS.register_module( - group_key=Tasks.hand_2d_keypoints, module_name=Models.hand_2d_keypoints) -class Hand2dKeyPoints(EasyCVBaseModel, TopDown): - - def __init__(self, model_dir=None, *args, **kwargs): - EasyCVBaseModel.__init__(self, model_dir, args, kwargs) - TopDown.__init__(self, *args, **kwargs) diff --git a/modelscope/models/cv/human_wholebody_keypoint/__init__.py b/modelscope/models/cv/human_wholebody_keypoint/__init__.py deleted file mode 100644 index 30e23457..00000000 --- a/modelscope/models/cv/human_wholebody_keypoint/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .human_wholebody_keypoint import HumanWholeBodyKeypoint - -else: - _import_structure = { - 'human_wholebody_keypoint': ['HumanWholeBodyKeypoint'] - } - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/models/cv/human_wholebody_keypoint/human_wholebody_keypoint.py b/modelscope/models/cv/human_wholebody_keypoint/human_wholebody_keypoint.py deleted file mode 100644 index dd3c0290..00000000 --- a/modelscope/models/cv/human_wholebody_keypoint/human_wholebody_keypoint.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.models.pose.top_down import TopDown - -from modelscope.metainfo import Models -from modelscope.models.builder import MODELS -from modelscope.models.cv.easycv_base import EasyCVBaseModel -from modelscope.utils.constant import Tasks - - -@MODELS.register_module( - group_key=Tasks.human_wholebody_keypoint, - module_name=Models.human_wholebody_keypoint) -class HumanWholeBodyKeypoint(EasyCVBaseModel, TopDown): - - def __init__(self, model_dir=None, *args, **kwargs): - EasyCVBaseModel.__init__(self, model_dir, args, kwargs) - TopDown.__init__(self, *args, **kwargs) diff --git a/modelscope/models/cv/image_panoptic_segmentation/__init__.py b/modelscope/models/cv/image_panoptic_segmentation/__init__.py index 1af5b6f8..2b2be4b7 100644 --- a/modelscope/models/cv/image_panoptic_segmentation/__init__.py +++ b/modelscope/models/cv/image_panoptic_segmentation/__init__.py @@ -5,7 +5,6 @@ from modelscope.utils.import_utils import LazyImportModule if TYPE_CHECKING: from .panseg_model import SwinLPanopticSegmentation - from .r50_panseg_model import R50PanopticSegmentation else: _import_structure = { diff --git a/modelscope/models/cv/image_panoptic_segmentation/r50_panseg_model.py b/modelscope/models/cv/image_panoptic_segmentation/r50_panseg_model.py deleted file mode 100644 index 73b6b76c..00000000 --- a/modelscope/models/cv/image_panoptic_segmentation/r50_panseg_model.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. - -from easycv.models.segmentation import Mask2Former - -from modelscope.metainfo import Models -from modelscope.models.builder import MODELS -from modelscope.models.cv.easycv_base import EasyCVBaseModel -from modelscope.utils.constant import Tasks - - -@MODELS.register_module( - group_key=Tasks.image_segmentation, - module_name=Models.r50_panoptic_segmentation) -class R50PanopticSegmentation(EasyCVBaseModel, Mask2Former): - - def __init__(self, model_dir=None, *args, **kwargs): - EasyCVBaseModel.__init__(self, model_dir, args, kwargs) - Mask2Former.__init__(self, *args, **kwargs) diff --git a/modelscope/models/cv/image_semantic_segmentation/segformer.py b/modelscope/models/cv/image_semantic_segmentation/segformer.py deleted file mode 100644 index 46303526..00000000 --- a/modelscope/models/cv/image_semantic_segmentation/segformer.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.models.segmentation import EncoderDecoder - -from modelscope.metainfo import Models -from modelscope.models.builder import MODELS -from modelscope.models.cv.easycv_base import EasyCVBaseModel -from modelscope.utils.constant import Tasks - - -@MODELS.register_module( - group_key=Tasks.image_segmentation, module_name=Models.segformer) -class Segformer(EasyCVBaseModel, EncoderDecoder): - - def __init__(self, model_dir=None, *args, **kwargs): - EasyCVBaseModel.__init__(self, model_dir, args, kwargs) - EncoderDecoder.__init__(self, *args, **kwargs) diff --git a/modelscope/models/cv/object_detection/dino.py b/modelscope/models/cv/object_detection/dino.py deleted file mode 100644 index e6c652f1..00000000 --- a/modelscope/models/cv/object_detection/dino.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.models.detection.detectors import Detection as _Detection - -from modelscope.metainfo import Models -from modelscope.models.builder import MODELS -from modelscope.models.cv.easycv_base import EasyCVBaseModel -from modelscope.utils.constant import Tasks - - -@MODELS.register_module( - group_key=Tasks.image_object_detection, module_name=Models.dino) -class DINO(EasyCVBaseModel, _Detection): - - def __init__(self, model_dir=None, *args, **kwargs): - EasyCVBaseModel.__init__(self, model_dir, args, kwargs) - _Detection.__init__(self, *args, **kwargs) diff --git a/modelscope/models/cv/object_detection/yolox_pai.py b/modelscope/models/cv/object_detection/yolox_pai.py deleted file mode 100644 index 7888cf82..00000000 --- a/modelscope/models/cv/object_detection/yolox_pai.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.models.detection.detectors import YOLOX as _YOLOX - -from modelscope.metainfo import Models -from modelscope.models.builder import MODELS -from modelscope.models.cv.easycv_base import EasyCVBaseModel -from modelscope.utils.constant import Tasks - - -@MODELS.register_module( - group_key=Tasks.image_object_detection, module_name=Models.yolox) -@MODELS.register_module( - group_key=Tasks.image_object_detection, - module_name=Models.image_object_detection_auto) -@MODELS.register_module( - group_key=Tasks.domain_specific_object_detection, module_name=Models.yolox) -class YOLOX(EasyCVBaseModel, _YOLOX): - - def __init__(self, model_dir=None, *args, **kwargs): - EasyCVBaseModel.__init__(self, model_dir, args, kwargs) - _YOLOX.__init__(self, *args, **kwargs) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/__init__.py b/modelscope/msdatasets/dataset_cls/custom_datasets/__init__.py index 9eb62168..a367fe79 100644 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/__init__.py +++ b/modelscope/msdatasets/dataset_cls/custom_datasets/__init__.py @@ -27,12 +27,6 @@ if TYPE_CHECKING: from .video_frame_interpolation import VideoFrameInterpolationDataset from .video_stabilization import VideoStabilizationDataset from .video_super_resolution import VideoSuperResolutionDataset - from .image_semantic_segmentation import SegDataset - from .face_2d_keypoins import FaceKeypointDataset - from .hand_2d_keypoints import HandCocoWholeBodyDataset - from .human_wholebody_keypoint import WholeBodyCocoTopDownDataset - from .image_classification import ClsDataset - from .object_detection import DetDataset, DetImagesMixDataset from .ocr_detection import DataLoader, ImageDataset, QuadMeasurer from .ocr_recognition_dataset import OCRRecognitionDataset from .image_colorization import ImageColorizationDataset @@ -66,12 +60,6 @@ else: 'video_frame_interpolation': ['VideoFrameInterpolationDataset'], 'video_stabilization': ['VideoStabilizationDataset'], 'video_super_resolution': ['VideoSuperResolutionDataset'], - 'image_semantic_segmentation': ['SegDataset'], - 'face_2d_keypoins': ['FaceKeypointDataset'], - 'hand_2d_keypoints': ['HandCocoWholeBodyDataset'], - 'human_wholebody_keypoint': ['WholeBodyCocoTopDownDataset'], - 'image_classification': ['ClsDataset'], - 'object_detection': ['DetDataset', 'DetImagesMixDataset'], 'ocr_detection': ['DataLoader', 'ImageDataset', 'QuadMeasurer'], 'ocr_recognition_dataset': ['OCRRecognitionDataset'], 'image_colorization': ['ImageColorizationDataset'], diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/face_2d_keypoins/__init__.py b/modelscope/msdatasets/dataset_cls/custom_datasets/face_2d_keypoins/__init__.py deleted file mode 100644 index e9d76b7e..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/face_2d_keypoins/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .face_2d_keypoints_dataset import FaceKeypointDataset - -else: - _import_structure = {'face_2d_keypoints_dataset': ['FaceKeypointDataset']} - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/face_2d_keypoins/face_2d_keypoints_dataset.py b/modelscope/msdatasets/dataset_cls/custom_datasets/face_2d_keypoins/face_2d_keypoints_dataset.py deleted file mode 100644 index 9f55901f..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/face_2d_keypoins/face_2d_keypoints_dataset.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.datasets.face import FaceKeypointDataset as _FaceKeypointDataset - -from modelscope.metainfo import CustomDatasets -from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS -from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \ - EasyCVBaseDataset -from modelscope.utils.constant import Tasks - - -@CUSTOM_DATASETS.register_module( - group_key=Tasks.face_2d_keypoints, - module_name=CustomDatasets.Face2dKeypointsDataset) -class FaceKeypointDataset(EasyCVBaseDataset, _FaceKeypointDataset): - """EasyCV dataset for face 2d keypoints. - - Args: - split_config (dict): Dataset root path from MSDataset, e.g. - {"train":"local cache path"} or {"evaluation":"local cache path"}. - preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for - the model if supplied. Not support yet. - mode: Training or Evaluation. - """ - - def __init__(self, - split_config=None, - preprocessor=None, - mode=None, - *args, - **kwargs) -> None: - EasyCVBaseDataset.__init__( - self, - split_config=split_config, - preprocessor=preprocessor, - mode=mode, - args=args, - kwargs=kwargs) - _FaceKeypointDataset.__init__(self, *args, **kwargs) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/hand_2d_keypoints/__init__.py b/modelscope/msdatasets/dataset_cls/custom_datasets/hand_2d_keypoints/__init__.py deleted file mode 100644 index 3af670e3..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/hand_2d_keypoints/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .hand_2d_keypoints_dataset import HandCocoWholeBodyDataset - -else: - _import_structure = { - 'hand_2d_keypoints_dataset': ['HandCocoWholeBodyDataset'] - } - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/hand_2d_keypoints/hand_2d_keypoints_dataset.py b/modelscope/msdatasets/dataset_cls/custom_datasets/hand_2d_keypoints/hand_2d_keypoints_dataset.py deleted file mode 100644 index c6163715..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/hand_2d_keypoints/hand_2d_keypoints_dataset.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.datasets.pose import \ - HandCocoWholeBodyDataset as _HandCocoWholeBodyDataset - -from modelscope.metainfo import CustomDatasets -from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS -from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \ - EasyCVBaseDataset -from modelscope.utils.constant import Tasks - - -@CUSTOM_DATASETS.register_module( - group_key=Tasks.hand_2d_keypoints, - module_name=CustomDatasets.HandCocoWholeBodyDataset) -class HandCocoWholeBodyDataset(EasyCVBaseDataset, _HandCocoWholeBodyDataset): - """EasyCV dataset for human hand 2d keypoints. - - Args: - split_config (dict): Dataset root path from MSDataset, e.g. - {"train":"local cache path"} or {"evaluation":"local cache path"}. - preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for - the model if supplied. Not support yet. - mode: Training or Evaluation. - """ - - def __init__(self, - split_config=None, - preprocessor=None, - mode=None, - *args, - **kwargs) -> None: - EasyCVBaseDataset.__init__( - self, - split_config=split_config, - preprocessor=preprocessor, - mode=mode, - args=args, - kwargs=kwargs) - _HandCocoWholeBodyDataset.__init__(self, *args, **kwargs) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/human_wholebody_keypoint/__init__.py b/modelscope/msdatasets/dataset_cls/custom_datasets/human_wholebody_keypoint/__init__.py deleted file mode 100644 index 472ed2d8..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/human_wholebody_keypoint/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .human_wholebody_keypoint_dataset import WholeBodyCocoTopDownDataset - -else: - _import_structure = { - 'human_wholebody_keypoint_dataset': ['WholeBodyCocoTopDownDataset'] - } - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/human_wholebody_keypoint/human_wholebody_keypoint_dataset.py b/modelscope/msdatasets/dataset_cls/custom_datasets/human_wholebody_keypoint/human_wholebody_keypoint_dataset.py deleted file mode 100644 index 59c97af8..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/human_wholebody_keypoint/human_wholebody_keypoint_dataset.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.datasets.pose import \ - WholeBodyCocoTopDownDataset as _WholeBodyCocoTopDownDataset - -from modelscope.metainfo import CustomDatasets -from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS -from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \ - EasyCVBaseDataset -from modelscope.utils.constant import Tasks - - -@CUSTOM_DATASETS.register_module( - group_key=Tasks.human_wholebody_keypoint, - module_name=CustomDatasets.HumanWholeBodyKeypointDataset) -class WholeBodyCocoTopDownDataset(EasyCVBaseDataset, - _WholeBodyCocoTopDownDataset): - """EasyCV dataset for human whole body 2d keypoints. - - Args: - split_config (dict): Dataset root path from MSDataset, e.g. - {"train":"local cache path"} or {"evaluation":"local cache path"}. - preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for - the model if supplied. Not support yet. - mode: Training or Evaluation. - """ - - def __init__(self, - split_config=None, - preprocessor=None, - mode=None, - *args, - **kwargs) -> None: - EasyCVBaseDataset.__init__( - self, - split_config=split_config, - preprocessor=preprocessor, - mode=mode, - args=args, - kwargs=kwargs) - _WholeBodyCocoTopDownDataset.__init__(self, *args, **kwargs) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/image_classification/__init__.py b/modelscope/msdatasets/dataset_cls/custom_datasets/image_classification/__init__.py deleted file mode 100644 index 95e8d7a1..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/image_classification/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .classification_dataset import ClsDataset - -else: - _import_structure = {'classification_dataset': ['ClsDataset']} - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/image_classification/classification_dataset.py b/modelscope/msdatasets/dataset_cls/custom_datasets/image_classification/classification_dataset.py deleted file mode 100644 index 386810c7..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/image_classification/classification_dataset.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.datasets.classification import ClsDataset as _ClsDataset - -from modelscope.metainfo import CustomDatasets -from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS -from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \ - EasyCVBaseDataset -from modelscope.utils.constant import Tasks - - -@CUSTOM_DATASETS.register_module( - group_key=Tasks.image_classification, - module_name=CustomDatasets.ClsDataset) -class ClsDataset(_ClsDataset): - """EasyCV dataset for classification. - - Args: - split_config (dict): Dataset root path from MSDataset, e.g. - {"train":"local cache path"} or {"evaluation":"local cache path"}. - preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for - the model if supplied. Not support yet. - mode: Training or Evaluation. - """ - - def __init__(self, - split_config=None, - preprocessor=None, - mode=None, - *args, - **kwargs) -> None: - EasyCVBaseDataset.__init__( - self, - split_config=split_config, - preprocessor=preprocessor, - mode=mode, - args=args, - kwargs=kwargs) - _ClsDataset.__init__(self, *args, **kwargs) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/image_semantic_segmentation/__init__.py b/modelscope/msdatasets/dataset_cls/custom_datasets/image_semantic_segmentation/__init__.py deleted file mode 100644 index 26121bdb..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/image_semantic_segmentation/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .segmentation_dataset import SegDataset - -else: - _import_structure = {'easycv_segmentation': ['SegDataset']} - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/image_semantic_segmentation/segmentation_dataset.py b/modelscope/msdatasets/dataset_cls/custom_datasets/image_semantic_segmentation/segmentation_dataset.py deleted file mode 100644 index 71e7c42b..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/image_semantic_segmentation/segmentation_dataset.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from easycv.datasets.segmentation import SegDataset as _SegDataset - -from modelscope.metainfo import CustomDatasets -from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS -from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \ - EasyCVBaseDataset -from modelscope.utils.constant import Tasks - - -@CUSTOM_DATASETS.register_module( - group_key=Tasks.image_segmentation, module_name=CustomDatasets.SegDataset) -class SegDataset(EasyCVBaseDataset, _SegDataset): - """EasyCV dataset for Sementic segmentation. - For more details, please refer to : - https://github.com/alibaba/EasyCV/blob/master/easycv/datasets/segmentation/raw.py . - - Args: - split_config (dict): Dataset root path from MSDataset, e.g. - {"train":"local cache path"} or {"evaluation":"local cache path"}. - preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for - the model if supplied. Not support yet. - mode: Training or Evaluation. - data_source: Data source config to parse input data. - pipeline: Sequence of transform object or config dict to be composed. - ignore_index (int): Label index to be ignored. - profiling: If set True, will print transform time. - """ - - def __init__(self, - split_config=None, - preprocessor=None, - mode=None, - *args, - **kwargs) -> None: - EasyCVBaseDataset.__init__( - self, - split_config=split_config, - preprocessor=preprocessor, - mode=mode, - args=args, - kwargs=kwargs) - _SegDataset.__init__(self, *args, **kwargs) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/object_detection/__init__.py b/modelscope/msdatasets/dataset_cls/custom_datasets/object_detection/__init__.py deleted file mode 100644 index 403163e9..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/object_detection/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .detection_dataset import DetDataset, DetImagesMixDataset - -else: - _import_structure = { - 'detection_dataset': ['DetDataset', 'DetImagesMixDataset'] - } - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/msdatasets/dataset_cls/custom_datasets/object_detection/detection_dataset.py b/modelscope/msdatasets/dataset_cls/custom_datasets/object_detection/detection_dataset.py deleted file mode 100644 index 66c11f64..00000000 --- a/modelscope/msdatasets/dataset_cls/custom_datasets/object_detection/detection_dataset.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. - -from easycv.datasets.detection import DetDataset as _DetDataset -from easycv.datasets.detection import \ - DetImagesMixDataset as _DetImagesMixDataset - -from modelscope.metainfo import CustomDatasets -from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS -from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \ - EasyCVBaseDataset -from modelscope.utils.constant import Tasks - - -@CUSTOM_DATASETS.register_module( - group_key=Tasks.image_object_detection, - module_name=CustomDatasets.DetDataset) -@CUSTOM_DATASETS.register_module( - group_key=Tasks.image_segmentation, module_name=CustomDatasets.DetDataset) -class DetDataset(EasyCVBaseDataset, _DetDataset): - """EasyCV dataset for object detection. - For more details, please refer to https://github.com/alibaba/EasyCV/blob/master/easycv/datasets/detection/raw.py . - - Args: - split_config (dict): Dataset root path from MSDataset, e.g. - {"train":"local cache path"} or {"evaluation":"local cache path"}. - preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for - the model if supplied. Not support yet. - mode: Training or Evaluation. - data_source: Data source config to parse input data. - pipeline: Transform config list - profiling: If set True, will print pipeline time - classes: A list of class names, used in evaluation for result and groundtruth visualization - """ - - def __init__(self, - split_config=None, - preprocessor=None, - mode=None, - *args, - **kwargs) -> None: - EasyCVBaseDataset.__init__( - self, - split_config=split_config, - preprocessor=preprocessor, - mode=mode, - args=args, - kwargs=kwargs) - _DetDataset.__init__(self, *args, **kwargs) - - -@CUSTOM_DATASETS.register_module( - group_key=Tasks.image_object_detection, - module_name=CustomDatasets.DetImagesMixDataset) -@CUSTOM_DATASETS.register_module( - group_key=Tasks.domain_specific_object_detection, - module_name=CustomDatasets.DetImagesMixDataset) -class DetImagesMixDataset(EasyCVBaseDataset, _DetImagesMixDataset): - """EasyCV dataset for object detection, a wrapper of multiple images mixed dataset. - Suitable for training on multiple images mixed data augmentation like - mosaic and mixup. For the augmentation pipeline of mixed image data, - the `get_indexes` method needs to be provided to obtain the image - indexes, and you can set `skip_flags` to change the pipeline running - process. At the same time, we provide the `dynamic_scale` parameter - to dynamically change the output image size. - output boxes format: cx, cy, w, h - - For more details, please refer to https://github.com/alibaba/EasyCV/blob/master/easycv/datasets/detection/mix.py . - - Args: - split_config (dict): Dataset root path from MSDataset, e.g. - {"train":"local cache path"} or {"evaluation":"local cache path"}. - preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for - the model if supplied. Not support yet. - mode: Training or Evaluation. - data_source (:obj:`DetSourceCoco`): Data source config to parse input data. - pipeline (Sequence[dict]): Sequence of transform object or - config dict to be composed. - dynamic_scale (tuple[int], optional): The image scale can be changed - dynamically. Default to None. - skip_type_keys (list[str], optional): Sequence of type string to - be skip pipeline. Default to None. - label_padding: out labeling padding [N, 120, 5] - """ - - def __init__(self, - split_config=None, - preprocessor=None, - mode=None, - *args, - **kwargs) -> None: - EasyCVBaseDataset.__init__( - self, - split_config=split_config, - preprocessor=preprocessor, - mode=mode, - args=args, - kwargs=kwargs) - _DetImagesMixDataset.__init__(self, *args, **kwargs) diff --git a/modelscope/pipelines/cv/__init__.py b/modelscope/pipelines/cv/__init__.py index 54289644..e9d7a785 100644 --- a/modelscope/pipelines/cv/__init__.py +++ b/modelscope/pipelines/cv/__init__.py @@ -9,7 +9,6 @@ if TYPE_CHECKING: from .animal_recognition_pipeline import AnimalRecognitionPipeline from .body_2d_keypoints_pipeline import Body2DKeypointsPipeline from .body_3d_keypoints_pipeline import Body3DKeypointsPipeline - from .hand_2d_keypoints_pipeline import Hand2DKeypointsPipeline from .cmdssl_video_embedding_pipeline import CMDSSLVideoEmbeddingPipeline from .card_detection_pipeline import CardDetectionPipeline from .hicossl_video_embedding_pipeline import HICOSSLVideoEmbeddingPipeline @@ -29,13 +28,10 @@ if TYPE_CHECKING: from .image_classification_pipeline import GeneralImageClassificationPipeline from .image_color_enhance_pipeline import ImageColorEnhancePipeline from .image_colorization_pipeline import ImageColorizationPipeline - from .image_classification_pipeline import ImageClassificationPipeline from .image_denoise_pipeline import ImageDenoisePipeline from .image_deblur_pipeline import ImageDeblurPipeline from .image_instance_segmentation_pipeline import ImageInstanceSegmentationPipeline from .image_matting_pipeline import ImageMattingPipeline - from .image_panoptic_segmentation_pipeline import ImagePanopticSegmentationPipeline - from .image_semantic_segmentation_pipeline import ImagePanopticSegmentationEasyCVPipeline from .image_portrait_enhancement_pipeline import ImagePortraitEnhancementPipeline from .image_reid_person_pipeline import ImageReidPersonPipeline from .image_semantic_segmentation_pipeline import ImageSemanticSegmentationPipeline @@ -46,7 +42,6 @@ if TYPE_CHECKING: from .image_inpainting_pipeline import ImageInpaintingPipeline from .image_paintbyexample_pipeline import ImagePaintbyexamplePipeline from .product_retrieval_embedding_pipeline import ProductRetrievalEmbeddingPipeline - from .realtime_object_detection_pipeline import RealtimeObjectDetectionPipeline from .live_category_pipeline import LiveCategoryPipeline from .ocr_detection_pipeline import OCRDetectionPipeline from .ocr_recognition_pipeline import OCRRecognitionPipeline @@ -59,10 +54,6 @@ if TYPE_CHECKING: from .video_category_pipeline import VideoCategoryPipeline from .virtual_try_on_pipeline import VirtualTryonPipeline from .shop_segmentation_pipleline import ShopSegmentationPipeline - from .easycv_pipelines import (EasyCVDetectionPipeline, - EasyCVSegmentationPipeline, - Face2DKeypointsPipeline, - HumanWholebodyKeypointsPipeline) from .text_driven_segmentation_pipleline import TextDrivenSegmentationPipeline from .movie_scene_segmentation_pipeline import MovieSceneSegmentationPipeline from .mog_face_detection_pipeline import MogFaceDetectionPipeline @@ -123,7 +114,6 @@ else: 'animal_recognition_pipeline': ['AnimalRecognitionPipeline'], 'body_2d_keypoints_pipeline': ['Body2DKeypointsPipeline'], 'body_3d_keypoints_pipeline': ['Body3DKeypointsPipeline'], - 'hand_2d_keypoints_pipeline': ['Hand2DKeypointsPipeline'], 'card_detection_pipeline': ['CardDetectionPipeline'], 'cmdssl_video_embedding_pipeline': ['CMDSSLVideoEmbeddingPipeline'], 'hicossl_video_embedding_pipeline': ['HICOSSLVideoEmbeddingPipeline'], @@ -140,7 +130,7 @@ else: 'face_recognition_onnx_fm_pipeline': ['FaceRecognitionOnnxFmPipeline'], 'general_recognition_pipeline': ['GeneralRecognitionPipeline'], 'image_classification_pipeline': - ['GeneralImageClassificationPipeline', 'ImageClassificationPipeline'], + ['GeneralImageClassificationPipeline'], 'image_cartoon_pipeline': ['ImageCartoonPipeline'], 'image_denoise_pipeline': ['ImageDenoisePipeline'], 'image_deblur_pipeline': ['ImageDeblurPipeline'], @@ -149,10 +139,6 @@ else: 'image_instance_segmentation_pipeline': ['ImageInstanceSegmentationPipeline'], 'image_matting_pipeline': ['ImageMattingPipeline'], - 'image_panoptic_segmentation_pipeline': [ - 'ImagePanopticSegmentationPipeline', - 'ImagePanopticSegmentationEasyCVPipeline' - ], 'image_portrait_enhancement_pipeline': ['ImagePortraitEnhancementPipeline'], 'image_reid_person_pipeline': ['ImageReidPersonPipeline'], @@ -164,8 +150,6 @@ else: ['Image2ImageTranslationPipeline'], 'product_retrieval_embedding_pipeline': ['ProductRetrievalEmbeddingPipeline'], - 'realtime_object_detection_pipeline': - ['RealtimeObjectDetectionPipeline'], 'live_category_pipeline': ['LiveCategoryPipeline'], 'image_to_image_generate_pipeline': ['Image2ImageGenerationPipeline'], 'image_inpainting_pipeline': ['ImageInpaintingPipeline'], @@ -180,12 +164,6 @@ else: 'video_category_pipeline': ['VideoCategoryPipeline'], 'virtual_try_on_pipeline': ['VirtualTryonPipeline'], 'shop_segmentation_pipleline': ['ShopSegmentationPipeline'], - 'easycv_pipelines': [ - 'EasyCVDetectionPipeline', - 'EasyCVSegmentationPipeline', - 'Face2DKeypointsPipeline', - 'HumanWholebodyKeypointsPipeline', - ], 'text_driven_segmentation_pipleline': ['TextDrivenSegmentationPipeline'], 'movie_scene_segmentation_pipeline': @@ -202,9 +180,8 @@ else: ['FaceAttributeRecognitionPipeline'], 'mtcnn_face_detection_pipeline': ['MtcnnFaceDetectionPipeline'], 'hand_static_pipeline': ['HandStaticPipeline'], - 'referring_video_object_segmentation_pipeline': [ - 'ReferringVideoObjectSegmentationPipeline' - ], + 'referring_video_object_segmentation_pipeline': + ['ReferringVideoObjectSegmentationPipeline'], 'language_guided_video_summarization_pipeline': [ 'LanguageGuidedVideoSummarizationPipeline' ], diff --git a/modelscope/pipelines/cv/easycv_pipelines/__init__.py b/modelscope/pipelines/cv/easycv_pipelines/__init__.py deleted file mode 100644 index e0209b85..00000000 --- a/modelscope/pipelines/cv/easycv_pipelines/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .detection_pipeline import EasyCVDetectionPipeline - from .segmentation_pipeline import EasyCVSegmentationPipeline - from .face_2d_keypoints_pipeline import Face2DKeypointsPipeline - from .human_wholebody_keypoint_pipeline import HumanWholebodyKeypointsPipeline -else: - _import_structure = { - 'detection_pipeline': ['EasyCVDetectionPipeline'], - 'segmentation_pipeline': ['EasyCVSegmentationPipeline'], - 'face_2d_keypoints_pipeline': ['Face2DKeypointsPipeline'], - 'human_wholebody_keypoint_pipeline': - ['HumanWholebodyKeypointsPipeline'], - } - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/pipelines/cv/easycv_pipelines/base.py b/modelscope/pipelines/cv/easycv_pipelines/base.py deleted file mode 100644 index 0a31be94..00000000 --- a/modelscope/pipelines/cv/easycv_pipelines/base.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import os.path as osp -from typing import Any - -import numpy as np -from easycv.utils.ms_utils import EasyCVMeta -from PIL import ImageFile - -from modelscope.hub.snapshot_download import snapshot_download -from modelscope.pipelines.util import is_official_hub_path -from modelscope.utils.config import Config -from modelscope.utils.constant import (DEFAULT_MODEL_REVISION, Invoke, - ModelFile, ThirdParty) -from modelscope.utils.device import create_device - - -class EasyCVPipeline(object): - """Base pipeline for EasyCV. - Loading configuration file of modelscope style by default, - but it is actually use the predictor api of easycv to predict. - So here we do some adaptation work for configuration and predict api. - """ - - def __init__(self, model: str, model_file_pattern='*.pt', *args, **kwargs): - """ - model (str): model id on modelscope hub or local model path. - model_file_pattern (str): model file pattern. - - """ - self.model_file_pattern = model_file_pattern - - assert isinstance(model, str) - if osp.exists(model): - model_dir = model - else: - assert is_official_hub_path( - model), 'Only support local model path and official hub path!' - model_dir = snapshot_download( - model_id=model, - revision=DEFAULT_MODEL_REVISION, - user_agent={ - Invoke.KEY: Invoke.PIPELINE, - ThirdParty.KEY: ThirdParty.EASYCV - }) - - assert osp.isdir(model_dir) - model_files = glob.glob( - os.path.join(model_dir, self.model_file_pattern)) - assert len( - model_files - ) == 1, f'Need one model file, but find {len(model_files)}: {model_files}' - - model_path = model_files[0] - self.model_path = model_path - self.model_dir = model_dir - - # get configuration file from source model dir - self.config_file = os.path.join(model_dir, ModelFile.CONFIGURATION) - assert os.path.exists( - self.config_file - ), f'Not find "{ModelFile.CONFIGURATION}" in model directory!' - - self.cfg = Config.from_file(self.config_file) - if 'device' in kwargs: - kwargs['device'] = create_device(kwargs['device']) - if 'predictor_config' in kwargs: - kwargs.pop('predictor_config') - self.predict_op = self._build_predict_op(**kwargs) - - def _build_predict_op(self, **kwargs): - """Build EasyCV predictor.""" - from easycv.predictors.builder import build_predictor - - easycv_config = self._to_easycv_config() - pipeline_op = build_predictor(self.cfg.pipeline.predictor_config, { - 'model_path': self.model_path, - 'config_file': easycv_config, - **kwargs - }) - return pipeline_op - - def _to_easycv_config(self): - """Adapt to EasyCV predictor.""" - # TODO: refine config compatibility problems - - easycv_arch = self.cfg.model.pop(EasyCVMeta.ARCH, None) - model_cfg = self.cfg.model - # Revert to the configuration of easycv - if easycv_arch is not None: - model_cfg.update(easycv_arch) - - easycv_config = Config(dict(model=model_cfg)) - - reserved_keys = [] - if hasattr(self.cfg, EasyCVMeta.META): - easycv_meta_cfg = getattr(self.cfg, EasyCVMeta.META) - reserved_keys = easycv_meta_cfg.get(EasyCVMeta.RESERVED_KEYS, []) - for key in reserved_keys: - easycv_config.merge_from_dict({key: getattr(self.cfg, key)}) - if 'test_pipeline' not in reserved_keys: - easycv_config.merge_from_dict( - {'test_pipeline': self.cfg.dataset.val.get('pipeline', [])}) - - return easycv_config - - def _is_single_inputs(self, inputs): - if isinstance(inputs, str) or (isinstance(inputs, list) - and len(inputs) == 1) or isinstance( - inputs, np.ndarray) or isinstance( - inputs, ImageFile.ImageFile): - return True - - return False - - def __call__(self, inputs) -> Any: - outputs = self.predict_op(inputs) - - if self._is_single_inputs(inputs): - outputs = outputs[0] - - return outputs diff --git a/modelscope/pipelines/cv/easycv_pipelines/detection_pipeline.py b/modelscope/pipelines/cv/easycv_pipelines/detection_pipeline.py deleted file mode 100644 index 2a95ebb4..00000000 --- a/modelscope/pipelines/cv/easycv_pipelines/detection_pipeline.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import Any - -from modelscope.metainfo import Pipelines -from modelscope.outputs import OutputKeys -from modelscope.pipelines.builder import PIPELINES -from modelscope.utils.constant import ModelFile, Tasks -from modelscope.utils.cv.image_utils import \ - show_image_object_detection_auto_result -from .base import EasyCVPipeline - - -@PIPELINES.register_module( - Tasks.image_object_detection, module_name=Pipelines.easycv_detection) -@PIPELINES.register_module( - Tasks.image_object_detection, - module_name=Pipelines.image_object_detection_auto) -@PIPELINES.register_module( - Tasks.domain_specific_object_detection, - module_name=Pipelines.hand_detection) -class EasyCVDetectionPipeline(EasyCVPipeline): - """Pipeline for easycv detection task.""" - - def __init__(self, - model: str, - model_file_pattern=ModelFile.TORCH_MODEL_FILE, - *args, - **kwargs): - """ - model (str): model id on modelscope hub or local model path. - model_file_pattern (str): model file pattern. - """ - - super(EasyCVDetectionPipeline, self).__init__( - model=model, - model_file_pattern=model_file_pattern, - *args, - **kwargs) - - def show_result(self, img_path, result, save_path=None): - show_image_object_detection_auto_result(img_path, result, save_path) - - def __call__(self, inputs) -> Any: - outputs = self.predict_op(inputs) - - scores = [] - labels = [] - boxes = [] - for output in outputs: - for score, label, box in zip(output['detection_scores'], - output['detection_classes'], - output['detection_boxes']): - scores.append(score) - labels.append(self.cfg.CLASSES[label]) - boxes.append([b for b in box]) - - results = [{ - OutputKeys.SCORES: scores, - OutputKeys.LABELS: labels, - OutputKeys.BOXES: boxes - } for output in outputs] - - if self._is_single_inputs(inputs): - results = results[0] - - return results diff --git a/modelscope/pipelines/cv/easycv_pipelines/face_2d_keypoints_pipeline.py b/modelscope/pipelines/cv/easycv_pipelines/face_2d_keypoints_pipeline.py deleted file mode 100644 index 0ddc6a6c..00000000 --- a/modelscope/pipelines/cv/easycv_pipelines/face_2d_keypoints_pipeline.py +++ /dev/null @@ -1,244 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import copy -import math -from typing import Any - -import cv2 -import numpy as np - -from modelscope.metainfo import Pipelines -from modelscope.outputs import OutputKeys -from modelscope.pipelines import pipeline -from modelscope.pipelines.builder import PIPELINES -from modelscope.preprocessors import LoadImage -from modelscope.utils.constant import ModelFile, Tasks -from modelscope.utils.logger import get_logger -from .base import EasyCVPipeline - -logger = get_logger() - - -@PIPELINES.register_module( - Tasks.face_2d_keypoints, module_name=Pipelines.face_2d_keypoints) -class Face2DKeypointsPipeline(EasyCVPipeline): - """Pipeline for face 2d keypoints detection.""" - - def __init__(self, - model: str, - model_file_pattern=ModelFile.TORCH_MODEL_FILE, - *args, - **kwargs): - """ - model (str): model id on modelscope hub or local model path. - model_file_pattern (str): model file pattern. - """ - - super(Face2DKeypointsPipeline, self).__init__( - model=model, - model_file_pattern=model_file_pattern, - *args, - **kwargs) - - # face detect pipeline - det_model_id = 'damo/cv_resnet_facedetection_scrfd10gkps' - self.face_detection = pipeline( - Tasks.face_detection, model=det_model_id) - - def show_result(self, img, points, scale=2, save_path=None): - return self.predict_op.show_result(img, points, scale, save_path) - - def _choose_face(self, det_result, min_face=10): - """ - choose face with maximum area - Args: - det_result: output of face detection pipeline - min_face: minimum size of valid face w/h - """ - bboxes = np.array(det_result[OutputKeys.BOXES]) - landmarks = np.array(det_result[OutputKeys.KEYPOINTS]) - if bboxes.shape[0] == 0: - logger.warning('No face detected!') - return None - # face idx with enough size - face_idx = [] - for i in range(bboxes.shape[0]): - box = bboxes[i] - if (box[2] - box[0]) >= min_face and (box[3] - box[1]) >= min_face: - face_idx += [i] - if len(face_idx) == 0: - logger.warning( - f'Face size not enough, less than {min_face}x{min_face}!') - return None - bboxes = bboxes[face_idx] - landmarks = landmarks[face_idx] - - return bboxes, landmarks - - def expend_box(self, box, w, h, scalex=0.3, scaley=0.5): - x1 = box[0] - y1 = box[1] - wb = box[2] - x1 - hb = box[3] - y1 - deltax = int(wb * scalex) - deltay1 = int(hb * scaley) - deltay2 = int(hb * scalex) - x1 = x1 - deltax - y1 = y1 - deltay1 - if x1 < 0: - deltax = deltax + x1 - x1 = 0 - if y1 < 0: - deltay1 = deltay1 + y1 - y1 = 0 - x2 = x1 + wb + 2 * deltax - y2 = y1 + hb + deltay1 + deltay2 - x2 = np.clip(x2, 0, w - 1) - y2 = np.clip(y2, 0, h - 1) - return [x1, y1, x2, y2] - - def rotate_point(self, angle, center, landmark): - rad = angle * np.pi / 180.0 - alpha = np.cos(rad) - beta = np.sin(rad) - M = np.zeros((2, 3), dtype=np.float32) - M[0, 0] = alpha - M[0, 1] = beta - M[0, 2] = (1 - alpha) * center[0] - beta * center[1] - M[1, 0] = -beta - M[1, 1] = alpha - M[1, 2] = beta * center[0] + (1 - alpha) * center[1] - - landmark_ = np.asarray([(M[0, 0] * x + M[0, 1] * y + M[0, 2], - M[1, 0] * x + M[1, 1] * y + M[1, 2]) - for (x, y) in landmark]) - return M, landmark_ - - def rotate_crop_img(self, img, pts, M): - imgT = cv2.warpAffine(img, M, (int(img.shape[1]), int(img.shape[0]))) - - x1 = pts[5][0] - x2 = pts[5][0] - y1 = pts[5][1] - y2 = pts[5][1] - for i in range(0, 9): - x1 = min(x1, pts[i][0]) - x2 = max(x2, pts[i][0]) - y1 = min(y1, pts[i][1]) - y2 = max(y2, pts[i][1]) - - height, width, _ = imgT.shape - x1 = min(max(0, int(x1)), width) - y1 = min(max(0, int(y1)), height) - x2 = min(max(0, int(x2)), width) - y2 = min(max(0, int(y2)), height) - sub_imgT = imgT[y1:y2, x1:x2] - - return sub_imgT, imgT, [x1, y1, x2, y2] - - def crop_img(self, imgT, pts): - enlarge_ratio = 1.1 - - x1 = np.min(pts[:, 0]) - x2 = np.max(pts[:, 0]) - y1 = np.min(pts[:, 1]) - y2 = np.max(pts[:, 1]) - w = x2 - x1 + 1 - h = y2 - y1 + 1 - x1 = int(x1 - (enlarge_ratio - 1.0) / 2.0 * w) - y1 = int(y1 - (enlarge_ratio - 1.0) / 2.0 * h) - x1 = max(0, x1) - y1 = max(0, y1) - - new_w = int(enlarge_ratio * w) - new_h = int(enlarge_ratio * h) - new_x1 = x1 - new_y1 = y1 - new_x2 = new_x1 + new_w - new_y2 = new_y1 + new_h - - height, width, _ = imgT.shape - - new_x1 = min(max(0, new_x1), width) - new_y1 = min(max(0, new_y1), height) - new_x2 = max(min(width, new_x2), 0) - new_y2 = max(min(height, new_y2), 0) - - sub_imgT = imgT[new_y1:new_y2, new_x1:new_x2] - - return sub_imgT, [new_x1, new_y1, new_x2, new_y2] - - def __call__(self, inputs) -> Any: - img = LoadImage.convert_to_ndarray(inputs) - h, w, c = img.shape - img_rgb = copy.deepcopy(img) - img_rgb = img_rgb[:, :, ::-1] - det_result = self.face_detection(img_rgb) - - bboxes = np.array(det_result[OutputKeys.BOXES]) - if bboxes.shape[0] == 0: - logger.warning('No face detected!') - results = { - OutputKeys.KEYPOINTS: [], - OutputKeys.POSES: [], - OutputKeys.BOXES: [] - } - return results - - boxes, keypoints = self._choose_face(det_result) - - output_boxes = [] - output_keypoints = [] - output_poses = [] - for index, box_ori in enumerate(boxes): - box = self.expend_box(box_ori, w, h, scalex=0.1, scaley=0.1) - y0 = int(box[1]) - y1 = int(box[3]) - x0 = int(box[0]) - x1 = int(box[2]) - sub_img = img[y0:y1, x0:x1] - - keypoint = keypoints[index] - pts = [[keypoint[0], keypoint[1]], [keypoint[2], keypoint[3]], - [keypoint[4], keypoint[5]], [keypoint[6], keypoint[7]], - [keypoint[8], keypoint[9]], [box[0], box[1]], - [box[2], box[1]], [box[0], box[3]], [box[2], box[3]]] - # radian - angle = math.atan2((pts[1][1] - pts[0][1]), - (pts[1][0] - pts[0][0])) - # angle - theta = angle * (180 / np.pi) - - center = [w // 2, h // 2] - cx, cy = center - M, landmark_ = self.rotate_point(theta, (cx, cy), pts) - sub_imgT, imgT, bbox = self.rotate_crop_img(img, landmark_, M) - - outputs = self.predict_op([sub_imgT])[0] - tmp_keypoints = outputs['point'] - - for idx in range(0, len(tmp_keypoints)): - tmp_keypoints[idx][0] += bbox[0] - tmp_keypoints[idx][1] += bbox[1] - - for idx in range(0, 6): - sub_img, bbox = self.crop_img(imgT, tmp_keypoints) - outputs = self.predict_op([sub_img])[0] - tmp_keypoints = outputs['point'] - for idx in range(0, len(tmp_keypoints)): - tmp_keypoints[idx][0] += bbox[0] - tmp_keypoints[idx][1] += bbox[1] - - M2, tmp_keypoints = self.rotate_point(-theta, (cx, cy), - tmp_keypoints) - - output_keypoints.append(np.array(tmp_keypoints)) - output_poses.append(np.array(outputs['pose'])) - output_boxes.append(np.array(box_ori)) - - results = { - OutputKeys.KEYPOINTS: output_keypoints, - OutputKeys.POSES: output_poses, - OutputKeys.BOXES: output_boxes - } - - return results diff --git a/modelscope/pipelines/cv/easycv_pipelines/human_wholebody_keypoint_pipeline.py b/modelscope/pipelines/cv/easycv_pipelines/human_wholebody_keypoint_pipeline.py deleted file mode 100644 index 903c4106..00000000 --- a/modelscope/pipelines/cv/easycv_pipelines/human_wholebody_keypoint_pipeline.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import os.path -from typing import Any - -from modelscope.metainfo import Pipelines -from modelscope.outputs import OutputKeys -from modelscope.pipelines.builder import PIPELINES -from modelscope.utils.constant import ModelFile, Tasks -from .base import EasyCVPipeline - - -@PIPELINES.register_module( - Tasks.human_wholebody_keypoint, - module_name=Pipelines.human_wholebody_keypoint) -class HumanWholebodyKeypointsPipeline(EasyCVPipeline): - """Pipeline for human wholebody 2d keypoints detection.""" - - def __init__(self, - model: str, - model_file_pattern=ModelFile.TORCH_MODEL_FILE, - *args, - **kwargs): - """ - model (str): model id on modelscope hub or local model path. - model_file_pattern (str): model file pattern. - """ - super(HumanWholebodyKeypointsPipeline, self).__init__( - model=model, - model_file_pattern=model_file_pattern, - *args, - **kwargs) - - def _build_predict_op(self, **kwargs): - """Build EasyCV predictor.""" - from easycv.predictors.builder import build_predictor - detection_predictor_type = self.cfg['DETECTION']['type'] - detection_model_path = os.path.join( - self.model_dir, self.cfg['DETECTION']['model_path']) - detection_cfg_file = os.path.join(self.model_dir, - self.cfg['DETECTION']['config_file']) - detection_score_threshold = self.cfg['DETECTION']['score_threshold'] - self.cfg.pipeline.predictor_config[ - 'detection_predictor_config'] = dict( - type=detection_predictor_type, - model_path=detection_model_path, - config_file=detection_cfg_file, - score_threshold=detection_score_threshold) - easycv_config = self._to_easycv_config() - pipeline_op = build_predictor(self.cfg.pipeline.predictor_config, { - 'model_path': self.model_path, - 'config_file': easycv_config, - **kwargs - }) - return pipeline_op - - def __call__(self, inputs) -> Any: - outputs = self.predict_op(inputs) - - results = [{ - OutputKeys.KEYPOINTS: output['keypoints'], - OutputKeys.BOXES: output['boxes'] - } for output in outputs] - - if self._is_single_inputs(inputs): - results = results[0] - - return results diff --git a/modelscope/pipelines/cv/easycv_pipelines/segmentation_pipeline.py b/modelscope/pipelines/cv/easycv_pipelines/segmentation_pipeline.py deleted file mode 100644 index bd09fc9b..00000000 --- a/modelscope/pipelines/cv/easycv_pipelines/segmentation_pipeline.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import Any - -import numpy as np - -from modelscope.metainfo import Pipelines -from modelscope.outputs import OutputKeys -from modelscope.pipelines.builder import PIPELINES -from modelscope.utils.constant import Tasks -from .base import EasyCVPipeline - - -@PIPELINES.register_module( - Tasks.image_segmentation, module_name=Pipelines.easycv_segmentation) -class EasyCVSegmentationPipeline(EasyCVPipeline): - """Pipeline for easycv segmentation task.""" - - def __init__(self, model: str, model_file_pattern='*.pt', *args, **kwargs): - """ - model (str): model id on modelscope hub or local model path. - model_file_pattern (str): model file pattern. - """ - - super(EasyCVSegmentationPipeline, self).__init__( - model=model, - model_file_pattern=model_file_pattern, - *args, - **kwargs) - - def __call__(self, inputs) -> Any: - outputs = self.predict_op(inputs) - - semantic_result = outputs[0]['seg_pred'] - - ids = np.unique(semantic_result)[::-1] - legal_indices = ids != len(self.predict_op.CLASSES) # for VOID label - ids = ids[legal_indices] - segms = (semantic_result[None] == ids[:, None, None]) - masks = [it.astype(np.int) for it in segms] - labels_txt = np.array(self.predict_op.CLASSES)[ids].tolist() - - results = { - OutputKeys.MASKS: masks, - OutputKeys.LABELS: labels_txt, - OutputKeys.SCORES: [0.999 for _ in range(len(labels_txt))] - } - return results diff --git a/modelscope/pipelines/cv/hand_2d_keypoints_pipeline.py b/modelscope/pipelines/cv/hand_2d_keypoints_pipeline.py deleted file mode 100644 index 63281e80..00000000 --- a/modelscope/pipelines/cv/hand_2d_keypoints_pipeline.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import os.path - -from modelscope.metainfo import Pipelines -from modelscope.pipelines.builder import PIPELINES -from modelscope.utils.constant import ModelFile, Tasks -from .easycv_pipelines.base import EasyCVPipeline - - -@PIPELINES.register_module( - Tasks.hand_2d_keypoints, module_name=Pipelines.hand_2d_keypoints) -class Hand2DKeypointsPipeline(EasyCVPipeline): - """Pipeline for hand pose keypoint task.""" - - def __init__(self, - model: str, - model_file_pattern=ModelFile.TORCH_MODEL_FILE, - *args, - **kwargs): - """ - model (str): model id on modelscope hub or local model path. - model_file_pattern (str): model file pattern. - """ - super(Hand2DKeypointsPipeline, self).__init__( - model=model, - model_file_pattern=model_file_pattern, - *args, - **kwargs) - - def _build_predict_op(self, **kwargs): - """Build EasyCV predictor.""" - from easycv.predictors.builder import build_predictor - detection_predictor_type = self.cfg['DETECTION']['type'] - detection_model_path = os.path.join( - self.model_dir, self.cfg['DETECTION']['model_path']) - detection_cfg_file = os.path.join(self.model_dir, - self.cfg['DETECTION']['config_file']) - detection_score_threshold = self.cfg['DETECTION']['score_threshold'] - self.cfg.pipeline.predictor_config[ - 'detection_predictor_config'] = dict( - type=detection_predictor_type, - model_path=detection_model_path, - config_file=detection_cfg_file, - score_threshold=detection_score_threshold) - easycv_config = self._to_easycv_config() - pipeline_op = build_predictor(self.cfg.pipeline.predictor_config, { - 'model_path': self.model_path, - 'config_file': easycv_config, - **kwargs - }) - return pipeline_op diff --git a/modelscope/pipelines/cv/image_panoptic_segmentation_pipeline.py b/modelscope/pipelines/cv/image_panoptic_segmentation_pipeline.py deleted file mode 100644 index fe941d9f..00000000 --- a/modelscope/pipelines/cv/image_panoptic_segmentation_pipeline.py +++ /dev/null @@ -1,135 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import Any, Dict, Union - -import cv2 -import numpy as np -import PIL -import torch - -from modelscope.metainfo import Pipelines -from modelscope.outputs import OutputKeys -from modelscope.pipelines.base import Input, Pipeline -from modelscope.pipelines.builder import PIPELINES -from modelscope.pipelines.cv.easycv_pipelines.base import EasyCVPipeline -from modelscope.preprocessors import load_image -from modelscope.utils.constant import Tasks -from modelscope.utils.logger import get_logger - -logger = get_logger() - - -@PIPELINES.register_module( - Tasks.image_segmentation, - module_name=Pipelines.image_panoptic_segmentation) -class ImagePanopticSegmentationPipeline(Pipeline): - - def __init__(self, model: str, **kwargs): - """ - use `model` to create a image panoptic segmentation pipeline for prediction - Args: - model: model id on modelscope hub. - """ - super().__init__(model=model, **kwargs) - - logger.info('panoptic segmentation model, pipeline init') - - def preprocess(self, input: Input) -> Dict[str, Any]: - from mmdet.datasets.pipelines import Compose - from mmcv.parallel import collate, scatter - from mmdet.datasets import replace_ImageToTensor - - cfg = self.model.cfg - # build the data pipeline - - if isinstance(input, str): - cfg.data.test.pipeline[0].type = 'LoadImageFromWebcam' - img = np.array(load_image(input)) - img = img[:, :, ::-1] # convert to bgr - elif isinstance(input, PIL.Image.Image): - cfg.data.test.pipeline[0].type = 'LoadImageFromWebcam' - img = np.array(input.convert('RGB')) - elif isinstance(input, np.ndarray): - cfg.data.test.pipeline[0].type = 'LoadImageFromWebcam' - if len(input.shape) == 2: - img = cv2.cvtColor(input, cv2.COLOR_GRAY2BGR) - else: - img = input - else: - raise TypeError(f'input should be either str, PIL.Image,' - f' np.array, but got {type(input)}') - - # collect data - data = dict(img=img) - cfg.data.test.pipeline = replace_ImageToTensor(cfg.data.test.pipeline) - test_pipeline = Compose(cfg.data.test.pipeline) - - data = test_pipeline(data) - # copy from mmdet_model collect data - data = collate([data], samples_per_gpu=1) - data['img_metas'] = [ - img_metas.data[0] for img_metas in data['img_metas'] - ] - data['img'] = [img.data[0] for img in data['img']] - if next(self.model.parameters()).is_cuda: - # scatter to specified GPU - data = scatter(data, [next(self.model.parameters()).device])[0] - - return data - - def forward(self, input: Dict[str, Any]) -> Dict[str, Any]: - results = self.model.inference(input) - - return results - - def postprocess(self, inputs: Dict[str, Any]) -> Dict[str, Any]: - # bz=1, tcguo - pan_results = inputs[0]['pan_results'] - INSTANCE_OFFSET = 1000 - - ids = np.unique(pan_results)[::-1] - legal_indices = ids != self.model.num_classes # for VOID label - ids = ids[legal_indices] - labels = np.array([id % INSTANCE_OFFSET for id in ids], dtype=np.int64) - segms = (pan_results[None] == ids[:, None, None]) - masks = [it.astype(np.int) for it in segms] - labels_txt = np.array(self.model.CLASSES)[labels].tolist() - - outputs = { - OutputKeys.MASKS: masks, - OutputKeys.LABELS: labels_txt, - OutputKeys.SCORES: [0.999 for _ in range(len(labels_txt))] - } - return outputs - - -@PIPELINES.register_module( - Tasks.image_segmentation, - module_name=Pipelines.image_panoptic_segmentation_easycv) -class ImagePanopticSegmentationEasyCVPipeline(EasyCVPipeline): - """Pipeline built upon easycv for image segmentation.""" - - def __init__(self, model: str, model_file_pattern='*.pt', *args, **kwargs): - """ - model (str): model id on modelscope hub or local model path. - model_file_pattern (str): model file pattern. - """ - super(ImagePanopticSegmentationEasyCVPipeline, self).__init__( - model=model, - model_file_pattern=model_file_pattern, - *args, - **kwargs) - - def __call__(self, inputs) -> Any: - outputs = self.predict_op(inputs) - easycv_results = outputs[0] - - results = { - OutputKeys.MASKS: - easycv_results[OutputKeys.MASKS], - OutputKeys.LABELS: - easycv_results[OutputKeys.LABELS], - OutputKeys.SCORES: - [0.999 for _ in range(len(easycv_results[OutputKeys.LABELS]))] - } - - return results diff --git a/modelscope/trainers/easycv/__init__.py b/modelscope/trainers/easycv/__init__.py deleted file mode 100644 index b1b8fc15..00000000 --- a/modelscope/trainers/easycv/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .utils import AddLrLogHook, EasyCVMetric -else: - _import_structure = {'utils': ['AddLrLogHook', 'EasyCVMetric']} - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/trainers/easycv/trainer.py b/modelscope/trainers/easycv/trainer.py deleted file mode 100644 index 58d6a440..00000000 --- a/modelscope/trainers/easycv/trainer.py +++ /dev/null @@ -1,183 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from copy import deepcopy -from functools import partial -from typing import Callable, Optional, Tuple, Union - -import torch -from easycv.utils.checkpoint import load_checkpoint as ev_load_checkpoint -from torch import nn -from torch.utils.data import Dataset - -from modelscope.metainfo import Trainers -from modelscope.models.base import TorchModel -from modelscope.msdatasets import MsDataset -from modelscope.preprocessors import Preprocessor -from modelscope.trainers import EpochBasedTrainer -from modelscope.trainers.base import TRAINERS -from modelscope.trainers.easycv.utils import register_util -from modelscope.trainers.hooks import HOOKS -from modelscope.trainers.parallel.builder import build_parallel -from modelscope.trainers.parallel.utils import is_parallel -from modelscope.utils.config import Config -from modelscope.utils.constant import DEFAULT_MODEL_REVISION -from modelscope.utils.import_utils import LazyImportModule -from modelscope.utils.registry import default_group - - -@TRAINERS.register_module(module_name=Trainers.easycv) -class EasyCVEpochBasedTrainer(EpochBasedTrainer): - """Epoch based Trainer for EasyCV. - - Args: - cfg_file(str): The config file of EasyCV. - model (:obj:`torch.nn.Module` or :obj:`TorchModel` or `str`): The model to be run, or a valid model dir - or a model id. If model is None, build_model method will be called. - train_dataset (`MsDataset` or `torch.utils.data.Dataset`, *optional*): - The dataset to use for training. - Note that if it's a `torch.utils.data.IterableDataset` with some randomization and you are training in a - distributed fashion, your iterable dataset should either use a internal attribute `generator` that is a - `torch.Generator` for the randomization that must be identical on all processes (and the Trainer will - manually set the seed of this `generator` at each epoch) or have a `set_epoch()` method that internally - sets the seed of the RNGs used. - eval_dataset (`MsDataset` or `torch.utils.data.Dataset`, *optional*): The dataset to use for evaluation. - preprocessor (:obj:`Preprocessor`, *optional*): The optional preprocessor. - NOTE: If the preprocessor has been called before the dataset fed into this trainer by user's custom code, - this parameter should be None, meanwhile remove the 'preprocessor' key from the cfg_file. - Else the preprocessor will be instantiated from the cfg_file or assigned from this parameter and - this preprocessing action will be executed every time the dataset's __getitem__ is called. - optimizers (`Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler._LRScheduler]`, *optional*): A tuple - containing the optimizer and the scheduler to use. - max_epochs: (int, optional): Total training epochs. - """ - - def __init__( - self, - cfg_file: Optional[str] = None, - model: Optional[Union[TorchModel, nn.Module, str]] = None, - arg_parse_fn: Optional[Callable] = None, - train_dataset: Optional[Union[MsDataset, Dataset]] = None, - eval_dataset: Optional[Union[MsDataset, Dataset]] = None, - preprocessor: Optional[Preprocessor] = None, - optimizers: Tuple[torch.optim.Optimizer, - torch.optim.lr_scheduler._LRScheduler] = (None, - None), - model_revision: Optional[str] = DEFAULT_MODEL_REVISION, - **kwargs): - - register_util.register_parallel() - register_util.register_part_mmcv_hooks_to_ms() - - super(EasyCVEpochBasedTrainer, self).__init__( - model=model, - cfg_file=cfg_file, - arg_parse_fn=arg_parse_fn, - preprocessor=preprocessor, - optimizers=optimizers, - model_revision=model_revision, - train_dataset=train_dataset, - eval_dataset=eval_dataset, - **kwargs) - - # reset data_collator - from mmcv.parallel import collate - - self.train_data_collator = partial( - collate, - samples_per_gpu=self.cfg.train.dataloader.batch_size_per_gpu) - self.eval_data_collator = partial( - collate, - samples_per_gpu=self.cfg.evaluation.dataloader.batch_size_per_gpu) - - # load pretrained model - load_from = self.cfg.get('load_from', None) - if load_from is not None: - ev_load_checkpoint( - self.model, - filename=load_from, - map_location=self.device, - strict=False, - ) - - # reset parallel - if not self._dist: - assert not is_parallel( - self.model - ), 'Not support model wrapped by custom parallel if not in distributed mode!' - dp_cfg = dict( - type='MMDataParallel', - module=self.model, - device_ids=[torch.cuda.current_device()]) - self.model = build_parallel(dp_cfg) - - def rebuild_config(self, cfg: Config): - cfg = super().rebuild_config(cfg) - # Register easycv hooks dynamicly. If the hook already exists in modelscope, - # the hook in modelscope will be used, otherwise register easycv hook into ms. - # We must manually trigger lazy import to detect whether the hook is in modelscope. - # TODO: use ast index to detect whether the hook is in modelscope - for h_i in cfg.train.get('hooks', []): - sig = ('HOOKS', default_group, h_i['type']) - LazyImportModule.import_module(sig) - if h_i['type'] not in HOOKS._modules[default_group]: - if h_i['type'] in [ - 'TensorboardLoggerHookV2', 'WandbLoggerHookV2' - ]: - raise ValueError( - 'Not support hook %s now, we will support it in the future!' - % h_i['type']) - register_util.register_hook_to_ms(h_i['type']) - return cfg - - def create_optimizer_and_scheduler(self): - """ Create optimizer and lr scheduler - """ - optimizer, lr_scheduler = self.optimizers - if optimizer is None: - optimizer_cfg = self.cfg.train.get('optimizer', None) - else: - optimizer_cfg = None - - optim_options = {} - if optimizer_cfg is not None: - optim_options = optimizer_cfg.pop('options', {}) - from easycv.apis.train import build_optimizer - optimizer = build_optimizer(self.model, optimizer_cfg) - - if lr_scheduler is None: - lr_scheduler_cfg = self.cfg.train.get('lr_scheduler', None) - else: - lr_scheduler_cfg = None - - lr_options = {} - # Adapt to mmcv lr scheduler hook. - # Please refer to: https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py - if lr_scheduler_cfg is not None: - assert optimizer is not None - lr_options = lr_scheduler_cfg.pop('options', {}) - assert 'policy' in lr_scheduler_cfg - policy_type = lr_scheduler_cfg.pop('policy') - if policy_type == policy_type.lower(): - policy_type = policy_type.title() - hook_type = policy_type + 'LrUpdaterHook' - lr_scheduler_cfg['type'] = hook_type - - self.cfg.train.lr_scheduler_hook = lr_scheduler_cfg - - self.optimizer = optimizer - self.lr_scheduler = lr_scheduler - - return self.optimizer, self.lr_scheduler, optim_options, lr_options - - def to_parallel(self, model) -> Union[nn.Module, TorchModel]: - if self.cfg.get('parallel', None) is not None: - dp_cfg = deepcopy(self.cfg['parallel']) - dp_cfg.update( - dict(module=model, device_ids=[torch.cuda.current_device()])) - return build_parallel(dp_cfg) - - dp_cfg = dict( - type='MMDistributedDataParallel', - module=model, - device_ids=[torch.cuda.current_device()]) - - return build_parallel(dp_cfg) diff --git a/modelscope/trainers/easycv/utils/__init__.py b/modelscope/trainers/easycv/utils/__init__.py deleted file mode 100644 index 23cfa36a..00000000 --- a/modelscope/trainers/easycv/utils/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from typing import TYPE_CHECKING - -from modelscope.utils.import_utils import LazyImportModule - -if TYPE_CHECKING: - from .hooks import AddLrLogHook - from .metric import EasyCVMetric - -else: - _import_structure = {'hooks': ['AddLrLogHook'], 'metric': ['EasyCVMetric']} - - import sys - - sys.modules[__name__] = LazyImportModule( - __name__, - globals()['__file__'], - _import_structure, - module_spec=__spec__, - extra_objects={}, - ) diff --git a/modelscope/trainers/easycv/utils/hooks.py b/modelscope/trainers/easycv/utils/hooks.py deleted file mode 100644 index 1f1a5c95..00000000 --- a/modelscope/trainers/easycv/utils/hooks.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -from modelscope.trainers.hooks import HOOKS, Priority -from modelscope.trainers.hooks.lr_scheduler_hook import LrSchedulerHook -from modelscope.utils.constant import LogKeys - - -@HOOKS.register_module(module_name='AddLrLogHook') -class AddLrLogHook(LrSchedulerHook): - """For EasyCV to adapt to ModelScope, the lr log of EasyCV is added in the trainer, - but the trainer of ModelScope does not and it is added in the lr scheduler hook. - But The lr scheduler hook used by EasyCV is the hook of mmcv, and there is no lr log. - It will be deleted in the future. - """ - PRIORITY = Priority.NORMAL - - def __init__(self): - pass - - def before_run(self, trainer): - pass - - def after_train_iter(self, trainer): - trainer.log_buffer.output[LogKeys.LR] = self._get_log_lr(trainer) - - def before_train_epoch(self, trainer): - trainer.log_buffer.output[LogKeys.LR] = self._get_log_lr(trainer) - - def after_train_epoch(self, trainer): - pass diff --git a/modelscope/trainers/easycv/utils/metric.py b/modelscope/trainers/easycv/utils/metric.py deleted file mode 100644 index d952ec3e..00000000 --- a/modelscope/trainers/easycv/utils/metric.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import itertools -from typing import Dict - -import numpy as np -import torch - -from modelscope.metrics.base import Metric -from modelscope.metrics.builder import METRICS - - -@METRICS.register_module(module_name='EasyCVMetric') -class EasyCVMetric(Metric): - """Adapt to ModelScope Metric for EasyCV evaluator. - """ - - def __init__(self, trainer=None, evaluators=None, *args, **kwargs): - from easycv.core.evaluation.builder import build_evaluator - - self.trainer = trainer - self.evaluators = build_evaluator(evaluators) - self.preds = [] - self.grountruths = [] - - def add(self, outputs: Dict, inputs: Dict): - self.preds.append(outputs) - del inputs - - def evaluate(self): - results = {} - for _, batch in enumerate(self.preds): - for k, v in batch.items(): - if k not in results: - results[k] = [] - results[k].append(v) - - for k, v in results.items(): - if len(v) == 0: - raise ValueError(f'empty result for {k}') - - if isinstance(v[0], torch.Tensor): - results[k] = torch.cat(v, 0) - elif isinstance(v[0], (list, np.ndarray)): - results[k] = list(itertools.chain.from_iterable(v)) - else: - raise ValueError( - f'value of batch prediction dict should only be tensor or list, {k} type is {v[0]}' - ) - - metric_values = self.trainer.eval_dataset.evaluate( - results, self.evaluators) - return metric_values - - def merge(self, other: 'EasyCVMetric'): - self.preds.extend(other.preds) - - def __getstate__(self): - return self.preds - - def __setstate__(self, state): - self.__init__() - self.preds = state diff --git a/modelscope/trainers/easycv/utils/register_util.py b/modelscope/trainers/easycv/utils/register_util.py deleted file mode 100644 index 04bf719b..00000000 --- a/modelscope/trainers/easycv/utils/register_util.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import inspect -import logging - -from modelscope.trainers.hooks import HOOKS -from modelscope.trainers.parallel.builder import PARALLEL -from modelscope.utils.registry import default_group - - -class _RegisterManager: - - def __init__(self): - self.registries = {} - - def add(self, module, name, group_key=default_group): - if module.name not in self.registries: - self.registries[module.name] = {} - if group_key not in self.registries[module.name]: - self.registries[module.name][group_key] = [] - - self.registries[module.name][group_key].append(name) - - def exists(self, module, name, group_key=default_group): - if self.registries.get(module.name, None) is None: - return False - if self.registries[module.name].get(group_key, None) is None: - return False - if name in self.registries[module.name][group_key]: - return True - - return False - - -_dynamic_register = _RegisterManager() - - -def register_parallel(): - from mmcv.parallel import MMDistributedDataParallel, MMDataParallel - - mmddp = 'MMDistributedDataParallel' - mmdp = 'MMDataParallel' - - if not _dynamic_register.exists(PARALLEL, mmddp): - _dynamic_register.add(PARALLEL, mmddp) - PARALLEL.register_module( - module_name=mmddp, module_cls=MMDistributedDataParallel) - if not _dynamic_register.exists(PARALLEL, mmdp): - _dynamic_register.add(PARALLEL, mmdp) - PARALLEL.register_module(module_name=mmdp, module_cls=MMDataParallel) - - -def register_hook_to_ms(hook_name, logger=None): - """Register EasyCV hook to ModelScope.""" - from easycv.hooks import HOOKS as _EV_HOOKS - - if hook_name not in _EV_HOOKS._module_dict: - raise ValueError( - f'Not found hook "{hook_name}" in EasyCV hook registries!') - - if _dynamic_register.exists(HOOKS, hook_name): - return - _dynamic_register.add(HOOKS, hook_name) - - obj = _EV_HOOKS._module_dict[hook_name] - HOOKS.register_module(module_name=hook_name, module_cls=obj) - - log_str = f'Register hook "{hook_name}" to modelscope hooks.' - logger.info(log_str) if logger is not None else logging.info(log_str) - - -def register_part_mmcv_hooks_to_ms(): - """Register required mmcv hooks to ModelScope. - Currently we only registered all lr scheduler hooks in EasyCV and mmcv. - Please refer to: - EasyCV: https://github.com/alibaba/EasyCV/blob/master/easycv/hooks/lr_update_hook.py - mmcv: https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py - """ - from mmcv.runner.hooks import lr_updater - from mmcv.runner.hooks import HOOKS as _MMCV_HOOKS - from easycv.hooks import StepFixCosineAnnealingLrUpdaterHook, YOLOXLrUpdaterHook - - mmcv_hooks_in_easycv = [('StepFixCosineAnnealingLrUpdaterHook', - StepFixCosineAnnealingLrUpdaterHook), - ('YOLOXLrUpdaterHook', YOLOXLrUpdaterHook)] - - members = inspect.getmembers(lr_updater) - members.extend(mmcv_hooks_in_easycv) - - for name, obj in members: - if name in _MMCV_HOOKS._module_dict: - if _dynamic_register.exists(HOOKS, name): - continue - _dynamic_register.add(HOOKS, name) - HOOKS.register_module( - module_name=name, - module_cls=obj, - ) diff --git a/tests/msdatasets/test_ms_dataset.py b/tests/msdatasets/test_ms_dataset.py index 8ded9a46..52b015ec 100644 --- a/tests/msdatasets/test_ms_dataset.py +++ b/tests/msdatasets/test_ms_dataset.py @@ -195,17 +195,6 @@ class MsDatasetTest(unittest.TestCase): ) print(next(iter(tf_dataset))) - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_streaming_load_coco(self): - small_coco_for_test = MsDataset.load( - dataset_name='EasyCV/small_coco_for_test', - split='train', - use_streaming=True, - download_mode=DownloadMode.FORCE_REDOWNLOAD) - dataset_sample_dict = next(iter(small_coco_for_test)) - print(dataset_sample_dict) - assert dataset_sample_dict.values() - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') def test_streaming_load_uni_fold(self): """Test case for loading large scale datasets.""" diff --git a/tests/pipelines/easycv_pipelines/__init__.py b/tests/pipelines/easycv_pipelines/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/pipelines/easycv_pipelines/test_panoptic_segmentation_pipeline.py b/tests/pipelines/easycv_pipelines/test_panoptic_segmentation_pipeline.py deleted file mode 100644 index 49e01251..00000000 --- a/tests/pipelines/easycv_pipelines/test_panoptic_segmentation_pipeline.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import unittest - -import cv2 - -from modelscope.outputs import OutputKeys -from modelscope.pipelines import pipeline -from modelscope.utils.constant import Tasks -from modelscope.utils.cv.image_utils import panoptic_seg_masks_to_image -from modelscope.utils.demo_utils import DemoCompatibilityCheck -from modelscope.utils.test_utils import test_level - - -class EasyCVPanopticSegmentationPipelineTest(unittest.TestCase, - DemoCompatibilityCheck): - img_path = 'data/test/images/image_semantic_segmentation.jpg' - - def setUp(self) -> None: - self.task = Tasks.image_segmentation - self.model_id = 'damo/cv_r50_panoptic-segmentation_cocopan' - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_r50(self): - segmentor = pipeline(task=self.task, model=self.model_id) - outputs = segmentor(self.img_path) - draw_img = panoptic_seg_masks_to_image(outputs[OutputKeys.MASKS]) - cv2.imwrite('result.jpg', draw_img) - print('print ' + self.model_id + ' success') - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_demo_compatibility(self): - self.compatibility_check() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/pipelines/easycv_pipelines/test_segmentation_pipeline.py b/tests/pipelines/easycv_pipelines/test_segmentation_pipeline.py deleted file mode 100644 index 5f6dac4b..00000000 --- a/tests/pipelines/easycv_pipelines/test_segmentation_pipeline.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import unittest -from distutils.version import LooseVersion - -import cv2 -import easycv -import numpy as np -from PIL import Image - -from modelscope.outputs import OutputKeys -from modelscope.pipelines import pipeline -from modelscope.utils.constant import Tasks -from modelscope.utils.cv.image_utils import semantic_seg_masks_to_image -from modelscope.utils.demo_utils import DemoCompatibilityCheck -from modelscope.utils.test_utils import test_level - - -class EasyCVSegmentationPipelineTest(unittest.TestCase, - DemoCompatibilityCheck): - img_path = 'data/test/images/image_segmentation.jpg' - - def setUp(self) -> None: - self.task = Tasks.image_segmentation - self.model_id = 'damo/cv_segformer-b0_image_semantic-segmentation_coco-stuff164k' - - def _internal_test_(self, model_id): - semantic_seg = pipeline(task=Tasks.image_segmentation, model=model_id) - outputs = semantic_seg(self.img_path) - - draw_img = semantic_seg_masks_to_image(outputs[OutputKeys.MASKS]) - cv2.imwrite('result.jpg', draw_img) - print('test ' + model_id + ' DONE') - - def _internal_test_batch_(self, model_id, num_samples=2, batch_size=2): - # TODO: support in the future - img = np.asarray(Image.open(self.img_path)) - num_samples = num_samples - batch_size = batch_size - semantic_seg = pipeline( - task=Tasks.image_segmentation, - model=model_id, - batch_size=batch_size) - outputs = semantic_seg([self.img_path] * num_samples) - - self.assertEqual(semantic_seg.predict_op.batch_size, batch_size) - self.assertEqual(len(outputs), num_samples) - - for output in outputs: - self.assertListEqual( - list(img.shape)[:2], list(output['seg_pred'].shape)) - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_segformer_b0(self): - model_id = 'damo/cv_segformer-b0_image_semantic-segmentation_coco-stuff164k' - self._internal_test_(model_id) - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_segformer_b1(self): - model_id = 'damo/cv_segformer-b1_image_semantic-segmentation_coco-stuff164k' - self._internal_test_(model_id) - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_segformer_b2(self): - model_id = 'damo/cv_segformer-b2_image_semantic-segmentation_coco-stuff164k' - self._internal_test_(model_id) - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_segformer_b3(self): - model_id = 'damo/cv_segformer-b3_image_semantic-segmentation_coco-stuff164k' - self._internal_test_(model_id) - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_segformer_b4(self): - model_id = 'damo/cv_segformer-b4_image_semantic-segmentation_coco-stuff164k' - self._internal_test_(model_id) - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_segformer_b5(self): - model_id = 'damo/cv_segformer-b5_image_semantic-segmentation_coco-stuff164k' - self._internal_test_(model_id) - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_demo_compatibility(self): - self.compatibility_check() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/easycv/__init__.py b/tests/trainers/easycv/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/trainers/easycv/test_easycv_trainer.py b/tests/trainers/easycv/test_easycv_trainer.py deleted file mode 100644 index 11f9a739..00000000 --- a/tests/trainers/easycv/test_easycv_trainer.py +++ /dev/null @@ -1,238 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import shutil -import tempfile -import unittest - -import json -import torch - -from modelscope.metainfo import Models, Pipelines, Trainers -from modelscope.msdatasets import MsDataset -from modelscope.trainers import build_trainer -from modelscope.utils.config import Config -from modelscope.utils.constant import LogKeys, ModeKeys, Tasks -from modelscope.utils.logger import get_logger -from modelscope.utils.test_utils import DistributedTestCase, test_level -from modelscope.utils.torch_utils import is_master - - -def train_func(work_dir, dist=False, log_interval=3, imgs_per_gpu=4): - import easycv - config_path = os.path.join( - os.path.dirname(easycv.__file__), - 'configs/detection/yolox/yolox_s_8xb16_300e_coco.py') - - cfg = Config.from_file(config_path) - - cfg.log_config.update( - dict(hooks=[ - dict(type='TextLoggerHook'), - dict(type='TensorboardLoggerHook') - ])) # not support TensorboardLoggerHookV2 - - ms_cfg_file = os.path.join(work_dir, 'ms_yolox_s_8xb16_300e_coco.json') - from easycv.utils.ms_utils import to_ms_config - - if is_master(): - to_ms_config( - cfg, - dump=True, - task=Tasks.image_object_detection, - ms_model_name=Models.yolox, - pipeline_name=Pipelines.easycv_detection, - save_path=ms_cfg_file) - - trainer_name = Trainers.easycv - train_dataset = MsDataset.load( - dataset_name='small_coco_for_test', namespace='EasyCV', split='train') - eval_dataset = MsDataset.load( - dataset_name='small_coco_for_test', - namespace='EasyCV', - split='validation') - - cfg_options = { - 'train.max_epochs': - 2, - 'train.dataloader.batch_size_per_gpu': - imgs_per_gpu, - 'evaluation.dataloader.batch_size_per_gpu': - 2, - 'train.hooks': [ - { - 'type': 'CheckpointHook', - 'interval': 1 - }, - { - 'type': 'EvaluationHook', - 'interval': 1 - }, - { - 'type': 'TextLoggerHook', - 'ignore_rounding_keys': None, - 'interval': log_interval - }, - ] - } - kwargs = dict( - cfg_file=ms_cfg_file, - train_dataset=train_dataset, - eval_dataset=eval_dataset, - work_dir=work_dir, - cfg_options=cfg_options, - launcher='pytorch' if dist else None) - - trainer = build_trainer(trainer_name, kwargs) - trainer.train() - - -@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest') -class EasyCVTrainerTestSingleGpu(unittest.TestCase): - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - self.tmp_dir = tempfile.TemporaryDirectory().name - if not os.path.exists(self.tmp_dir): - os.makedirs(self.tmp_dir) - - def tearDown(self): - super().tearDown() - shutil.rmtree(self.tmp_dir, ignore_errors=True) - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_single_gpu(self): - train_func(self.tmp_dir) - - results_files = os.listdir(self.tmp_dir) - json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json')) - self.assertEqual(len(json_files), 1) - - with open(json_files[0], 'r', encoding='utf-8') as f: - lines = [i.strip() for i in f.readlines()] - - self.assertDictContainsSubset( - { - LogKeys.MODE: ModeKeys.TRAIN, - LogKeys.EPOCH: 1, - LogKeys.ITER: 3, - LogKeys.LR: 0.00029 - }, json.loads(lines[0])) - self.assertDictContainsSubset( - { - LogKeys.MODE: ModeKeys.EVAL, - LogKeys.EPOCH: 1, - LogKeys.ITER: 10 - }, json.loads(lines[1])) - self.assertDictContainsSubset( - { - LogKeys.MODE: ModeKeys.TRAIN, - LogKeys.EPOCH: 2, - LogKeys.ITER: 3, - LogKeys.LR: 0.00205 - }, json.loads(lines[2])) - self.assertDictContainsSubset( - { - LogKeys.MODE: ModeKeys.EVAL, - LogKeys.EPOCH: 2, - LogKeys.ITER: 10 - }, json.loads(lines[3])) - self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files) - self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files) - for i in [0, 2]: - self.assertIn(LogKeys.DATA_LOAD_TIME, lines[i]) - self.assertIn(LogKeys.ITER_TIME, lines[i]) - self.assertIn(LogKeys.MEMORY, lines[i]) - self.assertIn('total_loss', lines[i]) - for i in [1, 3]: - self.assertIn( - 'CocoDetectionEvaluator_DetectionBoxes_Precision/mAP', - lines[i]) - self.assertIn('DetectionBoxes_Precision/mAP', lines[i]) - self.assertIn('DetectionBoxes_Precision/mAP@.50IOU', lines[i]) - self.assertIn('DetectionBoxes_Precision/mAP@.75IOU', lines[i]) - self.assertIn('DetectionBoxes_Precision/mAP (small)', lines[i]) - - -@unittest.skipIf(not torch.cuda.is_available() - or torch.cuda.device_count() <= 1, 'distributed unittest') -class EasyCVTrainerTestMultiGpus(DistributedTestCase): - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - self.tmp_dir = tempfile.TemporaryDirectory().name - if not os.path.exists(self.tmp_dir): - os.makedirs(self.tmp_dir) - - def tearDown(self): - super().tearDown() - shutil.rmtree(self.tmp_dir, ignore_errors=True) - - @unittest.skipUnless(test_level() >= 2, 'skip test in current test level') - def test_multi_gpus(self): - self.start( - train_func, - num_gpus=2, - work_dir=self.tmp_dir, - dist=True, - log_interval=2, - imgs_per_gpu=5) - - results_files = os.listdir(self.tmp_dir) - json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json')) - self.assertEqual(len(json_files), 1) - - with open(json_files[0], 'r', encoding='utf-8') as f: - lines = [i.strip() for i in f.readlines()] - - self.assertDictContainsSubset( - { - LogKeys.MODE: ModeKeys.TRAIN, - LogKeys.EPOCH: 1, - LogKeys.ITER: 2, - LogKeys.LR: 0.0002 - }, json.loads(lines[0])) - self.assertDictContainsSubset( - { - LogKeys.MODE: ModeKeys.EVAL, - LogKeys.EPOCH: 1, - LogKeys.ITER: 5 - }, json.loads(lines[1])) - self.assertDictContainsSubset( - { - LogKeys.MODE: ModeKeys.TRAIN, - LogKeys.EPOCH: 2, - LogKeys.ITER: 2, - LogKeys.LR: 0.0018 - }, json.loads(lines[2])) - self.assertDictContainsSubset( - { - LogKeys.MODE: ModeKeys.EVAL, - LogKeys.EPOCH: 2, - LogKeys.ITER: 5 - }, json.loads(lines[3])) - - self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files) - self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files) - - for i in [0, 2]: - self.assertIn(LogKeys.DATA_LOAD_TIME, lines[i]) - self.assertIn(LogKeys.ITER_TIME, lines[i]) - self.assertIn(LogKeys.MEMORY, lines[i]) - self.assertIn('total_loss', lines[i]) - for i in [1, 3]: - self.assertIn( - 'CocoDetectionEvaluator_DetectionBoxes_Precision/mAP', - lines[i]) - self.assertIn('DetectionBoxes_Precision/mAP', lines[i]) - self.assertIn('DetectionBoxes_Precision/mAP@.50IOU', lines[i]) - self.assertIn('DetectionBoxes_Precision/mAP@.75IOU', lines[i]) - self.assertIn('DetectionBoxes_Precision/mAP (small)', lines[i]) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/easycv/test_easycv_trainer_detection_dino.py b/tests/trainers/easycv/test_easycv_trainer_detection_dino.py deleted file mode 100644 index 90d1f691..00000000 --- a/tests/trainers/easycv/test_easycv_trainer_detection_dino.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import shutil -import tempfile -import unittest - -import torch - -from modelscope.metainfo import Trainers -from modelscope.msdatasets import MsDataset -from modelscope.trainers import build_trainer -from modelscope.utils.constant import LogKeys -from modelscope.utils.logger import get_logger -from modelscope.utils.test_utils import test_level - - -@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest') -class EasyCVTrainerTestDetectionDino(unittest.TestCase): - model_id = 'damo/cv_swinl_image-object-detection_dino' - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - - def _train(self, tmp_dir): - cfg_options = {'train.max_epochs': 1} - - trainer_name = Trainers.easycv - - train_dataset = MsDataset.load( - dataset_name='small_coco_for_test', - namespace='EasyCV', - split='train') - eval_dataset = MsDataset.load( - dataset_name='small_coco_for_test', - namespace='EasyCV', - split='validation') - - kwargs = dict( - model=self.model_id, - train_dataset=train_dataset, - eval_dataset=eval_dataset, - work_dir=tmp_dir, - cfg_options=cfg_options) - - trainer = build_trainer(trainer_name, kwargs) - trainer.train() - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_trainer_single_gpu(self): - temp_file_dir = tempfile.TemporaryDirectory() - tmp_dir = temp_file_dir.name - if not os.path.exists(tmp_dir): - os.makedirs(tmp_dir) - - self._train(tmp_dir) - - results_files = os.listdir(tmp_dir) - json_files = glob.glob(os.path.join(tmp_dir, '*.log.json')) - self.assertEqual(len(json_files), 1) - self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files) - - temp_file_dir.cleanup() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/easycv/test_easycv_trainer_face_2d_keypoints.py b/tests/trainers/easycv/test_easycv_trainer_face_2d_keypoints.py deleted file mode 100644 index e4f0c57e..00000000 --- a/tests/trainers/easycv/test_easycv_trainer_face_2d_keypoints.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import shutil -import tempfile -import unittest - -import torch - -from modelscope.metainfo import Trainers -from modelscope.msdatasets import MsDataset -from modelscope.trainers import build_trainer -from modelscope.utils.constant import DownloadMode, LogKeys, Tasks -from modelscope.utils.logger import get_logger -from modelscope.utils.test_utils import test_level - - -@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest') -class EasyCVTrainerTestFace2DKeypoints(unittest.TestCase): - model_id = 'damo/cv_mobilenet_face-2d-keypoints_alignment' - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - - def _train(self, tmp_dir): - cfg_options = {'train.max_epochs': 2} - - trainer_name = Trainers.easycv - - train_dataset = MsDataset.load( - dataset_name='face_2d_keypoints_dataset', - namespace='modelscope', - split='train', - download_mode=DownloadMode.REUSE_DATASET_IF_EXISTS) - eval_dataset = MsDataset.load( - dataset_name='face_2d_keypoints_dataset', - namespace='modelscope', - split='train', - download_mode=DownloadMode.REUSE_DATASET_IF_EXISTS) - - kwargs = dict( - model=self.model_id, - train_dataset=train_dataset, - eval_dataset=eval_dataset, - work_dir=tmp_dir, - cfg_options=cfg_options) - - trainer = build_trainer(trainer_name, kwargs) - trainer.train() - - @unittest.skip( - 'skip since face_2d_keypoints_dataset is set to private for now') - def test_trainer_single_gpu(self): - temp_file_dir = tempfile.TemporaryDirectory() - tmp_dir = temp_file_dir.name - if not os.path.exists(tmp_dir): - os.makedirs(tmp_dir) - - self._train(tmp_dir) - - results_files = os.listdir(tmp_dir) - json_files = glob.glob(os.path.join(tmp_dir, '*.log.json')) - self.assertEqual(len(json_files), 1) - self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files) - - temp_file_dir.cleanup() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/easycv/test_easycv_trainer_hand_2d_keypoints.py b/tests/trainers/easycv/test_easycv_trainer_hand_2d_keypoints.py deleted file mode 100644 index 270ecbc4..00000000 --- a/tests/trainers/easycv/test_easycv_trainer_hand_2d_keypoints.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import shutil -import tempfile -import unittest - -import torch - -from modelscope.metainfo import Trainers -from modelscope.msdatasets import MsDataset -from modelscope.trainers import build_trainer -from modelscope.utils.constant import DownloadMode, LogKeys, Tasks -from modelscope.utils.logger import get_logger -from modelscope.utils.test_utils import test_level - - -@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest') -class EasyCVTrainerTestHand2dKeypoints(unittest.TestCase): - model_id = 'damo/cv_hrnetw18_hand-pose-keypoints_coco-wholebody' - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - self.tmp_dir = tempfile.TemporaryDirectory().name - if not os.path.exists(self.tmp_dir): - os.makedirs(self.tmp_dir) - - def tearDown(self): - super().tearDown() - shutil.rmtree(self.tmp_dir, ignore_errors=True) - - def _train(self): - cfg_options = {'train.max_epochs': 20} - - trainer_name = Trainers.easycv - - train_dataset = MsDataset.load( - dataset_name='cv_hand_2d_keypoints_coco_wholebody', - namespace='chenhyer', - split='subtrain', - download_mode=DownloadMode.FORCE_REDOWNLOAD) - eval_dataset = MsDataset.load( - dataset_name='cv_hand_2d_keypoints_coco_wholebody', - namespace='chenhyer', - split='subtrain', - download_mode=DownloadMode.FORCE_REDOWNLOAD) - - kwargs = dict( - model=self.model_id, - train_dataset=train_dataset, - eval_dataset=eval_dataset, - work_dir=self.tmp_dir, - cfg_options=cfg_options) - - trainer = build_trainer(trainer_name, kwargs) - trainer.train() - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_trainer_single_gpu(self): - self._train() - - results_files = os.listdir(self.tmp_dir) - json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json')) - self.assertEqual(len(json_files), 1) - self.assertIn(f'{LogKeys.EPOCH}_10.pth', results_files) - self.assertIn(f'{LogKeys.EPOCH}_20.pth', results_files) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/easycv/test_easycv_trainer_hand_detection.py b/tests/trainers/easycv/test_easycv_trainer_hand_detection.py deleted file mode 100644 index 60ea1319..00000000 --- a/tests/trainers/easycv/test_easycv_trainer_hand_detection.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import shutil -import tempfile -import unittest - -import torch - -from modelscope.metainfo import Trainers -from modelscope.msdatasets import MsDataset -from modelscope.trainers import build_trainer -from modelscope.utils.constant import DownloadMode, LogKeys, Tasks -from modelscope.utils.logger import get_logger -from modelscope.utils.test_utils import test_level - - -class EasyCVTrainerTestHandDetection(unittest.TestCase): - model_id = 'damo/cv_yolox-pai_hand-detection' - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - - def _train(self, tmp_dir): - cfg_options = {'train.max_epochs': 2} - - trainer_name = Trainers.easycv - - train_dataset = MsDataset.load( - dataset_name='hand_detection_dataset', split='subtrain') - eval_dataset = MsDataset.load( - dataset_name='hand_detection_dataset', split='subtrain') - - kwargs = dict( - model=self.model_id, - train_dataset=train_dataset, - eval_dataset=eval_dataset, - work_dir=tmp_dir, - cfg_options=cfg_options) - - trainer = build_trainer(trainer_name, kwargs) - trainer.train() - - @unittest.skipUnless(test_level() >= 1, 'skip test in current test level') - def test_trainer_single_gpu(self): - temp_file_dir = tempfile.TemporaryDirectory() - tmp_dir = temp_file_dir.name - if not os.path.exists(tmp_dir): - os.makedirs(tmp_dir) - - self._train(tmp_dir) - - results_files = os.listdir(tmp_dir) - # json_files = glob.glob(os.path.join(tmp_dir, '*.log.json')) - self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files) - - temp_file_dir.cleanup() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/easycv/test_easycv_trainer_panoptic_mask2former.py b/tests/trainers/easycv/test_easycv_trainer_panoptic_mask2former.py deleted file mode 100644 index f6a6c41a..00000000 --- a/tests/trainers/easycv/test_easycv_trainer_panoptic_mask2former.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import shutil -import tempfile -import unittest - -import torch -from mmcv.runner.hooks import HOOKS as MMCV_HOOKS - -from modelscope.metainfo import Trainers -from modelscope.msdatasets import MsDataset -from modelscope.trainers import build_trainer -from modelscope.utils.constant import LogKeys, Tasks -from modelscope.utils.logger import get_logger -from modelscope.utils.test_utils import test_level - - -@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest') -class EasyCVTrainerTestPanopticMask2Former(unittest.TestCase): - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - self.tmp_dir = tempfile.TemporaryDirectory().name - if not os.path.exists(self.tmp_dir): - os.makedirs(self.tmp_dir) - - def tearDown(self): - super().tearDown() - shutil.rmtree(self.tmp_dir, ignore_errors=True) - - def _train(self): - cfg_options = {'train.max_epochs': 1} - - trainer_name = Trainers.easycv - - train_dataset = MsDataset.load( - dataset_name='COCO2017_panopic_subset', split='train') - eval_dataset = MsDataset.load( - dataset_name='COCO2017_panopic_subset', split='validation') - kwargs = dict( - model='damo/cv_r50_panoptic-segmentation_cocopan', - train_dataset=train_dataset, - eval_dataset=eval_dataset, - work_dir=self.tmp_dir, - cfg_options=cfg_options) - - trainer = build_trainer(trainer_name, kwargs) - - hook_name = 'YOLOXLrUpdaterHook' - mmcv_hook = MMCV_HOOKS._module_dict.pop(hook_name, None) - - trainer.train() - - MMCV_HOOKS._module_dict[hook_name] = mmcv_hook - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_single_gpu_mask2former_r50(self): - self._train() - - results_files = os.listdir(self.tmp_dir) - json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json')) - self.assertEqual(len(json_files), 1) - self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/easycv/test_easycv_trainer_realtime_object_detection.py b/tests/trainers/easycv/test_easycv_trainer_realtime_object_detection.py deleted file mode 100644 index 1171eed4..00000000 --- a/tests/trainers/easycv/test_easycv_trainer_realtime_object_detection.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import shutil -import tempfile -import unittest - -import torch - -from modelscope.hub.snapshot_download import snapshot_download -from modelscope.metainfo import Trainers -from modelscope.msdatasets import MsDataset -from modelscope.trainers import build_trainer -from modelscope.utils.constant import DownloadMode, LogKeys, Tasks -from modelscope.utils.logger import get_logger -from modelscope.utils.test_utils import test_level - - -@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest') -class EasyCVTrainerTestRealtimeObjectDetection(unittest.TestCase): - model_id = 'damo/cv_cspnet_image-object-detection_yolox' - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - - def _train(self, tmp_dir): - # cfg_options = {'train.max_epochs': 2} - self.cache_path = snapshot_download(self.model_id) - cfg_options = { - 'train.max_epochs': - 2, - 'train.dataloader.batch_size_per_gpu': - 4, - 'evaluation.dataloader.batch_size_per_gpu': - 2, - 'train.hooks': [ - { - 'type': 'CheckpointHook', - 'interval': 1 - }, - { - 'type': 'EvaluationHook', - 'interval': 1 - }, - { - 'type': 'TextLoggerHook', - 'ignore_rounding_keys': None, - 'interval': 2 - }, - ], - 'load_from': - os.path.join(self.cache_path, 'pytorch_model.bin') - } - - trainer_name = Trainers.easycv - - train_dataset = MsDataset.load( - dataset_name='small_coco_for_test', - namespace='EasyCV', - split='train') - eval_dataset = MsDataset.load( - dataset_name='small_coco_for_test', - namespace='EasyCV', - split='validation') - - kwargs = dict( - model=self.model_id, - # model_revision='v1.0.2', - train_dataset=train_dataset, - eval_dataset=eval_dataset, - work_dir=tmp_dir, - cfg_options=cfg_options) - - trainer = build_trainer(trainer_name, kwargs) - trainer.train() - - @unittest.skipUnless( - test_level() >= 0, - 'skip since face_2d_keypoints_dataset is set to private for now') - def test_trainer_single_gpu(self): - temp_file_dir = tempfile.TemporaryDirectory() - tmp_dir = temp_file_dir.name - if not os.path.exists(tmp_dir): - os.makedirs(tmp_dir) - - self._train(tmp_dir) - - results_files = os.listdir(tmp_dir) - json_files = glob.glob(os.path.join(tmp_dir, '*.log.json')) - self.assertEqual(len(json_files), 1) - self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files) - - temp_file_dir.cleanup() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/easycv/test_segformer.py b/tests/trainers/easycv/test_segformer.py deleted file mode 100644 index 90a66635..00000000 --- a/tests/trainers/easycv/test_segformer.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) Alibaba, Inc. and its affiliates. -import glob -import os -import shutil -import tempfile -import unittest - -import torch - -from modelscope.metainfo import Trainers -from modelscope.msdatasets import MsDataset -from modelscope.trainers import build_trainer -from modelscope.utils.constant import LogKeys, Tasks -from modelscope.utils.logger import get_logger -from modelscope.utils.test_utils import test_level - - -@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest') -class EasyCVTrainerTestSegformer(unittest.TestCase): - - def setUp(self): - self.logger = get_logger() - self.logger.info(('Testing %s.%s' % - (type(self).__name__, self._testMethodName))) - self.tmp_dir = tempfile.TemporaryDirectory().name - if not os.path.exists(self.tmp_dir): - os.makedirs(self.tmp_dir) - - def tearDown(self): - super().tearDown() - shutil.rmtree(self.tmp_dir, ignore_errors=True) - - def _train(self): - - cfg_options = { - 'train.max_epochs': 2, - 'model.decode_head.norm_cfg.type': 'BN' - } - - trainer_name = Trainers.easycv - train_dataset = MsDataset.load( - dataset_name='small_coco_stuff164k', - namespace='EasyCV', - split='train') - eval_dataset = MsDataset.load( - dataset_name='small_coco_stuff164k', - namespace='EasyCV', - split='validation') - kwargs = dict( - model= - 'damo/cv_segformer-b0_image_semantic-segmentation_coco-stuff164k', - train_dataset=train_dataset, - eval_dataset=eval_dataset, - work_dir=self.tmp_dir, - cfg_options=cfg_options) - - trainer = build_trainer(trainer_name, kwargs) - trainer.train() - - @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') - def test_single_gpu_segformer(self): - self._train() - - results_files = os.listdir(self.tmp_dir) - json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json')) - self.assertEqual(len(json_files), 1) - self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files) - self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/trainers/model_trainer_map.py b/tests/trainers/model_trainer_map.py index 4057c331..d4c4c09a 100644 --- a/tests/trainers/model_trainer_map.py +++ b/tests/trainers/model_trainer_map.py @@ -11,33 +11,18 @@ model_trainer_map = { ['tests/trainers/audio/test_separation_trainer.py'], 'speech_tts/speech_sambert-hifigan_tts_zh-cn_multisp_pretrain_16k': ['tests/trainers/audio/test_tts_trainer.py'], - 'damo/cv_mobilenet_face-2d-keypoints_alignment': - ['tests/trainers/easycv/test_easycv_trainer_face_2d_keypoints.py'], - 'damo/cv_hrnetw18_hand-pose-keypoints_coco-wholebody': - ['tests/trainers/easycv/test_easycv_trainer_hand_2d_keypoints.py'], - 'damo/cv_yolox-pai_hand-detection': - ['tests/trainers/easycv/test_easycv_trainer_hand_detection.py'], - 'damo/cv_r50_panoptic-segmentation_cocopan': - ['tests/trainers/easycv/test_easycv_trainer_panoptic_mask2former.py'], - 'damo/cv_segformer-b0_image_semantic-segmentation_coco-stuff164k': - ['tests/trainers/easycv/test_segformer.py'], 'damo/cv_resnet_carddetection_scrfd34gkps': ['tests/trainers/test_card_detection_scrfd_trainer.py'], - 'damo/multi-modal_clip-vit-base-patch16_zh': [ - 'tests/trainers/test_clip_trainer.py' - ], - 'damo/nlp_space_pretrained-dialog-model': [ - 'tests/trainers/test_dialog_intent_trainer.py' - ], - 'damo/cv_resnet_facedetection_scrfd10gkps': [ - 'tests/trainers/test_face_detection_scrfd_trainer.py' - ], - 'damo/nlp_structbert_faq-question-answering_chinese-base': [ - 'tests/trainers/test_finetune_faq_question_answering.py' - ], - 'PAI/nlp_gpt3_text-generation_0.35B_MoE-64': [ - 'tests/trainers/test_finetune_gpt_moe.py' - ], + 'damo/multi-modal_clip-vit-base-patch16_zh': + ['tests/trainers/test_clip_trainer.py'], + 'damo/nlp_space_pretrained-dialog-model': + ['tests/trainers/test_dialog_intent_trainer.py'], + 'damo/cv_resnet_facedetection_scrfd10gkps': + ['tests/trainers/test_face_detection_scrfd_trainer.py'], + 'damo/nlp_structbert_faq-question-answering_chinese-base': + ['tests/trainers/test_finetune_faq_question_answering.py'], + 'PAI/nlp_gpt3_text-generation_0.35B_MoE-64': + ['tests/trainers/test_finetune_gpt_moe.py'], 'damo/nlp_gpt3_text-generation_1.3B': [ 'tests/trainers/test_finetune_gpt3.py' ],