Skip to content

feat: depend on the groundingdino conda package instead of vendoring it - #2

Draft
phreed wants to merge 7 commits into
mainfrom
feat/use-groundingdino-package
Draft

feat: depend on the groundingdino conda package instead of vendoring it#2
phreed wants to merge 7 commits into
mainfrom
feat/use-groundingdino-package

Conversation

@phreed

@phreed phreed commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Part of #1 — this is the downstream half. The upstream half is
IDEA-Research/GroundingDINO#458, #459, #460 and #461.

Removes the vendored copy of GroundingDINO and depends on the conda package instead.

Why

Every change this repository had made under groundingdino/ is now a pull request against
upstream, and the conda-forge feedstock builds the result. Keeping a fork in a subdirectory
after that buys nothing and actively hides which changes are ours.

The four files, and where they went:

File Upstream PR
models/GroundingDINO/bertwarper.py IDEA-Research/GroundingDINO#458
models/GroundingDINO/csrc/MsDeformAttn/ms_deform_attn_cuda.cu IDEA-Research/GroundingDINO#459
version.py IDEA-Research/GroundingDINO#460
config/GroundingDINO_SwinB_cfg.py IDEA-Research/GroundingDINO#461

What survives, and why it has to

groundingdino/config/ stays. Twenty call sites across eighteen files load those two model
configs by path, not by import:

CONFIG_PATH = "groundingdino/config/GroundingDINO_SwinB_cfg.py"

groundingdino/__init__.py is deleted, and that deletion is the load-bearing part of this
change rather than tidying.

A groundingdino/ directory in the working directory is found before site-packages. With an
__init__.py it is a regular package and wins immediately, silently shadowing the conda package
that is supposed to replace it. Without one it is only a namespace portion: Python records it,
keeps scanning sys.path, finds the installed regular package, and uses that.

docker/Dockerfile.ros2 now asserts this at image build time rather than leaving it to be
discovered at run time:

RUN python3 -c "import groundingdino, sys; p = groundingdino.__file__ or ''; \
    sys.exit(0) if 'site-packages' in p or 'dist-packages' in p else \
    sys.exit(f'groundingdino resolved to {p!r}, not the installed package')"

Also removed

  • setup.py — existed to build the vendored CUDA extension.
  • recipe.yaml — built the detector; the feedstock owns that now.
  • pixi.toml — merged into pyproject.toml, so one file describes this project to both pip
    and pixi. Two files stating the same dependency set is how they drift apart.
  • pixi.lock — regenerated against the new environment.
  • Dockerfile — GroundingDINO's own, inherited by the fork. It COPYs docker_test.py, which
    exists upstream and not here, so it has been unbuildable since the fork, and nothing
    references it.
  • environment.yaml — superseded by [tool.pixi], and pointed at a requirements.txt that has
    never existed in this repository (the file is r.txt).

docker/Dockerfile.ros2 also asked pip for that same nonexistent requirements.txt; fixed while
in the area. It now clones GroundingDINO and compiles the extension from there, pinned to the
branch carrying the four fixes until they merge upstream.

Dependency changes worth review

[project].dependencies is deliberately empty and [tool.pixi.dependencies] is the single
authoritative list. Stating the same names in both makes pixi resolve them a second time against
PyPI, where groundingdino-py is still 0.4.0 and carries none of these fixes:

Because only groundingdino-py<=0.4.0 is available and you require
groundingdino-py>=0.4.1, we can conclude that your requirements are unsatisfiable.

It would be wrong even if it resolved — torch from PyPI beside pytorch from conda is two
builds of one library in one environment.

The pytorch and nvidia channels are gone, and with them the channel-priority = "disabled"
they needed to coexist. groundingdino-py-cuda is built against conda-forge's CUDA pytorch, so
drawing pytorch from the pytorch channel would mix two builds of it. One channel, one pytorch.

The CUDA build toolchain drops out of the environment entirely — cuda-nvcc, cuda-toolkit,
gxx_linux-64, ninja, and the libcublas / libcusolver / libcusparse / libcurand -dev
packages were all there only to compile the vendored extension.

Swap groundingdino-py-cuda for groundingdino-py-cpu and the environment resolves on a machine
with no GPU at all — correctly, but slowly, and it must stay in float32 because grid_sample has
no half-precision CPU kernel.

Verified

resolves to : .../st/.pixi/envs/default/lib/python3.10/site-packages/groundingdino/__init__.py
extension   : ['..._C.cpython-310-x86_64-linux-gnu.so']
_C forward  : True
local config: groundingdino | training params: True

Not mergeable yet

pyproject.toml points at a local channel, because groundingdino-py 0.4.1 does not exist
publicly until conda-forge/groundingdino-py-feedstock#3 lands and publishes.

That feedstock PR no longer waits on upstream review: it builds upstream's own tree and carries
the three fixes as patches, which is conda-forge's mechanism for exactly this. So the remaining
chain is short — feedstock merges and publishes, this drops the local channel and comes out of
draft. The upstream PRs can land on their own schedule; each patch is deleted as its PR does.

docker/Dockerfile.ros2 still clones phreed:integration/split-fixes. That container builds the
extension with pip rather than installing the conda package, so it needs a git ref rather than a
channel. It is a fetchable branch and only a build-time input, but it is worth revisiting once the
upstream PRs merge — at which point it can clone IDEA-Research/main directly.

phreed added 3 commits July 31, 2026 13:39
Removes the vendored copy of GroundingDINO. Every fix this project made to
that tree is now a pull request against IDEA-Research/GroundingDINO, and the
conda-forge feedstock builds it, so keeping a fork in a subdirectory buys
nothing and hides which changes are ours.

groundingdino/config/ stays: every eval and demo script loads the two model
configs by path, not by import. groundingdino/__init__.py is deleted, which
is what makes that safe -- a directory without it is only a namespace
portion, and a namespace portion loses to the installed regular package.
Left in place it would shadow the dependency.

setup.py and recipe.yaml go with it: both existed to build the detector.
pixi.toml is merged into pyproject.toml, so one file describes the project
to both pip and pixi, and the CUDA build toolchain drops out of the
environment entirely.
docker/Dockerfile.ros2 still built the detector out of this repository:
`python3 setup.py clean --all` followed by an editable install. setup.py is
gone, so the image no longer built at all. It now clones GroundingDINO and
compiles the extension from there, pinned to the branch carrying this
project's fixes until they merge upstream.

That file also asked pip for requirements.txt, which has never existed here
-- the file is r.txt. Fixed while in the area.

The image now asserts at build time that `import groundingdino` resolves to
site-packages. The ./groundingdino config directory has no __init__.py, so
it is only a namespace portion and loses to the installed package, but that
is subtle enough to be worth failing the build over rather than debugging
in a running container.

Dockerfile is GroundingDINO's own, inherited by the fork. It COPYs
docker_test.py, which exists in GroundingDINO and not here, so it has been
unbuildable since the fork, and nothing references it.

environment.yaml is superseded by [tool.pixi] in pyproject.toml, and points
at the same nonexistent requirements.txt.

pixi.lock described the environment pixi.toml declared, and pixi.toml is
merged away. It is regenerated once groundingdino-py is resolvable.
Verified end to end for the first time, which turned up three problems the
pixi.toml merge introduced.

The `pytorch` and `nvidia` channels are gone. groundingdino-py-cuda is built
against conda-forge's CUDA pytorch, so keeping them meant two builds of the
same library in one environment -- and the merge had also dropped the
`channel-priority = "disabled"` that let the three channels coexist, so the
solve failed outright on libcusolver.

[project].dependencies is now empty. Listing the conda dependencies there as
well made pixi resolve them a second time against PyPI, where
groundingdino-py is still 0.4.0 and carries none of the fixes this project
contributed.  [tool.pixi.dependencies] is the one authoritative list.

pytorch-cuda is dropped: it is the `pytorch` channel's spelling, and
groundingdino-py-cuda already requires `pytorch *cuda*`, so the CUDA build is
selected by the detector rather than pinned here.

[system-requirements] moves onto the platform entry, which is where pixi now
wants it.

Confirmed in the built environment: `import groundingdino` resolves to
site-packages rather than the ./groundingdino config directory, _C loads and
exposes ms_deform_attn_forward, both transformers fixes are present in the
shipped package, and SLConfig still loads the kept config by path.
phreed added 4 commits July 31, 2026 16:48
The feedstock no longer builds a groundingdino-py-cpu metapackage; it was an
empty package whose only content was a constraint against something opt-in.
Running without the extension is just not installing groundingdino-py-cuda.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant