Skip to content

[WIP] Add Ovis2.5 - #40321

Closed
thisisiron wants to merge 4 commits into
huggingface:mainfrom
thisisiron:add-ovis2_5
Closed

thisisiron wants to merge 4 commits into
huggingface:mainfrom
thisisiron:add-ovis2_5

Conversation

@thisisiron

Copy link
Copy Markdown
Contributor

What does this PR do?

This PR adds support for Ovis2.5, a multimodal vision-language model designed for native-resolution visual perception and reflective reasoning.

Ovis2.5 is released in two variants:

This is still a draft PR. Further integration and testing to follow.

Who can review?

Anyone in the community is free to review the PR once the tests have passed. Feel free to tag
members/contributors who may be interested in your PR.

@github-actions

Copy link
Copy Markdown
Contributor

[For maintainers] Suggested jobs to run (before merge)

run-slow: auto

@Rocketknight1

Copy link
Copy Markdown
Member

cc @zucchini-nlp

@zucchini-nlp

Copy link
Copy Markdown
Member

Reviewing, sorry for delay

@zucchini-nlp zucchini-nlp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure if the PR is ready for review. Just left a few general comments

The is an updated version of the [Ovis](https://arxiv.org/abs/2405.20797) model developed by the AIDC-AI team at Alibaba International Digital Commerce Group.

[Ovis2.5](https://arxiv.org/abs/2508.11737) is a multimodal vision-language model, available in 2B and 9B parameter versions. It introduces a native-resolution vision transformer (NaViT) that processes images at their original resolutions, preserving both fine details and global layout—crucial for visually dense inputs like complex charts and documents. The model also features a novel reflective reasoning capability, including self-checking and revision, accessible via an optional thinking mode at inference time.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Lte's add an abstract in italics to follow general model doc guidelines

from transformers import AutoModelForVision2Seq, AutoTokenizer, AutoProcessor

model = AutoModelForVision2Seq.from_pretrained(
"",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

missing model id?

from transformers.image_utils import load_images, load_video
from transformers import AutoModelForVision2Seq, AutoTokenizer, AutoProcessor

model = AutoModelForVision2Seq.from_pretrained(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

AutoModelForVision2Seq is deprecated, we need to ise AutoModelForImageTextToText

Comment on lines +60 to +72
url = "http://images.cocodataset.org/val2014/COCO_val2014_000000537955.jpg"
image = Image.open(requests.get(url, stream=True).raw)
messages = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
print(messages)

inputs = processor(
images=[image],
text=messages,
return_tensors="pt",
)
inputs = inputs.to("cuda:0")
inputs['pixel_values'] = inputs['pixel_values'].to(torch.bfloat16)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can do shorter with

processor.apply_chat_template(messages, tokenize=True, return_dict=True, return_tensors='pt')

See llava docs for an example

print(output_text)
```

<!-- TODO: Convert Ovis2 to Ovis2.5 -->

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

todo and delete comment

Comment on lines +159 to +168
# Apply patch embeddings to already patchified pixel values
target_dtype = self.patch_embedding.weight.dtype
if isinstance(self.patch_embedding, nn.Linear):
patch_embeds = self.patch_embedding(pixel_values.to(dtype=target_dtype))
elif isinstance(self.patch_embedding, nn.Conv2d):
pixel_values = pixel_values.view(
-1, self.config.num_channels * self.config.temporal_patch_size, self.patch_size, self.patch_size
)
patch_embeds = self.patch_embedding(pixel_values.to(dtype=target_dtype))
patch_embeds = patch_embeds.reshape(-1, self.embed_dim)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

continuing on above comment, this looks weird if we are checking on module type. In case we need both position embedding types, i thing it's better to have separate classes for each and just call it

Comment on lines +179 to +191
# pos_embed = self.pos_embed.reshape(1, ori_h, ori_w, -1).permute(0, 3, 1, 2)
cnt = 0
for t, h, w in grid_thws:
thw = t * h * w
pe = F.interpolate(positional_embeddings, size=(h, w), mode="bicubic", align_corners=False)
pe = pe.permute(0, 2, 3, 1).reshape(1, h * w, -1)
pe = pe[0].repeat(t, 1)
pe = pe.reshape(
t, h // self.hidden_stride, self.hidden_stride, w // self.hidden_stride, self.hidden_stride, -1
)
pe = pe.permute(0, 1, 3, 2, 4, 5).reshape(thw, -1)
pos_embed_new[cnt : cnt + thw] = pe
cnt += thw

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

could be in self.interpolate_position_embeddings(grid_twh) to be aligned with other ViT models

None if config.fullatt_block_indexes is None else [int(i) for i in config.fullatt_block_indexes.split("|")]
)

def rot_pos_emb(self, grid_thw):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks like the rope from Qwen2.5-VL, maybe we should use modular with Qwen2.5-Vision then?

Comment on lines +291 to +309
r"""
Args:
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation.
This is useful if you want more control over how to convert `input_ids` indices into associated vectors
than the model's internal embedding lookup matrix.
attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
- 1 for tokens that are **not masked**,
- 0 for tokens that are **masked**.
[What are attention masks?](../glossary#attention-mask)
output_attentions (`bool`, *optional*):
Whether or not to return the attentions tensors of all attention layers. See `attentions` under
returned tensors for more detail.
output_hidden_states (`bool`, *optional*):
Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors
for more detail.
return_dict (`bool`, *optional*):
Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

let's use @autodocstring instead to auto-generate docs

Comment on lines +350 to +355
if self.gradient_checkpointing and self.training:
hidden_states = self._gradient_checkpointing_func(
block.__call__, hidden_states, cu_seqlens_tmp, position_embeddings
)
else:
hidden_states = block(hidden_states, cu_seqlens_tmp, position_embeddings)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

GC can be handled better by using GradientCheckpointingLayer :)

@thisisiron

Copy link
Copy Markdown
Contributor Author

@zucchini-nlp, I’m still working on adding the model. Sorry for the confusion. I’ll ping you once it’s ready for review. Thank you for taking the time to review.

@zucchini-nlp

Copy link
Copy Markdown
Member

Oke, i will unsubscribe myself then :)

@zucchini-nlp

Copy link
Copy Markdown
Member

@thisisiron hey, is this PR still active? Ovis2.5 is getting community interest, so lmk if you need help with finalizing the PR

@thisisiron

Copy link
Copy Markdown
Contributor Author

@zucchini-nlp, I’ve been quite busy recently and haven’t been able to make proper progress on this. Apologies for the delay. Please feel free to close the PR so that someone else can continue the work.

@zucchini-nlp

zucchini-nlp commented Sep 16, 2025 •

Copy link
Copy Markdown
Member

No probs :) In case you want to take over and finish the PR, cc @mahimairaja. The next step would be to address comments from last review

@thisisiron thisisiron closed this Mar 30, 2026
This was referenced Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants