sunandbean's picture
Add files using upload-large-folder tool
33d23e1 verified
Raw History Blame Contribute Delete
3.44 kB
# SPDX-FileCopyrightText: © 2025 Tenstorrent USA, Inc.
# SPDX-License-Identifier: Apache-2.0
from typing import List, Optional, Union
import open_clip
import torch
import torch.nn as nn
from PIL import Image
class CLIPEncoder(nn.Module):
"""
A class for encoding images and texts using a specified CLIP model and computing the similarity between them.
Attributes:
-----------
clip_version: str
The version of the CLIP model to be used.
pretrained: str
The pre-trained weights to load.
model: nn.Module
The CLIP model.
preprocess: Callable
The preprocessing transform to apply to the input image.
device: str
The device to which the model is moved.
"""
def __init__(
self,
clip_version: str = "ViT-B/32",
pretrained: Optional[str] = "",
cache_dir: Optional[str] = None,
):
"""
Initializes the CLIPEncoder with the specified CLIP model version and pre-trained weights.
Parameters:
-----------
clip_version: str, optional
The version of the CLIP model to be used. Defaults to 'ViT-B/32'.
pretrained: str, optional
The pre-trained weights to load. If not provided, it defaults based on clip_version.
cache_dir: str, optional
The directory to cache the model. Defaults to None.
device: str, optional
The device to which the model is moved. Defaults to 'cuda'.
"""
super().__init__()
self.clip_version = clip_version
self.pretrained = pretrained if pretrained else self._get_default_pretrained()
self.model, _, self.preprocess = open_clip.create_model_and_transforms(
self.clip_version, pretrained=self.pretrained, cache_dir=cache_dir
)
self.model.eval()
def _get_default_pretrained(self) -> str:
"""Returns the default pretrained weights based on the clip_version."""
return "openai"
@torch.no_grad()
def get_clip_score(self, text: Union[str, List[str]], image: Union[Image.Image, torch.Tensor]) -> torch.Tensor:
"""
Computes the similarity score between the given text(s) and image using the CLIP model.
Parameters:
-----------
text: Union[str, List[str]]
The text or list of texts to compare with the image.
image: Image.Image
The input image.
Returns:
--------
torch.Tensor
The similarity score between the text(s) and image.
"""
# Preprocess the image and move it to the specified device
image = self.preprocess(image).unsqueeze(0)
# Normalize the image features
image_features = self.model.encode_image(image).float()
image_features /= image_features.norm(dim=-1, keepdim=True)
# If a single text string is provided, convert it to a list
if not isinstance(text, (list, tuple)):
text = [text]
# Tokenize the text and move it to the specified device
text = open_clip.tokenize(text)
# Normalize the text features
text_features = self.model.encode_text(text).float()
text_features /= text_features.norm(dim=-1, keepdim=True)
# Compute the similarity between the image and text features
similarity = image_features @ text_features.T
return similarity