def package_model( fingerprint: Fingerprint, output_directory: Text, train_path: Text, fixed_model_name: Optional[Text] = None, model_prefix: Text = "", ) -> Text: """ Compress a trained model. Args: fingerprint: fingerprint of the model output_directory: path to the directory in which the model should be stored train_path: path to uncompressed model fixed_model_name: name of the compressed model file model_prefix: prefix of the compressed model file Returns: path to 'tar.gz' model file """ output_directory = create_output_path( output_directory, prefix=model_prefix, fixed_name=fixed_model_name ) create_package_rasa(train_path, output_directory, fingerprint) print_success( "Your Rasa model is trained and saved at '{}'.".format( os.path.abspath(output_directory) ) ) return output_directory
def train_nlu(config: Text, nlu_data: Text, output: Text, train_path: Optional[Text]) -> Optional["Interpreter"]: """Trains a NLU model. Args: config: Path to the config file for NLU. nlu_data: Path to the NLU training data. output: Output path. train_path: If `None` the model will be trained in a temporary directory, otherwise in the provided directory. Returns: If `train_path` is given it returns the path to the model archive, otherwise the path to the directory with the trained model files. """ import rasa_nlu _train_path = train_path or tempfile.mkdtemp() _, nlu_model, _ = rasa_nlu.train(config, nlu_data, _train_path, project="", fixed_model_name="nlu") if not train_path: nlu_data = data.get_nlu_directory(nlu_data) output_path = create_output_path(output, prefix="nlu-") new_fingerprint = model.model_fingerprint(config, nlu_data=nlu_data) model.create_package_rasa(_train_path, output_path, new_fingerprint) print_success("Your Rasa NLU model is trained and saved at '{}'." "".format(output_path)) return nlu_model
def print_train_or_instructions(args: argparse.Namespace, path: Text) -> None: import questionary print_success("Finished creating project structure.") should_train = questionary.confirm( "Do you want to train an initial model? 💪🏽").skip_if(args.no_prompt, default=True) if should_train: print_success("Training an initial model...") config = os.path.join(path, DEFAULT_CONFIG_PATH) training_files = os.path.join(path, DEFAULT_DATA_PATH) domain = os.path.join(path, DEFAULT_DOMAIN_PATH) output = os.path.join(path, create_output_path()) args.model = rasa.train(domain, config, training_files, output) print_run_or_instructions(args, path) else: print_success( "No problem 👍🏼. You can also train a model later by going " "to the project directory and running 'rasa train'." "".format(path))
def create_model_path(model_name, path_to_model): parent_dir = os.path.abspath(os.path.join(path_to_model, os.pardir)) if model_name is not None: if not model_name.endswith(".tar.gz"): model_name += ".tar.gz" output_path = os.path.join(parent_dir, model_name) else: output_path = create_output_path(parent_dir, prefix="nlu-") return output_path
def train_project(path: Text) -> Optional[Text]: print_success("Training an initial model...") config = os.path.join(path, DEFAULT_CONFIG_PATH) training_files = os.path.join(path, DEFAULT_DATA_PATH) domain = os.path.join(path, DEFAULT_DOMAIN_PATH) output = os.path.join(path, create_output_path()) model = rasa.train(domain, config, training_files, output) return model
def train_nlu(config: Text, nlu_data: Text, output: Text, train_path: Optional[Text]) -> Optional[Text]: """Trains a NLU model. Args: config: Path to the config file for NLU. nlu_data: Path to the NLU training data. output: Output path. train_path: If `None` the model will be trained in a temporary directory, otherwise in the provided directory. Returns: If `train_path` is given it returns the path to the model archive, otherwise the path to the directory with the trained model files. """ import rasa.nlu.train config = get_valid_config(config, CONFIG_MANDATORY_KEYS_NLU) if not train_path: # training NLU only hence the training files still have to be selected skill_imports = SkillSelector.load(config) nlu_data_directory = data.get_nlu_directory(nlu_data, skill_imports) else: nlu_data_directory = nlu_data if not os.listdir(nlu_data_directory): print_error( "No NLU data given. Please provide NLU data in order to train " "a Rasa NLU model.") return _train_path = train_path or tempfile.mkdtemp() print_color("Start training NLU model ...", color=bcolors.OKBLUE) _, nlu_model, _ = rasa.nlu.train(config, nlu_data_directory, _train_path, fixed_model_name="nlu") print_color("Done.", color=bcolors.OKBLUE) if not train_path: output_path = create_output_path(output, prefix="nlu-") new_fingerprint = model.model_fingerprint(config, nlu_data=nlu_data_directory) model.create_package_rasa(_train_path, output_path, new_fingerprint) print_success( "Your Rasa NLU model is trained and saved at '{}'.".format( output_path)) return output_path return _train_path
async def _train_core_with_validated_data( domain: Domain, config: Text, story_directory: Text, output: Text, train_path: Optional[Text] = None, fixed_model_name: Optional[Text] = None, uncompress: bool = False, kwargs: Optional[Dict] = None, ) -> Optional[Text]: """Train Core with validated training and config data.""" import rasa.core.train if not os.listdir(story_directory): print_error( "No dialogue data given. Please provide dialogue data in order to " "train a Rasa Core model.") return _train_path = train_path or tempfile.mkdtemp() # normal (not compare) training print_color("Start training dialogue model ...", color=bcolors.OKBLUE) await rasa.core.train( domain_file=domain, stories_file=story_directory, output_path=os.path.join(_train_path, "core"), policy_config=config, kwargs=kwargs, ) print_color("Done.", color=bcolors.OKBLUE) if not train_path: # Only Core was trained. output_path = create_output_path(output, prefix="core-", fixed_name=fixed_model_name) new_fingerprint = model.model_fingerprint(config, domain, stories=story_directory) model.create_package_rasa(_train_path, output_path, new_fingerprint) if uncompress: output_path = decompress(output_path) print_success( "Your Rasa Core model is trained and saved at '{}'.".format( output_path)) return output_path return _train_path
async def train_core_async( domain: Text, config: Text, stories: Text, output: Text, train_path: Optional[Text] = None, kwargs: Optional[Dict] = None, ) -> Optional[Text]: """Trains a Core model. Args: domain: Path to the domain file. config: Path to the config file for Core. stories: Path to the Core training data. output: Output path. train_path: If `None` the model will be trained in a temporary directory, otherwise in the provided directory. kwargs: Additional training parameters. Returns: If `train_path` is given it returns the path to the model archive, otherwise the path to the directory with the trained model files. """ import rasa.core.train config = get_valid_config(config, CONFIG_MANDATORY_KEYS_CORE) _train_path = train_path or tempfile.mkdtemp() # normal (not compare) training core_model = await rasa.core.train( domain_file=domain, stories_file=data.get_core_directory(stories), output_path=os.path.join(_train_path, "core"), policy_config=config, kwargs=kwargs, ) if not train_path: # Only Core was trained. stories = data.get_core_directory(stories) output_path = create_output_path(output, prefix="core-") new_fingerprint = model.model_fingerprint(config, domain, stories=stories) model.create_package_rasa(_train_path, output_path, new_fingerprint) print_success( "Your Rasa Core model is trained and saved at '{}'.".format( output_path)) return core_model
def _package_model( new_fingerprint: Fingerprint, output_path: Text, train_path: Text, fixed_model_name: Optional[Text] = None, model_prefix: Text = "", ): output_path = create_output_path(output_path, prefix=model_prefix, fixed_name=fixed_model_name) model.create_package_rasa(train_path, output_path, new_fingerprint) print_success("Your Rasa model is trained and saved at '{}'.".format( os.path.abspath(output_path))) return output_path
def _train_nlu_with_validated_data( config: Text, nlu_data_directory: Text, output: Text, train_path: Optional[Text] = None, fixed_model_name: Optional[Text] = None, uncompress: bool = False, ) -> Optional[Text]: """Train NLU with validated training and config data.""" import rasa.nlu.train if not os.listdir(nlu_data_directory): print_error( "No NLU data given. Please provide NLU data in order to train " "a Rasa NLU model.") return _train_path = train_path or tempfile.mkdtemp() print_color("Start training NLU model ...", color=bcolors.OKBLUE) _, nlu_model, _ = rasa.nlu.train(config, nlu_data_directory, _train_path, fixed_model_name="nlu") print_color("Done.", color=bcolors.OKBLUE) if not train_path: # Only NLU was trained output_path = create_output_path(output, prefix="nlu-", fixed_name=fixed_model_name) new_fingerprint = model.model_fingerprint(config, nlu_data=nlu_data_directory) model.create_package_rasa(_train_path, output_path, new_fingerprint) if uncompress: output_path = decompress(output_path) print_success( "Your Rasa NLU model is trained and saved at '{}'.".format( output_path)) return output_path return _train_path
def print_train_or_instructions(args: argparse.Namespace, path: Text) -> None: print_success("Your bot is ready to go!") should_train = questionary.confirm("Do you want me to train an initial " "model for the bot? 💪🏽").ask() if should_train: config = os.path.join(path, DEFAULT_CONFIG_PATH) training_files = os.path.join(path, DEFAULT_DATA_PATH) domain = os.path.join(path, DEFAULT_DOMAIN_PATH) output = os.path.join(path, create_output_path()) args.model = rasa.train(domain, config, training_files, output) print_run_or_instructions(args, path) else: print_success("No problem 👍🏼. You can also train me later by going " "to the project directory and running 'rasa train'." "".format(path))
async def train_core_async(domain: Text, config: Text, stories: Text, output: Text, train_path: Optional[Text]) -> Optional[Text]: """Trains a Core model. Args: domain: Path to the domain file. config: Path to the config file for Core. stories: Path to the Core training data. output: Output path. train_path: If `None` the model will be trained in a temporary directory, otherwise in the provided directory. Returns: If `train_path` is given it returns the path to the model archive, otherwise the path to the directory with the trained model files. """ import rasa_core.train # normal (not compare) training core_model = await rasa_core.train(domain_file=domain, stories_file=stories, output_path=os.path.join( train_path, "core"), policy_config=config) if not train_path: # Only Core was trained. stories = data.get_core_directory(stories) output_path = create_output_path(output, prefix="core-") new_fingerprint = model.model_fingerprint(config, domain, stories=stories) model.create_package_rasa(train_path, output_path, new_fingerprint) print_success("Your Rasa Core model is trained and saved at '{}'." "".format(output_path)) return core_model
async def train_async(domain: Text, config: Text, training_files: Union[Text, List[Text]], output: Text = DEFAULT_MODELS_PATH, force_training: bool = False) -> Optional[Text]: """Trains a Rasa model (Core and NLU). Args: domain: Path to the domain file. config: Path to the config for Core and NLU. training_files: Paths to the training data for Core and NLU. output: Output path. force_training: If `True` retrain model even if data has not changed. Returns: Path of the trained model archive. """ train_path = tempfile.mkdtemp() old_model = model.get_latest_model(output) retrain_core = True retrain_nlu = True story_directory, nlu_data_directory = data.get_core_nlu_directories( training_files) new_fingerprint = model.model_fingerprint(config, domain, nlu_data_directory, story_directory) if not force_training and old_model: unpacked = model.unpack_model(old_model) old_core, old_nlu = model.get_model_subdirectories(unpacked) last_fingerprint = model.fingerprint_from_path(unpacked) if not model.core_fingerprint_changed(last_fingerprint, new_fingerprint): target_path = os.path.join(train_path, "core") retrain_core = not model.merge_model(old_core, target_path) if not model.nlu_fingerprint_changed(last_fingerprint, new_fingerprint): target_path = os.path.join(train_path, "nlu") retrain_nlu = not model.merge_model(old_nlu, target_path) if force_training or retrain_core: await train_core_async(domain, config, story_directory, output, train_path) else: print("Dialogue data / configuration did not change. " "No need to retrain dialogue model.") if force_training or retrain_nlu: train_nlu(config, nlu_data_directory, output, train_path) else: print("NLU data / configuration did not change. " "No need to retrain NLU model.") if retrain_core or retrain_nlu: output = create_output_path(output) model.create_package_rasa(train_path, output, new_fingerprint) print("Train path: '{}'.".format(train_path)) print_success("Your bot is trained and ready to take for a spin!") return output else: print("Nothing changed. You can use the old model stored at {}" "".format(os.path.abspath(old_model))) return old_model
async def train_async( domain: Text, config: Text, training_files: Union[Text, List[Text]], output: Text = DEFAULT_MODELS_PATH, force_training: bool = False, kwargs: Optional[Dict] = None, ) -> Optional[Text]: """Trains a Rasa model (Core and NLU). Args: domain: Path to the domain file. config: Path to the config for Core and NLU. training_files: Paths to the training data for Core and NLU. output: Output path. force_training: If `True` retrain model even if data has not changed. kwargs: Additional training parameters. Returns: Path of the trained model archive. """ config = get_valid_config(config, CONFIG_MANDATORY_KEYS) train_path = tempfile.mkdtemp() old_model = model.get_latest_model(output) retrain_core = True retrain_nlu = True story_directory, nlu_data_directory = data.get_core_nlu_directories(training_files) new_fingerprint = model.model_fingerprint( config, domain, nlu_data_directory, story_directory ) dialogue_data_not_present = not os.listdir(story_directory) nlu_data_not_present = not os.listdir(nlu_data_directory) if dialogue_data_not_present and nlu_data_not_present: print_error( "No training data given. Please provide dialogue and NLU data in " "order to train a Rasa model." ) return if dialogue_data_not_present: print_warning( "No dialogue data present. Just a Rasa NLU model will be trained." ) return train_nlu(config, nlu_data_directory, output, None) if nlu_data_not_present: print_warning("No NLU data present. Just a Rasa Core model will be trained.") return await train_core_async( domain, config, story_directory, output, None, kwargs ) if not force_training and old_model: unpacked = model.unpack_model(old_model) old_core, old_nlu = model.get_model_subdirectories(unpacked) last_fingerprint = model.fingerprint_from_path(unpacked) if not model.core_fingerprint_changed(last_fingerprint, new_fingerprint): target_path = os.path.join(train_path, "core") retrain_core = not model.merge_model(old_core, target_path) if not model.nlu_fingerprint_changed(last_fingerprint, new_fingerprint): target_path = os.path.join(train_path, "nlu") retrain_nlu = not model.merge_model(old_nlu, target_path) if force_training or retrain_core: await train_core_async( domain, config, story_directory, output, train_path, kwargs ) else: print ( "Dialogue data / configuration did not change. " "No need to retrain dialogue model." ) if force_training or retrain_nlu: train_nlu(config, nlu_data_directory, output, train_path) else: print ("NLU data / configuration did not change. No need to retrain NLU model.") if retrain_core or retrain_nlu: output = create_output_path(output) model.create_package_rasa(train_path, output, new_fingerprint) print_success("Your bot is trained and ready to take for a spin!") return output else: print_success( "Nothing changed. You can use the old model stored at '{}'" "".format(os.path.abspath(old_model)) ) return old_model
async def train_async( domain: Optional, config: Text, training_files: Optional[Union[Text, List[Text]]], output_path: Text = DEFAULT_MODELS_PATH, force_training: bool = False, fixed_model_name: Optional[Text] = None, uncompress: bool = False, kwargs: Optional[Dict] = None, ) -> Optional[Text]: """Trains a Rasa model (Core and NLU). Args: domain: Path to the domain file. config: Path to the config for Core and NLU. training_files: Paths to the training data for Core and NLU. output_path: Output path. force_training: If `True` retrain model even if data has not changed. fixed_model_name: Name of model to be stored. uncompress: If `True` the model will not be compressed. kwargs: Additional training parameters. Returns: Path of the trained model archive. """ config = get_valid_config(config, CONFIG_MANDATORY_KEYS) train_path = tempfile.mkdtemp() old_model = model.get_latest_model(output_path) retrain_core = True retrain_nlu = True skill_imports = SkillSelector.load(config) try: domain = Domain.load(domain, skill_imports) except InvalidDomain as e: print_error(e) return None story_directory, nlu_data_directory = data.get_core_nlu_directories( training_files, skill_imports) new_fingerprint = model.model_fingerprint(config, domain, nlu_data_directory, story_directory) dialogue_data_not_present = not os.listdir(story_directory) nlu_data_not_present = not os.listdir(nlu_data_directory) if dialogue_data_not_present and nlu_data_not_present: print_error( "No training data given. Please provide dialogue and NLU data in " "order to train a Rasa model.") return if dialogue_data_not_present: print_warning( "No dialogue data present. Just a Rasa NLU model will be trained.") return _train_nlu_with_validated_data( config=config, nlu_data_directory=nlu_data_directory, output=output_path, fixed_model_name=fixed_model_name, uncompress=uncompress, ) if nlu_data_not_present: print_warning( "No NLU data present. Just a Rasa Core model will be trained.") return await _train_core_with_validated_data( domain=domain, config=config, story_directory=story_directory, output=output_path, fixed_model_name=fixed_model_name, uncompress=uncompress, kwargs=kwargs, ) if not force_training and old_model: unpacked = model.unpack_model(old_model) old_core, old_nlu = model.get_model_subdirectories(unpacked) last_fingerprint = model.fingerprint_from_path(unpacked) if not model.core_fingerprint_changed(last_fingerprint, new_fingerprint): target_path = os.path.join(train_path, "core") retrain_core = not model.merge_model(old_core, target_path) if not model.nlu_fingerprint_changed(last_fingerprint, new_fingerprint): target_path = os.path.join(train_path, "nlu") retrain_nlu = not model.merge_model(old_nlu, target_path) if force_training or retrain_core: await _train_core_with_validated_data( domain=domain, config=config, story_directory=story_directory, output=output_path, train_path=train_path, fixed_model_name=fixed_model_name, uncompress=uncompress, kwargs=kwargs, ) else: print("Dialogue data / configuration did not change. " "No need to retrain dialogue model.") if force_training or retrain_nlu: _train_nlu_with_validated_data( config=config, nlu_data_directory=nlu_data_directory, output=output_path, train_path=train_path, fixed_model_name=fixed_model_name, uncompress=uncompress, ) else: print( "NLU data / configuration did not change. No need to retrain NLU model." ) if retrain_core or retrain_nlu: output_path = create_output_path(output_path, fixed_name=fixed_model_name) model.create_package_rasa(train_path, output_path, new_fingerprint) if uncompress: output_path = decompress(output_path) print_success("Your Rasa model is trained and saved at '{}'.".format( output_path)) return output_path else: print_success( "Nothing changed. You can use the old model stored at '{}'" "".format(os.path.abspath(old_model))) return old_model
async def train_core_async( domain: Union[Domain, Text], config: Text, stories: Text, output: Text, train_path: Optional[Text] = None, kwargs: Optional[Dict] = None, ) -> Optional[Text]: """Trains a Core model. Args: domain: Path to the domain file. config: Path to the config file for Core. stories: Path to the Core training data. output: Output path. train_path: If `None` the model will be trained in a temporary directory, otherwise in the provided directory. kwargs: Additional training parameters. Returns: If `train_path` is given it returns the path to the model archive, otherwise the path to the directory with the trained model files. """ import rasa.core.train config = get_valid_config(config, CONFIG_MANDATORY_KEYS_CORE) _train_path = train_path or tempfile.mkdtemp() if isinstance(Domain, str) or not train_path: skill_imports = SkillSelector.load(config) domain = Domain.load(domain, skill_imports) story_directory = data.get_core_directory(stories, skill_imports) else: story_directory = stories if not os.listdir(story_directory): print_error( "No dialogue data given. Please provide dialogue data in order to " "train a Rasa Core model.") return # normal (not compare) training print_color("Start training dialogue model ...", color=bcolors.OKBLUE) await rasa.core.train( domain_file=domain, stories_file=story_directory, output_path=os.path.join(_train_path, "core"), policy_config=config, kwargs=kwargs, ) print_color("Done.", color=bcolors.OKBLUE) if not train_path: # Only Core was trained. output_path = create_output_path(output, prefix="core-") new_fingerprint = model.model_fingerprint(config, domain, stories=story_directory) model.create_package_rasa(_train_path, output_path, new_fingerprint) print_success( "Your Rasa Core model is trained and saved at '{}'.".format( output_path)) return output_path return _train_path