Video-Text-to-Text
Transformers
Safetensors
English
Chinese
videochat3
feature-extraction
video-language-model
vision-language-model
multimodal
video-understanding
image-understanding
streaming-video
custom_code
Instructions to use MCG-NJU/VideoChat3-4B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use MCG-NJU/VideoChat3-4B with Transformers:
# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("MCG-NJU/VideoChat3-4B", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
Update inference_fast_vc3.py
Browse files- inference_fast_vc3.py +32 -12
inference_fast_vc3.py
CHANGED
|
@@ -311,20 +311,28 @@ class StreamingSession:
|
|
| 311 |
round_idx: int,
|
| 312 |
include_question: bool,
|
| 313 |
frame_max_pixels: Optional[int] = None,
|
|
|
|
|
|
|
| 314 |
) -> List[dict]:
|
| 315 |
"""Build user message content for a single frame."""
|
| 316 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 317 |
text = time_tag
|
| 318 |
if include_question and self.question:
|
| 319 |
text = f"{self.question}\n{text}"
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
image_item
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
|
|
|
|
|
|
| 328 |
|
| 329 |
def _inject_question(self, msg: dict) -> None:
|
| 330 |
"""Prepend the question into the text part of a user message (in-place)."""
|
|
@@ -350,6 +358,8 @@ class StreamingSession:
|
|
| 350 |
frame: Image.Image,
|
| 351 |
round_idx: int,
|
| 352 |
frame_max_pixels: Optional[int] = None,
|
|
|
|
|
|
|
| 353 |
) -> None:
|
| 354 |
if not self._messages:
|
| 355 |
# First frame: include question if global_question or round matches question_time.
|
|
@@ -363,7 +373,8 @@ class StreamingSession:
|
|
| 363 |
{
|
| 364 |
"role": "user",
|
| 365 |
"content": self._user_content(
|
| 366 |
-
frame, round_idx, include_q, frame_max_pixels
|
|
|
|
| 367 |
),
|
| 368 |
}
|
| 369 |
)
|
|
@@ -384,7 +395,8 @@ class StreamingSession:
|
|
| 384 |
{
|
| 385 |
"role": "user",
|
| 386 |
"content": self._user_content(
|
| 387 |
-
frame, round_idx, include_q, frame_max_pixels
|
|
|
|
| 388 |
),
|
| 389 |
}
|
| 390 |
)
|
|
@@ -430,9 +442,17 @@ class StreamingSession:
|
|
| 430 |
frame: Image.Image,
|
| 431 |
round_idx: int,
|
| 432 |
frame_max_pixels: Optional[int] = None,
|
|
|
|
|
|
|
| 433 |
) -> str:
|
| 434 |
"""Feed one frame and return the model answer for this round."""
|
| 435 |
-
self._append_turn(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
|
| 437 |
if self.debug:
|
| 438 |
msgs = self._messages
|
|
|
|
| 311 |
round_idx: int,
|
| 312 |
include_question: bool,
|
| 313 |
frame_max_pixels: Optional[int] = None,
|
| 314 |
+
time_start: Optional[float] = None,
|
| 315 |
+
time_end: Optional[float] = None,
|
| 316 |
) -> List[dict]:
|
| 317 |
"""Build user message content for a single frame."""
|
| 318 |
+
if time_start is None:
|
| 319 |
+
time_start = float(round_idx)
|
| 320 |
+
if time_end is None:
|
| 321 |
+
time_end = time_start + 1.0
|
| 322 |
+
time_tag = f"<{time_start:g}s-{time_end:g}s>"
|
| 323 |
text = time_tag
|
| 324 |
if include_question and self.question:
|
| 325 |
text = f"{self.question}\n{text}"
|
| 326 |
+
frames = frame if isinstance(frame, (list, tuple)) else [frame]
|
| 327 |
+
content = []
|
| 328 |
+
for one_frame in frames:
|
| 329 |
+
image_item: dict = {"type": "image", "image": one_frame}
|
| 330 |
+
if frame_max_pixels is not None:
|
| 331 |
+
image_item["min_pixels"] = 28 * 28
|
| 332 |
+
image_item["max_pixels"] = frame_max_pixels
|
| 333 |
+
content.append(image_item)
|
| 334 |
+
content.append({"type": "text", "text": text})
|
| 335 |
+
return content
|
| 336 |
|
| 337 |
def _inject_question(self, msg: dict) -> None:
|
| 338 |
"""Prepend the question into the text part of a user message (in-place)."""
|
|
|
|
| 358 |
frame: Image.Image,
|
| 359 |
round_idx: int,
|
| 360 |
frame_max_pixels: Optional[int] = None,
|
| 361 |
+
time_start: Optional[float] = None,
|
| 362 |
+
time_end: Optional[float] = None,
|
| 363 |
) -> None:
|
| 364 |
if not self._messages:
|
| 365 |
# First frame: include question if global_question or round matches question_time.
|
|
|
|
| 373 |
{
|
| 374 |
"role": "user",
|
| 375 |
"content": self._user_content(
|
| 376 |
+
frame, round_idx, include_q, frame_max_pixels,
|
| 377 |
+
time_start, time_end,
|
| 378 |
),
|
| 379 |
}
|
| 380 |
)
|
|
|
|
| 395 |
{
|
| 396 |
"role": "user",
|
| 397 |
"content": self._user_content(
|
| 398 |
+
frame, round_idx, include_q, frame_max_pixels,
|
| 399 |
+
time_start, time_end,
|
| 400 |
),
|
| 401 |
}
|
| 402 |
)
|
|
|
|
| 442 |
frame: Image.Image,
|
| 443 |
round_idx: int,
|
| 444 |
frame_max_pixels: Optional[int] = None,
|
| 445 |
+
time_start: Optional[float] = None,
|
| 446 |
+
time_end: Optional[float] = None,
|
| 447 |
) -> str:
|
| 448 |
"""Feed one frame and return the model answer for this round."""
|
| 449 |
+
self._append_turn(
|
| 450 |
+
frame,
|
| 451 |
+
round_idx,
|
| 452 |
+
frame_max_pixels=frame_max_pixels,
|
| 453 |
+
time_start=time_start,
|
| 454 |
+
time_end=time_end,
|
| 455 |
+
)
|
| 456 |
|
| 457 |
if self.debug:
|
| 458 |
msgs = self._messages
|