So, I've been working on an application using python and tkinter that will allow someone to use an offline LLM to ask questions regarding files that they can upload. We are using langchain_chroma to handle the embeddings. I dont think I can share my source code but I will share my imports as I believe this will help:
We have a populate_database.py file:
import argparse
import os
import shutil
from langchain_community.document_loaders import PyPDFDirectoryLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain.schema.document import Document
from embedding import embedding_function
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from langchain_community.document_loaders import UnstructuredWordDocumentLoader
embedding.py file:
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoModel
import torch
main.py:
from time import sleep
import tkinter as tk
from tkinter import scrolledtext, filedialog
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
from langchain_chroma import Chroma
from langchain.prompts import PromptTemplate
from populate_database import add_documents_to_chroma, clear_database
from embedding import embedding_function
import gc
We are using two models:
- One for the actual LLM that the user interacts with from: .5-3B
- And one to handle the embeddings from:
The project structure is as follows:
- chroma (folder for the database)
- data (just some sample pdf's for testing)
- Qwen2.5-3B (LLM model folder)
- multilingual-e5-large (model folder for embeddings)
- dist (from attempted compilation)
- build (from attempted compilation)
- embedding.py
- main.py
- populate_database.py
The command I used was simply:
pyinstaller main.py --onefile -w
Full error message is as follows:
NameError: name 'ONNXMiniLM_L6_V2' is not defined
Traceback (most recent call last):
File "main.py", line 6, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "langchain_chroma\__init__.py", line 6, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "langchain_chroma\vectorstores.py", line 25, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "chromadb\__init__.py", line 3, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "chromadb\api\__init__.py", line 34, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "chromadb\api\models\Collection.py", line 3, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "chromadb\api\models\CollectionCommon.py", line 100, in <module>
File "chromadb\api\models\CollectionCommon.py", line 112, in CollectionCommon
File "chromadb\utils\embedding_functions\__init__.py", line 57, in DefaultEmbeddingFunction
NameError: name 'ONNXMiniLM_L6_V2' is not defined
I have tried the steps here: chromadb 'ONNXMiniLM_L6_V2' embedding not defined with pyinstaller
But have not found success. Any help would be greatly appreciated.
So, I've been working on an application using python and tkinter that will allow someone to use an offline LLM to ask questions regarding files that they can upload. We are using langchain_chroma to handle the embeddings. I dont think I can share my source code but I will share my imports as I believe this will help:
We have a populate_database.py file:
import argparse
import os
import shutil
from langchain_community.document_loaders import PyPDFDirectoryLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain.schema.document import Document
from embedding import embedding_function
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from langchain_community.document_loaders import UnstructuredWordDocumentLoader
embedding.py file:
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoModel
import torch
main.py:
from time import sleep
import tkinter as tk
from tkinter import scrolledtext, filedialog
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
from langchain_chroma import Chroma
from langchain.prompts import PromptTemplate
from populate_database import add_documents_to_chroma, clear_database
from embedding import embedding_function
import gc
We are using two models:
- One for the actual LLM that the user interacts with from: https://huggingface.co/Qwen/Qwen2.5-3B
- And one to handle the embeddings from: https://huggingface.co/intfloat/multilingual-e5-large
The project structure is as follows:
- chroma (folder for the database)
- data (just some sample pdf's for testing)
- Qwen2.5-3B (LLM model folder)
- multilingual-e5-large (model folder for embeddings)
- dist (from attempted compilation)
- build (from attempted compilation)
- embedding.py
- main.py
- populate_database.py
The command I used was simply:
pyinstaller main.py --onefile -w
Full error message is as follows:
NameError: name 'ONNXMiniLM_L6_V2' is not defined
Traceback (most recent call last):
File "main.py", line 6, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "langchain_chroma\__init__.py", line 6, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "langchain_chroma\vectorstores.py", line 25, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "chromadb\__init__.py", line 3, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "chromadb\api\__init__.py", line 34, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "chromadb\api\models\Collection.py", line 3, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "chromadb\api\models\CollectionCommon.py", line 100, in <module>
File "chromadb\api\models\CollectionCommon.py", line 112, in CollectionCommon
File "chromadb\utils\embedding_functions\__init__.py", line 57, in DefaultEmbeddingFunction
NameError: name 'ONNXMiniLM_L6_V2' is not defined
I have tried the steps here: chromadb 'ONNXMiniLM_L6_V2' embedding not defined with pyinstaller
But have not found success. Any help would be greatly appreciated.
Share Improve this question asked Mar 18 at 17:29 Nigel MathewsNigel Mathews 11 Answer
Reset to default 0Hidden imports are not visible to the pyinstaller.
This function implicitly imports modules.
A class named ONNXMiniLM_L6_V2
from one of these modules.
This class also uses importlib.import_module
to import such dependencies as "onnxruntime", "tokenizers", and "tqdm".
So we need to deal with all these imports.
The issue with hidden imports
To reproduce this error, we need a minimal project for pyinstaller.
Environment:
- Windows 10
- Python 3.11.9
- chromadb 0.6.3
- pyinstaller 6.12.0
Project sructure:
somedir\
env # virtual environment directory
pyinst # directory for pyinstaler files
embedding.py # additional file for --onefile
main.py
Python files:
embedding.py
def embedding_function():
return "Hello"
main.py
import tkinter as tk
import chromadb
from embedding import embedding_function
root = tk.Tk()
label = tk.Label(root, text=embedding_function())
label.pack()
root.mainloop()
Steps to reproduce:
Create the Python files and the
pyinst
directory in some directory.Run the following in cmd.
Volume:\somedir>python -m venv env
Volume:\somedir>env\scripts\activate
(env) Volume:\somedir>python -m pip install chromadb
...
(env) Volume:\somedir>python -m pip install pyinstaller
...
(env) Volume:\somedir>cd pyinst
(env) Volume:\somedir\pyinst>python -m PyInstaller "Volume:\somedir\main.py" --onefile -w
...
Pyinstaller will generate the necessary directories and the main.spec
file.
pyinst\
build # directory
dist # directory, main.exe here
main.spec
When I try to run main.exe
I get the same error NameError: name 'ONNXMiniLM_L6_V2' is not defined
.
Solutions
Hook and spec file
At this point, we need to create a hook for chromadb
and edit the spec file to handle hidden imports.
- Create a hook file and save it to the desired location.
hook-chromadb.py
from PyInstaller.utils.hooks import collect_submodules
# --collect-submodules
hiddenimports = collect_submodules('chromadb')
- Edit the spec file to add all the dependencies mentioned above.
Edit hiddenimports
(--hidden-import) and hookspath
(--additional-hooks-dir).
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['Volume:\\somedir\\main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=['onnxruntime', 'tokenizers', 'tqdm'],
hookspath=['Volume:\\path to the directory where the hook file is located'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='main',
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,
)
Run pyinstaller:
(env) Volume:\somedir\pyinst>python -m PyInstaller main.spec --clean
...
Now I can run main.exe
without errors and see the root window.
CLI example
We do the same thing.
(env) Volume:\somedir\pyinst>python -m PyInstaller "Volume:\somedir\main.py" --onefile -w --collect-submodules chromadb --hidden-import onnxruntime --hidden-import tokenizers --hidden-import tqdm --clean
The generated spec file in this case:
# -*- mode: python ; coding: utf-8 -*-
from PyInstaller.utils.hooks import collect_submodules
hiddenimports = ['onnxruntime', 'tokenizers', 'tqdm']
hiddenimports += collect_submodules('chromadb')
a = Analysis(
['Volume:\\somedir\\main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='main',
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,
)
You can do the same for other dependencies if they have hidden imports.