Ejemplo n.º 1
0
def save_framework_info(framework: Any, path: Optional[str] = None):
    """
    Save the framework info for a given framework.
    If path is provided, will save to a json file at that path.
    If path is not provided, will print out the info.

    :param framework: The item to detect the ML framework for.
        See :func:`detect_framework` for more information.
    :type framework: Any
    :param path: The path, if any, to save the info to in json format.
        If not provided will print out the info.
    :type path: Optional[str]
    """
    _LOGGER.debug(
        "saving framework info for framework %s to %s",
        framework,
        path if path else "sys.out",
    )
    info = (framework_info(framework)
            if not isinstance(framework, FrameworkInfo) else framework)

    if path:
        path = clean_path(path)
        create_parent_dirs(path)

        with open(path, "w") as file:
            file.write(info.json())

        _LOGGER.info("saved framework info for framework %s in file at %s",
                     framework, path),
    else:
        print(info.json(indent=4))
        _LOGGER.info("printed out framework info for framework %s", framework)
Ejemplo n.º 2
0
 def __init__(
     self,
     model: keras.Model,
     output_dir: str,
 ):
     self._model = model
     self._output_dir = clean_path(output_dir)
Ejemplo n.º 3
0
    def __init__(
        self,
        root: str = default_dataset_path(
            "imagenet"),  # default to imagenet location
        train: bool = True,
        rand_trans: bool = False,
        image_size: int = 224,
    ):
        if torchvision_import_error is not None:
            raise torchvision_import_error

        root = clean_path(root)
        non_rand_resize_scale = 256.0 / 224.0  # standard used
        init_trans = ([
            transforms.RandomResizedCrop(image_size),
            transforms.RandomHorizontalFlip(),
        ] if rand_trans else [
            transforms.Resize(round(non_rand_resize_scale * image_size)),
            transforms.CenterCrop(image_size),
        ])

        trans = [
            *init_trans,
            transforms.ToTensor(),
            transforms.Normalize(mean=IMAGENET_RGB_MEANS,
                                 std=IMAGENET_RGB_STDS),
        ]
        root = os.path.join(os.path.abspath(os.path.expanduser(root)),
                            "train" if train else "val")

        super().__init__(root, transform=transforms.Compose(trans))

        if train:
            # make sure we dont preserve the folder structure class order
            random.shuffle(self.samples)
Ejemplo n.º 4
0
    def __init__(self, download_root: str, dataset_size: ImagenetteSize,
                 download: bool):
        self._download_root = clean_path(download_root)
        self._dataset_size = dataset_size
        self._download = download

        if dataset_size == ImagenetteSize.s160:
            self._extract_name = "imagenette-160"
        elif dataset_size == ImagenetteSize.s320:
            self._extract_name = "imagenette-320"
        elif dataset_size == ImagenetteSize.full:
            self._extract_name = "imagenette"
        else:
            raise ValueError(
                "Unknown ImagenetteSize given of {}".format(dataset_size))

        self._extracted_root = os.path.join(self._download_root,
                                            self._extract_name)

        if download:
            self._download_and_extract()
        else:
            file_path = "{}.tar".format(self._extracted_root)

            if not os.path.exists(file_path):
                raise ValueError(
                    "could not find original tar for the dataset at {}".format(
                        file_path))
Ejemplo n.º 5
0
    def __init__(
        self,
        root: str = default_dataset_path("imagenet"),
        train: bool = True,
        rand_trans: bool = False,
        image_size: Union[None, int, Tuple[int, int]] = 224,
        pre_resize_transforms=SplitsTransforms(
            train=(
                random_scaling_crop(),
                tf.image.random_flip_left_right,
            ),
            val=(imagenet_pre_resize_processor(), ),
        ),
        post_resize_transforms=SplitsTransforms(
            train=(torch_imagenet_normalizer(), ),
            val=(torch_imagenet_normalizer(), )),
    ):
        root = clean_path(root)
        super().__init__(
            root,
            train,
            image_size=image_size,
            pre_resize_transforms=pre_resize_transforms,
            post_resize_transforms=post_resize_transforms,
        )

        if train:
            # make sure we don't preserve the folder structure class order
            random.shuffle(self.samples)
