deepinsight / deepinsight/insightface

PyInstaller bundled: get_object fails with FileNotFoundError for meanshape_68.pkl

Open
#2,888 1 comment 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.