explosion / spaCy

💫 Industrial-strength Natural Language Processing (NLP) in Python
https://spacy.io
MIT License
30.31k stars 4.41k forks source link

[BUG] -- Arguments `enable` and `disable` not working as expected in `spacy.load` #13591

Open it176131 opened 3 months ago

it176131 commented 3 months ago

How to reproduce the behaviour

The problem

This raises error E1042.

import spacy

spacy.load("en_core_web_sm", enable=["senter"])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[4], line 2
      1 # Error E1042.
----> 2 nlp = spacy.load("en_core_web_sm", enable=["senter"])

File ~\ADO\ml_kg\env\Lib\site-packages\spacy\__init__.py:51, in load(name, vocab, disable, enable, exclude, config)
     27 def load(
     28     name: Union[str, Path],
     29     *,
   (...)
     34     config: Union[Dict[str, Any], Config] = util.SimpleFrozenDict(),
     35 ) -> Language:
     36     """Load a spaCy model from an installed package or a local path.
     37 
     38     name (str): Package name or model path.
   (...)
     49     RETURNS (Language): The loaded nlp object.
     50     """
---> 51     return util.load_model(
     52         name,
     53         vocab=vocab,
     54         disable=disable,
     55         enable=enable,
     56         exclude=exclude,
     57         config=config,
     58     )

File ~\ADO\ml_kg\env\Lib\site-packages\spacy\util.py:465, in load_model(name, vocab, disable, enable, exclude, config)
    463     return get_lang_class(name.replace("blank:", ""))()
    464 if is_package(name):  # installed as package
--> 465     return load_model_from_package(name, **kwargs)  # type: ignore[arg-type]
    466 if Path(name).exists():  # path to model data directory
    467     return load_model_from_path(Path(name), **kwargs)  # type: ignore[arg-type]

File ~\ADO\ml_kg\env\Lib\site-packages\spacy\util.py:501, in load_model_from_package(name, vocab, disable, enable, exclude, config)
    484 """Load a model from an installed package.
    485 
    486 name (str): The package name.
   (...)
    498 RETURNS (Language): The loaded nlp object.
    499 """
    500 cls = importlib.import_module(name)
--> 501 return cls.load(vocab=vocab, disable=disable, enable=enable, exclude=exclude, config=config)

File ~\ADO\ml_kg\env\Lib\site-packages\en_core_web_sm\__init__.py:10, in load(**overrides)
      9 def load(**overrides):
---> 10     return load_model_from_init_py(__file__, **overrides)

File ~\ADO\ml_kg\env\Lib\site-packages\spacy\util.py:682, in load_model_from_init_py(init_file, vocab, disable, enable, exclude, config)
    680 if not model_path.exists():
    681     raise IOError(Errors.E052.format(path=data_path))
--> 682 return load_model_from_path(
    683     data_path,
    684     vocab=vocab,
    685     meta=meta,
    686     disable=disable,
    687     enable=enable,
    688     exclude=exclude,
    689     config=config,
    690 )

File ~\ADO\ml_kg\env\Lib\site-packages\spacy\util.py:539, in load_model_from_path(model_path, meta, vocab, disable, enable, exclude, config)
    537 overrides = dict_to_dot(config, for_overrides=True)
    538 config = load_config(config_path, overrides=overrides)
--> 539 nlp = load_model_from_config(
    540     config,
    541     vocab=vocab,
    542     disable=disable,
    543     enable=enable,
    544     exclude=exclude,
    545     meta=meta,
    546 )
    547 return nlp.from_disk(model_path, exclude=exclude, overrides=overrides)

File ~\ADO\ml_kg\env\Lib\site-packages\spacy\util.py:587, in load_model_from_config(config, meta, vocab, disable, enable, exclude, auto_fill, validate)
    584 # This will automatically handle all codes registered via the languages
    585 # registry, including custom subclasses provided via entry points
    586 lang_cls = get_lang_class(nlp_config["lang"])
--> 587 nlp = lang_cls.from_config(
    588     config,
    589     vocab=vocab,
    590     disable=disable,
    591     enable=enable,
    592     exclude=exclude,
    593     auto_fill=auto_fill,
    594     validate=validate,
    595     meta=meta,
    596 )
    597 return nlp

File ~\ADO\ml_kg\env\Lib\site-packages\spacy\language.py:1973, in Language.from_config(cls, config, vocab, disable, enable, exclude, meta, auto_fill, validate)
   1965         warnings.warn(
   1966             Warnings.W123.format(
   1967                 enable=enable,
   1968                 enabled=enabled,
   1969             )
   1970         )
   1972 # Ensure sets of disabled/enabled pipe names are not contradictory.
-> 1973 disabled_pipes = cls._resolve_component_status(
   1974     list({*disable, *config["nlp"].get("disabled", [])}),
   1975     enable,
   1976     config["nlp"]["pipeline"],
   1977 )
   1978 nlp._disabled = set(p for p in disabled_pipes if p not in exclude)
   1980 nlp.batch_size = config["nlp"]["batch_size"]

File ~\ADO\ml_kg\env\Lib\site-packages\spacy\language.py:2153, in Language._resolve_component_status(disable, enable, pipe_names)
   2151     # If any pipe to be enabled is in to_disable, the specification is inconsistent.
   2152     if len(set(enable) & to_disable):
-> 2153         raise ValueError(Errors.E1042.format(enable=enable, disable=disable))
   2155 return tuple(to_disable)

ValueError: [E1042] `enable=['senter']` and `disable=['senter']` are inconsistent with each other.
If you only passed one of `enable` or `disable`, the other argument is specified in your pipeline's configuration.
In that case pass an empty list for the previously not specified argument to avoid this error.

Based on the error message I tried setting the disable argument to an empty list, but this raises the same error:

# Another error E1042.
nlp = spacy.load("en_core_web_sm", enable=["senter"], disable=[])
ValueError: [E1042] `enable=['senter']` and `disable=['senter']` are inconsistent with each other.
If you only passed one of `enable` or `disable`, the other argument is specified in your pipeline's configuration.
In that case pass an empty list for the previously not specified argument to avoid this error.

This lead me to believe that something is wrong with the disable argument.

# Runs, but does not return as expected.
nlp = spacy.load("en_core_web_sm", disable=[])
nlp.disabled  # ['senter']

Hacky solutions

I've found at least two ways to get around it.

  1. Bypass the enable/disable arguments and supply a dictionary to the config argument:

    # Runs and returns as expected.
    nlp = spacy.load("en_core_web_sm", config={"nlp": {"disabled": []}})
    nlp.disabled  # []
    "senter" in nlp.pipe_names  # True
  2. Or load the model as-is and enable the component after-the-fact:

    # Runs and returns as expected.
    nlp = spacy.load("en_core_web_sm")
    nlp.enable_pipe("senter")
    nlp.disabled  # []
    "senter" in nlp.pipe_names  # True

Thoughts?

I don't really like either of the hacky solutions as I'd expect the enable/disable arguments to handle this. I'd be willing to submit a PR if this is indeed a bug.

Your Environment

it176131 commented 1 month ago

@ines & @honnibal —

Sorry to bother you but is this user error, incorrect documentation, or a bug?