Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix open-clip-torch model inference #5395

Merged
merged 3 commits into from
Jan 21, 2025
Merged

Conversation

jacobsela
Copy link
Contributor

@jacobsela jacobsela commented Jan 16, 2025

What changes are proposed in this pull request?

Fix open clip zoo model.

See #5026 (comment) for details.

How is this patch tested? If it is not, please explain why.

import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset("coco-2017", split="validation", max_samples=10, shuffle=True)
model = foz.load_zoo_model("open-clip-torch")

dataset.apply_model(model, label_field="predictions")

Summary by CodeRabbit

  • Refactor
    • Updated preprocessing method for OpenClip model.
    • Simplified image preprocessing during prediction.

These changes enhance the efficiency of the OpenClip model's image processing capabilities, leading to improved performance.

Copy link
Contributor

coderabbitai bot commented Jan 16, 2025

Walkthrough

The pull request modifies the TorchOpenClipModel class in the fiftyone/utils/open_clip.py file. The changes primarily focus on adjusting the preprocessing attribute and method, specifically replacing self.preprocess with self._preprocess_aux. Additionally, the image preprocessing logic in the _predict_all method has been simplified by removing the unsqueezing operation. These updates enhance the control flow during image processing within the model.

Changes

File Change Summary
fiftyone/utils/open_clip.py - Replaced self.preprocess with self._preprocess_aux
- Simplified image preprocessing in _predict_all by removing unsqueeze(0)
- Updated context management for tensor operations using contextlib.ExitStack

Possibly related PRs

  • Bugfix: use device in all Torch models #5026: This PR modifies the TorchOpenClipModel class in fiftyone/utils/open_clip.py, specifically enhancing tensor device management in the _predict_all method, which is directly related to the changes made in the main PR regarding the same method.

Suggested reviewers

  • mwoodson1
  • danielgural
  • harpreetsahota204

Poem

🐰 In the world of code, we hop and play,
Preprocessing images in a brand new way.
With a flick of the paw, we simplify,
No more unsqueezing, just let them fly!
OpenClip shines, with elegance and grace,
A rabbit's joy in this coding space! 🎉

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
fiftyone/utils/open_clip.py (1)

92-92: Consider a more descriptive name for the preprocessing method.

The name _preprocess_aux is not very descriptive. Consider renaming it to better reflect its purpose, such as _preprocess_image or _clip_preprocess.

-            self._preprocess_aux,
+            self._preprocess_image,
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 985758b and 01cc875.

📒 Files selected for processing (1)
  • fiftyone/utils/open_clip.py (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.10)
  • GitHub Check: test / test-app
  • GitHub Check: build / build
  • GitHub Check: lint / eslint
  • GitHub Check: e2e / test-e2e
  • GitHub Check: build
🔇 Additional comments (2)
fiftyone/utils/open_clip.py (2)

Line range hint 138-152: Add tests for preprocessing changes.

The modifications to the preprocessing workflow could affect model predictions. Please add tests to verify:

  1. The shape of preprocessed tensors
  2. Model predictions with the new preprocessing flow
  3. Batch processing behavior

Would you like me to help create test cases for these scenarios?


138-138: Verify tensor shape requirements.

The removal of .unsqueeze(0) suggests that self._preprocess now handles the batch dimension differently. Please verify that the tensor shape matches what the model expects.

Let's check the OpenCLIP source code to understand the preprocessing behavior:

✅ Verification successful

Tensor shape handling is correct

The removal of .unsqueeze(0) is valid as the batch dimension is properly handled by torch.stack(imgs) after preprocessing. The implementation correctly maintains the expected tensor shape for the model's encode_image method.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check OpenCLIP's preprocessing implementation
rg -A 10 "create_model_and_transforms" $(fd -t f -e py . | grep -i "clip")

Length of output: 917


Script:

#!/bin/bash
# Search for transform or preprocessing related code
rg -A 5 "def _preprocess" fiftyone/utils/open_clip.py

Length of output: 55


Script:

#!/bin/bash
# Check the class definition and imports
cat fiftyone/utils/open_clip.py

Length of output: 4905

fiftyone/utils/open_clip.py Outdated Show resolved Hide resolved
@jacobsela
Copy link
Contributor Author

rebased to bugfix/zoo-clip-support-for-multi-gpu-setups

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (18)
docs/source/getting_started/upgrading-mongodb.rst (3)

