CoolFace
Apppublic

Peterz98/DiffspeechResearch

sourceHugging Faceupdated 3y agoView on Hugging Face
0likes
adapt.py202 linesDownload Raw Back to mfa_usr
1import shutil2import os3import time4from montreal_forced_aligner import __version__5from montreal_forced_aligner.corpus.align_corpus import AlignableCorpus6from montreal_forced_aligner.dictionary import Dictionary, MultispeakerDictionary7from montreal_forced_aligner.aligner import TrainableAligner, PretrainedAligner8from montreal_forced_aligner.models import AcousticModel9from montreal_forced_aligner.config import TEMP_DIR, align_yaml_to_config, load_basic_align, load_command_configuration, \10    train_yaml_to_config11from montreal_forced_aligner.utils import get_available_acoustic_languages, get_pretrained_acoustic_path, \12    get_available_dict_languages, validate_dictionary_arg13from montreal_forced_aligner.helper import setup_logger, log_config14from montreal_forced_aligner.exceptions import ArgumentError15 16 17def load_adapt_config():18    training_config, align_config = train_yaml_to_config('mfa_usr/adapt_config.yaml', require_mono=False)19    training_config.training_configs[0].fmllr_iterations = list(20        range(0, training_config.training_configs[0].num_iterations))21    training_config.training_configs[0].realignment_iterations = list(range(0, training_config.training_configs[22        0].num_iterations))23    return training_config, align_config24 25 26class AcousticModel2(AcousticModel):27    def adaptation_config(self):28        train, align = load_adapt_config()29        return train30 31 32def adapt_model(args, unknown_args=None):33    command = 'align'34    all_begin = time.time()35    if not args.temp_directory:36        temp_dir = TEMP_DIR37    else:38        temp_dir = os.path.expanduser(args.temp_directory)39    corpus_name = os.path.basename(args.corpus_directory)40    if corpus_name == '':41        args.corpus_directory = os.path.dirname(args.corpus_directory)42        corpus_name = os.path.basename(args.corpus_directory)43    data_directory = os.path.join(temp_dir, corpus_name)44    if args.config_path:45        align_config = align_yaml_to_config(args.config_path)46    else:47        align_config = load_basic_align()48    align_config.use_mp = not args.disable_mp49    align_config.debug = args.debug50    align_config.overwrite = args.overwrite51    align_config.cleanup_textgrids = not args.disable_textgrid_cleanup52 53    if unknown_args:54        align_config.update_from_args(unknown_args)55    conf_path = os.path.join(data_directory, 'config.yml')56    if getattr(args, 'clean', False) and os.path.exists(data_directory):57        print('Cleaning old directory!')58        shutil.rmtree(data_directory, ignore_errors=True)59    if getattr(args, 'verbose', False):60        log_level = 'debug'61    else:62        log_level = 'info'63    logger = setup_logger(command, data_directory, console_level=log_level)64    logger.debug('ALIGN CONFIG:')65    log_config(logger, align_config)66    conf = load_command_configuration(conf_path, {'dirty': False,67                                                  'begin': all_begin,68                                                  'version': __version__,69                                                  'type': command,70                                                  'corpus_directory': args.corpus_directory,71                                                  'dictionary_path': args.dictionary_path,72                                                  'acoustic_model_path': args.acoustic_model_path})73    if conf['dirty'] or conf['type'] != command \74            or conf['corpus_directory'] != args.corpus_directory \75            or conf['version'] != __version__ \76            or conf['dictionary_path'] != args.dictionary_path:77        logger.warning(78            'WARNING: Using old temp directory, this might not be ideal for you, use the --clean flag to ensure no '79            'weird behavior for previous versions of the temporary directory.')80        if conf['dirty']:81            logger.debug('Previous run ended in an error (maybe ctrl-c?)')82        if conf['type'] != command:83            logger.debug('Previous run was a different subcommand than {} (was {})'.format(command, conf['type']))84        if conf['corpus_directory'] != args.corpus_directory:85            logger.debug('Previous run used source directory '86                         'path {} (new run: {})'.format(conf['corpus_directory'], args.corpus_directory))87        if conf['version'] != __version__:88            logger.debug('Previous run was on {} version (new run: {})'.format(conf['version'], __version__))89        if conf['dictionary_path'] != args.dictionary_path:90            logger.debug('Previous run used dictionary path {} '91                         '(new run: {})'.format(conf['dictionary_path'], args.dictionary_path))92        if conf['acoustic_model_path'] != args.acoustic_model_path:93            logger.debug('Previous run used acoustic model path {} '94                         '(new run: {})'.format(conf['acoustic_model_path'], args.acoustic_model_path))95 96    os.makedirs(data_directory, exist_ok=True)97    model_directory = os.path.join(data_directory, 'acoustic_models')98    os.makedirs(model_directory, exist_ok=True)99    acoustic_model = AcousticModel2(args.acoustic_model_path, root_directory=model_directory)100    print("| acoustic_model.meta", acoustic_model.meta)101    acoustic_model.log_details(logger)102    training_config = acoustic_model.adaptation_config()103    training_config.training_configs[0].update({'beam': align_config.beam, 'retry_beam': align_config.retry_beam})104    training_config.update_from_align(align_config)105    logger.debug('ADAPT TRAINING CONFIG:')106    log_config(logger, training_config)107    audio_dir = None108    if args.audio_directory:109        audio_dir = args.audio_directory110    try:111        corpus = AlignableCorpus(args.corpus_directory, data_directory,112                                 speaker_characters=args.speaker_characters,113                                 num_jobs=args.num_jobs, sample_rate=align_config.feature_config.sample_frequency,114                                 logger=logger, use_mp=align_config.use_mp, punctuation=align_config.punctuation,115                                 clitic_markers=align_config.clitic_markers, audio_directory=audio_dir)116        if corpus.issues_check:117            logger.warning('Some issues parsing the corpus were detected. '118                           'Please run the validator to get more information.')119        logger.info(corpus.speaker_utterance_info())120        if args.dictionary_path.lower().endswith('.yaml'):121            dictionary = MultispeakerDictionary(args.dictionary_path, data_directory, logger=logger,122                                                punctuation=align_config.punctuation,123                                                clitic_markers=align_config.clitic_markers,124                                                compound_markers=align_config.compound_markers,125                                                multilingual_ipa=acoustic_model.meta['multilingual_ipa'],126                                                strip_diacritics=acoustic_model.meta.get('strip_diacritics', None),127                                                digraphs=acoustic_model.meta.get('digraphs', None))128        else:129            dictionary = Dictionary(args.dictionary_path, data_directory, logger=logger,130                                    punctuation=align_config.punctuation,131                                    clitic_markers=align_config.clitic_markers,132                                    compound_markers=align_config.compound_markers,133                                    multilingual_ipa=acoustic_model.meta['multilingual_ipa'],134                                    strip_diacritics=acoustic_model.meta.get('strip_diacritics', None),135                                    digraphs=acoustic_model.meta.get('digraphs', None))136        acoustic_model.validate(dictionary)137 138        begin = time.time()139        previous = PretrainedAligner(corpus, dictionary, acoustic_model, align_config,140                                     temp_directory=data_directory,141                                     debug=getattr(args, 'debug', False), logger=logger)142        a = TrainableAligner(corpus, dictionary, training_config, align_config,143                             temp_directory=data_directory,144                             debug=getattr(args, 'debug', False), logger=logger, pretrained_aligner=previous)145        logger.debug('Setup adapter in {} seconds'.format(time.time() - begin))146        a.verbose = args.verbose147 148        begin = time.time()149        a.train()150        logger.debug('Performed adaptation in {} seconds'.format(time.time() - begin))151 152        begin = time.time()153        a.save(args.output_model_path, root_directory=model_directory)154        a.export_textgrids(args.output_directory)155        logger.debug('Exported TextGrids in {} seconds'.format(time.time() - begin))156        logger.info('All done!')157 158    except Exception as _:159        conf['dirty'] = True160        raise161    finally:162        handlers = logger.handlers[:]163        for handler in handlers:164            handler.close()165            logger.removeHandler(handler)166        conf.save(conf_path)167 168 169def validate_args(args, downloaded_acoustic_models, download_dictionaries):170    if not os.path.exists(args.corpus_directory):171        raise ArgumentError('Could not find the corpus directory {}.'.format(args.corpus_directory))172    if not os.path.isdir(args.corpus_directory):173        raise ArgumentError('The specified corpus directory ({}) is not a directory.'.format(args.corpus_directory))174 175    args.dictionary_path = validate_dictionary_arg(args.dictionary_path, download_dictionaries)176 177    if args.acoustic_model_path.lower() in downloaded_acoustic_models:178        args.acoustic_model_path = get_pretrained_acoustic_path(args.acoustic_model_path.lower())179    elif args.acoustic_model_path.lower().endswith(AcousticModel.extension):180        if not os.path.exists(args.acoustic_model_path):181            raise ArgumentError('The specified model path does not exist: ' + args.acoustic_model_path)182    else:183        raise ArgumentError(184            'The language \'{}\' is not currently included in the distribution, '185            'please align via training or specify one of the following language names: {}.'.format(186                args.acoustic_model_path.lower(), ', '.join(downloaded_acoustic_models)))187 188 189def run_adapt_model(args, unknown_args=None, downloaded_acoustic_models=None, download_dictionaries=None):190    if downloaded_acoustic_models is None:191        downloaded_acoustic_models = get_available_acoustic_languages()192    if download_dictionaries is None:193        download_dictionaries = get_available_dict_languages()194    try:195        args.speaker_characters = int(args.speaker_characters)196    except ValueError:197        pass198    args.corpus_directory = args.corpus_directory.rstrip('/').rstrip('\\')199 200    validate_args(args, downloaded_acoustic_models, download_dictionaries)201    adapt_model(args, unknown_args)202