Exemple #1
0
    def test_local_and_two_global_namespace_plugins(self):
        available_plugins = set(discover_plugins())
        self.assertSetEqual(set(), available_plugins)

        # We make plugins "a" and "c" available as packages, each from other directories, as if they were
        # separate installed projects ("global" usage of the plugins).
        # We move to another directory with a different plugin "b", as if it were another separate project
        # which is not installed ("local" usage of the plugin declared in the namespace).
        with pip_install(self.project_a_fixtures_root, "a"), pip_install(
                self.project_c_fixtures_root,
                "c"), push_python_project(self.project_b_fixtures_root):
            available_plugins = set(discover_plugins())
            self.assertSetEqual(
                {
                    "allennlp_plugins.a", "allennlp_plugins.b",
                    "allennlp_plugins.c"
                },
                available_plugins,
            )

            import_plugins()
            subcommands_available = Subcommand.list_available()
            self.assertIn("a", subcommands_available)
            self.assertIn("b", subcommands_available)
            self.assertIn("c", subcommands_available)
Exemple #2
0
    def from_path(
        cls,
        archive_path: Union[str, PathLike],
        predictor_name: str = None,
        cuda_device: int = -1,
        dataset_reader_to_load: str = "validation",
        frozen: bool = True,
        import_plugins: bool = True,
        overrides: Union[str, Dict[str, Any]] = "",
        **kwargs,
    ) -> "Predictor":
        """
        Instantiate a `Predictor` from an archive path.

        If you need more detailed configuration options, such as overrides,
        please use `from_archive`.

        # Parameters

        archive_path : `Union[str, PathLike]`
            The path to the archive.
        predictor_name : `str`, optional (default=`None`)
            Name that the predictor is registered as, or None to use the
            predictor associated with the model.
        cuda_device : `int`, optional (default=`-1`)
            If `cuda_device` is >= 0, the model will be loaded onto the
            corresponding GPU. Otherwise it will be loaded onto the CPU.
        dataset_reader_to_load : `str`, optional (default=`"validation"`)
            Which dataset reader to load from the archive, either "train" or
            "validation".
        frozen : `bool`, optional (default=`True`)
            If we should call `model.eval()` when building the predictor.
        import_plugins : `bool`, optional (default=`True`)
            If `True`, we attempt to import plugins before loading the predictor.
            This comes with additional overhead, but means you don't need to explicitly
            import the modules that your predictor depends on as long as those modules
            can be found by `allennlp.common.plugins.import_plugins()`.
        overrides : `Union[str, Dict[str, Any]]`, optional (default = `""`)
            JSON overrides to apply to the unarchived `Params` object.
        **kwargs : `Any`
            Additional key-word arguments that will be passed to the `Predictor`'s
            `__init__()` method.

        # Returns

        `Predictor`
            A Predictor instance.
        """
        if import_plugins:
            plugins.import_plugins()
        return Predictor.from_archive(
            load_archive(archive_path,
                         cuda_device=cuda_device,
                         overrides=overrides),
            predictor_name,
            dataset_reader_to_load=dataset_reader_to_load,
            frozen=frozen,
            extra_args=kwargs,
        )
Exemple #3
0
    def setup_class(cls):
        # Make sure all the classes we need are registered.
        import_plugins()

        # Patch dataset paths.
        for dataset_patch, patch_targets in DATASET_PATCHES.items():
            for patch_target in patch_targets:
                os.environ[patch_target] = str(dataset_patch)
Exemple #4
0
    def from_path(
        cls,
        archive_path: Union[str, PathLike],
        *,
        interpreter_name: Optional[str] = None,
        train_data_path: Optional[DatasetReaderInput] = None,
        train_data_loader: Lazy[DataLoader] = Lazy(
            SimpleDataLoader.from_dataset_reader),
        test_data_loader: Lazy[DataLoader] = Lazy(
            SimpleDataLoader.from_dataset_reader),
        params_to_freeze: Optional[List[str]] = None,
        cuda_device: int = -1,
        import_plugins: bool = True,
        overrides: Union[str, Dict[str, Any]] = "",
        **extras,
    ) -> "InfluenceInterpreter":
        """
        Load an `InfluenceInterpreter` from an archive path.

        # Parameters

        archive_path : `Union[str, PathLike]`, required
            The path to the archive file.
        interpreter_name : `Optional[str]`, optional (default = `None`)
            The registered name of the an interpreter class. If not specified,
            the default implementation (`SimpleInfluence`) will be used.
        train_data_path : `Optional[DatasetReaderInput]`, optional (default = `None`)
            If not specified, `train_data_path` will be taken from the archive's config.
        train_data_loader : `Lazy[DataLoader]`, optional (default = `Lazy(SimpleDataLoader)`)
        test_data_loader : `Lazy[DataLoader]`, optional (default = `Lazy(SimpleDataLoader)`)
        params_to_freeze : `Optional[List[str]]`, optional (default = `None`)
        cuda_device : `int`, optional (default = `-1`)
        import_plugins : `bool`, optional (default = `True`)
            If `True`, we attempt to import plugins before loading the `InfluenceInterpreter`.
            This comes with additional overhead, but means you don't need to explicitly
            import the modules that your implementation depends on as long as those modules
            can be found by `allennlp.common.plugins.import_plugins()`.
        overrides : `Union[str, Dict[str, Any]]`, optional (default = `""`)
            JSON overrides to apply to the unarchived `Params` object.
        **extras : `Any`
            Extra parameters to pass to the interpreter's `__init__()` method.

        """
        if import_plugins:
            plugins.import_plugins()
        return cls.from_archive(
            load_archive(archive_path,
                         cuda_device=cuda_device,
                         overrides=overrides),
            interpreter_name=interpreter_name,
            train_data_path=train_data_path,
            train_data_loader=train_data_loader,
            test_data_loader=test_data_loader,
            params_to_freeze=params_to_freeze,
            cuda_device=cuda_device,
            **extras,
        )
Exemple #5
0
    def test_file_plugin(self):
        available_plugins = set(discover_plugins())
        self.assertSetEqual(set(), available_plugins)

        with pushd(self.project_d_fixtures_root):
            available_plugins = set(discover_plugins())
            self.assertSetEqual({"d"}, available_plugins)

            import_plugins()
            subcommands_available = Subcommand.list_available()
            self.assertIn("d", subcommands_available)
Exemple #6
0
    def test_local_namespace_plugin(self):
        available_plugins = set(discover_plugins())
        self.assertSetEqual(set(), available_plugins)

        with pushd(self.project_b_fixtures_root):
            available_plugins = set(discover_plugins())
            self.assertSetEqual({"allennlp_plugins.b"}, available_plugins)

            import_plugins()
            subcommands_available = Subcommand.list_available()
            self.assertIn("b", subcommands_available)
Exemple #7
0
    def test_global_namespace_plugin(self):
        available_plugins = set(discover_plugins())
        self.assertSetEqual(set(), available_plugins)

        with pip_install(self.project_a_fixtures_root, "a"):
            available_plugins = set(discover_plugins())
            self.assertSetEqual({"allennlp_plugins.a"}, available_plugins)

            import_plugins()
            subcommands_available = Subcommand.list_available()
            self.assertIn("a", subcommands_available)
Exemple #8
0
    def test_file_plugin(self):
        available_plugins = set(discover_plugins())
        assert available_plugins == set()

        with pushd(self.plugins_root):
            available_plugins = set(discover_plugins())
            assert available_plugins == {"d"}

            import_plugins()
            subcommands_available = Subcommand.list_available()
            assert "d" in subcommands_available