5-6: Add specific backup instructions.

While the documentation correctly emphasizes the importance of backups, it should provide specific instructions or link to MongoDB's backup documentation for users to follow.

Add a link to MongoDB's backup documentation or include specific backup commands:

 Voxel51 advises performing database backups of your mongodb
-data directory whenever performing a database upgrade.
+data directory whenever performing a database upgrade. For instructions
+on backing up your MongoDB data, see the
+`MongoDB backup documentation <https://www.mongodb.com/docs/manual/core/backups/>`_.

39-43: Specify minimum version requirements.

The upgrade instructions should specify why these particular versions are required for MongoDB 8 compatibility.

Add a note explaining the version requirements:

 2. Upgrade Fiftyone to 1.3.0+ and Fiftyone-db to 1.2.0+
+
+    .. note::
+
+        These versions are required as they include support for MongoDB 8
+        and necessary database migration tools.

     .. code-block:: shell

69-69: Add example MongoDB URI format.

The documentation should include an example of what the MongoDB URI looks like to help users identify it correctly.

Add an example URI format:

-        mongosh "$URI_FROM_ABOVE"
+        # Example URI format: mongodb://localhost:27017
+        mongosh "$URI_FROM_ABOVE"
docs/source/getting_started/install.rst (1)

211-216: Enhance the Ubuntu 24 upgrade note with more context.

The note should explain why Ubuntu 24 users specifically need to upgrade their MongoDB binaries.

Add more context to the note:

 .. note::

   If you are a FiftyOne 1.2.0 or lower user with an Ubuntu 24 operating system, 
   you will need to 
-  :ref:`upgrade your mongodb binaries <mongodb-7-to-8>`.
+  :ref:`upgrade your mongodb binaries <mongodb-7-to-8>` due to Ubuntu 24's
+  requirement for MongoDB 8.0 or higher.
fiftyone/utils/iou.py (2)

698-701: Simplify initialization of ious using a ternary operator

You can simplify the initialization of the ious variable by using a ternary operator, which makes the code more concise.

Apply this diff:

-    if sparse:
-        ious = defaultdict(list)
-    else:
-        ious = np.zeros((len(preds), len(gts)))
+    ious = defaultdict(list) if sparse else np.zeros((len(preds), len(gts)))
🧰 Tools
🪛 Ruff (0.8.2)

698-701: Use ternary operator ious = defaultdict(list) if sparse else np.zeros((len(preds), len(gts))) instead of if-else-block

Replace if-else-block with ious = defaultdict(list) if sparse else np.zeros((len(preds), len(gts)))

(SIM108)


709-709: Remove unused variable bbox_iou_fcn

The local variable bbox_iou_fcn is assigned but never used in the function _compute_dense_mask_ious. It's recommended to remove this unused variable to clean up the code.

Apply this diff:

-    bbox_iou_fcn = compute_bbox_iou
🧰 Tools
🪛 Ruff (0.8.2)

709-709: Local variable bbox_iou_fcn is assigned to but never used

Remove assignment to unused variable bbox_iou_fcn

(F841)

fiftyone/core/odm/embedded_document.py (1)

75-76: Simplify nested if statements

You can combine the nested if statements at lines 75-76 into a single condition for improved code readability.

Apply this diff:

-        if key is not None:
-            if isinstance(getattr(self.__class__, key, None), property):
+        if key is not None and isinstance(getattr(self.__class__, key, None), property):
🧰 Tools
🪛 Ruff (0.8.2)

75-76: Use a single if statement instead of nested if statements

(SIM102)

app/packages/core/src/plugins/SchemaIO/components/AutocompleteView.tsx (2)

130-136: Use strict equality operators

In line 130, consider using strict equality operators === and !== to avoid unintended type coercion.

Apply this diff:

-  const valuesOnlyIsDefault = valuesOnly == undefined || valuesOnly == null;
+  const valuesOnlyIsDefault = valuesOnly === undefined || valuesOnly === null;

Alternatively, since valuesOnly == null checks for both null and undefined, you could simplify the condition:

-  const valuesOnlyIsDefault = valuesOnly == undefined || valuesOnly == null;
+  const valuesOnlyIsDefault = valuesOnly == null;

77-77: Use strict equality operator in comparison

In isOptionEqualToValue, consider using === instead of == for a strict equality check between option and value.

Apply this diff:

-  return option == value;
+  return option === value;
tests/unittests/documents.py (2)

77-97: Consider adding more test cases for reserved attributes.

While the test covers the basic scenarios, consider adding test cases for:

  • Other reserved attributes besides has_mask
  • Attempting to modify multiple reserved attributes simultaneously

98-114: Add test cases for malformed exception messages.

The test covers standard patterns but should also verify behavior with:

  • Empty exception messages
  • Messages without quotes
  • Messages with multiple property patterns
app/packages/core/src/plugins/SchemaIO/components/DynamicIO.tsx (1)

39-44: LGTM! Enhanced schema fallback mechanism.

The additional fallback to computedSchema provides better robustness. Consider extracting the schema resolution logic to a separate function for better readability:

-      onChange(
-        path,
-        value,
-        schema ?? subSchema ?? computedSchema,
-        computedAncestors
-      );
+      const resolvedSchema = schema ?? subSchema ?? computedSchema;
+      onChange(path, value, resolvedSchema, computedAncestors);
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (1)

10-10: Consider using named import for better tree-shaking.

-import { AutocompleteView } from ".";
+import { AutocompleteView } from "./AutocompleteView";
fiftyone/core/odm/mixins.py (1)

1872-1878: LGTM! Clean implementation of nested path filtering.

The function effectively prevents operations on nested paths, enhancing the robustness of field operations.

Consider this minor optimization for better performance with large path lists:

def _remove_nested_paths(paths):
-    return [
-        path
-        for path in paths
-        if not any(path.startswith(p + ".") for p in paths)
-    ]
+    paths = sorted(paths, key=len)  # Sort by length to check shorter paths first
+    result = []
+    for path in paths:
+        if not any(path.startswith(p + ".") for p in result):
+            result.append(path)
+    return result
plugins/operators/__init__.py (2)

1788-1790: Track and fix the App bug preventing view setting.

The TODO comment indicates a known App bug that prevents setting the view after saving. Consider creating a tracking issue for this bug.

Would you like me to create a GitHub issue to track this App bug?


647-647: Optimize dictionary key iteration.

Replace key in dict.keys() with key in dict for better performance in these locations:

-for key in schema.keys():
+for key in schema:

Also applies to: 755-755, 907-907, 982-982

🧰 Tools
🪛 Ruff (0.8.2)

647-647: Use key in dict instead of key in dict.keys()

Remove .keys()

(SIM118)

fiftyone/operators/types.py (1)

1929-1929: Consider documenting the clone behavior.

Instead of suppressing the pylint warning, consider adding a docstring to the clone method explaining that it creates the tooltips attribute. This would make the code more maintainable and self-documenting.

fiftyone/core/dataset.py (1)

1939-1940: Consider using list comprehension for better readability.

The loop can be simplified using a more Pythonic list comprehension.

-        for list_field in list_fields:
-            pipeline.append({"$unwind": "$" + list_field})
+        pipeline.extend({"$unwind": "$" + list_field} for list_field in list_fields)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01cc875 and c0dd032.

⛔ Files ignored due to path filters (4)
  • app/packages/app/src/pages/datasets/__generated__/DatasetPageQuery.graphql.ts is excluded by !**/__generated__/**, !**/__generated__/**
  • app/packages/relay/src/fragments/__generated__/datasetAppConfigFragment.graphql.ts is excluded by !**/__generated__/**, !**/__generated__/**
  • app/packages/relay/src/queries/__generated__/datasetQuery.graphql.ts is excluded by !**/__generated__/**, !**/__generated__/**
  • fiftyone/zoo/models/manifest-torch.json is excluded by !**/*.json
📒 Files selected for processing (42)
  • app/packages/core/src/components/Modal/ImaVidLooker.tsx (2 hunks)
  • app/packages/core/src/plugins/OperatorIO/utils/index.ts (1 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/AutocompleteView.tsx (4 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (2 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/DynamicIO.tsx (1 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (3 hunks)
  • app/packages/core/src/plugins/SchemaIO/index.tsx (2 hunks)
  • app/packages/looker/src/elements/imavid/index.ts (4 hunks)
  • app/packages/looker/src/lookers/imavid/constants.ts (0 hunks)
  • app/packages/looker/src/lookers/imavid/controller.ts (6 hunks)
  • app/packages/looker/src/util.ts (1 hunks)
  • app/packages/operators/src/components/OperatorExecutionButton/index.tsx (1 hunks)
  • app/packages/relay/src/fragments/datasetAppConfigFragment.ts (1 hunks)
  • app/packages/state/src/hooks/useCreateLooker.ts (4 hunks)
  • app/packages/state/src/recoil/selectors.ts (1 hunks)
  • app/packages/state/src/recoil/types.ts (1 hunks)
  • app/schema.graphql (1 hunks)
  • docs/source/getting_started/install.rst (1 hunks)
  • docs/source/getting_started/upgrading-mongodb.rst (1 hunks)
  • docs/source/release-notes.rst (1 hunks)
  • docs/source/user_guide/evaluation.rst (2 hunks)
  • fiftyone/constants.py (1 hunks)
  • fiftyone/core/dataset.py (1 hunks)
  • fiftyone/core/odm/__init__.py (1 hunks)
  • fiftyone/core/odm/dataset.py (2 hunks)
  • fiftyone/core/odm/embedded_document.py (3 hunks)
  • fiftyone/core/odm/mixins.py (4 hunks)
  • fiftyone/operators/types.py (2 hunks)
  • fiftyone/server/query.py (1 hunks)
  • fiftyone/utils/clip/zoo.py (1 hunks)
  • fiftyone/utils/eval/coco.py (1 hunks)
  • fiftyone/utils/eval/openimages.py (1 hunks)
  • fiftyone/utils/iou.py (9 hunks)
  • fiftyone/utils/open_clip.py (6 hunks)
  • fiftyone/utils/super_gradients.py (1 hunks)
  • fiftyone/utils/transformers.py (14 hunks)
  • fiftyone/utils/ultralytics.py (3 hunks)
  • package/graphql/setup.py (1 hunks)
  • plugins/operators/__init__.py (20 hunks)
  • requirements/common.txt (1 hunks)
  • setup.py (1 hunks)
  • tests/unittests/documents.py (2 hunks)
🔥 Files not summarized due to errors (1)
  • fiftyone/utils/clip/zoo.py: Error: Disallowed special token found: <|endoftext|>
💤 Files with no reviewable changes (1)
  • app/packages/looker/src/lookers/imavid/constants.ts
✅ Files skipped from review due to trivial changes (6)
  • requirements/common.txt
  • app/packages/core/src/plugins/OperatorIO/utils/index.ts
  • setup.py
  • package/graphql/setup.py
  • fiftyone/utils/eval/openimages.py
  • fiftyone/utils/eval/coco.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • fiftyone/utils/open_clip.py
🧰 Additional context used
📓 Path-based instructions (14)
app/packages/relay/src/fragments/datasetAppConfigFragment.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/state/src/recoil/types.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/operators/src/components/OperatorExecutionButton/index.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/state/src/recoil/selectors.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/util.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/components/Modal/ImaVidLooker.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/plugins/SchemaIO/components/DynamicIO.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/plugins/SchemaIO/index.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/state/src/hooks/useCreateLooker.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/elements/imavid/index.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/lookers/imavid/controller.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/plugins/SchemaIO/components/AutocompleteView.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🪛 Ruff (0.8.2)
fiftyone/core/odm/__init__.py

66-66: .embedded_document.DynamicEmbeddedDocumentException imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

fiftyone/core/odm/embedded_document.py

75-76: Use a single if statement instead of nested if statements

(SIM102)

fiftyone/utils/iou.py

698-701: Use ternary operator ious = defaultdict(list) if sparse else np.zeros((len(preds), len(gts))) instead of if-else-block

Replace if-else-block with ious = defaultdict(list) if sparse else np.zeros((len(preds), len(gts)))

(SIM108)


709-709: Local variable bbox_iou_fcn is assigned to but never used

Remove assignment to unused variable bbox_iou_fcn

(F841)

plugins/operators/__init__.py

647-647: Use key in dict instead of key in dict.keys()

Remove .keys()

(SIM118)


755-755: Use key in dict instead of key in dict.keys()

Remove .keys()

(SIM118)


907-907: Use key in dict instead of key in dict.keys()

Remove .keys()

(SIM118)


982-982: Use key in dict instead of key in dict.keys()

Remove .keys()

(SIM118)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.11)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.10)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.9)
  • GitHub Check: test / test-app
  • GitHub Check: build / build
  • GitHub Check: e2e / test-e2e
  • GitHub Check: build
🔇 Additional comments (61)
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (3)

1062-1071: LGTM! Clean implementation of the settings button.

The settings button is well-integrated with the existing UI components and follows React best practices for state updates.


1655-1656: LGTM! Clear and consistent sorting implementation.

The sorting logic properly handles both A-Z and Z-A cases, aligning with the sort options defined in CLASS_PERFORMANCE_SORT_OPTIONS.

Also applies to: 1658-1658


1681-1681: LGTM! Robust handling of the none class in matrix generation.

The condition correctly ensures that the none class is included when limiting matrix size, preventing potential data loss while maintaining backward compatibility.

fiftyone/utils/transformers.py (14)

326-328: Device attribute added correctly to the configuration class

The self.device attribute is properly parsed and defaulted based on CUDA availability. This allows for flexible device management based on the user's hardware setup.


457-458: Model device assignment is correctly implemented

The device is correctly set using torch.device, and the model is moved to the specified device with self.model.to(self.device). This ensures that the model runs on the intended hardware.


503-504: Correct device handling in zero-shot transformer initialization

The device is appropriately configured, and the model is moved to self.device. This maintains consistency in device management across different model classes.


589-589: Model loading with device specification is correctly handled

When loading the model, it is immediately moved to the specified device using .to(device), enhancing flexibility in device management.


649-649: Inputs correctly moved to the specified device for prediction

The inputs are properly moved to self.device before model inference, ensuring compatibility with the device on which the model resides.


701-701: Model loading with device specification is correctly handled

The image classification model is correctly loaded and moved to the specified device, enhancing performance and flexibility.


708-708: Inputs correctly moved to the specified device for prediction

The inputs are properly moved to self.device during prediction, ensuring that the tensors are on the same device as the model.


756-757: Device handling is correctly implemented

The device is appropriately set, and the model is moved to self.device. This is consistent with device management practices in other parts of the code.


766-766: Processor loading is correctly implemented

The processor is correctly loaded from name_or_path using transformers.AutoProcessor.from_pretrained(), ensuring that it matches the model configuration.


777-779: Model loading and device assignment are correctly handled

The detector model is obtained using _get_detector_from_processor() and moved to the specified device with .to(config.device), ensuring correct device placement.


790-790: Inputs correctly moved to the specified device for prediction

The inputs are properly moved to self.device before running inference, which is essential for models running on non-default devices.


832-832: Model loading with device specification is correctly handled

The object detection model is correctly loaded and moved to config.device, maintaining consistency in device management.


886-886: Model loading with device specification is correctly handled

The semantic segmentation model is loaded and moved to the specified device, which enhances flexibility and performance.


938-938: Model loading with device specification is correctly handled

The depth estimation model is correctly loaded and moved to config.device, aligning with the device management strategy.

fiftyone/utils/super_gradients.py (1)

99-99: Device assignment updated to use self.device

The model is now moved to self.device instead of using .cuda(), which enhances device flexibility and supports both CPU and GPU execution.

fiftyone/utils/ultralytics.py (3)

23-23: Torch module imported correctly using lazy import

The torch module is properly imported using fou.lazy_import("torch"), ensuring it is only loaded when needed.


382-384: Device attribute added correctly to the configuration class

The self.device attribute is appropriately parsed and defaulted based on CUDA availability, enhancing device management in the configuration.


397-398: Model device assignment is correctly implemented

The device is correctly set using torch.device(config.device), and the model is moved to self.device, ensuring compatibility with the user's hardware.

fiftyone/core/odm/embedded_document.py (4)

34-37: Well-defined exception class DynamicEmbeddedDocumentException

The new exception class DynamicEmbeddedDocumentException is properly defined with a clear docstring, enhancing error handling in dynamic document operations.


55-60: Proper error handling in __init__ method

The addition of the try-except block in the __init__ method effectively handles AttributeError exceptions, ensuring that reserved attribute exceptions are raised appropriately.


63-69: Effective exception management in __setattr__ method

The try-except block in the __setattr__ method correctly captures AttributeError exceptions and invokes the _raise_reserved_attribute_exception method, maintaining robust error handling.


73-98: Correct implementation of reserved attribute exception handling

The methods _raise_reserved_attribute_exception and _extract_attribute_from_exception are well-implemented to identify and handle reserved attribute names, enhancing the robustness of the DynamicEmbeddedDocument class.

🧰 Tools
🪛 Ruff (0.8.2)

75-76: Use a single if statement instead of nested if statements

(SIM102)

app/packages/core/src/plugins/SchemaIO/components/AutocompleteView.tsx (1)

102-110: getValuesOnlySettingFromSchema function is well-structured

The function getValuesOnlySettingFromSchema correctly derives the valuesOnly setting based on the schema and view properties.

app/packages/relay/src/fragments/datasetAppConfigFragment.ts (1)

9-9: Addition of dynamicGroupsTargetFrameRate field

The new field dynamicGroupsTargetFrameRate is appropriately added to the GraphQL fragment, enhancing the dataset app configuration.

app/packages/core/src/plugins/SchemaIO/index.tsx (2)

67-76: LGTM! Well-implemented value coercion logic

The coerceValue function effectively handles edge cases for empty strings and arrays, converting them to null based on the schema type.


23-29: LGTM! Proper integration of coerceValue

The integration of coerceValue in the onIOChange callback ensures consistent handling of empty values before state updates and callbacks.

fiftyone/constants.py (1)

45-45: Verify compatibility testing for version range extension

The compatibility range has been extended to include versions up to 1.5. Please ensure that:

  1. All features remain compatible with the extended version range
  2. No breaking changes are introduced
  3. Proper testing has been performed with datasets from all supported versions
app/packages/operators/src/components/OperatorExecutionButton/index.tsx (1)

96-102: LGTM! Clean implementation of disabled state

The early return for disabled state is well-implemented and maintains consistency with the component's existing patterns.

tests/unittests/documents.py (1)

57-76: LGTM! Well-structured test for valid detection creation.

The test thoroughly validates both standard and custom attributes, including their modification.

app/packages/state/src/recoil/types.ts (1)

122-122: LGTM! Well-placed type definition.

The dynamicGroupsTargetFrameRate property is correctly typed as number and appropriately placed in the DatasetAppConfig interface.

app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (1)

159-174: LGTM! Well-structured conditional rendering with AutocompleteView.

The implementation correctly handles multiple selection cases with appropriate default configurations.

app/packages/looker/src/lookers/imavid/controller.ts (2)

17-17: LGTM!

The property is well-named and correctly typed.


35-35: LGTM!

The property is correctly initialized from the constructor config.

Also applies to: 44-44

app/packages/state/src/hooks/useCreateLooker.ts (3)

29-29: LGTM!

The import is correctly placed and follows the file's import pattern.


66-68: LGTM!

The Recoil value is correctly retrieved and follows naming conventions.


234-234: LGTM!

The frame rate value is consistently used in both the controller and config.

Also applies to: 244-244

app/packages/core/src/components/Modal/ImaVidLooker.tsx (2)

40-42: LGTM!

The Recoil value is correctly retrieved and follows naming conventions.


226-227: LGTM!

The frame rate and total frames are correctly configured for the timeline.

app/packages/looker/src/elements/imavid/index.ts (6)

83-84: LGTM!

The properties are well-named and correctly typed.


351-353: LGTM!

The frame rate is correctly used in the offset calculation.


429-429: LGTM!

The frame rate is correctly destructured from the config.


451-451: LGTM!

The frame rate is correctly assigned to the target frame rate.


453-453: LGTM!

The condition correctly checks for uninitialized timeout delay.


455-458: LGTM!

The frame rate is correctly used in calculating the timeout delay.

app/packages/state/src/recoil/selectors.ts (1)

160-165: LGTM! Well-implemented selector for dynamic groups frame rate.

The selector is properly typed, uses nullish coalescing for the default value, and follows Recoil best practices.

fiftyone/server/query.py (1)

214-214: LGTM! Consistent configuration field addition.

The field type and default value align with the frontend implementation.

fiftyone/core/odm/dataset.py (1)

530-531: LGTM! Well-documented configuration field.

The field is properly documented and consistently implemented across the stack.

Also applies to: 550-550

plugins/operators/__init__.py (5)

247-261: Field validation logic looks good!

The validation for both sample and frame fields is thorough and handles:

  • Field existence checks
  • Nested field cases (with "." in field names)
  • Clear error messages for invalid fields

Also applies to: 365-379


593-598: Good implementation of multi-field clearing!

The execution methods now properly handle multiple fields using the plural versions of the clear methods (clear_sample_fields and clear_frame_fields).

Also applies to: 692-697


644-670: Well-implemented field selection with validation!

The implementation includes:

  • Prevention of duplicate field selection
  • Filtering of already selected fields
  • Proper validation for field existence and read-only status

Also applies to: 752-782

🧰 Tools
🪛 Ruff (0.8.2)

647-647: Use key in dict instead of key in dict.keys()

Remove .keys()

(SIM118)


1450-1452: Good implementation of multi-field deletion!

The execution method now properly handles multiple fields using the plural version of the delete method (delete_summary_fields).


1626-1633: Well-implemented group slice deletion with current slice handling!

The implementation includes:

  • Support for multiple slice deletions
  • Proper handling when deleting the current slice
  • Automatic fallback to default slice when needed
fiftyone/operators/types.py (1)

1597-1598: Great addition of flexibility to AutocompleteView!

The new parameters enhance the component's functionality:

  • allow_user_input: Enables free-form input beyond predefined choices
  • allow_duplicates: Permits selection of the same choice multiple times
app/packages/looker/src/util.ts (1)

256-261: LGTM! Clean frame timing calculation

The function correctly calculates milliseconds per frame using the provided frameRate parameter, with appropriate normalization of playback rates for smoother playback.

app/schema.graphql (1)

251-251: LGTM! Well-defined schema field

The new required field dynamicGroupsTargetFrameRate is properly defined with appropriate type and nullability constraints for frame rate configuration.

docs/source/user_guide/evaluation.rst (1)

732-734: Great documentation improvement!

The added clarification about IoU computation for instance segmentation tasks improves technical accuracy by explicitly stating that IoUs are computed between dense pixel masks rather than bounding boxes when use_masks=True.

docs/source/release-notes.rst (2)

Line range hint 1-11: LGTM! Documentation structure follows best practices

The release notes are well-structured with:

  • Clear version numbering
  • Release dates
  • Categorized changes (App, Core, Brain, etc.)
  • Consistent formatting throughout

6-11: ⚠️ Potential issue

Latest release notes should be updated

The latest release notes section shows "FiftyOne Teams 2.4.0" released on January 10, 2025, which is a future date. This should be updated to reflect the actual latest release.

-*Released January 10, 2025*
+*Released <actual_release_date>*

Likely invalid or redundant comment.

fiftyone/utils/transformers.py Outdated Show resolved Hide resolved
fiftyone/utils/iou.py Outdated Show resolved Hide resolved
fiftyone/utils/iou.py Outdated Show resolved Hide resolved
fiftyone/core/odm/__init__.py Outdated Show resolved Hide resolved
mwoodson1
mwoodson1 previously approved these changes Jan 16, 2025
Copy link
Contributor

@mwoodson1 mwoodson1 left a comment

Choose a reason for hiding this comment

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

lgtm 👍

Copy link
Contributor

@brimoor brimoor left a comment

Choose a reason for hiding this comment

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

Please retarget this at release/v1.3.0 and ensure that no commits from other PRs are present in the diff

I did it

@brimoor brimoor changed the base branch from develop to release/v1.3.0 January 18, 2025 19:47
@brimoor brimoor dismissed mwoodson1’s stale review January 18, 2025 19:47

The base branch was changed.

@brimoor brimoor changed the title open clip fix Fix open-clip-torch model inference Jan 18, 2025
Copy link
Contributor

@brimoor brimoor left a comment

Choose a reason for hiding this comment

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

@jacobsela are you able to run this on a mac with CPU only?

I'm running this:

import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset(
    "coco-2017",
    split="validation",
    dataset_name=fo.get_default_dataset_name(),
    max_samples=10,
    shuffle=True,
)

model = foz.load_zoo_model("open-clip-torch")

dataset.apply_model(model, label_field="predictions")

With these deps:

open_clip_torch==2.30.0
torch==2.1.0

I get this error:

Error: Expected attn_mask dtype to be bool or to match query dtype, but got attn_mask.dtype: float and  query.dtype: c10::BFloat16 instead.

And with these deps:

open_clip_torch==2.30.0
torch==2.2.2

I get this error:

Error: Got unsupported ScalarType BFloat16

Perhaps this model cannot support CPU?
mlfoundations/open_clip#484 (comment)

@jacobsela
Copy link
Contributor Author

@brimoor

I'm getting the same error on Mac w/ CPU (`TypeError: Got unsupported ScalarType BFloat16').

I tried to see if I'm able to run this on MPS. That does work for torch>=2.5.0, see pytorch/pytorch#99272 for details.

I can either add a condition for the AMP for open clip depending on the device type, or we can say that if you are on Mac then you should use mps with these models. IDK how many of our users are still using intel chip Macs. Let me know the best way to proceed.

Copy link
Contributor

@brimoor brimoor left a comment

Choose a reason for hiding this comment

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

@jacobsela I added your suggested change and now this works on CPU again ✅

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
fiftyone/utils/open_clip.py (1)

61-61: ⚠️ Potential issue

Move initialization after model loading.

The self.preprocess attribute is assigned before self._preprocess_aux is initialized in _load_model. This could lead to a None value being assigned.

Move this line after the model is loaded in _load_model:

-        self.preprocess = self._preprocess_aux
         self._text_features = None

And add it to _load_model after the model initialization:

         self._tokenizer = open_clip.get_tokenizer(config.clip_model)
         self._model.eval()
+        self.preprocess = self._preprocess_aux
         return self._model
🧹 Nitpick comments (1)
fiftyone/utils/open_clip.py (1)

147-154: Improved GPU context management with device-specific handling.

The changes improve GPU operation handling by:

  1. Using ExitStack for better context management
  2. Adding device-specific autocast for better Mac compatibility
  3. Moving device transfer before autocast context

This addresses the TypeError issues on Mac CPUs mentioned in the PR comments.

Consider adding error handling for unsupported device types to provide better user feedback.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23d6a6d and cb28481.

📒 Files selected for processing (1)
  • fiftyone/utils/open_clip.py (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.10)
  • GitHub Check: test / test-app
  • GitHub Check: build / build
  • GitHub Check: e2e / test-e2e
  • GitHub Check: build
🔇 Additional comments (2)
fiftyone/utils/open_clip.py (2)

93-93: Verify preprocessing function compatibility.

The preprocessing function is obtained from open_clip.create_model_and_transforms. Let's verify its usage across different hardware setups.

✅ Verification successful

Preprocessing implementation verified as hardware-agnostic and safe.

The preprocessing function is correctly obtained from open_clip.create_model_and_transforms and applied uniformly across different hardware setups. The implementation follows standard PyTorch patterns where device handling is managed at the model level, not in the preprocessing stage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for preprocessing function usage and potential hardware-specific handling
# Look for any special handling of preprocessing in open_clip
rg -A 5 "create_model_and_transforms" 

# Check for any device-specific preprocessing
rg -A 5 "preprocess.*device" 

Length of output: 471


Script:

#!/bin/bash
# Find usage of preprocessing functions and related error handling
ast-grep --pattern 'self._preprocess_aux'

