Пример #1
0
    async def parse(self, data: Dict[Text, Any]) -> Dict[Text, Any]:
        project = data.get("project", RasaNLUModelConfig.DEFAULT_PROJECT_NAME)
        model = data.get("model")

        if project not in self.project_store:
            projects = self._list_projects(self.project_dir)

            cloud_provided_projects = self._list_projects_in_cloud()
            projects.extend(cloud_provided_projects)

            if project not in projects:
                raise InvalidProjectError(
                    "No project found with name '{}'.".format(project)
                )
            else:
                try:
                    self.project_store[project] = Project(
                        self.component_builder,
                        project,
                        self.project_dir,
                        self.remote_storage,
                    )
                except Exception as e:
                    raise InvalidProjectError(
                        "Unable to load project '{}'. Error: {}".format(project, e)
                    )

        time = data.get("time")
        response = self.project_store[project].parse(data["text"], time, model)

        if self.responses:
            self.responses.info(response)

        return self.format_response(response)
Пример #2
0
    def unload_model(self, project: Optional[Text], model: Text) -> Dict[Text, Any]:
        """Unload a model from server memory."""

        if project is None:
            raise InvalidProjectError("No project specified")
        elif project not in self.project_store:
            raise InvalidProjectError("Project {} could not be found".format(project))

        try:
            unloaded_model = self.project_store[project].unload(model)
            return unloaded_model
        except KeyError:
            raise InvalidProjectError(
                "Failed to unload model {} for project {}.".format(model, project)
            )
Пример #3
0
    async def start_train_process(
        self,
        data_file: Text,
        project: Text,
        train_config: RasaNLUModelConfig,
        model_name: Optional[Text] = None,
    ) -> Text:
        """Start a model training."""

        if not project:
            raise InvalidProjectError("Missing project name to train")

        if self._worker_processes <= self._current_worker_processes:
            raise MaxWorkerProcessError

        if project in self.project_store:
            self.project_store[project].status = STATUS_TRAINING
        elif project not in self.project_store:
            self.project_store[project] = Project(
                self.component_builder, project, self.project_dir, self.remote_storage
            )
            self.project_store[project].status = STATUS_TRAINING

        loop = asyncio.get_event_loop()

        logger.debug("New training queued")

        self._current_worker_processes += 1
        self.project_store[project].current_worker_processes += 1

        task = loop.run_in_executor(
            self.pool,
            do_train_in_worker,
            train_config,
            data_file,
            self.project_dir,
            project,
            model_name,
            self.remote_storage,
        )

        try:
            model_path = await task
            model_dir = os.path.basename(os.path.normpath(model_path))
            self.project_store[project].update(model_dir)

            if (
                self.project_store[project].current_worker_processes == 1
                and self.project_store[project].status == STATUS_TRAINING
            ):
                self.project_store[project].status = STATUS_READY
            return model_path
        except Exception as e:
            logger.warning(e)
            self.project_store[project].status = STATUS_FAILED
            self.project_store[project].error_message = str(e)
            raise
        finally:
            self._current_worker_processes -= 1
            self.project_store[project].current_worker_processes -= 1
Пример #4
0
    def evaluate(
        self, data: Text, project: Optional[Text] = None, model: Optional[Text] = None
    ) -> Dict[Text, Any]:
        """Perform a model evaluation."""

        project = project or RasaNLUModelConfig.DEFAULT_PROJECT_NAME
        model = model or None
        file_name = utils.create_temporary_file(data, "_training_data")

        if project not in self.project_store:
            raise InvalidProjectError("Project {} could not be found".format(project))

        model_name = self.project_store[project]._dynamic_load_model(model)

        self.project_store[project]._loader_lock.acquire()
        try:
            if not self.project_store[project]._models.get(model_name):
                interpreter = self.project_store[project]._interpreter_for_model(
                    model_name
                )
                self.project_store[project]._models[model_name] = interpreter
        finally:
            self.project_store[project]._loader_lock.release()

        return run_evaluation(
            data_path=file_name,
            model=self.project_store[project]._models[model_name],
            errors_filename=None,
        )
Пример #5
0
    def start_train_process(self,
                            data_file: Text,
                            project: Text,
                            train_config: RasaNLUModelConfig,
                            model_name: Optional[Text] = None) -> Deferred:
        """Start a model training."""

        if not project:
            raise InvalidProjectError("Missing project name to train")

        if self._training_processes <= self._current_training_processes:
            raise MaxTrainingError

        if project in self.project_store:
            self.project_store[project].status = STATUS_TRAINING
        elif project not in self.project_store:
            self.project_store[project] = Project(self.component_builder,
                                                  project, self.project_dir,
                                                  self.remote_storage)
            self.project_store[project].status = STATUS_TRAINING

        def training_callback(model_path):
            model_dir = os.path.basename(os.path.normpath(model_path))
            self.project_store[project].update(model_dir)
            self._current_training_processes -= 1
            self.project_store[project].current_training_processes -= 1
            if (self.project_store[project].status == STATUS_TRAINING
                    and self.project_store[project].current_training_processes
                    == 0):
                self.project_store[project].status = STATUS_READY
            return model_path

        def training_errback(failure):
            logger.warning(failure)

            self._current_training_processes -= 1
            self.project_store[project].current_training_processes -= 1
            self.project_store[project].status = STATUS_FAILED
            self.project_store[project].error_message = str(failure)

            return failure

        logger.debug("New training queued")

        self._current_training_processes += 1
        self.project_store[project].current_training_processes += 1

        result = self.pool.submit(do_train_in_worker,
                                  train_config,
                                  data_file,
                                  path=self.project_dir,
                                  project=project,
                                  fixed_model_name=model_name,
                                  storage=self.remote_storage)
        result = deferred_from_future(result)
        result.addCallback(training_callback)
        result.addErrback(training_errback)

        return result
Пример #6
0
    def evaluate(self,
                 data: Text,
                 project: Optional[Text] = None,
                 model: Optional[Text] = None) -> Deferred:
        """Perform a model evaluation."""

        logger.debug("Evaluation request received for "
                     "project '{}' and model '{}'.".format(project, model))

        if self._worker_processes <= self._current_worker_processes:
            raise MaxWorkerProcessError

        project = project or RasaNLUModelConfig.DEFAULT_PROJECT_NAME
        data_path = utils.create_temporary_file(data, "_training_data")

        if project not in self.project_store:
            raise InvalidProjectError("Project '{}' could not "
                                      "be found.".format(project))

        model = model or self.project_store[project]._dynamic_load_model(model)

        if model == FALLBACK_MODEL_NAME:
            raise UnsupportedModelError("No model in project '{}' to "
                                        "evaluate.".format(project))

        model_path = os.path.join(self.project_store[project]._path, model)

        def evaluation_callback(result):
            logger.debug("Evaluation was successful")

            self._current_worker_processes -= 1
            self.project_store[project].current_worker_processes -= 1

            return result

        def evaluation_errback(failure):
            logger.warning(failure)

            self._current_worker_processes -= 1
            self.project_store[project].current_worker_processes -= 1

            return failure

        logger.debug("New evaluation queued.")

        self._current_worker_processes += 1
        self.project_store[project].current_worker_processes += 1

        result = self.pool.submit(run_evaluation,
                                  data_path,
                                  model_path,
                                  errors_filename=None)

        result = deferred_from_future(result)
        result.addCallback(evaluation_callback)
        result.addErrback(evaluation_errback)

        return result
Пример #7
0
    async def evaluate(
        self, data: Text, project: Optional[Text] = None, model: Optional[Text] = None
    ) -> Dict:
        """Perform a model evaluation."""

        logger.debug(
            "Evaluation request received for "
            "project '{}' and model '{}'.".format(project, model)
        )

        if self._worker_processes <= self._current_worker_processes:
            raise MaxWorkerProcessError

        project = project or RasaNLUModelConfig.DEFAULT_PROJECT_NAME
        data_path = utils.create_temporary_file(data, "_training_data")

        if project not in self.project_store:
            raise InvalidProjectError(
                "Project '{}' could not be found.".format(project)
            )

        model = model or self.project_store[project]._dynamic_load_model(model)

        if model == FALLBACK_MODEL_NAME:
            raise UnsupportedModelError(
                "No model in project '{}' to evaluate.".format(project)
            )

        model_path = os.path.join(self.project_store[project]._path, model)

        logger.debug("New evaluation queued.")

        self._current_worker_processes += 1
        self.project_store[project].current_worker_processes += 1

        loop = asyncio.get_event_loop()

        task = loop.run_in_executor(self.pool, run_evaluation, data_path, model_path)

        try:
            return await task
        except Exception as e:
            logger.warning(e)
            self.project_store[project].status = STATUS_FAILED
            self.project_store[project].error_message = str(e)
            raise
        finally:
            self._current_worker_processes -= 1
            self.project_store[project].current_worker_processes -= 1