예제 #1
0
def register_model_from_yaml(file_path: Union[Path, str]):
    # check if file exist
    file_path = Path(file_path)
    assert file_path.exists(
    ), f'Model definition file at {str(file_path)} does not exist'

    # read yaml
    with open(file_path) as f:
        model_config = yaml.safe_load(f)
    model_yaml = MLModelFromYaml.parse_obj(model_config)
    # copy model weight to cache directory
    model_in_saved_path = model_yaml.saved_path
    if model_in_saved_path != model_yaml.weight:
        copy2(model_yaml.weight, model_in_saved_path)

    # zip weight folder
    if model_yaml.engine == Engine.TFS:
        weight_dir = model_yaml.weight
        make_archive(weight_dir.with_suffix('.zip'), 'zip', weight_dir)

    model_data = model_yaml.dict(exclude_none=True,
                                 exclude={'convert', 'profile'})
    model = MLModel.parse_obj(model_data)
    register_model(model,
                   convert=model_yaml.convert,
                   profile=model_yaml.profile)
예제 #2
0
def publish(
    file_or_dir: Optional[Path] = typer.Argument(None,
                                                 help='Model weight files',
                                                 exists=True),
    architecture: Optional[str] = typer.Option(None,
                                               '-n',
                                               '--name',
                                               help='Architecture'),
    framework: Optional[Framework] = typer.Option(None,
                                                  '-fw',
                                                  '--framework',
                                                  help='Framework'),
    engine: Optional[Engine] = typer.Option(None,
                                            '-e',
                                            '--engine',
                                            help='Engine'),
    version: Optional[int] = typer.Option(None,
                                          '-v',
                                          '--version',
                                          min=1,
                                          help='Version number'),
    task: Optional[Task] = typer.Option(None, '-t', '--task', help='Task'),
    dataset: Optional[str] = typer.Option(None,
                                          '-d',
                                          '--dataset',
                                          help='Dataset name'),
    metric: Dict[Metric, float] = typer.Option(
        '{}',
        help='Metrics in the form of mapping JSON string. The map type is '
        '`Dict[types.models.mlmodel.Metric, float]`. An example is \'{"acc": 0.76}.\'',
    ),
    inputs: List[IOShape] = typer.Option(
        [],
        '-i',
        '--input',
        help=
        'List of shape definitions for input tensors. An example of one shape definition is '
        '\'{"name": "input", "shape": [-1, 3, 224, 224], "dtype": "TYPE_FP32", "format": "FORMAT_NCHW"}\'',
    ),
    outputs: List[IOShape] = typer.Option(
        [],
        '-o',
        '--output',
        help=
        'List of shape definitions for output tensors. An example of one shape definition is '
        '\'{"name": "output", "shape": [-1, 1000], "dtype": "TYPE_FP32"}\'',
    ),
    convert: Optional[bool] = typer.Option(
        True,
        '-c',
        '--convert',
        is_flag=True,
        help='Convert the model to other possible format.',
    ),
    profile: Optional[bool] = typer.Option(
        False,
        '-p',
        '--profile',
        is_flag=True,
        help='Profile the published model(s).',
    ),
    yaml_file: Optional[Path] = typer.Option(
        None,
        '-f',
        '--yaml-file',
        exists=True,
        file_okay=True,
        help=
        'Path to configuration YAML file. You should either set the `yaml_file` field or fields '
        '(`FILE_OR_DIR`, `--name`, `--framework`, `--engine`, `--version`, `--task`, `--dataset`,'
        '`--metric`, `--input`, `--output`).'),
):
    meta_info = (file_or_dir, architecture, framework, engine, version, task,
                 dataset, metric, inputs, outputs)
    # check either using parameters, or using YAML
    if yaml_file and not any(meta_info):
        with open(yaml_file) as f:
            model_config = yaml.safe_load(f)
        try:
            model_yaml = MLModelFromYaml.parse_obj(model_config)
        except ValidationError as exc:
            typer.echo(exc, err=True, color=True)
            raise typer.Exit(422)
    elif not yaml_file and all(meta_info):
        model_yaml = MLModelFromYaml(
            weight=file_or_dir,
            architecture=architecture,
            framework=framework,
            engine=engine,
            version=version,  # noqa
            dataset=dataset,
            metric=metric,
            task=task,
            inputs=inputs,
            outputs=outputs,
            convert=convert,
            profile=profile)
    else:
        typer.echo(
            'Incorrect parameter, you should set either YAML_FILE, or all of the (FILE_OR_DIR, --name,'
            '--framework, --engine, --version, --task, --dataset, --metric, --input, --output)'
        )
        raise typer.Exit(422)

    # build request parameters
    payload = {'convert': model_yaml.convert, 'profile': model_yaml.profile}
    data = model_yaml.dict(use_enum_values=True,
                           exclude_none=True,
                           exclude={'convert', 'profile', 'weight'})
    form_data = {k: str(v) for k, v in data.items()}
    file_or_dir = model_yaml.weight

    # read weight files
    files = list()
    key = 'files'
    try:
        # read weight file
        if file_or_dir.is_dir():
            for file in filter(Path.is_file, file_or_dir.rglob('*')):
                name = Path(file).relative_to(file_or_dir.parent)
                files.append(
                    (key, (str(name), open(file,
                                           'rb'), 'application/example')))
        else:
            files.append(
                (key, (file_or_dir.name, open(file_or_dir,
                                              'rb'), 'application/example')))
        with requests.post(
                f'{app_settings.api_v1_prefix}/model/',
                params=payload,
                data=form_data,
                files=files,
        ) as r:
            typer.echo(r.json(), color=True)
    finally:
        for file in files:
            file[1][1].close()
