remove easycv codes, plugin access

Link: https://code.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/11965727

* remove easycv codes

* fix custome msdatasets import and remove metainfo

* fix pipeline imports

* fix pre-check

* fix models import

* fix pre-check

* merge master
This commit is contained in:
jiangnana.jnn
2023-05-09 17:58:01 +08:00
committed by wenmeng.zwm
parent 038c5fea48
commit 46072898da
56 changed files with 15 additions and 2779 deletions

View File

@@ -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'

View File

@@ -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,

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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 = {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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'],

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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'
],

View File

@@ -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={},
)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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={},
)

View File

@@ -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)

View File

@@ -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={},
)

View File

@@ -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

View File

@@ -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

View File

@@ -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,
)

View File

@@ -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."""

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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'
],