Exemple #1
0
 def _run_local(self):
     _LOGGER.info(
         "adding data file(s) to project_id {} from file path {}".format(
             self.project_id, self.uri
         )
     )
     if os.path.isdir(self.uri):
         _LOGGER.info("Path {} is directory".format(self.uri))
         yield JobProgressSchema().dump(
             {"iter_indefinite": False, "iter_val": 0.0, "iter_class": "copy_folder"}
         )
         for progress, _ in self._run_copy_folder(self.uri):
             yield JobProgressSchema().dump(
                 {
                     "iter_indefinite": False,
                     "iter_val": progress,
                     "iter_class": "copy_folder",
                 }
             )
     else:
         _LOGGER.info("Path {} is file".format(self.uri))
         yield JobProgressSchema().dump(
             {"iter_indefinite": True, "iter_class": "copy"}
         )
         self._run_copy_file(self.uri, self._get_project_data())
Exemple #2
0
    def _run_pruning_sensitivity(
        self,
        model: ProjectModel,
        data: DataLoader,
        profile: ProjectLossProfile,
        num_steps: int,
    ):
        analysis = None

        for (analysis, progress) in pruning_perf_sens_one_shot_iter(
                model.file_path,
                data,
                self.batch_size,
                self.core_count,
                self.iterations_per_check,
                self.warmup_iterations_per_check,
                optimization_level=
                0,  # TODO: fix timings so optimization_level=1 works
                iters_sleep_time=
                0.1,  # hack for current issue with deepsparse and GIL
        ):
            yield JobProgressSchema().dump({
                "iter_indefinite": False,
                "iter_class": "analysis",
                "iter_val": progress.val,
                "num_steps": num_steps,
                "step_index": 1,  # baseline always runs before
                "step_class": "pruning_estimation",
            })

        # update but do not save until everything is completed so we don't hammer the DB
        CreatePerfProfileJobWorker.add_profile_pruning_results(
            profile, analysis.results_model, analysis.results)
Exemple #3
0
    def _run_baseline_perf(
        self,
        model: ProjectModel,
        data: DataLoader,
        profile: ProjectLossProfile,
        num_steps: int,
    ):
        analysis = None

        for (analysis, progress) in pruning_perf_sens_one_shot_iter(
                model.file_path,
                data,
                self.batch_size,
                self.core_count,
                self.iterations_per_check,
                self.warmup_iterations_per_check,
                sparsity_levels=[0.0],
                optimization_level=1,
        ):
            yield JobProgressSchema().dump({
                "iter_indefinite": False,
                "iter_class": "analysis",
                "iter_val": progress.val,
                "num_steps": num_steps,
                "step_index": 0,  # baseline always runs first
                "step_class": "baseline_estimation",
            })

        # update but do not save until everything is completed so we don't hammer the DB
        CreatePerfProfileJobWorker.add_profile_baseline_results(
            profile, analysis.results_model, analysis.results)
    def _run_download(self) -> Iterator[Dict[str, Any]]:
        _LOGGER.info(
            ("adding model file to project_id {} and "
             "model_id {} from url {}").format(self.project_id, self.model_id,
                                               self.uri))

        # yield start progress to mark the expected flow
        yield JobProgressSchema().dump({
            "iter_indefinite": False,
            "iter_class": "download",
            "iter_val": 0.0
        })

        model = self._get_project_model()

        with NamedTemporaryFile() as temp:
            temp_path = os.path.join(gettempdir(), temp.name)

            for download_progress in download_file_iter(self._uri,
                                                        temp_path,
                                                        overwrite=True):
                progress_val = (float(download_progress.downloaded) /
                                float(download_progress.content_length)
                                if download_progress.content_length else None)

                yield JobProgressSchema().dump({
                    "iter_indefinite": False,
                    "iter_class": "download",
                    "iter_val": progress_val,
                })

            ModelFromPathJobWorker._save_project_model(model, temp_path)

        _LOGGER.info("added model file to project_id {} and "
                     "model_id {} from url {}".format(self.project_id,
                                                      self.model_id, self.uri))
