Visual Document Retrieval
Transformers
Safetensors
ColPali
multilingual
colqwen3
feature-extraction
text
image
video
multimodal-embedding
vidore
multilingual-embedding
custom_code
Instructions to use TomoroAI/tomoro-colqwen3-embed-4b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use TomoroAI/tomoro-colqwen3-embed-4b with Transformers:
# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("TomoroAI/tomoro-colqwen3-embed-4b", trust_remote_code=True, device_map="auto") - ColPali
How to use TomoroAI/tomoro-colqwen3-embed-4b with ColPali:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
Update README.md
Browse files
README.md
CHANGED
|
@@ -229,10 +229,8 @@ ColQwen3 generalizes to short videos while learning from image-text retrieval ta
|
|
| 229 |
|
| 230 |
```python
|
| 231 |
from pathlib import Path
|
| 232 |
-
from typing import Any, Dict
|
| 233 |
|
| 234 |
import torch
|
| 235 |
-
from torch.nn.utils.rnn import pad_sequence
|
| 236 |
from transformers import AutoModel, AutoProcessor
|
| 237 |
|
| 238 |
MODEL_ID = "TomoroAI/tomoro-colqwen3-embed-4b"
|
|
@@ -252,42 +250,8 @@ model = AutoModel.from_pretrained(
|
|
| 252 |
device_map=DEVICE,
|
| 253 |
).eval()
|
| 254 |
|
| 255 |
-
queries = ["Retrieve the football video", "Find the basketball clip"]
|
| 256 |
-
videos = ["sample_videos/football.mp4", "sample_videos/basketball.mp4"]
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
def _pad_video_sequences(batch: Dict[str, Any], video_paths: list[str]) -> Dict[str, Any]:
|
| 260 |
-
"""Recompute and pad flattened video patches so they align with grid metadata."""
|
| 261 |
-
pixel_values = batch.get("pixel_values_videos")
|
| 262 |
-
grid = batch.get("video_grid_thw")
|
| 263 |
-
if not isinstance(pixel_values, torch.Tensor) or not isinstance(grid, torch.Tensor):
|
| 264 |
-
return batch
|
| 265 |
-
if pixel_values.ndim == 3:
|
| 266 |
-
return batch
|
| 267 |
-
|
| 268 |
-
rebuilt = processor.video_processor(
|
| 269 |
-
videos=video_paths,
|
| 270 |
-
return_tensors="pt",
|
| 271 |
-
return_metadata=True,
|
| 272 |
-
data_format="channels_first",
|
| 273 |
-
do_convert_rgb=True,
|
| 274 |
-
)
|
| 275 |
-
seq_grid = rebuilt["video_grid_thw"]
|
| 276 |
-
flat_pixels = rebuilt["pixel_values_videos"]
|
| 277 |
-
offsets = (seq_grid[:, 0] * seq_grid[:, 1] * seq_grid[:, 2]).tolist()
|
| 278 |
-
|
| 279 |
-
sequences = []
|
| 280 |
-
cursor = 0
|
| 281 |
-
for offset in offsets:
|
| 282 |
-
next_cursor = cursor + offset
|
| 283 |
-
sequences.append(flat_pixels[cursor:next_cursor])
|
| 284 |
-
cursor = next_cursor
|
| 285 |
-
|
| 286 |
-
batch["pixel_values_videos"] = pad_sequence(sequences, batch_first=True)
|
| 287 |
-
batch["video_grid_thw"] = seq_grid
|
| 288 |
-
if "video_metadata" in batch:
|
| 289 |
-
batch["video_metadata"] = rebuilt.get("video_metadata", batch["video_metadata"])
|
| 290 |
-
return batch
|
| 291 |
|
| 292 |
|
| 293 |
def encode_queries(texts):
|
|
@@ -301,12 +265,12 @@ def encode_videos(paths):
|
|
| 301 |
vids = [str(Path(p).expanduser()) for p in paths]
|
| 302 |
feats = processor(
|
| 303 |
videos=vids,
|
| 304 |
-
return_tensors="pt",
|
| 305 |
padding="longest",
|
|
|
|
| 306 |
videos_kwargs={"return_metadata": True},
|
| 307 |
)
|
| 308 |
-
feats = _pad_video_sequences(feats, vids)
|
| 309 |
feats.pop("video_metadata", None) # drop metadata before forwarding to the model
|
|
|
|
| 310 |
feats = {k: v.to(DEVICE) if isinstance(v, torch.Tensor) else v for k, v in feats.items()}
|
| 311 |
with torch.inference_mode():
|
| 312 |
out = model(**feats)
|
|
|
|
| 229 |
|
| 230 |
```python
|
| 231 |
from pathlib import Path
|
|
|
|
| 232 |
|
| 233 |
import torch
|
|
|
|
| 234 |
from transformers import AutoModel, AutoProcessor
|
| 235 |
|
| 236 |
MODEL_ID = "TomoroAI/tomoro-colqwen3-embed-4b"
|
|
|
|
| 250 |
device_map=DEVICE,
|
| 251 |
).eval()
|
| 252 |
|
| 253 |
+
queries = ["Retrieve the football video", "Find the basketball clip", "Find the swimming clip", "Find the wrestling clip"]
|
| 254 |
+
videos = ["/root/sample_videos/football.mp4", "/root/sample_videos/basketball.mp4", "/root/sample_videos/swimming.mp4", "/root/sample_videos/wrestling.mp4"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
|
| 256 |
|
| 257 |
def encode_queries(texts):
|
|
|
|
| 265 |
vids = [str(Path(p).expanduser()) for p in paths]
|
| 266 |
feats = processor(
|
| 267 |
videos=vids,
|
|
|
|
| 268 |
padding="longest",
|
| 269 |
+
return_tensors=None, # keep metadata as Python objects until we drop it
|
| 270 |
videos_kwargs={"return_metadata": True},
|
| 271 |
)
|
|
|
|
| 272 |
feats.pop("video_metadata", None) # drop metadata before forwarding to the model
|
| 273 |
+
feats = feats.convert_to_tensors(tensor_type="pt")
|
| 274 |
feats = {k: v.to(DEVICE) if isinstance(v, torch.Tensor) else v for k, v in feats.items()}
|
| 275 |
with torch.inference_mode():
|
| 276 |
out = model(**feats)
|