Skip to content

fix(multimodal): lazy load package exports - #11186

Closed
glamr-agent wants to merge 3 commits into
ai-dynamo:mainfrom
glamr-agent:fix/11172-lazy-multimodal-imports
Closed

glamr-agent wants to merge 3 commits into
ai-dynamo:mainfrom
glamr-agent:fix/11172-lazy-multimodal-imports

Conversation

@glamr-agent

@glamr-agent glamr-agent commented Jul 2, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #11172

Summary

  • Lazily resolves dynamo.common.multimodal re-exports through module-level __getattr__ so ImageLoader does not eagerly import embedding cache/transfer modules.
  • Preserves embedding sender/receiver factory APIs with lazy callables that import heavy classes only when instantiated.
  • Adds a subprocess regression test that blocks torch imports while importing ImageLoader from the package.

Validation

  • PYTHONPATH=components/src python - <<'PY' ... import dynamo.common.multimodal ... PY
  • python -m compileall -q components/src/dynamo/common/multimodal/__init__.py components/src/dynamo/common/tests/multimodal/test_image_loader.py
  • git diff --check

Notes

  • python -m pytest components/src/dynamo/common/tests/multimodal/test_image_loader.py could not run in this runner because pytest, pip, and ensurepip are not installed.

Open in Devin Review

Summary by CodeRabbit

  • Bug Fixes

    • Improved multimodal loading so components are imported only when needed, helping avoid unnecessary startup overhead and import-time issues.
    • Updated embedding sender/receiver creation to defer loading until used, making related features more reliable in environments without optional dependencies.
  • Tests

    • Added coverage to ensure image loading utilities can be imported without pulling in heavyweight ML dependencies.

Signed-off-by: Coding Agent <svc-glamr@nvidia.com>
@glamr-agent
glamr-agent requested review from a team as code owners July 2, 2026 20:12
@copy-pr-bot

copy-pr-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@datadog-official

This comment has been minimized.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread components/src/dynamo/common/tests/multimodal/test_image_loader.py Outdated
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The multimodal package __init__.py replaces eager imports with a lazy export registry and __getattr__-based resolution, plus lazy embedding sender/receiver factories that defer submodule imports until invocation. A new subprocess-based test verifies that importing ImageLoader no longer pulls in torch.

Changes

Lazy multimodal imports

Layer / File(s) Summary
Lazy export registry and resolution
components/src/dynamo/common/multimodal/__init__.py
Adds _LAZY_EXPORTS mapping symbol names to module paths, _load_export() to import and cache attributes, and module-level __getattr__() to serve missing attributes on demand.
Lazy embedding sender/receiver factories
components/src/dynamo/common/multimodal/__init__.py
Adds _lazy_factory, _embedding_sender_factory, _embedding_receiver_factory helpers; EMBEDDING_SENDER_FACTORIES and EMBEDDING_RECEIVER_FACTORIES now map to callables that defer imports until invoked, including the NIXL read receiver case with max_items=0.
Torch-free import regression test
components/src/dynamo/common/tests/multimodal/test_image_loader.py
Adds subprocess, sys, textwrap imports and a new subprocess-based test that blocks torch imports via a custom meta_path finder and asserts ImageLoader/validate_media_url import without pulling in torch.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Related issues: Resolves the eager torch import chain issue (#11172) where importing ImageLoader from dynamo.common.multimodal transitively imported torch via AsyncEncoderCache.

Suggested labels: enhancement, performance, tests

Suggested reviewers: maintainers familiar with dynamo.common.multimodal package structure

Poem

A rabbit hops, no torch in tow,
Lazy imports let it go,
__getattr__ waits with patient care,
Fetching modules from thin air,
Subprocess sniffs — no heavy freight,
ImageLoader now loads light and straight. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the change, but it does not follow the required template sections like Overview, Details, or Where should reviewer start? Add the missing template sections, especially a structured Related Issues entry and a reviewer-start section.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: making multimodal package exports lazy.
Linked Issues check ✅ Passed The lazy getattr re-exports and lazy embedding factories address the import-chain issue, and the new test guards against torch imports.
Out of Scope Changes check ✅ Passed The test and lazy-loading changes support the issue's import-lightweight objective and do not add unrelated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/src/dynamo/common/tests/multimodal/test_image_loader.py`:
- Around line 43-67: The subprocess-based import test in
test_package_image_loader_import_does_not_import_torch can hang indefinitely
because the subprocess.run call has no timeout. Update this test to guard the
child process with a timeout on subprocess.run, and add the appropriate pytest
timeout marker for the test so it cannot stall in CI. Use the existing test
function name and its subprocess.run invocation as the place to apply the fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4658a066-ff8d-458f-91df-d6883553c4ac

📥 Commits

Reviewing files that changed from the base of the PR and between 4a8c55b and 4c79c99.

📒 Files selected for processing (2)
  • components/src/dynamo/common/multimodal/__init__.py
  • components/src/dynamo/common/tests/multimodal/test_image_loader.py

Comment thread components/src/dynamo/common/tests/multimodal/test_image_loader.py Outdated
Comment thread components/src/dynamo/common/tests/multimodal/test_image_loader.py Outdated
@MatejKosec MatejKosec self-assigned this Jul 6, 2026
Signed-off-by: Dynamo Agent <dynamo-agent@users.noreply.github.com>
@glamr-agent
glamr-agent temporarily deployed to external_collaborator July 6, 2026 08:16 — with GitHub Actions Inactive
Signed-off-by: Coding Agent <svc-glamr@nvidia.com>

This branch was previously deployed

1 inactive deployment
external_collaborator — f4c9fa13 Deployed Jul 6, 2026 by glamr-agent via ok-to-test #2187
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Importing ImageLoader from dynamo.common.multimodal eagerly pulls in torch via __init__.py

2 participants