Exemple #5
0
    def _run_baseline_loss(self, model: ProjectModel,
                           profile: ProjectLossProfile, num_steps: int):
        analysis = None

        for (analysis, progress) in pruning_loss_sens_magnitude_iter(
                model.file_path, [0.0]):
            yield JobProgressSchema().dump({
                "iter_indefinite": False,
                "iter_class": "analysis",
                "iter_val": progress.val,
                "num_steps": num_steps,
                "step_index": 0,  # baseline always runs first
                "step_class": "baseline_estimation",
            })

        # update but do not save until everything is completed so we don't hammer the DB
        CreateLossProfileJobWorker.add_profile_baseline_results(
            profile, analysis.results_model, analysis.results)
Exemple #6
0
    def _run_weight_magnitude_pruning_sensitivity(self, model: ProjectModel,
                                                  profile: ProjectLossProfile,
                                                  num_steps: int):
        if self.pruning_structure != "unstructured":
            raise ValueError(
                "pruning_structure of {} is not currently supported".format(
                    self.pruning_structure))

        analysis = None

        for (analysis,
             progress) in pruning_loss_sens_magnitude_iter(model.file_path):
            yield JobProgressSchema().dump({
                "iter_indefinite": False,
                "iter_class": "analysis",
                "iter_val": progress.val,
                "num_steps": num_steps,
                "step_index": 1,  # baseline always runs before
                "step_class": "pruning_estimation",
            })

        # update but do not save until everything is completed so we don't hammer the DB
        CreateLossProfileJobWorker.add_profile_pruning_results(
            profile, analysis.results_model, analysis.results)
    def _run_local(self) -> Iterator[Dict[str, Any]]:
        _LOGGER.info(
            ("adding model file to project_id {} and "
             "model_id {} from file path {}").format(self.project_id,
                                                     self.model_id, self.uri))

        # yield start progress to mark the expected flow
        yield JobProgressSchema().dump({
            "iter_indefinite": True,
            "iter_class": "copy"
        })

        model = self._get_project_model()

        if not os.path.exists(self._uri):
            raise ValueError("local path of {} does not exist".format(
                self._uri))

        ModelFromPathJobWorker._save_project_model(model, self._uri)

        _LOGGER.info(
            ("added model file to project_id {} and "
             "model_id {} from file path {}").format(self.project_id,
                                                     self.model_id, self.uri))
    def run(self) -> Iterator[Dict[str, Any]]:
        """
        Perform the work for the job.
        Runs and saves the appropriate benchmark based on the configuration

        :return: an iterator containing progress update information
        """
        _LOGGER.info(("running benchmark for project_id {} and "
                      "model_id {} and benchmark_id {} with "
                      "core_counts:{}, batch sizes:{} "
                      "instruction_sets:{}, inference_models:{} ").format(
                          self.project_id,
                          self.model_id,
                          self.benchmark_id,
                          self.core_counts,
                          self.batch_sizes,
                          self.instruction_sets,
                          self.inference_models,
                      ))

        project_model = self._get_project_model()
        project_model.validate_filesystem()
        benchmark = self._get_project_benchmark()
        benchmark.result = {"benchmarks": []}
        sys_info = get_ml_sys_info()
        cores_per_socket = (sys_info["cores_per_socket"]
                            if "cores_per_socket" in sys_info else 1)
        num_sockets = sys_info[
            "num_sockets"] if "num_sockets" in sys_info else 1
        max_cores = cores_per_socket * num_sockets

        optims = set()
        for inference_model in self.inference_models:
            inference_model_optimization = inference_model[
                "inference_model_optimization"]
            if inference_model_optimization:
                optims.add(inference_model_optimization)

        iterables = [
            x for x in itertools.product(self.core_counts, self.batch_sizes,
                                         self.inference_models)
        ]
        num_steps = len(iterables) + len(optims)
        step_index = 0

        pruned_models = {}

        for inference_model_optimization in optims:
            model_proto = check_load_model(project_model.file_path)

            for progress in self._get_pruned_model_proto(
                    model_proto, inference_model_optimization):
                yield JobProgressSchema().dump({
                    "iter_indefinite":
                    False,
                    "iter_class":
                    "benchmark",
                    "iter_val": (step_index + progress) / num_steps,
                    "num_steps":
                    num_steps,
                    "step_index":
                    step_index,
                    "step_class":
                    "pruning_{}".format(inference_model_optimization),
                })
            pruned_models[inference_model_optimization] = model_proto

            step_index += 1

        for core_count, batch_size, inference_model in iterables:
            inference_engine = inference_model["inference_engine"]
            inference_model_optimization = inference_model[
                "inference_model_optimization"]

            model = project_model.file_path

            if inference_model_optimization:
                model = pruned_models[inference_model_optimization]

            if inference_engine == ORT_CPU_ENGINE and (core_count == max_cores
                                                       or core_count < 1):
                runner = ORTModelRunner(model, batch_size=batch_size)
            elif inference_engine == ORT_CPU_ENGINE and (
                    core_count != max_cores and core_count > 0):
                _LOGGER.error(
                    "Can only run onnxruntime with max core count of {}".
                    format(max_cores))
                raise Exception(
                    "Can only run onnxruntime with max core count of {}".
                    format(max_cores))
            elif inference_engine == DEEPSPARSE_ENGINE:
                runner = DeepSparseModelRunner(model, batch_size, core_count)
            elif inference_engine == ORT_GPU_ENGINE:
                raise NotImplementedError()
            else:
                raise ValueError(
                    "Invalid inference engine {}".format(inference_engine))

            step_class = ("{}_optim_{}_batch_size_{}_core_count_{}".format(
                inference_engine,
                inference_model_optimization,
                batch_size,
                core_count,
            ) if inference_model_optimization else
                          "{}_batch_size_{}_core_count_{}".format(
                              inference_engine, batch_size, core_count))

            _LOGGER.debug(step_class)

            for progress in self._run_benchmark(
                    benchmark,
                    model,
                    runner,
                    core_count,
                    batch_size,
                    inference_engine,
                    inference_model_optimization,
                    num_steps,
                    step_index,
            ):
                yield JobProgressSchema().dump({
                    "iter_indefinite": False,
                    "iter_class": "benchmark",
                    "iter_val": progress,
                    "num_steps": num_steps,
                    "step_index": step_index,
                    "step_class": step_class,
                })
            step_index += 1
        benchmark.save()
Exemple #9
0
    def _run_download(self):
        _LOGGER.info(
            ("adding data file(s) to project_id {} from url {}").format(
                self.project_id, self.uri
            )
        )

        yield JobProgressSchema().dump(
            {"iter_indefinite": False, "iter_class": "download", "iter_val": 0.0}
        )

        with NamedTemporaryFile() as temp:
            temp_path = os.path.join(gettempdir(), temp.name)

            for download_progress in download_file_iter(
                self._uri, temp_path, overwrite=True
            ):
                progress_val = (
                    float(download_progress.downloaded)
                    / float(download_progress.content_length)
                    if download_progress.content_length
                    else None
                )

                yield JobProgressSchema().dump(
                    {
                        "iter_indefinite": False,
                        "iter_class": "download",
                        "iter_val": progress_val / 3 if progress_val else 0,
                        "step_class": "download",
                        "step_index": 0,
                    }
                )

            if tarfile.is_tarfile(temp_path):
                _LOGGER.info("Untarring file downloaded from {}".format(self.uri))
                yield JobProgressSchema().dump(
                    {
                        "iter_indefinite": False,
                        "iter_class": "download",
                        "iter_val": 1 / 3,
                        "step_class": "untarring",
                        "step_index": 1,
                    }
                )
                with TemporaryDirectory() as extract_path, tarfile.open(
                    temp_path, "r"
                ) as tar:
                    tar.extractall(extract_path)
                    yield JobProgressSchema().dump(
                        {
                            "iter_indefinite": False,
                            "iter_class": "download",
                            "iter_val": 2 / 3,
                            "step_class": "untarring",
                            "step_index": 1,
                        }
                    )
                    for progress, _ in self._run_copy_folder(extract_path):
                        yield JobProgressSchema().dump(
                            {
                                "iter_indefinite": False,
                                "iter_class": "download",
                                "iter_val": 2 / 3 + progress / 3,
                                "step_class": "copy_folder",
                                "step_index": 2,
                            }
                        )
            else:
                self._run_copy_file(temp_path, self._get_project_data())
                yield JobProgressSchema().dump(
                    {
                        "iter_indefinite": False,
                        "iter_class": "download",
                        "iter_val": 1,
                        "step_class": "copy",
                        "step_index": 1,
                    }
                )