Ejemplo n.º 6
0
def save_benchmark_results(
    model: Any,
    data: Any,
    batch_size: int,
    iterations: int,
    warmup_iterations: int,
    framework: Optional[str],
    provider: Optional[str] = None,
    device: Optional[str] = None,
    save_path: Optional[str] = None,
    framework_args: Dict[str, Any] = {},
    show_progress: bool = False,
):
    """
    Saves the benchmark results ran for specific framework.
    If path is provided, will save to a json file at the path.
    If path is not provided, will print out the info.

    If no framework is provided, will detect the framework based on the model.

    :param model: model to benchmark
    :param data: data to benchmark
    :param batch_size: batch size
    :param iterations: number of iterations
    :param warmup_iterations: number of warmup iterations
    :param framework: the specific framework run the benchmark in
    :param provider: the specific inference provider to use
    :param device: the specific device to use
    :param save_path: path to save the benchmark results
    :param framework_args: additional framework specific arguments to
        pass to the runner
    :param show_progress: True to show a tqdm bar when running, False otherwise
    """
    results = execute_in_sparseml_framework(
        framework if framework is not None else model,
        "run_benchmark",
        model,
        data,
        batch_size=batch_size,
        iterations=iterations,
        warmup_iterations=warmup_iterations,
        provider=provider,
        device=device,
        framework_args=framework_args,
        show_progress=show_progress,
    )

    if save_path:
        save_path = clean_path(save_path)
        create_parent_dirs(save_path)

        with open(save_path, "w") as file:
            file.write(results.json(indent=4))

        _LOGGER.info(f"saved benchmark results in file at {save_path}"),
    else:
        print(results.json(indent=4))
        _LOGGER.info("printed out benchmark results")
Ejemplo n.º 7
0
 def load(file_path) -> "ModelInfo":
     """
     :param file_path: file path to JSON file to load ModelInfo object from
     :return: the loaded ModelInfo object
     """
     file_path = clean_path(file_path)
     with open(file_path, "r") as file:
         model_info_dict = json.load(file)
     return ModelInfo.from_dict(model_info_dict)
Ejemplo n.º 8
0
    def save(self, file_path: str):
        """
        :param file_path: the file path to save the yaml config representation to
        """
        file_path = clean_path(file_path)
        create_parent_dirs(file_path)

        with open(file_path, "w") as yaml_file:
            yaml_file.write(str(self))
Ejemplo n.º 9
0
    def __init__(
        self,
        module: Module,
        output_dir: str,
    ):
        if is_parallel_model(module):
            module = module.module

        self._module = deepcopy(module).to("cpu").eval()
        self._output_dir = clean_path(output_dir)
Ejemplo n.º 10
0
    def load_json(path: str):
        """
        :param path: the path to load a previous analysis from
        :return: the ModelAnalyzer instance from the json
        """
        path = clean_path(path)

        with open(path, "r") as file:
            objs = json.load(file)

        return ModelAnalyzer.from_dict(objs)
Ejemplo n.º 11
0
    def save_descs(descs: List, path: str):
        """
        Save a list of AnalyzedLayerDesc to a json file

        :param descs: a list of descriptions to save
        :param path: the path to save the descriptions at
        """
        path = clean_path(path)
        create_parent_dirs(path)
        save_obj = {"descriptions": [desc.dict() for desc in descs]}

        with open(path, "w") as file:
            json.dump(save_obj, file)
Ejemplo n.º 12
0
    def save_json(self, path: str):
        """
        :param path: the path to save the json file at representing the analyzed
            results
        """
        if not path.endswith(".json"):
            path += ".json"

        path = clean_path(path)
        create_parent_dirs(path)

        with open(path, "w") as file:
            dictionary = self.dict()
            json.dump(dictionary, file, indent=2)
Ejemplo n.º 13
0
def check_load_model(model: Union[str, ModelProto]) -> ModelProto:
    """
    Load an ONNX model from a given file path if supplied.
    If already a model proto, then returns.

    :param model: the model proto or path to the model onnx file to check for loading
    :return: the loaded onnx ModelProto
    """
    if isinstance(model, ModelProto):
        return model

    if isinstance(model, str):
        return onnx.load(clean_path(model))

    raise ValueError("unknown type given for model: {}".format(model))
Ejemplo n.º 14
0
def load_benchmark_info(load: str) -> BenchmarkInfo:
    """
    Load the benchmark info from a file or raw json.
    If load exists as a path, will read from the file and use that.
    Otherwise will try to parse the input as a raw json str.

    :param load: Either a file path to a json file or a raw json string.
    :type load: str
    :return: The loaded benchmark info.
    :rtype: FrameworkInfo
    """
    loaded_path = clean_path(load)

    if os.path.exists(loaded_path):
        with open(loaded_path, "r") as file:
            load = file.read()

    info = BenchmarkInfo.parse_raw(load)

    return info
Ejemplo n.º 15
0
def train_setup():
    def _create_optim(_model: Module) -> Optimizer:
        return SGD(
            _model.parameters(),
            lr=0.1,
            momentum=0.9,
            nesterov=True,
            weight_decay=0.0001,
        )

    # fill in the appropriate values below for your training flow
    train(
        working_dir=clean_path("."),
        config_path="/PATH/TO/CONFIG.yaml",
        model=None,
        train_dataset=None,
        val_dataset=None,
        batch_size=64,
        optim_const=_create_optim,
        loss=None,
        devices=default_device(),
    )
Ejemplo n.º 16
0
    def __init__(
        self,
        root: str,
        train: bool,
        image_size: Union[None, int, Tuple[int, int]] = 224,
        pre_resize_transforms: Union[
            SplitsTransforms, None] = SplitsTransforms(
                train=(
                    random_scaling_crop(),
                    tensorflow.image.random_flip_left_right,
                ),
                val=None,
            ),
        post_resize_transforms: Union[SplitsTransforms,
                                      None] = SplitsTransforms(
                                          train=(
                                              default_imagenet_normalizer(), ),
                                          val=(
                                              default_imagenet_normalizer(), ),
                                      ),
    ):
        self._root = os.path.join(clean_path(root),
                                  "train" if train else "val")
        if not os.path.exists(self._root):
            raise ValueError("Data set folder {} must exist".format(
                self._root))
        self._train = train
        if image_size is not None:
            self._image_size = (image_size if isinstance(image_size, tuple)
                                else (image_size, image_size))
        else:
            self._image_size = None
        self._pre_resize_transforms = pre_resize_transforms
        self._post_resize_transforms = post_resize_transforms

        self._num_images = len(
            [None for _ in glob.glob(os.path.join(self._root, "*", "*"))])
        self._num_classes = len(
            [None for _ in glob.glob(os.path.join(self._root, "*", ""))])
Ejemplo n.º 17
0
    def load_descs(path: str) -> List:
        """
        Load a list of AnalyzedLayerDesc from a json file

        :param path: the path to load the descriptions from
        :return: the loaded list of AnalyzedLayerDesc
        """
        path = clean_path(path)

        with open(path, "r") as file:
            obj = json.load(file)

        descs = []

        for desc_obj in obj["descriptions"]:
            desc_obj["type_"] = desc_obj["type"]
            del desc_obj["type"]
            del desc_obj["terminal"]
            del desc_obj["prunable"]
            descs.append(AnalyzedLayerDesc(**desc_obj))

        return descs
Ejemplo n.º 18
0
    def __init__(
        self,
        root: str,
        train: bool,
        image_size: int = 224,
        pre_resize_transforms: Union[
            SplitsTransforms, None] = SplitsTransforms(
                train=(
                    random_scaling_crop(),
                    tf_compat.image.random_flip_left_right,
                    tf_compat.image.random_flip_up_down,
                ),
                val=None,
            ),
        post_resize_transforms: Union[SplitsTransforms,
                                      None] = SplitsTransforms(
                                          train=(imagenet_normalizer, ),
                                          val=(
                                              center_square_crop(),
                                              imagenet_normalizer,
                                          ),
                                      ),
    ):
        self._root = os.path.join(clean_path(root),
                                  "train" if train else "val")
        if not os.path.exists(self._root):
            raise ValueError("Data set folder {} must exist".format(
                self._root))
        self._train = train
        self._image_size = image_size
        self._pre_resize_transforms = pre_resize_transforms
        self._post_resize_transforms = post_resize_transforms

        self._num_images = len(
            [None for _ in glob.glob(os.path.join(self._root, "*", "*"))])
        self._num_classes = len(
            [None for _ in glob.glob(os.path.join(self._root, "*", ""))])
Ejemplo n.º 19
0
 def __init__(self, output_dir: str):
     self._output_dir = clean_path(output_dir)
