langchain icon indicating copy to clipboard operation
langchain copied to clipboard

Issue: Can we use pyinstaller to pack the program with langchain

Open jiayuewu opened this issue 1 year ago • 2 comments

Issue you'd like to raise.

I write a pyqt5 GUI and use the langchain to realize chat function. But it seems I cannot pack the langchian package by pyinstaller.

Suggestion:

No response

jiayuewu avatar May 12 '23 03:05 jiayuewu

Thanks for reporting the issue! Could you provide code to reproduce?

vowelparrot avatar May 12 '23 07:05 vowelparrot

Thanks for reporting the issue! Could you provide code to reproduce?

Thank you for your response. I'm having trouble packing the langchain package using the following minimal code:

from langchain.llms import OpenAI from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

llm = OpenAI(streaming=True, callbacks=[StreamingStdOutCallbackHandler()], temperature=0, openai_api_key='xxx') user_message = input("Type your question here: ") resp = llm(user_message)

I then use PyInstaller with the following command: pyinstaller --onefile --noconsole bot.py

However, the Langchain package doesn't appear in the User/AppData/Local/Temp/xxx directory, and I am unable to run the generated exe file.

jiayuewu avatar May 12 '23 08:05 jiayuewu

stuck in the same scenario is there any workaround?

subhojit-me avatar Jul 12 '23 14:07 subhojit-me

Hello, is this issue resolved? Please let me know if this issue is resolved.

Thanks

sarthakforwet avatar Jul 22 '23 16:07 sarthakforwet

Just doing the job by copying the llama-index, langchain and related python packages from installed site-packages folder to the exe folder of pyinstaller generated exe, so that when running the exe, the exe can find the related python packages in the same directory.

do not know if its suitable in production or not but i did not found any solution yet.

subhojit-me avatar Jul 23 '23 08:07 subhojit-me

Yeah, I was also able to resolve the issue with my code by doing what you just said. Thanks.

sarthakforwet avatar Jul 23 '23 16:07 sarthakforwet

Just doing the job by copying the llama-index, langchain and related python packages from installed site-packages folder to the exe folder of pyinstaller generated exe, so that when running the exe, the exe can find the related python packages in the same directory.

do not know if its suitable in production or not but i did not found any solution yet.

does this also work, when creating the exe in --onefile mode?

Mazzesy avatar Jul 23 '23 19:07 Mazzesy

Just doing the job by copying the llama-index, langchain and related python packages from installed site-packages folder to the exe folder of pyinstaller generated exe, so that when running the exe, the exe can find the related python packages in the same directory. do not know if its suitable in production or not but i did not found any solution yet.

does this also work, when creating the exe in --onefile mode?

no its dont work in --onefile mode, in single exe output the exe looks for the file in some folder from AppData i think, i do not know why, please also let me know if this can be changed by passing any option.

subhojit-me avatar Jul 23 '23 20:07 subhojit-me

Even I'm facing a similar issue, though it works by removing --onefile, I really need it to work with --onefile. Please let me know if there are any workarounds/fixes

kshah00 avatar Jul 28 '23 09:07 kshah00

adding the langchain folder in the spec file using the line below works: a.datas += Tree('path/to/folder', prefix='langchain')

Mazzesy avatar Aug 13 '23 16:08 Mazzesy

Hello - i am still not able to package a running script using langchain - (i would like to create an executable with --onefile on Windows and Mac)

Where should i add this statement: a.datas += Tree('path/to/folder', prefix='langchain') in the spec-file so i can create an excecutable with --onefile?

This is my actual spec-file:

# -*- mode: python ; coding: utf-8 -*-
from PyInstaller.utils.hooks import collect_data_files
from PyInstaller.utils.hooks import copy_metadata

datas = []
datas += collect_data_files('langchain')
datas += copy_metadata('tqdm')
datas += copy_metadata('regex')
datas += copy_metadata('requests')
datas += copy_metadata('packaging')
datas += copy_metadata('filelock')


a = Analysis(
    ['URLanswering.py'],
    pathex=[],
    binaries=[],
    datas=datas,
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
)
pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='URLanswering',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

Rapid1898-code avatar Nov 03 '23 11:11 Rapid1898-code

I think changing to datas += collect_data_files('langchain') to datas += Tree('path/to/folder', prefix='langchain') should work

Mazzesy avatar Nov 03 '23 11:11 Mazzesy

Thx a lot - 2 questions -

  1. How can i tell pyinstaller that he should use a specific spec-file? (even when using --onefile)?
  2. Is this path to the langchain-folder correct G:\DEV\.venv\langchain\Lib\site-packages or do you have to provide the path like that G:\DEV\.venv\langchain\Lib\site-packages\langchain

Rapid1898-code avatar Nov 03 '23 12:11 Rapid1898-code

to run PyInstaller with the spec-file use py -m PyInstaller name_of_spec-file. Use the path to the actual folder, so G:\DEV\.venv\langchain\Lib\site-packages\langchain

Mazzesy avatar Nov 03 '23 12:11 Mazzesy

Thx again - when i run the above statement i get this error:

$ py -m Pyinstaller URLAnswering.spec
G:\DEV\.venv\langchain\Scripts\python.exe: No module named Pyinstaller
(langchain) 

Rapid1898-code avatar Nov 03 '23 13:11 Rapid1898-code

you have to write PyInstaller with a big I

Mazzesy avatar Nov 03 '23 13:11 Mazzesy

ok - then i get this error:

$ py -m PyInstaller URLAnswering.spec
245 INFO: PyInstaller: 6.1.0
245 INFO: Python: 3.10.7
252 INFO: Platform: Windows-10-10.0.19045-SP0
255 WARNING: collect_data_files - skipping data collection for module 'frozendict' as it is not a package.
256 INFO: checking Tree
377 INFO: Extending PYTHONPATH with paths
['G:\\DEV\\Python-Diverses\\langchain']
608 INFO: Appending 'datas' from .spec
Traceback (most recent call last):
  File "C:\Users\marku\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\marku\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "G:\DEV\.venv\langchain\lib\site-packages\PyInstaller\__main__.py", line 209, in <module>
    run()
  File "G:\DEV\.venv\langchain\lib\site-packages\PyInstaller\__main__.py", line 189, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "G:\DEV\.venv\langchain\lib\site-packages\PyInstaller\__main__.py", line 61, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "G:\DEV\.venv\langchain\lib\site-packages\PyInstaller\building\build_main.py", line 1042, in main
    build(specfile, distpath, workpath, clean_build)
  File "G:\DEV\.venv\langchain\lib\site-packages\PyInstaller\building\build_main.py", line 982, in build
    exec(code, spec_namespace)
  File "URLAnswering.spec", line 8, in <module>
    a = Analysis(
  File "G:\DEV\.venv\langchain\lib\site-packages\PyInstaller\building\build_main.py", line 465, in __init__
    for dest_name, src_name in format_binaries_and_datas(datas, workingdir=spec_dir)]
  File "G:\DEV\.venv\langchain\lib\site-packages\PyInstaller\building\utils.py", line 420, in format_binaries_and_datas
    for src_root_path_or_glob, trg_root_dir in binaries_or_datas:
ValueError: too many values to unpack (expected 2)
(langchain)

Rapid1898-code avatar Nov 03 '23 14:11 Rapid1898-code

My spec-file looks like this:

# -*- mode: python ; coding: utf-8 -*-


block_cipher = None


