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)
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) )
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
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, )
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
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
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