Ejemplo n.º 20
0
def train(
    working_dir: str,
    config_path: str,
    model: Module,
    train_dataset: Dataset,
    val_dataset: Dataset,
    batch_size: int,
    optim_const: Callable[[Module], Optimizer],
    loss: Union[LossWrapper, Callable[[Any, Any], Tensor]],
    devices: str,
):
    """
    Dataset setup
    """
    LOGGER.info("batch_size set to {}".format(batch_size))
    LOGGER.info("train_dataset set to {}".format(train_dataset))
    LOGGER.info("val_dataset set to {}".format(val_dataset))

    train_loader = DataLoader(
        train_dataset,
        batch_size=batch_size,
        shuffle=True,
        num_workers=8,
        pin_memory=True,
    )
    val_loader = DataLoader(
        val_dataset,
        batch_size=batch_size,
        shuffle=False,
        num_workers=8,
        pin_memory=True,
    )

    """
    Model, optimizer, loss setup
    """
    model_dir = clean_path(os.path.join(working_dir, "model"))
    optim = optim_const(model)

    LOGGER.info("model set to {}".format(model))
    LOGGER.info("optimizer set to {}".format(optim))
    LOGGER.info("loss set to {}".format(loss))
    LOGGER.info("devices set to {}".format(devices))

    """
    Manager and config setup
    """
    manager = ScheduledModifierManager.from_yaml(config_path)
    logs_dir = clean_path(os.path.join(working_dir, "logs"))
    loggers = [TensorBoardLogger(logs_dir), PythonLogger()]
    optim = ScheduledOptimizer(
        optim, model, manager, steps_per_epoch=len(train_loader), loggers=loggers
    )

    """
    Training and testing
    """
    model, device, device_ids = model_to_device(model, devices)
    trainer = ModuleTrainer(model, device, loss, optim, loggers=loggers)
    tester = ModuleTester(model, device, loss, loggers=loggers, log_steps=-1)

    epoch = -1
    tester.run_epoch(val_loader, epoch=epoch)

    for epoch in range(manager.max_epochs):
        LOGGER.info("starting training epoch {}".format(epoch))
        train_res = trainer.run_epoch(train_loader, epoch)
        LOGGER.info("finished training epoch {}: {}".format(epoch, train_res))
        val_res = tester.run_epoch(val_loader, epoch)
        LOGGER.info("finished validation epoch {}: {}".format(epoch, val_res))

    exporter = ModuleExporter(model, model_dir)
    exporter.export_pytorch(optim, epoch)

    for data in val_loader:
        exporter.export_onnx(data)
Ejemplo n.º 21
0
    def pb_to_onnx(
        inputs: List[Union[str, tf_compat.Tensor]],
        outputs: List[Union[str, tf_compat.Tensor]],
        pb_path: str,
        onnx_path: str,
        opset: int = default_onnx_opset(),
        custom_op_handlers=None,
        extra_opset=None,
        shape_override: Dict[str, List] = None,
    ):
        """
        Export an ONNX format for the graph from PB format.
        Should not be called within an active graph or session.

        :param inputs: the inputs the graph should be created for,
            can be either a list of names or a list of tensors
        :param outputs: the outputs the graph should be created for,
            can be either a list of names or a list of tensors
        :param pb_path: path to the existing PB file
        :param onnx_path: path to the output ONNX file
        :param opset: ONNX opset
        :param custom_op_handlers: dictionary of custom op handlers
        :param extra_opset: list of extra opset's
        :param shape_override: new shape to override
        """
        try:
            from tf2onnx import constants, optimizer, utils
            from tf2onnx.tfonnx import process_tf_graph, tf_optimize
        except ModuleNotFoundError:
            raise ModuleNotFoundError(
                "tf2onnx must be installed on the system before using export_onnx"
            )

        try:
            from tf2onnx import tf_loader as loader
        except Exception:
            from tf2onnx import loader

        pb_path = clean_path(pb_path)

        if not os.path.exists(pb_path):
            raise FileNotFoundError(
                ("no pb file for the model found at {}").format(pb_path)
            )

        inputs = [inp if isinstance(inp, str) else inp.name for inp in inputs]
        outputs = [out if isinstance(out, str) else out.name for out in outputs]

        graph_def, inputs, outputs = loader.from_graphdef(pb_path, inputs, outputs)
        graph_def = tf_optimize(inputs, outputs, graph_def, fold_constant=True)

        with tf_compat.Graph().as_default() as tf_graph:
            tf_compat.import_graph_def(graph_def, name="")

        with tf_compat.Session(graph=tf_graph):
            graph = process_tf_graph(
                tf_graph,
                continue_on_error=False,
                target=",".join(constants.DEFAULT_TARGET),
                opset=opset,
                custom_op_handlers=custom_op_handlers,
                extra_opset=extra_opset,
                shape_override=shape_override,
                input_names=inputs,
                output_names=outputs,
            )

        onnx_graph = optimizer.optimize_graph(graph)
        model_proto = onnx_graph.make_model("converted from {}".format(pb_path))

        onnx_path = clean_path(onnx_path)
        create_parent_dirs(onnx_path)
        utils.save_protobuf(onnx_path, model_proto)