Tested environment: Ubuntu 24, Miniforge3, CUDA 12.1, GPU with compute capability 8.9 (e.g. RTX 4090). This guide documents every fix discovered during a multi-day debugging session. Follow it top to bottom without skipping steps.
Make sure the following are already installed on your system:
nvcc available at /usr/local/cuda)git, wgetTORCH_CUDA_ARCH_LIST in the build step accordingly
(e.g. "8.0" for A100, "7.5" for RTX 20xx, "8.6" for RTX 30xx).mkdir -p ~/Documents/Projects
cd ~/Documents/Projects
# Main RexSeek repo
git clone https://github.com/IDEA-Research/RexSeek.git
# GroundingDINO goes INSIDE the demos folder
cd RexSeek/demos
git clone https://github.com/IDEA-Research/GroundingDINO.git
Create the output directory for results:
mkdir -p ~/Documents/Projects/RexSeek/outputs
⚠️ Critical: Use Python 3.10.11 specifically. The conda-forge build of Python 3.10.19 (
h3c07f61_3_cpython) has a brokenzipfilemodule that corrupts large CUDA wheel installs and causes random stdlib corruption at runtime (manifesting as randomsre_parse,configparser,tokenizecrashes). Python 3.10.11 is stable.
conda create -n rexseek python=3.10.11 -c conda-forge -y
conda activate rexseek
# Verify
python --version
# Must show: Python 3.10.11
⚠️ Critical: pip 26.x has a regression in its dependency resolver (
UnboundLocalError: local variable 'specifier_set') that breaks PyTorch CUDA wheel installs. Downgrade pip first, then useuvfor all actual package installs — it bypasses Python's zipfile module entirely and is dramatically faster.
python -m pip install "pip<26"
pip install uv
uv pip install "setuptools<70"
uv pip install "numpy==1.26.4"
uv pip install torch==2.5.1 torchvision==0.20.1 --index-url https://download.pytorch.org/whl/cu121
uv pip install transformers==4.44.2 accelerate==1.5.2 timm==1.0.15 "safetensors==0.5.3" "Pillow==11.1.0"
⚠️
supervisionwill pull in incompatible versions of numpy and opencv. Force-reinstall the pinned versions immediately after.
uv pip install "supervision==0.25.1"
uv pip install "numpy==1.26.4" "opencv-python==4.8.1.78" \
--no-deps \
--reinstall-package numpy \
--reinstall-package opencv-python
Verify:
python -c "import numpy; import cv2; print('numpy:', numpy.__version__); print('cv2:', cv2.__version__)"
# Must show: numpy: 1.26.4 cv2: 4.8.1
uv pip install "spacy==3.8.3"
python -m spacy download en_core_web_sm
uv pip install open_clip_torch==2.31.0 pycocotools==2.0.8 deepspeed==0.16.4
uv pip install tabulate==0.9.0 termcolor==2.5.0 typer==0.15.2 shortuuid==1.0.13 \
huggingface_hub addict yapf
export CUDA_HOME=/usr/local/cuda
export BUILD_WITH_CUDA=True
export TORCH_CUDA_ARCH_LIST="8.9" # Change to match your GPU compute capability
export PIP_USER=false
export LD_LIBRARY_PATH=$HOME/miniforge3/envs/rexseek/lib/python3.10/site-packages/torch/lib:${LD_LIBRARY_PATH:-}
The original setup.py calls install_torch() which tries to reinstall PyTorch and will break your environment. Patch it out:
cd ~/Documents/Projects/RexSeek/demos/GroundingDINO
python -c "
import re
content = open('setup.py').read()
patched = re.sub(r'^(\s*)install_torch\(\)\s*$', r'\1# install_torch() # patched', content, flags=re.MULTILINE)
open('setup.py', 'w').write(patched)
print('Patched OK')
"
rm -rf build/ dist/ groundingdino.egg-info/ 2>/dev/null || true
find groundingdino/ -name "_C*.so" -delete 2>/dev/null || true
python setup.py build_ext --inplace 2>&1 | tail -5
The last output line should look like:
copying build/.../groundingdino/_C.cpython-310-x86_64-linux-gnu.so -> groundingdino
python -c "import groundingdino._C; print('CUDA ops OK')"
GroundingDINO needs to be importable from inside the RexSeek demos directory. Register it via a .pth file:
SITE_PACKAGES=$HOME/miniforge3/envs/rexseek/lib/python3.10/site-packages
echo "$HOME/Documents/Projects/RexSeek/demos/GroundingDINO" > $SITE_PACKAGES/groundingdino.pth
# Verify it resolves to the right location
python -c "import groundingdino; print(groundingdino.__file__)"
# Must show: .../RexSeek/demos/GroundingDINO/groundingdino/__init__.py
Install RexSeek in editable mode without overriding pinned deps:
cd ~/Documents/Projects/RexSeek
uv pip install -e . --no-deps
mkdir -p ~/Documents/Projects/RexSeek/demos/GroundingDINO/weights
wget -q --show-progress \
https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth \
-O ~/Documents/Projects/RexSeek/demos/GroundingDINO/weights/groundingdino_swint_ogc.pth
cd ~/Documents/Projects/RexSeek
python -c "
from huggingface_hub import snapshot_download
snapshot_download(repo_id='IDEA-Research/RexSeek-3B', local_dir='./weights/RexSeek-3B')
print('Done')
"
Two patches must be applied to rexseek_grounding_dino_spacy.py before inference will work correctly.
re/sre_compile prewarm headerThis ensures the stdlib re module is fully initialized before any downstream package touches it:
python - << 'EOF'
import os, re
path = os.path.expanduser("~/Documents/Projects/RexSeek/demos/rexseek_grounding_dino_spacy.py")
content = open(path).read()
lines_content = content.split('\n')
start = 0
for i, line in enumerate(lines_content):
stripped = line.strip()
if stripped and not any(stripped.startswith(p) for p in (
'import sys', 'import types', 'import re', 'import sre',
'import collections', 'import configparser', 'import textwrap',
'import enum', 'import importlib', '_ds', 'sys.modules', '#'
)):
start = i
break
clean = '\n'.join(lines_content[start:])
header = 'import re\nimport sre_compile\n\n'
open(path, 'w').write(header + clean)
print('Script reset OK, starts with:', lines_content[start][:60])
EOF
The default spacy_noun_phrases function returns complex noun chunks that GroundingDINO cannot match when the prompt contains person-related words. This patch forces it to return "person" as the grounding anchor for person-related queries:
python - << 'PYEOF'
import os
path = os.path.expanduser("~/Documents/Projects/RexSeek/demos/rexseek_grounding_dino_spacy.py")
content = open(path).read()
old_func = (
'def spacy_noun_phrases(caption):\n'
' """Extract noun phrases from a given text caption using spaCy.\n'
'\n'
' Args:\n'
' caption (str): The input text caption to process.\n'
'\n'
' Returns:\n'
' list[str]: A list of lowercase noun phrases extracted from the caption.\n'
' """\n'
' doc = nlp(caption)\n'
' nouns = []\n'
' for nounc in doc.noun_chunks:\n'
' nouns.append(str(nounc).lower())\n'
' return nouns'
)
new_func = (
'def spacy_noun_phrases(caption):\n'
' doc = nlp(caption)\n'
' tokens = [t.text.lower() for t in doc]\n'
' PERSON_WORDS = {"person", "man", "woman", "people", "human", "boy", "girl",\n'
' "child", "guy", "lady", "gentleman", "student", "worker"}\n'
' for word in PERSON_WORDS:\n'
' if word in tokens:\n'
' return ["person"]\n'
' nouns = [str(nounc).lower() for nounc in doc.noun_chunks]\n'
' return nouns if nouns else ["person"]'
)
if old_func in content:
open(path, 'w').write(content.replace(old_func, new_func))
print('Person-anchor patch: OK')
else:
print('Pattern not found - may already be patched')
PYEOF
Run this before any inference to confirm everything is wired up correctly:
cd ~/Documents/Projects/RexSeek
python -c "
import torch, numpy as np, cv2, spacy, groundingdino
import groundingdino._C
print('torch :', torch.__version__)
print('numpy :', np.__version__)
print('opencv :', cv2.__version__)
print('CUDA :', torch.cuda.is_available())
assert int(np.__version__.split('.')[0]) < 2, 'numpy must be < 2!'
nlp = spacy.load('en_core_web_sm')
print('spacy : OK')
print('gdino :', groundingdino.__file__)
print('ALL CHECKS PASSED')
"
Expected output:
torch : 2.5.1+cu121
numpy : 1.26.4
opencv : 4.8.1
CUDA : True
spacy : OK
gdino : .../RexSeek/demos/GroundingDINO/groundingdino/__init__.py
ALL CHECKS PASSED
cd ~/Documents/Projects/RexSeek
CUDA_VISIBLE_DEVICES=0 python demos/rexseek_grounding_dino_spacy.py \
--image demos/demo_images/demo1.jpg \
--output outputs/test_out.jpg \
--referring "person that is giving a proposal" \
--box-threshold 0.25 \
--text-threshold 0.25
| Argument | Description |
|---|---|
--image | Path to input image (JPG or PNG). PNGs with transparency (RGBA) are auto-converted to RGB. |
--output | Path to save the annotated output image. |
--referring | Natural language referring expression (e.g. "man holding a luggage"). |
--box-threshold | Confidence threshold for bounding box detection (default: 0.25). |
--text-threshold | Confidence threshold for text grounding (default: 0.25). |
| Issue | Cause | Fix |
|---|---|---|
UnboundLocalError: local variable 'specifier_set' during install | pip 26.x regression in dependency resolver | Run python -m pip install "pip<26" before any other installs |
'bool' object has no attribute 'decompress' | Corrupted cached .whl files from a failed pip 26 run | Run pip cache purge then reinstall with --no-cache-dir |
'ZipInfo' object has no attribute 'fp' | Broken zipfile module in Python 3.10.19 conda-forge build | Use uv pip install instead of pip install for all packages |
Random sre_parse / configparser / tokenize crashes at runtime | Python 3.10.19 conda-forge build (h3c07f61_3_cpython) corrupts stdlib state | Recreate env with Python 3.10.11 — this is the definitive fix |
supervision breaks numpy/opencv version pins | supervision pulls incompatible transitive deps | Force-reinstall numpy==1.26.4 and opencv-python==4.8.1.78 with --no-deps immediately after |
| GroundingDINO build fails / tries to reinstall torch | setup.py calls install_torch() | Patch it out before building (see Build step) |
| Person-referring queries return no boxes or wrong boxes | spaCy noun chunks don't match GroundingDINO text anchors | Apply person-anchor noun extraction patch (Patch 2) |
| CUDA ops build fails or produces wrong output | TORCH_CUDA_ARCH_LIST doesn't match your GPU | Set it to your GPU's actual compute capability (e.g. 8.6 for RTX 30xx) |
Tested environment: Ubuntu 24, Miniforge3, CUDA 12.1, GPU with compute capability 8.9 (e.g. RTX 4090). This guide documents every fix discovered during a multi-day debugging session. Follow it top to bottom without skipping steps.
Make sure the following are already installed on your system:
nvcc available at /usr/local/cuda)git, wgetTORCH_CUDA_ARCH_LIST in the build step accordingly
(e.g. "8.0" for A100, "7.5" for RTX 20xx, "8.6" for RTX 30xx).mkdir -p ~/Documents/Projects
cd ~/Documents/Projects
# Main RexSeek repo
git clone https://github.com/IDEA-Research/RexSeek.git
# GroundingDINO goes INSIDE the demos folder
cd RexSeek/demos
git clone https://github.com/IDEA-Research/GroundingDINO.git
Create the output directory for results:
mkdir -p ~/Documents/Projects/RexSeek/outputs
⚠️ Critical: Use Python 3.10.11 specifically. The conda-forge build of Python 3.10.19 (
h3c07f61_3_cpython) has a brokenzipfilemodule that corrupts large CUDA wheel installs and causes random stdlib corruption at runtime (manifesting as randomsre_parse,configparser,tokenizecrashes). Python 3.10.11 is stable.
conda create -n rexseek python=3.10.11 -c conda-forge -y
conda activate rexseek
# Verify
python --version
# Must show: Python 3.10.11
⚠️ Critical: pip 26.x has a regression in its dependency resolver (
UnboundLocalError: local variable 'specifier_set') that breaks PyTorch CUDA wheel installs. Downgrade pip first, then useuvfor all actual package installs — it bypasses Python's zipfile module entirely and is dramatically faster.
python -m pip install "pip<26"
pip install uv
uv pip install "setuptools<70"
uv pip install "numpy==1.26.4"
uv pip install torch==2.5.1 torchvision==0.20.1 --index-url https://download.pytorch.org/whl/cu121
uv pip install transformers==4.44.2 accelerate==1.5.2 timm==1.0.15 "safetensors==0.5.3" "Pillow==11.1.0"
⚠️
supervisionwill pull in incompatible versions of numpy and opencv. Force-reinstall the pinned versions immediately after.
uv pip install "supervision==0.25.1"
uv pip install "numpy==1.26.4" "opencv-python==4.8.1.78" \
--no-deps \
--reinstall-package numpy \
--reinstall-package opencv-python
Verify:
python -c "import numpy; import cv2; print('numpy:', numpy.__version__); print('cv2:', cv2.__version__)"
# Must show: numpy: 1.26.4 cv2: 4.8.1
uv pip install "spacy==3.8.3"
python -m spacy download en_core_web_sm
uv pip install open_clip_torch==2.31.0 pycocotools==2.0.8 deepspeed==0.16.4
uv pip install tabulate==0.9.0 termcolor==2.5.0 typer==0.15.2 shortuuid==1.0.13 \
huggingface_hub addict yapf
export CUDA_HOME=/usr/local/cuda
export BUILD_WITH_CUDA=True
export TORCH_CUDA_ARCH_LIST="8.9" # Change to match your GPU compute capability
export PIP_USER=false
export LD_LIBRARY_PATH=$HOME/miniforge3/envs/rexseek/lib/python3.10/site-packages/torch/lib:${LD_LIBRARY_PATH:-}
The original setup.py calls install_torch() which tries to reinstall PyTorch and will break your environment. Patch it out:
cd ~/Documents/Projects/RexSeek/demos/GroundingDINO
python -c "
import re
content = open('setup.py').read()
patched = re.sub(r'^(\s*)install_torch\(\)\s*$', r'\1# install_torch() # patched', content, flags=re.MULTILINE)
open('setup.py', 'w').write(patched)
print('Patched OK')
"
rm -rf build/ dist/ groundingdino.egg-info/ 2>/dev/null || true
find groundingdino/ -name "_C*.so" -delete 2>/dev/null || true
python setup.py build_ext --inplace 2>&1 | tail -5
The last output line should look like:
copying build/.../groundingdino/_C.cpython-310-x86_64-linux-gnu.so -> groundingdino
python -c "import groundingdino._C; print('CUDA ops OK')"
GroundingDINO needs to be importable from inside the RexSeek demos directory. Register it via a .pth file:
SITE_PACKAGES=$HOME/miniforge3/envs/rexseek/lib/python3.10/site-packages
echo "$HOME/Documents/Projects/RexSeek/demos/GroundingDINO" > $SITE_PACKAGES/groundingdino.pth
# Verify it resolves to the right location
python -c "import groundingdino; print(groundingdino.__file__)"
# Must show: .../RexSeek/demos/GroundingDINO/groundingdino/__init__.py
Install RexSeek in editable mode without overriding pinned deps:
cd ~/Documents/Projects/RexSeek
uv pip install -e . --no-deps
mkdir -p ~/Documents/Projects/RexSeek/demos/GroundingDINO/weights
wget -q --show-progress \
https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth \
-O ~/Documents/Projects/RexSeek/demos/GroundingDINO/weights/groundingdino_swint_ogc.pth
cd ~/Documents/Projects/RexSeek
python -c "
from huggingface_hub import snapshot_download
snapshot_download(repo_id='IDEA-Research/RexSeek-3B', local_dir='./weights/RexSeek-3B')
print('Done')
"
Two patches must be applied to rexseek_grounding_dino_spacy.py before inference will work correctly.
re/sre_compile prewarm headerThis ensures the stdlib re module is fully initialized before any downstream package touches it:
python - << 'EOF'
import os, re
path = os.path.expanduser("~/Documents/Projects/RexSeek/demos/rexseek_grounding_dino_spacy.py")
content = open(path).read()
lines_content = content.split('\n')
start = 0
for i, line in enumerate(lines_content):
stripped = line.strip()
if stripped and not any(stripped.startswith(p) for p in (
'import sys', 'import types', 'import re', 'import sre',
'import collections', 'import configparser', 'import textwrap',
'import enum', 'import importlib', '_ds', 'sys.modules', '#'
)):
start = i
break
clean = '\n'.join(lines_content[start:])
header = 'import re\nimport sre_compile\n\n'
open(path, 'w').write(header + clean)
print('Script reset OK, starts with:', lines_content[start][:60])
EOF
The default spacy_noun_phrases function returns complex noun chunks that GroundingDINO cannot match when the prompt contains person-related words. This patch forces it to return "person" as the grounding anchor for person-related queries:
python - << 'PYEOF'
import os
path = os.path.expanduser("~/Documents/Projects/RexSeek/demos/rexseek_grounding_dino_spacy.py")
content = open(path).read()
old_func = (
'def spacy_noun_phrases(caption):\n'
' """Extract noun phrases from a given text caption using spaCy.\n'
'\n'
' Args:\n'
' caption (str): The input text caption to process.\n'
'\n'
' Returns:\n'
' list[str]: A list of lowercase noun phrases extracted from the caption.\n'
' """\n'
' doc = nlp(caption)\n'
' nouns = []\n'
' for nounc in doc.noun_chunks:\n'
' nouns.append(str(nounc).lower())\n'
' return nouns'
)
new_func = (
'def spacy_noun_phrases(caption):\n'
' doc = nlp(caption)\n'
' tokens = [t.text.lower() for t in doc]\n'
' PERSON_WORDS = {"person", "man", "woman", "people", "human", "boy", "girl",\n'
' "child", "guy", "lady", "gentleman", "student", "worker"}\n'
' for word in PERSON_WORDS:\n'
' if word in tokens:\n'
' return ["person"]\n'
' nouns = [str(nounc).lower() for nounc in doc.noun_chunks]\n'
' return nouns if nouns else ["person"]'
)
if old_func in content:
open(path, 'w').write(content.replace(old_func, new_func))
print('Person-anchor patch: OK')
else:
print('Pattern not found - may already be patched')
PYEOF
Run this before any inference to confirm everything is wired up correctly:
cd ~/Documents/Projects/RexSeek
python -c "
import torch, numpy as np, cv2, spacy, groundingdino
import groundingdino._C
print('torch :', torch.__version__)
print('numpy :', np.__version__)
print('opencv :', cv2.__version__)
print('CUDA :', torch.cuda.is_available())
assert int(np.__version__.split('.')[0]) < 2, 'numpy must be < 2!'
nlp = spacy.load('en_core_web_sm')
print('spacy : OK')
print('gdino :', groundingdino.__file__)
print('ALL CHECKS PASSED')
"
Expected output:
torch : 2.5.1+cu121
numpy : 1.26.4
opencv : 4.8.1
CUDA : True
spacy : OK
gdino : .../RexSeek/demos/GroundingDINO/groundingdino/__init__.py
ALL CHECKS PASSED
cd ~/Documents/Projects/RexSeek
CUDA_VISIBLE_DEVICES=0 python demos/rexseek_grounding_dino_spacy.py \
--image demos/demo_images/demo1.jpg \
--output outputs/test_out.jpg \
--referring "person that is giving a proposal" \
--box-threshold 0.25 \
--text-threshold 0.25
| Argument | Description |
|---|---|
--image | Path to input image (JPG or PNG). PNGs with transparency (RGBA) are auto-converted to RGB. |
--output | Path to save the annotated output image. |
--referring | Natural language referring expression (e.g. "man holding a luggage"). |
--box-threshold | Confidence threshold for bounding box detection (default: 0.25). |
--text-threshold | Confidence threshold for text grounding (default: 0.25). |
| Issue | Cause | Fix |
|---|---|---|
UnboundLocalError: local variable 'specifier_set' during install | pip 26.x regression in dependency resolver | Run python -m pip install "pip<26" before any other installs |
'bool' object has no attribute 'decompress' | Corrupted cached .whl files from a failed pip 26 run | Run pip cache purge then reinstall with --no-cache-dir |
'ZipInfo' object has no attribute 'fp' | Broken zipfile module in Python 3.10.19 conda-forge build | Use uv pip install instead of pip install for all packages |
Random sre_parse / configparser / tokenize crashes at runtime | Python 3.10.19 conda-forge build (h3c07f61_3_cpython) corrupts stdlib state | Recreate env with Python 3.10.11 — this is the definitive fix |
supervision breaks numpy/opencv version pins | supervision pulls incompatible transitive deps | Force-reinstall numpy==1.26.4 and opencv-python==4.8.1.78 with --no-deps immediately after |
| GroundingDINO build fails / tries to reinstall torch | setup.py calls install_torch() | Patch it out before building (see Build step) |
| Person-referring queries return no boxes or wrong boxes | spaCy noun chunks don't match GroundingDINO text anchors | Apply person-anchor noun extraction patch (Patch 2) |
| CUDA ops build fails or produces wrong output | TORCH_CUDA_ARCH_LIST doesn't match your GPU | Set it to your GPU's actual compute capability (e.g. 8.6 for RTX 30xx) |