deepinsight / deepinsight/insightface
PyInstaller bundled: get_object fails with FileNotFoundError for meanshape_68.pkl
- Dominant language
- Python
- Stars
- 29.7k
- Forks
- 6.1k
- PR merge metrics
- No merged PRs in 30d
Description
## Bug: `get_object` uses `sys._MEIPASS` which doesn't contain `objects/` in PyInstaller builds
### Version
insightface 1.0.1
### Steps to Reproduce
1. Build a PyInstaller executable that imports `insightface` (e.g. using `--collect-all insightface`)
2. Run the bundled executable
3. Create a `FaceAnalysis` instance with `allowed_modules=["recognition", "detection", "genderage", "landmark_3d_68", "landmark_2d_106"]` or just `name="buffalo_l"`
### Expected Behavior
The landmark models load successfully. `meanshape_68.pkl` is found and deserialized.
### Actual Behavior
The application prints:
```
[Error] File not found:
```
and the `Landmark` model initialization fails silently (returns None), leading to cascading `AttributeError` when `app.get()` returns faces with `landmark_3d_68 = None`:
```
AttributeError: 'NoneType' object has no attribute 'shape'
```
### Root Cause
In `insightface/data/pickle_object.py`, the `get_object()` function:
```python
def get_object(name):
if getattr(sys, 'frozen', False):
base_dir = sys._MEIPASS # <-- Problem: _MEIPASS is PyInstaller's temp dir
else:
base_dir = Path(__file__).parent.absolute() # insightface/data/
objects_dir = osp.join(base_dir, 'objects') # → _MEIPASS/objects/ (EMPTY!)
# The actual PKL is at insightface/data/objects/meanshape_68.pkl
```
When `sys.frozen` is True (PyInstaller), it uses `sys._MEIPASS` as the base directory. However, `sys._MEIPASS` points to the temporary extracted directory (e.g. `C:\Users\...\AppData\Local\Temp\_MEIxxxxxx\`), which does **not** contain the `objects/` subdirectory. The PKL file lives at `site-packages/insightface/data/objects/meanshape_68.pkl`.
In contrast, the non-frozen path correctly uses `Path(__file__).parent.absolute()` which resolves to `insightface/data/`, where `objects/` actually exists.
### Proposed Fix
Option A — fall back to the package-relative path:
```python
def get_object(name):
objects_dirs = []
if getattr(sys, 'frozen', False):
objects_dirs.append(sys._MEIPASS)
objects_dirs.append(str(Path(__file__).parent.absolute()))
if not name.endswith('.pkl'):
name = name + ".pkl"
for base_dir in objects_dirs:
filepath = osp.join(base_dir, 'objects', name)
if osp.exists(filepath):
with open(filepath, 'rb') as f:
return pickle.load(f)
print(f"[Error] File not found: objects/{name}")
return None
```
Option B — use `importlib.resources` for the fallback path.
### Environment
- Python: 3.12
- insightface: 1.0.1
- OS: Windows 11
- PyInstaller: bundled via `--collect-all insightface`
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in insightface/data/pickle_object.py and inspect get_object() with the frozen PyInstaller path and its package-relative fallback. Reproduce with --collect-all insightface, then verify that meanshape_68.pkl loads for FaceAnalysis and landmark_3d_68 is initialized without the reported cascading AttributeError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100