a = Analysis(
    ['mainpy'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

a.datas += Tree('path//to//langchain', prefix='langchain')

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='start',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
app = BUNDLE(
    exe,
    name='start.app',
    icon=None,
    bundle_identifier=None,
)

Mazzesy avatar Nov 03 '23 14:11 Mazzesy

Thx a lot for support - i tried to change the spec-file to this:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['URLAnswering.py'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='URLAnswering',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

But i still get an error

G:\DEV\Python-Diverses\Langchain>URLAnswering.exe
Traceback (most recent call last):
  File "G:\DEV\Python-Diverses\Langchain\URLAnswering.py", line 13, in <module>
    from langchain.chains import RetrievalQA
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "langchain\chains\__init__.py", line 50, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "langchain\chains\llm_summarization_checker\base.py", line 19, in <module>
  File "langchain\prompts\prompt.py", line 184, in from_file
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\marku\\AppData\\Local\\Temp\\_MEI85922\\langchain\\chains\\llm_summarization_checker\\prompts\\create_facts.txt'
[19116] Failed to execute script 'URLAnswering' due to unhandled exception!

Rapid1898-code avatar Nov 04 '23 08:11 Rapid1898-code

the line a.datas += Tree('path//to//langchain', prefix='langchain') is missing in your spec file

Mazzesy avatar Nov 05 '23 12:11 Mazzesy

Thx again -

I now used this spec-file

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['URLAnswering.py'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure)

a.datas += Tree('G:\DEV\.venv\langchain\Lib\site-packages\langchain', prefix='langchain')

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='URLAnswering',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

and get this error now

G:\DEV\Python-Diverses\Langchain>URLAnswering.exe
Program name: URLAnswering.py
Prepare to interpret the content of local files and store to a vector-db...
Traceback (most recent call last):
  File "transformers\utils\versions.py", line 102, in require_version
  File "importlib\metadata\__init__.py", line 984, in version
  File "importlib\metadata\__init__.py", line 957, in distribution
  File "importlib\metadata\__init__.py", line 548, in from_name
importlib.metadata.PackageNotFoundError: No package metadata was found for tqdm

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "langchain\embeddings\huggingface.py", line 58, in __init__
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "sentence_transformers\__init__.py", line 3, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "sentence_transformers\datasets\__init__.py", line 3, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "sentence_transformers\datasets\ParallelSentencesDataset.py", line 4, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "sentence_transformers\SentenceTransformer.py", line 11, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "transformers\__init__.py", line 26, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "transformers\dependency_versions_check.py", line 57, in <module>
  File "transformers\utils\versions.py", line 117, in require_version_core
  File "transformers\utils\versions.py", line 104, in require_version
importlib.metadata.PackageNotFoundError: No package metadata was found for The 'tqdm>=4.27' distribution was not found and is required by this application.
Try: pip install transformers -U or pip install -e '.[dev]' if you're working with git main

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "URLAnswering.py", line 33, in <module>
    embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2", model_kwargs={'device': 'cpu'})
  File "langchain\embeddings\huggingface.py", line 61, in __init__
ImportError: Could not import sentence_transformers python package. Please install it with `pip install sentence-transformers`.
[17544] Failed to execute script 'URLAnswering' due to unhandled exception!

Rapid1898-code avatar Nov 05 '23 18:11 Rapid1898-code

Did you install sentence-transformers with with pip install sentence-transformers as mentioned in the traceback call?

Mazzesy avatar Nov 05 '23 18:11 Mazzesy

Yes is its installed: sentence-transformers 2.2.2

(and also the python-program is running fine - only when i create the executable with pyinstaller i get the error)

Rapid1898-code avatar Nov 05 '23 19:11 Rapid1898-code

when you run the exe-file, there should be a temporary folder in AppData/local (I think), where all the data from the program is stored. If the package sentence-transformers is not there, try to pack the sentence-transformers as well with the spec-file. So adding a.datas += Tree('G:\DEV\.venv\langchain\Lib\site-packages\sentence-transformers', prefix='sentence-transformers') might help

Mazzesy avatar Nov 05 '23 19:11 Mazzesy

I now added this statement to the spec-file: a.datas += Tree('G:\DEV\.venv\langchain\Lib\site-packages\sentence_transformers', prefix='sentence_transformers') but i still get the same error as above

(i realized that in the error-message the package is called "sentence-transformers`" with an "-" but in the path its stored with an underscore "_")

Rapid1898-code avatar Nov 05 '23 19:11 Rapid1898-code

If adding that statement did not work, you could try adding a hook. Create a hook-sentence-transformers.py file with

from PyInstaller.utils.hooks import collect_data_files

datas = collect_data_files('sentence-transformers')

Save it in the same folder as your script and change hookspath=[] to hookspath=["."]. Maybe that help

I don't think the issue with the "-" or "_" is relevant.

Mazzesy avatar Nov 05 '23 21:11 Mazzesy

Hello - i tried what you suggest but still get the same error -

created a hook-sentence-transformers.py in the same folder as the py- and spec-file:

from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files('sentence-transformers')

Changed the spec-file:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['URLAnswering.py'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[],
    hookspath=["."],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure)

a.datas += Tree('G:\DEV\.venv\langchain\Lib\site-packages\langchain', prefix='langchain')
a.datas += Tree('G:\DEV\.venv\langchain\Lib\site-packages\sentence_transformers', prefix='sentence_transformers')

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='URLAnswering',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

And get this error when running the executeable:

Program name: URLAnswering.py
Prepare to interpret the content of local files and store to a vector-db...
Traceback (most recent call last):
  File "transformers\utils\versions.py", line 102, in require_version
  File "importlib\metadata\__init__.py", line 984, in version
  File "importlib\metadata\__init__.py", line 957, in distribution
  File "importlib\metadata\__init__.py", line 548, in from_name
importlib.metadata.PackageNotFoundError: No package metadata was found for tqdm

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "langchain\embeddings\huggingface.py", line 58, in __init__
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "sentence_transformers\__init__.py", line 3, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "sentence_transformers\datasets\__init__.py", line 3, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "sentence_transformers\datasets\ParallelSentencesDataset.py", line 4, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "sentence_transformers\SentenceTransformer.py", line 11, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "transformers\__init__.py", line 26, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "transformers\dependency_versions_check.py", line 57, in <module>
  File "transformers\utils\versions.py", line 117, in require_version_core
  File "transformers\utils\versions.py", line 104, in require_version
importlib.metadata.PackageNotFoundError: No package metadata was found for The 'tqdm>=4.27' distribution was not found and is required by this application.
Try: pip install transformers -U or pip install -e '.[dev]' if you're working with git main

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "URLAnswering.py", line 33, in <module>
    embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2", model_kwargs={'device': 'cpu'})
  File "langchain\embeddings\huggingface.py", line 61, in __init__
ImportError: Could not import sentence_transformers python package. Please install it with `pip install sentence-transformers`.
[22216] Failed to execute script 'URLAnswering' due to unhandled exception!

Rapid1898-code avatar Nov 07 '23 12:11 Rapid1898-code

unfortunately, I don't have another idea...

Mazzesy avatar Nov 07 '23 18:11 Mazzesy

Thx a lot never the less for your help and efforts

Rapid1898-code avatar Nov 08 '23 08:11 Rapid1898-code

@Mazzesy I just wanted to let you know that I was able to get it working. Thank you for your service. The spec file didn't work at first because some other datas needed to be added such as pinecone and tiktoken, but I just guess and checked for which datas needed to added and eventually found the right ones.

beongeist avatar Dec 07 '23 15:12 beongeist