Exemple #9
0
def parse_args(
    prog: Optional[str] = None
) -> Tuple[argparse.ArgumentParser, argparse.Namespace]:
    """
    Creates the argument parser for the main program and uses it to parse the args.
    """
    parser = ArgumentParserWithDefaults(description="Run AllenNLP", prog=prog)
    parser.add_argument("--version",
                        action="version",
                        version=f"%(prog)s {__version__}")

    subparsers = parser.add_subparsers(title="Commands", metavar="")

    subcommands: Set[str] = set()

    def add_subcommands():
        for subcommand_name in sorted(Subcommand.list_available()):
            if subcommand_name in subcommands:
                continue
            subcommands.add(subcommand_name)
            subcommand_class = Subcommand.by_name(subcommand_name)
            subcommand = subcommand_class()
            subparser = subcommand.add_subparser(subparsers)
            if subcommand_class.requires_plugins:
                subparser.add_argument(
                    "--include-package",
                    type=str,
                    action="append",
                    default=[],
                    help="additional packages to include",
                )

    # Add all default registered subcommands first.
    add_subcommands()

    # If we need to print the usage/help, or the subcommand is unknown,
    # we'll call `import_plugins()` to register any plugin subcommands first.
    argv = sys.argv[1:]
    plugins_imported: bool = False
    if not argv or argv == ["--help"] or argv[0] not in subcommands:
        import_plugins()
        plugins_imported = True
        # Add subcommands again in case one of the plugins has a registered subcommand.
        add_subcommands()

    # Now we can parse the arguments.
    args = parser.parse_args()

    if not plugins_imported and Subcommand.by_name(
            argv[0]).requires_plugins:  # type: ignore
        import_plugins()

    return parser, args
Exemple #10
0
def get_pretrained_models() -> Dict[str, ModelCard]:
    """
    Returns a mapping of [`ModelCard`](/models/common/model_card#modelcard)s for all
    available pretrained models.
    """
    import_plugins()

    pretrained_models = {}
    model_card_paths = os.path.join(
        os.path.dirname(os.path.realpath(__file__)), "modelcards", "*.json"
    )

    for model_card_path in glob.glob(model_card_paths):
        if "template" not in model_card_path:
            model_card = ModelCard.from_params(params=Params.from_file(model_card_path))
            pretrained_models[model_card.id] = model_card
    return pretrained_models
Exemple #11
0
    def test_local_namespace_plugin_different_path(self):
        available_plugins = set(discover_plugins())
        self.assertSetEqual(set(), available_plugins)

        with tempfile.TemporaryDirectory() as temp_dir_b:
            distutils.dir_util.copy_tree(self.project_b_fixtures_root, temp_dir_b)

            # We move to another directory with a different plugin "b", as if it were another
            # separate project which is not installed ("local" usage of the plugin declared in
            # the namespace).
            with pushd(temp_dir_b):
                available_plugins = set(discover_plugins())
                self.assertSetEqual({"allennlp_plugins.b"}, available_plugins)

                import_plugins()
                subcommands_available = Subcommand.list_available()
                self.assertIn("b", subcommands_available)
Exemple #12
0
def init_load_model():
    """
    The [`run`](./train.md#run) command only knows about the registered classes in the ``allennlp``
    codebase. In particular, once you start creating your own `Model` s and so forth, it won't
    work for them, unless you use the ``--include-package`` flag or you make your code available
    as a plugin (see [`plugins`](./plugins.md)).
    """
    global predict_manager, cuda_place
    import_plugins()

    parser = create_parser("allennlp")
    args = parser.parse_args()
    args.archive_file = r"models/ace05_event/model.tar.gz"
    args.cuda_device = cuda_place
    args.input_file = r"data/ace-event/processed-data/default-settings/json/test.json"
    args.output_file = r"predictions/event_predict.json"
    args.use_dataset_reader = True
    args.include_package = "dygie"
    args.predictor = "dygie"
    args.weights_file = None
    args.overrides = ''
    args.dataset_reader_choice = 'validation'
    args.batch_size = 1
    args.silent = False

    # print(dir(args))
    # print(args.include_package)
    # for package_name in args.include_package:
    #     import_module_and_submodules_new(package_name)
    import_module_and_submodules_new('dygie')
    import_module_and_submodules_new('dygie.predictors.dygie')
    import_module_and_submodules_new('dygie.models.dygie')
    # predictor = DyGIEPredictor.from_path(os.path.join(current_path, 'models/ace05_event/model.tar.gz'), predictor_name="dygie")
    predictor = predict._get_predictor(args)

    predict_manager = predict._PredictManager(
        predictor,
        args.input_file,
        args.output_file,
        args.batch_size,
        not args.silent,
        args.use_dataset_reader,
    )
