def test_export_file_is_not_none(self, patches):
            patches.path_exists.return_value = False
            ModelExportUtils.check_mar_already_exists('some-model',
                                                      '/Users/Piyush/', False)

            patches.path_exists.assert_called_once_with(
                '/Users/Piyush/some-model.mar')
        def test_onnx_file_is_none(self, patches):
            patches.utils.find_unique.return_value = None
            ModelExportUtils.check_custom_model_types(
                model_path=self.model_path, model_name=None)

            patches.utils.find_unique.assert_called()
            patches.utils.convert_onnx_model.assert_not_called()
        def test_export_file_already_exists_with_override(self, patches):
            patches.path_exists.return_value = True

            ModelExportUtils.check_mar_already_exists('some-model', None, True)

            patches.path_exists.assert_called_once_with(
                '/Users/dummyUser/some-model.mar')
 def test_regex_pass(self):
     model_names = [
         'my-awesome-model', 'Aa.model', 'a', 'aA.model', 'a1234.model',
         'a-A-A.model', '123-abc'
     ]
     for m in model_names:
         ModelExportUtils.check_model_name_regex_or_exit(m)
 def test_regex_fail(self):
     model_names = [
         'abc%', '123.abc', '12-model-a.model', '##.model', '-.model'
     ]
     for m in model_names:
         with pytest.raises(ModelArchiverError):
             ModelExportUtils.check_model_name_regex_or_exit(m)
        def test_export_file_already_exists_with_override_false(self, patches):
            patches.path_exists.return_value = True

            with pytest.raises(ModelArchiverError):
                ModelExportUtils.check_mar_already_exists('some-model', None, False)

            patches.path_exists.assert_called_once_with('/Users/dummyUser/some-model.mar')
        def test_export_file_is_none_tar(self, patches):
            patches.path_exists.return_value = False
            ret_val = ModelExportUtils.check_mar_already_exists(
                'some-model', None, False, archive_format='tgz')

            patches.path_exists.assert_called_once_with(
                "/Users/dummyUser/some-model.tar.gz")
            assert ret_val == "/Users/dummyUser"
        def test_export_file_is_none(self, patches):
            patches.path_exists.return_value = False
            ret_val = ModelExportUtils.check_mar_already_exists(
                'some-model', None, False)

            patches.path_exists.assert_called_once_with(
                "/Users/dummyUser/some-model.mar")
            assert ret_val == "/Users/dummyUser"
 def test_manifest_json(self):
     manifest = ModelExportUtils.generate_manifest_json(self.args)
     manifest_json = json.loads(manifest)
     assert manifest_json['runtime'] == RuntimeType.PYTHON.value
     assert 'engine' in manifest_json
     assert 'model' in manifest_json
     assert 'publisher' in manifest_json
     assert 'license' not in manifest_json
    def test_export_model_method(self, patches):
        patches.export_utils.check_mar_already_exists.return_value = '/Users/dummyUser/'
        patches.export_utils.check_custom_model_types.return_value = '/Users/dummyUser', ['a.txt', 'b.txt']
        patches.export_utils.zip.return_value = None

        package_model(self.args, ModelExportUtils.generate_manifest_json(self.args))
        patches.export_utils.validate_inputs.assert_called()
        patches.export_utils.archive.assert_called()
        patches.export_utils.clean_temp_files.assert_called()
示例#11
0
def mmcls2torchserve(
    config_file: str,
    checkpoint_file: str,
    output_folder: str,
    model_name: str,
    model_version: str = '1.0',
    force: bool = False,
):
    """Converts mmclassification model (config + checkpoint) to TorchServe
    `.mar`.

    Args:
        config_file:
            In MMClassification config format.
            The contents vary for each task repository.
        checkpoint_file:
            In MMClassification checkpoint format.
            The contents vary for each task repository.
        output_folder:
            Folder where `{model_name}.mar` will be created.
            The file created will be in TorchServe archive format.
        model_name:
            If not None, used for naming the `{model_name}.mar` file
            that will be created under `output_folder`.
            If None, `{Path(checkpoint_file).stem}` will be used.
        model_version:
            Model's version.
        force:
            If True, if there is an existing `{model_name}.mar`
            file under `output_folder` it will be overwritten.
    """
    mmcv.mkdir_or_exist(output_folder)

    config = mmcv.Config.fromfile(config_file)

    with TemporaryDirectory() as tmpdir:
        config.dump(f'{tmpdir}/config.py')

        args = Namespace(
            **{
                'model_file': f'{tmpdir}/config.py',
                'serialized_file': checkpoint_file,
                'handler': f'{Path(__file__).parent}/mmcls_handler.py',
                'model_name': model_name or Path(checkpoint_file).stem,
                'version': model_version,
                'export_path': output_folder,
                'force': force,
                'requirements_file': None,
                'extra_files': None,
                'runtime': 'python',
                'archive_format': 'default'
            })
        manifest = ModelExportUtils.generate_manifest_json(args)
        package_model(args, manifest)
示例#12
0
def mmgen2torchserver(config_file: str,
                      checkpoint_file: str,
                      output_folder: str,
                      model_name: str,
                      model_version: str = '1.0',
                      model_type: str = 'unconditional',
                      force: bool = False):
    """Converts MMGeneration model (config + checkpoint) to TorchServe `.mar`.

    Args:
        config_file (str): Path of config file. The config should in
            MMGeneration format.
        checkpoint_file (str): Path of checkpoint. The checkpoint should in
            MMGeneration checkpoint format.
        output_folder (str): Folder where `{model_name}.mar` will be created.
            The file created will be in TorchServe archive format.
        model_name (str): Name of the generated ``'mar'`` file. If not None,
            used for naming the `{model_name}.mar` file that will be created
            under `output_folder`. If None, `{Path(checkpoint_file).stem}`
            will be used.
        model_version (str, optional): Model's version. Defaults to '1.0'.
        model_type (str, optional): Type of the model to be convert. Handler
            named ``{model_type}_handler`` would be used to generate ``mar``
            file. Defaults to 'unconditional'.
        force (bool, optional): If True, existing `{model_name}.mar` will be
            overwritten. Default to False.
    """
    mmcv.mkdir_or_exist(output_folder)

    config = mmcv.Config.fromfile(config_file)

    with TemporaryDirectory() as tmpdir:
        config.dump(f'{tmpdir}/config.py')

        args = Namespace(
            **{
                'model_file': f'{tmpdir}/config.py',
                'serialized_file': checkpoint_file,
                'handler':
                f'{Path(__file__).parent}/mmgen_{model_type}_handler.py',
                'model_name': model_name or Path(checkpoint_file).stem,
                'version': model_version,
                'export_path': output_folder,
                'force': force,
                'requirements_file': None,
                'extra_files': None,
                'runtime': 'python',
                'archive_format': 'default'
            })
        manifest = ModelExportUtils.generate_manifest_json(args)
        package_model(args, manifest)
        def test_onnx_file_is_not_none(self, patches):
            onnx_file = 'some-file.onnx'
            patches.utils.find_unique.return_value = onnx_file
            patches.utils.convert_onnx_model.return_value = ('sym', 'param')

            temp, exclude = ModelExportUtils.check_custom_model_types(
                self.model_path)
            patches.utils.convert_onnx_model.assert_called_once_with(
                self.model_path, onnx_file, None)

            assert len(temp) == 2
            assert len(exclude) == 1
            assert temp[0] == os.path.join(self.model_path, 'sym')
            assert temp[1] == os.path.join(self.model_path, 'param')
            assert exclude[0] == onnx_file
示例#14
0
    def pack(self,
             model,
             dst_path,
             model_name,
             model_version,
             additional_files=None):
        """
        Package a model into the MAR archive so that it can be used for serving using TorchServing

        :param model: an object representing a model
        :type model: torch.nn.Module
        :param dst_path: the destination base path (do not include the filename) of the MAR
        :type dst_path: str
        :param model_name: the name of the model (will be also used to define the prediction endpoint)
        :type model_name: str
        :param model_version: a string encoding the version of the model
        :type model_version: str
        :param additional_files: an optional list of files that should be included in the MAR
        :type additional_files: iterable

        :return: None
        """
        if additional_files is None:
            additional_files = []

        # save model
        torch.save(model, os.path.join(self.tmp_dir, 'model.pt'))

        args = ArgClass(
            os.path.join(self.tmp_dir, 'model.pt'), self.handler, ','.join([
                os.path.join(self.tmp_dir, 'pre_process_tform.pkl'),
                os.path.join(self.tmp_dir, 'post_process_tform.pkl'),
                os.path.join(self.tmp_dir, 'metadata.json')
            ] + additional_files), dst_path, model_name, model_version)

        manifest = ModelExportUtils.generate_manifest_json(args)

        package_model(args, manifest=manifest)
 def test_with_exit(self):
     files = ['a.onnx', 'b.onnx', 'c.txt']
     suffix = '.onnx'
     with pytest.raises(ModelArchiverError):
         ModelExportUtils.find_unique(files, suffix)
 def test_with_starts_with_dot(self):
     assert ModelExportUtils.directory_filter('.gitignore', self.unwanted_dirs) is False
 def test_with_return_true(self):
     assert ModelExportUtils.directory_filter('my-model', self.unwanted_dirs) is True
 def test_with_return_true(self):
     assert ModelExportUtils.file_filter('abc.mxnet', self.files_to_exclude) is True
 def test_with_unwanted_dirs(self):
     assert ModelExportUtils.directory_filter('__MACOSX', self.unwanted_dirs) is False
 def test_with_pyc(self):
     assert ModelExportUtils.file_filter('abc.pyc', self.files_to_exclude) is False
 def test_with_ds_store(self):
     assert ModelExportUtils.file_filter('.DS_Store', self.files_to_exclude) is False
示例#22
0
 def test_export_file_already_exists_with_override_false(self, patches):
     patches.path_exists.return_value = True
     with pytest.raises(ModelArchiverError):
         ModelExportUtils.check_mar_already_exists(
             'some-model', None, False)
     _validate_mar(patches)
 def test_with_return_false(self):
     assert ModelExportUtils.file_filter('abc.onnx', self.files_to_exclude) is False
 def test_model(self):
     mod = ModelExportUtils.generate_model(self.args)
     assert mod.model_name == self.model_name
     assert mod.handler == self.handler
 def test_engine(self):
     eng = ModelExportUtils.generate_engine(self.args)
     assert eng.engine_name == EngineType(self.engine)
 def test_publisher(self):
     pub = ModelExportUtils.generate_publisher(self.args)
     assert pub.email == self.email
     assert pub.author == self.author
示例#27
0
 def test_export_file_already_exists_with_override(self, patches):
     patches.path_exists.return_value = True
     ModelExportUtils.check_mar_already_exists('some-model', None, True)
     _validate_mar(patches)
 def test_with_count_zero(self):
     files = ['a.txt', 'b.txt', 'c.txt']
     suffix = '.mxnet'
     val = ModelExportUtils.find_unique(files, suffix)
     assert val is None
示例#29
0
def mmpose2torchserve(config_file: str,
                      checkpoint_file: str,
                      output_folder: str,
                      model_name: str,
                      model_version: str = '1.0',
                      force: bool = False):
    """Converts MMPose model (config + checkpoint) to TorchServe `.mar`.

    Args:
        config_file:
            In MMPose config format.
            The contents vary for each task repository.
        checkpoint_file:
            In MMPose checkpoint format.
            The contents vary for each task repository.
        output_folder:
            Folder where `{model_name}.mar` will be created.
            The file created will be in TorchServe archive format.
        model_name:
            If not None, used for naming the `{model_name}.mar` file
            that will be created under `output_folder`.
            If None, `{Path(checkpoint_file).stem}` will be used.
        model_version:
            Model's version.
        force:
            If True, if there is an existing `{model_name}.mar`
            file under `output_folder` it will be overwritten.
    """

    mmcv.mkdir_or_exist(output_folder)

    config = mmcv.Config.fromfile(config_file)

    with TemporaryDirectory() as tmpdir:
        model_file = osp.join(tmpdir, 'config.py')
        config.dump(model_file)
        handler_path = osp.join(osp.dirname(__file__), 'mmpose_handler.py')
        model_name = model_name or osp.splitext(
            osp.basename(checkpoint_file))[0]

        # use mmcv CheckpointLoader if checkpoint is not from a local file
        if not osp.isfile(checkpoint_file):
            ckpt = CheckpointLoader.load_checkpoint(checkpoint_file)
            checkpoint_file = osp.join(tmpdir, 'checkpoint.pth')
            with open(checkpoint_file, 'wb') as f:
                torch.save(ckpt, f)

        args = Namespace(
            **{
                'model_file': model_file,
                'serialized_file': checkpoint_file,
                'handler': handler_path,
                'model_name': model_name,
                'version': model_version,
                'export_path': output_folder,
                'force': force,
                'requirements_file': None,
                'extra_files': None,
                'runtime': 'python',
                'archive_format': 'default'
            })
        manifest = ModelExportUtils.generate_manifest_json(args)
        package_model(args, manifest)
        def test_clean_call(self, patches):
            temp_files = ['a', 'b', 'c']
            ModelExportUtils.clean_temp_files(temp_files)

            patches.remove.assert_called()
            assert patches.remove.call_count == len(temp_files)