Skip to content

Enable Gemma4 video input#4114

Draft
yatarkan wants to merge 13 commits into
openvinotoolkit:masterfrom
yatarkan:yt/gemma4-video
Draft

Enable Gemma4 video input#4114
yatarkan wants to merge 13 commits into
openvinotoolkit:masterfrom
yatarkan:yt/gemma4-video

Conversation

@yatarkan

@yatarkan yatarkan commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds video input support for Gemma4 model family.

CVS-185850

Checklist:

  • This PR follows GenAI Contributing guidelines.
  • Tests have been updated or added to cover the new code.
  • This PR fully addresses the ticket.
  • I have made corresponding changes to the documentation.

Copilot AI review requested due to automatic review settings July 8, 2026 11:59
@github-actions github-actions Bot added category: visual language Visual language pipeline category: GGUF GGUF file reader labels Jul 8, 2026

Copilot AI left a comment

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.

Pull request overview

This PR extends the Gemma4 VLM implementation to accept video inputs by introducing a video placeholder token, adding Gemma4 video frame encoding, and merging video embeddings into the text embeddings flow. It also updates the Python VLM pipeline tests to exercise Gemma4 as a video-capable model.

Changes:

  • Add Gemma4 video placeholder token to VLM configuration and Python test prompt generation.
  • Implement Gemma4 video encoding (encode_frames / encode_videos) and video-aware prompt normalization + embedding merge.
  • Register Gemma4 tiny-random model IDs as video models in the Python test suite.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
tests/python_tests/test_vlm_pipeline.py Adds Gemma4 model IDs to the video test matrix and defines `<
src/cpp/src/visual_language/vlm_config.hpp Introduces video_token configuration (default `<
src/cpp/src/visual_language/gemma4/classes.hpp Extends Gemma4 vision encoder + inputs embedder interfaces to support video inputs.
src/cpp/src/visual_language/gemma4/classes.cpp Implements video metadata handling, frame encoding/concatenation, video tag expansion in prompts, and video embedding merge.

Comment thread src/cpp/src/visual_language/gemma4/classes.cpp
Comment thread src/cpp/src/visual_language/gemma4/classes.cpp Outdated
Comment thread src/cpp/src/visual_language/gemma4/classes.cpp Outdated
Comment thread src/cpp/src/visual_language/gemma4/classes.cpp Outdated
Copilot AI review requested due to automatic review settings July 9, 2026 22:03
@github-actions github-actions Bot added the category: GH Pages Docs Github Pages documentation label Jul 9, 2026

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Comment on lines +167 to +181
if (!video_config.do_sample_frames) {
video_metadata.frames_indices.resize(total_num_frames);
std::iota(video_metadata.frames_indices.begin(), video_metadata.frames_indices.end(), 0);
return;
}

size_t num_frames = video_config.num_frames;

if (num_frames == 0) {
num_frames = std::min(total_num_frames, video_config.max_frames > 0 ? video_config.max_frames : total_num_frames);
}

num_frames = std::min(num_frames, total_num_frames);
OPENVINO_ASSERT(num_frames > 0, "Number of frames to sample must be positive.");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Gemma4 video processor config does not have fps and min_frames params and they are not used in HF transformers implementation

Comment on lines +652 to 660
void InputsEmbedderGemma4::encode_vision_token_ids() {
std::call_once(m_vision_token_ids_once_flag, [this]() {
const auto encoded_vision_tokens =
m_tokenizer.encode(m_vlm_config.image_token + m_vlm_config.video_token, ov::genai::add_special_tokens(false)).input_ids;
OPENVINO_ASSERT(encoded_vision_tokens.get_size() == 2, "Encoded vision tokens must contain two tokens");
m_image_token_id = encoded_vision_tokens.data<int64_t>()[0];
m_video_token_id = encoded_vision_tokens.data<int64_t>()[1];
});
}

@yatarkan yatarkan Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Such pattern is already used in GenAI to have a single tokenizer.encode call

Comment on lines +286 to +297
std::vector<ov::Tensor> frame_features;
frame_features.reserve(frames.size());

for (const auto& frame : frames) {
EncodedImage encoded = encode_with_config(frame, m_video_processor_config);
frame_features.push_back(std::move(encoded.resized_source));
}

// Concatenate all frame features: [1, total_tokens, hidden_size]
size_t num_soft_tokens_per_frame = frame_features[0].get_shape()[1];
const size_t hidden_size = frame_features[0].get_shape()[2];
const size_t total_tokens = frames.size() * num_soft_tokens_per_frame;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Input video frames (and its embeddings) are expected to have the same shape and element type

Copilot AI review requested due to automatic review settings July 10, 2026 12:03

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Comment on lines +547 to +551
for (size_t f = 0; f < encoded_video.frame_num; ++f) {
ov::Tensor frame_embed(elem_type, {1, tokens_per_frame, hidden_size});
std::memcpy(frame_embed.data(), src + f * bytes_per_frame, bytes_per_frame);
video_embeds.push_back(std::move(frame_embed));
}
Comment thread src/cpp/src/visual_language/gemma4/classes.cpp
Comment thread tests/python_tests/test_vlm_pipeline.py
Copilot AI review requested due to automatic review settings July 10, 2026 15:12

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Comment on lines +205 to 210
std::vector<size_t> original_video_indices(video_frames_num);
std::iota(original_video_indices.begin(), original_video_indices.end(), 0);

if (video_metadata.frames_indices.empty() || video_metadata.frames_indices == original_video_indices) {
return video;
}
Comment on lines 6 to +11
#include <cmath>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <numeric>

Comment thread src/cpp/src/visual_language/gemma4/classes.cpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: GGUF GGUF file reader category: GH Pages Docs Github Pages documentation category: visual language Visual language pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants