Spaces:
Runtime error
Runtime error
| import shutil | |
| import os | |
| import time | |
| from montreal_forced_aligner import __version__ | |
| from montreal_forced_aligner.corpus.align_corpus import AlignableCorpus | |
| from montreal_forced_aligner.dictionary import Dictionary, MultispeakerDictionary | |
| from montreal_forced_aligner.aligner import TrainableAligner, PretrainedAligner | |
| from montreal_forced_aligner.models import AcousticModel | |
| from montreal_forced_aligner.config import TEMP_DIR, align_yaml_to_config, load_basic_align, load_command_configuration, \ | |
| train_yaml_to_config | |
| from montreal_forced_aligner.utils import get_available_acoustic_languages, get_pretrained_acoustic_path, \ | |
| get_available_dict_languages, validate_dictionary_arg | |
| from montreal_forced_aligner.helper import setup_logger, log_config | |
| from montreal_forced_aligner.exceptions import ArgumentError | |
| def load_adapt_config(): | |
| training_config, align_config = train_yaml_to_config('mfa_usr/adapt_config.yaml', require_mono=False) | |
| training_config.training_configs[0].fmllr_iterations = list( | |
| range(0, training_config.training_configs[0].num_iterations)) | |
| training_config.training_configs[0].realignment_iterations = list(range(0, training_config.training_configs[ | |
| 0].num_iterations)) | |
| return training_config, align_config | |
| class AcousticModel2(AcousticModel): | |
| def adaptation_config(self): | |
| train, align = load_adapt_config() | |
| return train | |
| def adapt_model(args, unknown_args=None): | |
| command = 'align' | |
| all_begin = time.time() | |
| if not args.temp_directory: | |
| temp_dir = TEMP_DIR | |
| else: | |
| temp_dir = os.path.expanduser(args.temp_directory) | |
| corpus_name = os.path.basename(args.corpus_directory) | |
| if corpus_name == '': | |
| args.corpus_directory = os.path.dirname(args.corpus_directory) | |
| corpus_name = os.path.basename(args.corpus_directory) | |
| data_directory = os.path.join(temp_dir, corpus_name) | |
| if args.config_path: | |
| align_config = align_yaml_to_config(args.config_path) | |
| else: | |
| align_config = load_basic_align() | |
| align_config.use_mp = not args.disable_mp | |
| align_config.debug = args.debug | |
| align_config.overwrite = args.overwrite | |
| align_config.cleanup_textgrids = not args.disable_textgrid_cleanup | |
| if unknown_args: | |
| align_config.update_from_args(unknown_args) | |
| conf_path = os.path.join(data_directory, 'config.yml') | |
| if getattr(args, 'clean', False) and os.path.exists(data_directory): | |
| print('Cleaning old directory!') | |
| shutil.rmtree(data_directory, ignore_errors=True) | |
| if getattr(args, 'verbose', False): | |
| log_level = 'debug' | |
| else: | |
| log_level = 'info' | |
| logger = setup_logger(command, data_directory, console_level=log_level) | |
| logger.debug('ALIGN CONFIG:') | |
| log_config(logger, align_config) | |
| conf = load_command_configuration(conf_path, {'dirty': False, | |
| 'begin': all_begin, | |
| 'version': __version__, | |
| 'type': command, | |
| 'corpus_directory': args.corpus_directory, | |
| 'dictionary_path': args.dictionary_path, | |
| 'acoustic_model_path': args.acoustic_model_path}) | |
| if conf['dirty'] or conf['type'] != command \ | |
| or conf['corpus_directory'] != args.corpus_directory \ | |
| or conf['version'] != __version__ \ | |
| or conf['dictionary_path'] != args.dictionary_path: | |
| logger.warning( | |
| 'WARNING: Using old temp directory, this might not be ideal for you, use the --clean flag to ensure no ' | |
| 'weird behavior for previous versions of the temporary directory.') | |
| if conf['dirty']: | |
| logger.debug('Previous run ended in an error (maybe ctrl-c?)') | |
| if conf['type'] != command: | |
| logger.debug('Previous run was a different subcommand than {} (was {})'.format(command, conf['type'])) | |
| if conf['corpus_directory'] != args.corpus_directory: | |
| logger.debug('Previous run used source directory ' | |
| 'path {} (new run: {})'.format(conf['corpus_directory'], args.corpus_directory)) | |
| if conf['version'] != __version__: | |
| logger.debug('Previous run was on {} version (new run: {})'.format(conf['version'], __version__)) | |
| if conf['dictionary_path'] != args.dictionary_path: | |
| logger.debug('Previous run used dictionary path {} ' | |
| '(new run: {})'.format(conf['dictionary_path'], args.dictionary_path)) | |
| if conf['acoustic_model_path'] != args.acoustic_model_path: | |
| logger.debug('Previous run used acoustic model path {} ' | |
| '(new run: {})'.format(conf['acoustic_model_path'], args.acoustic_model_path)) | |
| os.makedirs(data_directory, exist_ok=True) | |
| model_directory = os.path.join(data_directory, 'acoustic_models') | |
| os.makedirs(model_directory, exist_ok=True) | |
| acoustic_model = AcousticModel2(args.acoustic_model_path, root_directory=model_directory) | |
| print("| acoustic_model.meta", acoustic_model.meta) | |
| acoustic_model.log_details(logger) | |
| training_config = acoustic_model.adaptation_config() | |
| training_config.training_configs[0].update({'beam': align_config.beam, 'retry_beam': align_config.retry_beam}) | |
| training_config.update_from_align(align_config) | |
| logger.debug('ADAPT TRAINING CONFIG:') | |
| log_config(logger, training_config) | |
| audio_dir = None | |
| if args.audio_directory: | |
| audio_dir = args.audio_directory | |
| try: | |
| corpus = AlignableCorpus(args.corpus_directory, data_directory, | |
| speaker_characters=args.speaker_characters, | |
| num_jobs=args.num_jobs, sample_rate=align_config.feature_config.sample_frequency, | |
| logger=logger, use_mp=align_config.use_mp, punctuation=align_config.punctuation, | |
| clitic_markers=align_config.clitic_markers, audio_directory=audio_dir) | |
| if corpus.issues_check: | |
| logger.warning('Some issues parsing the corpus were detected. ' | |
| 'Please run the validator to get more information.') | |
| logger.info(corpus.speaker_utterance_info()) | |
| if args.dictionary_path.lower().endswith('.yaml'): | |
| dictionary = MultispeakerDictionary(args.dictionary_path, data_directory, logger=logger, | |
| punctuation=align_config.punctuation, | |
| clitic_markers=align_config.clitic_markers, | |
| compound_markers=align_config.compound_markers, | |
| multilingual_ipa=acoustic_model.meta['multilingual_ipa'], | |
| strip_diacritics=acoustic_model.meta.get('strip_diacritics', None), | |
| digraphs=acoustic_model.meta.get('digraphs', None)) | |
| else: | |
| dictionary = Dictionary(args.dictionary_path, data_directory, logger=logger, | |
| punctuation=align_config.punctuation, | |
| clitic_markers=align_config.clitic_markers, | |
| compound_markers=align_config.compound_markers, | |
| multilingual_ipa=acoustic_model.meta['multilingual_ipa'], | |
| strip_diacritics=acoustic_model.meta.get('strip_diacritics', None), | |
| digraphs=acoustic_model.meta.get('digraphs', None)) | |
| acoustic_model.validate(dictionary) | |
| begin = time.time() | |
| previous = PretrainedAligner(corpus, dictionary, acoustic_model, align_config, | |
| temp_directory=data_directory, | |
| debug=getattr(args, 'debug', False), logger=logger) | |
| a = TrainableAligner(corpus, dictionary, training_config, align_config, | |
| temp_directory=data_directory, | |
| debug=getattr(args, 'debug', False), logger=logger, pretrained_aligner=previous) | |
| logger.debug('Setup adapter in {} seconds'.format(time.time() - begin)) | |
| a.verbose = args.verbose | |
| begin = time.time() | |
| a.train() | |
| logger.debug('Performed adaptation in {} seconds'.format(time.time() - begin)) | |
| begin = time.time() | |
| a.save(args.output_model_path, root_directory=model_directory) | |
| a.export_textgrids(args.output_directory) | |
| logger.debug('Exported TextGrids in {} seconds'.format(time.time() - begin)) | |
| logger.info('All done!') | |
| except Exception as _: | |
| conf['dirty'] = True | |
| raise | |
| finally: | |
| handlers = logger.handlers[:] | |
| for handler in handlers: | |
| handler.close() | |
| logger.removeHandler(handler) | |
| conf.save(conf_path) | |
| def validate_args(args, downloaded_acoustic_models, download_dictionaries): | |
| if not os.path.exists(args.corpus_directory): | |
| raise ArgumentError('Could not find the corpus directory {}.'.format(args.corpus_directory)) | |
| if not os.path.isdir(args.corpus_directory): | |
| raise ArgumentError('The specified corpus directory ({}) is not a directory.'.format(args.corpus_directory)) | |
| args.dictionary_path = validate_dictionary_arg(args.dictionary_path, download_dictionaries) | |
| if args.acoustic_model_path.lower() in downloaded_acoustic_models: | |
| args.acoustic_model_path = get_pretrained_acoustic_path(args.acoustic_model_path.lower()) | |
| elif args.acoustic_model_path.lower().endswith(AcousticModel.extension): | |
| if not os.path.exists(args.acoustic_model_path): | |
| raise ArgumentError('The specified model path does not exist: ' + args.acoustic_model_path) | |
| else: | |
| raise ArgumentError( | |
| 'The language \'{}\' is not currently included in the distribution, ' | |
| 'please align via training or specify one of the following language names: {}.'.format( | |
| args.acoustic_model_path.lower(), ', '.join(downloaded_acoustic_models))) | |
| def run_adapt_model(args, unknown_args=None, downloaded_acoustic_models=None, download_dictionaries=None): | |
| if downloaded_acoustic_models is None: | |
| downloaded_acoustic_models = get_available_acoustic_languages() | |
| if download_dictionaries is None: | |
| download_dictionaries = get_available_dict_languages() | |
| try: | |
| args.speaker_characters = int(args.speaker_characters) | |
| except ValueError: | |
| pass | |
| args.corpus_directory = args.corpus_directory.rstrip('/').rstrip('\\') | |
| validate_args(args, downloaded_acoustic_models, download_dictionaries) | |
| adapt_model(args, unknown_args) | |