Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 36 additions & 8 deletions vllm/model_executor/models/nemotron_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,20 @@ def __init__(
self.norm_mean = torch.Tensor(OPENAI_CLIP_MEAN).reshape(1, 3, 1, 1)
self.norm_std = torch.Tensor(OPENAI_CLIP_STD).reshape(1, 3, 1, 1)

# Create transforms
self._create_transforms()
# Defer transform creation until first use to avoid importing cv2 at init time
self.transform = None
self.torch_transform = None
self.target_height = None
self.target_width = None

def _ensure_transforms_initialized(self):
"""
Lazily initialize transforms on first use to avoid
importing cv2 during processor creation.
"""
if self.transform is not None:
return # Already initialized

def _create_transforms(self):
"""Create transform objects."""
try:
import albumentations as A
except ImportError as err:
Expand All @@ -406,6 +415,16 @@ def _create_transforms(self):
"albumentations`."
) from err

try:
import cv2
except ImportError as err:
raise ImportError(
"The package `opencv-python` (cv2) is required to use "
"NemotronParse model. Please install it with `pip install "
"opencv-python`. Note that OpenCV may also require system-level "
"dependencies such as libxcb.so.1 on Linux systems."
) from err

# Ensure final_size is a tuple of integers
if isinstance(self.final_size, (list, tuple)):
self.target_height, self.target_width = (
Expand All @@ -415,8 +434,6 @@ def _create_transforms(self):
else:
self.target_height = self.target_width = int(self.final_size)

import cv2

self.transform = A.Compose(
[
A.PadIfNeeded(
Expand All @@ -438,6 +455,16 @@ def _create_transforms(self):
def _resize_with_aspect_ratio(self, image: np.ndarray) -> np.ndarray:
"""Resize image maintaining aspect ratio (exact replica of original
LongestMaxSizeHW)."""
try:
import cv2
except ImportError as err:
raise ImportError(
"The package `opencv-python` (cv2) is required to use "
"NemotronParse model. Please install it with `pip install "
"opencv-python`. Note that OpenCV may also require system-level "
"dependencies such as libxcb.so.1 on Linux systems."
) from err
Comment on lines +458 to +466
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.

high

This try-except block for importing cv2 is a duplicate of the one in _ensure_transforms_initialized. This code duplication can lead to maintenance issues where one block is updated but the other is not.

To avoid this, you can cache the imported cv2 module as an instance attribute. Here's a suggested refactoring:

  1. In NemotronParseImageProcessor.__init__, add self._cv2 = None.

  2. In _ensure_transforms_initialized, modify the cv2 import block to cache the module:

    # In _ensure_transforms_initialized()
    try:
        import cv2
        self._cv2 = cv2
    except ImportError as err:
        # ... error handling
    
    # ... later in the same method, use self._cv2
    self.transform = A.Compose(
        [
            A.PadIfNeeded(
                # ...
                border_mode=self._cv2.BORDER_CONSTANT,
                # ...
            ),
        ]
    )
  3. Then, in this method (_resize_with_aspect_ratio), you can remove this duplicated block and just use the cached module:

    # In _resize_with_aspect_ratio()
    # The _ensure_transforms_initialized method is called in preprocess()
    # before this method, so self._cv2 should be available.
    cv2 = self._cv2
    
    # ...
    
    return cv2.resize(...)

This approach centralizes the import logic and makes the code cleaner and easier to maintain.


height, width = image.shape[:2]
max_size_height = self.target_height
max_size_width = self.target_width
Expand All @@ -458,8 +485,6 @@ def _resize_with_aspect_ratio(self, image: np.ndarray) -> np.ndarray:
new_height = int(new_width / aspect_ratio)

# Use cv2.INTER_LINEAR like the original
import cv2

return cv2.resize(
image, (new_width, new_height), interpolation=cv2.INTER_LINEAR
)
Expand Down Expand Up @@ -505,6 +530,9 @@ def preprocess(
Args:
images: Input image(s)
"""
# Ensure transforms are initialized (this is where cv2 will be imported)
self._ensure_transforms_initialized()

# Ensure images is a list
if not isinstance(images, list):
images = [images]
Expand Down