Exemple #13
0
    def test_reload_plugins_adds_new(self):
        available_plugins = set(discover_plugins())
        self.assertSetEqual(set(), available_plugins)

        with pip_install(self.project_a_fixtures_root, "a"):
            available_plugins = set(discover_plugins())
            self.assertSetEqual({"allennlp_plugins.a"}, available_plugins)

            import_plugins()
            subcommands_available = Subcommand.list_available()
            self.assertIn("a", subcommands_available)

            with pip_install(self.project_c_fixtures_root, "c"):
                available_plugins = set(discover_plugins())
                self.assertSetEqual({"allennlp_plugins.a", "allennlp_plugins.c"}, available_plugins)

                import_plugins()
                subcommands_available = Subcommand.list_available()
                self.assertIn("a", subcommands_available)
                self.assertIn("c", subcommands_available)
Exemple #14
0
def main(prog: Optional[str] = None) -> None:
    """
    The [`run`](./train.md#run) command only knows about the registered classes in the ``allennlp``
    codebase. In particular, once you start creating your own `Model` s and so forth, it won't
    work for them, unless you use the ``--include-package`` flag or you make your code available
    as a plugin (see [`plugins`](./plugins.md)).
    """
    import_plugins()

    parser = create_parser(prog)
    args = parser.parse_args()

    # If a subparser is triggered, it adds its work as `args.func`.
    # So if no such attribute has been added, no subparser was triggered,
    # so give the user some help.
    if "func" in dir(args):
        # Import any additional modules needed (to register custom classes).
        for package_name in args.include_package:
            import_module_and_submodules(package_name)
        args.func(args)
    else:
        parser.print_help()
Exemple #15
0
 def from_path(
     cls,
     archive_path: str,
     predictor_name: str = None,
     cuda_device: int = -1,
     dataset_reader_to_load: str = "validation",
     frozen: bool = True,
     import_plugins: bool = True,
     language: str = "en_core_web_sm",
     restrict_frames: bool = False,
     restrict_roles: bool = False,
 ) -> "Predictor":
     if import_plugins:
         plugins.import_plugins()
     return SrlTransformersPredictor.from_archive(
         load_archive(archive_path, cuda_device=cuda_device),
         predictor_name,
         dataset_reader_to_load=dataset_reader_to_load,
         frozen=frozen,
         language=language,
         restrict_frames=restrict_frames,
         restrict_roles=restrict_roles,
     )
#!/usr/bin/env python
"""
Ensures models are automatically found by allennlp.
"""
import logging

from allennlp.common.plugins import import_plugins
from allennlp.models import Model

logging.basicConfig(level=logging.INFO)

import_plugins()
Model.by_name("copynet_seq2seq")
Exemple #17
0
def _train_worker(
    process_rank: int,
    params: Params,
    serialization_dir: str,
    file_friendly_logging: bool = False,
    include_package: List[str] = None,
    batch_weight_key: str = "",
    node_rank: int = 0,
    master_addr: str = "127.0.0.1",
    master_port: int = 29500,
    world_size: int = 1,
    distributed_device_ids: List[str] = None,
) -> Optional[Model]:
    """
    Helper to train the configured model/experiment. In distributed mode, this is spawned as a
    worker process. In a single GPU experiment, this returns the ``Model`` object and in distributed
    training, nothing is returned.

    # Parameters

    process_rank : ``int``
        The process index that is initialized using the GPU device id.
    params : ``Params``
        A parameter object specifying an AllenNLP Experiment.
    serialization_dir : ``str``
        The directory in which to save results and logs.
    file_friendly_logging : ``bool``, optional (default=False)
        If ``True``, we add newlines to tqdm output, even on an interactive terminal, and we slow
        down tqdm's output to only once every 10 seconds.
    include_package : ``List[str]``, optional
        In distributed mode, since this function would have been spawned as a separate process,
        the extra imports need to be done again. NOTE: This does not have any effect in single
        GPU training.
    batch_weight_key : ``str``, optional (default="")
        If non-empty, name of metric used to weight the loss on a per-batch basis.
    node_rank : ``int``, optional
        Rank of the node.
    master_addr : ``str``, optional (default="127.0.0.1")
        Address of the master node for distributed training.
    master_port : ``str``, optional (default="29500")
        Port of the master node for distributed training.
    world_size : ``int``, optional
        The number of processes involved in distributed training.
    distributed_device_ids: ``List[str]``, optional
        IDs of the devices used involved in distributed training.

    # Returns

    best_model : ``Model``
        The model with the best epoch weights.
    """
    common_util.prepare_global_logging(serialization_dir,
                                       file_friendly_logging,
                                       rank=process_rank,
                                       world_size=world_size)
    common_util.prepare_environment(params)

    distributed = world_size > 1

    # not using `allennlp.common.util.is_master` as the process group is yet to be initialized
    master = process_rank == 0

    include_package = include_package or []

    if distributed:
        # Since the worker is spawned and not forked, the extra imports need to be done again.
        import_plugins()
        for package_name in include_package:
            common_util.import_submodules(package_name)

        num_procs_per_node = len(distributed_device_ids)
        # The Unique identifier of the worker process among all the processes in the
        # distributed training group is computed here. This is used while initializing
        # the process group using `init_process_group`
        global_rank = node_rank * num_procs_per_node + process_rank

        # Number of processes per node is useful to know if a process
        # is a master in the local node(node in which it is running)
        os.environ["ALLENNLP_PROCS_PER_NODE"] = str(num_procs_per_node)

        # In distributed training, the configured device is always going to be a list.
        # The corresponding gpu id for the particular worker is obtained by picking the id
        # from the device list with the rank as index
        gpu_id = distributed_device_ids[process_rank]  # type: ignore

        # Till now, "cuda_device" might not be set in the trainer params.
        # But a worker trainer needs to only know about its specific GPU id.
        params["trainer"]["cuda_device"] = gpu_id
        params["trainer"]["world_size"] = world_size
        params["trainer"]["distributed"] = True

        torch.cuda.set_device(int(gpu_id))
        dist.init_process_group(
            backend="nccl",
            init_method=f"tcp://{master_addr}:{master_port}",
            world_size=world_size,
            rank=global_rank,
        )
        logging.info(f"Process group of world size {world_size} initialized "
                     f"for distributed training in worker {global_rank}")

    train_loop = TrainModel.from_params(
        params=params,
        serialization_dir=serialization_dir,
        local_rank=process_rank,
        batch_weight_key=batch_weight_key,
    )

    try:
        if distributed:  # let the setup get ready for all the workers
            dist.barrier()

        metrics = train_loop.run()
    except KeyboardInterrupt:
        # if we have completed an epoch, try to create a model archive.
        if master and os.path.exists(
                os.path.join(serialization_dir, _DEFAULT_WEIGHTS)):
            logging.info(
                "Training interrupted by the user. Attempting to create "
                "a model archive using the current best epoch weights.")
            archive_model(serialization_dir)
        raise

    if master:
        train_loop.finish(metrics)

    if not distributed:
        return train_loop.model

    return None  # to make mypy happy
Exemple #18
0
def _train_worker(
    process_rank: int,
    params: Params,
    serialization_dir: Union[str, PathLike],
    include_package: List[str] = None,
    dry_run: bool = False,
    node_rank: int = 0,
    primary_addr: str = "127.0.0.1",
    primary_port: int = 29500,
    world_size: int = 1,
    distributed_device_ids: List[int] = None,
    file_friendly_logging: bool = False,
    include_in_archive: List[str] = None,
    distributed_params: Optional[Params] = None,
) -> Optional[Model]:
    """
    Helper to train the configured model/experiment. In distributed mode, this is spawned as a
    worker process. In a single GPU experiment, this returns the `Model` object and in distributed
    training, nothing is returned.

    # Parameters

    process_rank : `int`
        The process index that is initialized using the GPU device id.
    params : `Params`
        A parameter object specifying an AllenNLP Experiment.
    serialization_dir : `str`
        The directory in which to save results and logs.
    include_package : `List[str]`, optional
        In distributed mode, since this function would have been spawned as a separate process,
        the extra imports need to be done again. NOTE: This does not have any effect in single
        GPU training.
    dry_run : `bool`, optional (default=`False`)
        Do not train a model, but create a vocabulary, show dataset statistics and other training
        information.
    node_rank : `int`, optional
        Rank of the node.
    primary_addr : `str`, optional (default=`"127.0.0.1"`)
        Address of the primary node for distributed training.
    primary_port : `str`, optional (default=`"29500"`)
        Port of the primary node for distributed training.
    world_size : `int`, optional
        The number of processes involved in distributed training.
    distributed_device_ids: `List[str]`, optional
        IDs of the devices used involved in distributed training.
    file_friendly_logging : `bool`, optional (default=`False`)
        If `True`, we add newlines to tqdm output, even on an interactive terminal, and we slow
        down tqdm's output to only once every 10 seconds.
    include_in_archive : `List[str]`, optional
        Paths relative to `serialization_dir` that should be archived in addition to the default ones.
    distributed_params : `Optional[Params]`, optional
        Additional distributed params.

    # Returns

    best_model : `Optional[Model]`
        The model with the best epoch weights or `None` if in distributed training or in dry run.
    """
    common_logging.FILE_FRIENDLY_LOGGING = file_friendly_logging

    common_logging.prepare_global_logging(
        serialization_dir,
        rank=process_rank,
        world_size=world_size,
    )
    common_util.prepare_environment(params)

    distributed = world_size > 1

    primary = process_rank == 0

    include_package = include_package or []

    ddp_accelerator: Optional[DdpAccelerator] = None

    if distributed:
        assert distributed_device_ids is not None
        assert distributed_params is not None

        # Since the worker is spawned and not forked, the extra imports need to be done again.
        # Both the ones from the plugins and the ones from `include_package`.
        import_plugins()
        for package_name in include_package:
            common_util.import_module_and_submodules(package_name)

        num_procs_per_node = len(distributed_device_ids)
        # The Unique identifier of the worker process among all the processes in the
        # distributed training group is computed here. This is used while initializing
        # the process group using `init_process_group`
        global_rank = node_rank * num_procs_per_node + process_rank

        # Number of processes per node is useful to know if a process
        # is a primary in the local node(node in which it is running)
        os.environ["ALLENNLP_PROCS_PER_NODE"] = str(num_procs_per_node)

        # In distributed training, the configured device is always going to be a list.
        # The corresponding gpu id for the particular worker is obtained by picking the id
        # from the device list with the rank as index
        gpu_id = int(distributed_device_ids[process_rank])  # type: ignore

        # Till now, "cuda_device" might not be set in the trainer params.
        # But a worker trainer needs to only know about its specific GPU id.
        params["trainer"]["local_rank"] = process_rank
        params["trainer"]["cuda_device"] = gpu_id
        params["trainer"]["world_size"] = world_size
        params["trainer"]["distributed"] = True

        if gpu_id >= 0:
            torch.cuda.set_device(gpu_id)
            dist.init_process_group(
                backend="nccl",
                init_method=f"tcp://{primary_addr}:{primary_port}",
                world_size=world_size,
                rank=global_rank,
            )
        else:
            dist.init_process_group(
                backend="gloo",
                init_method=f"tcp://{primary_addr}:{primary_port}",
                world_size=world_size,
                rank=global_rank,
            )

        if "ddp_accelerator" in distributed_params:
            ddp_accelerator_params = distributed_params.pop("ddp_accelerator")
            ddp_accelerator = DdpAccelerator.from_params(
                ddp_accelerator_params,
                local_rank=process_rank,
                world_size=world_size,
                cuda_device=gpu_id,
            )

        logging.info(f"Process group of world size {world_size} initialized "
                     f"for distributed training in worker {global_rank}")

    train_loop = TrainModel.from_params(
        params=params,
        serialization_dir=serialization_dir,
        local_rank=process_rank,
        ddp_accelerator=ddp_accelerator,
    )

    if dry_run:
        return None

    try:
        if distributed:  # let the setup get ready for all the workers
            dist.barrier()

        metrics = train_loop.run()
    except KeyboardInterrupt:
        # if we have completed an epoch, try to create a model archive.
        if primary:
            best_weights_path = train_loop.trainer.get_best_weights_path()
            if best_weights_path is None:
                logging.info(
                    "Training interrupted by the user, and no best model has been saved. "
                    "No model archive created.")
            else:
                logging.info(
                    "Training interrupted by the user. Attempting to create "
                    "a model archive using the current best epoch weights.")
                archive_model(
                    serialization_dir,
                    weights=best_weights_path,
                    include_in_archive=include_in_archive,
                )
        raise

    if primary:
        train_loop.finish(metrics)

    if not distributed:
        return train_loop.model

    return None