예제 #3
0
def convert(
        id: str = typer.Option(None, '-i', '--id', help='ID of model.'),
        yaml_file: Optional[Path] = typer.
    Option(
        None,
        '-f',
        '--yaml-file',
        exists=True,
        file_okay=True,
        help=
        'Path to configuration YAML file. You should either set the `yaml_file` field or fields '
        '(`FILE_OR_DIR`, `--name`, `--framework`, `--engine`, `--version`, `--task`, `--dataset`,'
        '`--metric`, `--input`, `--output`).'),
        register: bool = typer.Option(
            False,
            '-r',
            '--register',
            is_flag=True,
            help='register the converted models to modelhub, default false')):
    model = None
    if id is None and yaml_file is None:
        typer.echo(
            "WARNING: Please assign a way to find the target model! details refer to --help"
        )
        raise RuntimeError
    if id is not None and yaml_file is not None:
        typer.echo("WARNING: Do not use -id and -path at the same time!")
        raise RuntimeError
    elif id is not None and yaml_file is None:
        if ModelDB.exists_by_id(id):
            model = ModelDB.get_by_id(id)
        else:
            typer.echo(f"model id: {id} does not exist in modelhub")
    elif id is None and yaml_file is not None:
        # get MLModel from yaml file
        with open(yaml_file) as f:
            model_config = yaml.safe_load(f)
        model_yaml = MLModelFromYaml.parse_obj(model_config)
        model_in_saved_path = model_yaml.saved_path
        if model_in_saved_path != model_yaml.weight:
            copy2(model_yaml.weight, model_in_saved_path)
        if model_yaml.engine == Engine.TFS:
            weight_dir = model_yaml.weight
            make_archive(weight_dir.with_suffix('.zip'), 'zip', weight_dir)

        model_data = model_yaml.dict(exclude_none=True,
                                     exclude={'convert', 'profile'})
        model = MLModel.parse_obj(model_data)

    # auto execute all possible convert and return a list of save paths of every converted model
    generated_dir_list = generate_model_family(model)
    typer.echo(f"Converted models are save in: {generated_dir_list}")
    if register:
        model_data = model.dict(
            exclude={'weight', 'id', 'model_status', 'engine'})
        for model_dir in generated_dir_list:
            parse_result = parse_path_plain(model_dir)
            engine = parse_result['engine']
            model_cvt = MLModel(**model_data,
                                weight=model_dir,
                                engine=engine,
                                model_status=[ModelStatus.CONVERTED])
            ModelDB.save(model_cvt)
            typer.echo(
                f"converted {engine} are successfully registered in Modelhub")