# Look for any preprocessing-related functions or methods
rg -A 5 "preprocess" 

# Check for any validation or error handling around preprocessing
rg -B 2 -A 5 "try.*preprocess|except.*preprocess"

Length of output: 24655


139-139: Verify tensor dimensions after preprocessing.

The removal of .unsqueeze(0) suggests that self._preprocess now handles the batch dimension correctly. Let's verify this assumption.

✅ Verification successful

Tensor dimensions are correctly handled

The preprocessing implementation is safe. The batch dimension is properly managed through torch.stack after individual image preprocessing, making the explicit .unsqueeze(0) unnecessary.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for tensor dimension handling in preprocessing
# Look for any dimension-related operations in preprocessing
rg -A 5 "unsqueeze.*preprocess" 
rg -A 5 "\.shape.*preprocess"

Length of output: 65


Script:

#!/bin/bash
# Find the implementation of _preprocess method
ast-grep --pattern 'def _preprocess(self, $_):
    $$$'

# Backup search using ripgrep
rg -A 10 "def _preprocess"

Length of output: 999


Script:

#!/bin/bash
# Look for preprocessing implementation in open_clip.py
cat fiftyone/utils/open_clip.py

# Search for any tensor operations or transformations
rg -A 5 "transform|tensor|Tensor" fiftyone/utils/open_clip.py

Length of output: 5471

@jacobsela
Copy link
Contributor Author

Thank you @brimoor

@jacobsela jacobsela merged commit d228b88 into release/v1.3.0 Jan 21, 2025
12 of 14 checks passed
@jacobsela jacobsela deleted the bugfix/open_clip branch January 21, 2025 00:08
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.

3 participants