oberprah
oberprah

Reputation: 187

Create binary of spaCy with PyInstaller

I would like to create a binary of my python code, that contains spaCy.

# main.py

import spacy
import en_core_web_sm

def main() -> None:
    nlp = spacy.load("en_core_web_sm")
    # nlp = en_core_web_sm.load()
    doc = nlp("This is an example")
    print([(w.text, w.pos_) for w in doc])

if __name__ == "__main__":
    main()

Besides my code, I created two PyInstaller-hooks, as described here

To create the binary I use the following command pyinstaller main.py --additional-hooks-dir=..

On the execution of the binary I get the following error message:

Traceback (most recent call last):
  File "main.py", line 19, in <module>
    main()
  File "main.py", line 12, in main
    nlp = spacy.load("en_core_web_sm")
  File "spacy/__init__.py", line 47, in load
  File "spacy/util.py", line 329, in load_model
OSError: [E050] Can't find model 'en_core_web_sm'. It doesn't seem to be a Python package or a valid path to a data directory.

If I use nlp = en_core_web_sm.load() instead if nlp = spacy.load("en_core_web_sm") to load the spacy model, I get the following error:

Traceback (most recent call last):
  File "main.py", line 19, in <module>
    main()
  File "main.py", line 13, in main
    nlp = en_core_web_sm.load()
  File "en_core_web_sm/__init__.py", line 10, in load
  File "spacy/util.py", line 514, in load_model_from_init_py
  File "spacy/util.py", line 389, in load_model_from_path
  File "spacy/util.py", line 426, in load_model_from_config
  File "spacy/language.py", line 1662, in from_config
  File "spacy/language.py", line 768, in add_pipe
  File "spacy/language.py", line 659, in create_pipe
  File "thinc/config.py", line 722, in resolve
  File "thinc/config.py", line 771, in _make
  File "thinc/config.py", line 826, in _fill
  File "thinc/config.py", line 825, in _fill
  File "thinc/config.py", line 1016, in make_promise_schema
  File "spacy/util.py", line 137, in get
catalogue.RegistryError: [E893] Could not find function 'spacy.Tok2Vec.v1' in function registry 'architectures'. If you're using a custom function, make sure the code is available. If the function is provided by a third-party package, e.g. spacy-transformers, make sure the package is installed in your environment.

Upvotes: 2

Views: 1236

Answers (2)

Me W
Me W

Reputation: 1

I encountered the same issue and nailed it by copying the spacy-legacy package to the compiled destination directory.

You can also hook it up by Pyinstaller but I did not really try that.

I hope my answer helps.

Upvotes: 0

Alison Thompson
Alison Thompson

Reputation: 11

I had this same issue. After the error message you posted above, did you see an "Available names: ..." message? This message suggested that spacy.Tok2Vec.v2 was available but not v1. I was able to edit the config file for en_core_web_sm (for me at dist<name>\en_core_web_sm\en_core_web_sm-3.0.0\config.cfg) and change all references for spacy.Tok2Vec.v1 -> spacy.Tok2Vec.v2. I also had to do this for spacy.MaxoutWindowEncoder.v1. It's still a mystery to me as to why I'm having the issue only in the pyinstaller distributable and not my non-compiled script.

Upvotes: 1

Related Questions