-
Notifications
You must be signed in to change notification settings - Fork 33.8k
add HyperClovaX Vision #44314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
add HyperClovaX Vision #44314
Changes from all commits
647ac9d
f420da6
3aeac2e
c3f0231
d231dff
e67eaf7
a33087b
26ad483
7df5a6d
8638c8b
f459f54
2fff572
0212ef5
eb222b7
781c956
c59d586
21816a2
843f314
bd62dfa
05ff2e9
a509a21
82b81f0
ab921aa
6add4b7
23040f4
9b03a52
a5955d1
85b38c1
76182ab
8a0aae6
148254b
97ba6f4
b36fe34
f3a116b
72473dc
aeb2b0e
434d253
1a66ff5
851d8e8
bd14fe8
5968960
bbbc25e
c2eecb5
1cdac66
41cea6a
714e3ae
30f2e46
2b85eeb
ab7e019
6b9c917
9818509
d5f814f
5ac0ec1
7667b0d
058e84c
55cdd31
f2199fc
bb7c123
8c48213
5af4a31
0d5d548
f77d904
3b7cc5b
f14d8df
113c360
50acbe9
db81d86
eb498d6
4c02f57
2d64070
9725d57
1b99fa9
f341f97
4b3ed30
2a3b4ac
a8fb5bd
23fd708
9838ff3
f69d101
d65cfce
532768c
57695f9
6865715
dbf1a4d
c3d26ac
ea1e6b7
5cef112
92c75e0
7ef1cc9
2d24b65
6602e5b
2589d01
3d9662d
bb5769f
361d35f
8d873c3
ef7b049
8f085c8
9000231
c2bc144
83748fb
dbea6b5
9437fb8
7fb344a
41b1a00
a56fd5c
01c4964
3db1711
dcbc59e
23a8be5
c03e704
4c8d788
c2cf581
fbb6a4d
7f89129
ed957e7
e941367
0c64154
80a9622
d2740d3
a4e7a48
42a028a
88e9c63
36388fa
0d112c7
724f795
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,265 @@ | ||
| <!--Copyright 2026 NAVER Corp. and The HuggingFace Inc. team. All rights reserved. | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
| the License. You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
| an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
| specific language governing permissions and limitations under the License. | ||
|
|
||
| ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be | ||
| rendered properly in your Markdown viewer. | ||
|
|
||
| --> | ||
| *This model was released on {release_date} and added to Hugging Face Transformers on 2026-05-26.* | ||
|
|
||
| <div style="float: right;"> | ||
| <div class="flex flex-wrap space-x-1"> | ||
| <img alt="FlashAttention" src="https://img.shields.io/badge/%E2%9A%A1%EF%B8%8E%20FlashAttention-eae0c8?style=flat"> | ||
| <img alt="SDPA" src="https://img.shields.io/badge/SDPA-DE3412?style=flat&logo=pytorch&logoColor=white"> | ||
| </div> | ||
| </div> | ||
|
|
||
| # HyperCLOVAX Vision V2 | ||
|
|
||
| HyperCLOVAX Vision V2 is a multimodal vision-language model developed by NAVER. It combines the [HyperClovaX](./hyperclovax.md) language model backbone with a [Qwen2.5-VL](./qwen2_5_vl) vision encoder. The model supports text, image, and video inputs and is capable of chain-of-thought reasoning via built-in thinking tokens (`<think>...</think>`). | ||
|
|
||
| You can find the original HyperCLOVAX-SEED-Think-32B checkpoint on the [naver-hyperclovax/HyperCLOVAX-SEED-Think-32B](https://huggingface.co/naver-hyperclovax/HyperCLOVAX-SEED-Think-32B) page. | ||
|
|
||
| The example below demonstrates how to generate text based on an image with [`HyperCLOVAXVisionV2ForConditionalGeneration`]. | ||
|
|
||
| <hfoptions id="usage"> | ||
| <hfoption id="Image input"> | ||
|
|
||
| ```python | ||
| from transformers import HyperCLOVAXVisionV2ForConditionalGeneration, HyperCLOVAXVisionV2Processor | ||
|
|
||
| model = HyperCLOVAXVisionV2ForConditionalGeneration.from_pretrained( | ||
| "naver-hyperclovax/HyperCLOVAX-SEED-Think-32B", | ||
| device_map="auto", | ||
| ) | ||
| processor = HyperCLOVAXVisionV2Processor.from_pretrained("naver-hyperclovax/HyperCLOVAX-SEED-Think-32B") | ||
|
|
||
| messages = [ | ||
| { | ||
| "role": "system", | ||
| "content": "You are a helpful assistant.", | ||
| }, | ||
| { | ||
| "role": "user", | ||
| "content": [ | ||
| { | ||
| "type": "image_url", | ||
| "image_url": {"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg"}, | ||
| }, | ||
| {"type": "text", "text": "Describe this image."}, | ||
| ], | ||
| }, | ||
| ] | ||
|
|
||
| inputs = processor.apply_chat_template( | ||
| messages, | ||
| add_generation_prompt=True, | ||
| tokenize=True, | ||
| return_dict=True, | ||
| return_tensors="pt", | ||
| ).to(model.device) | ||
|
|
||
| generated_ids = model.generate(**inputs, max_new_tokens=256) | ||
| generated_ids_trimmed = [ | ||
| out_ids[len(in_ids):] for in_ids, out_ids in zip(inputs.input_ids, generated_ids) | ||
| ] | ||
| output_text = processor.batch_decode( | ||
| generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False | ||
| ) | ||
| print(output_text) | ||
| ``` | ||
|
|
||
| </hfoption> | ||
| <hfoption id="Video input"> | ||
|
|
||
| ```python | ||
| from transformers import HyperCLOVAXVisionV2ForConditionalGeneration, HyperCLOVAXVisionV2Processor | ||
|
|
||
| model = HyperCLOVAXVisionV2ForConditionalGeneration.from_pretrained( | ||
| "naver-hyperclovax/HyperCLOVAX-SEED-Think-32B", | ||
| device_map="auto", | ||
| ) | ||
| processor = HyperCLOVAXVisionV2Processor.from_pretrained("naver-hyperclovax/HyperCLOVAX-SEED-Think-32B") | ||
|
|
||
| messages = [ | ||
| { | ||
| "role": "system", | ||
| "content": "You are a helpful assistant.", | ||
| }, | ||
| { | ||
| "role": "user", | ||
| "content": [ | ||
| { | ||
| "type": "image_url", | ||
| "image_url": {"url": "/path/to/video.mp4"}, | ||
| }, | ||
| {"type": "text", "text": "Describe this video."}, | ||
| ], | ||
| }, | ||
| ] | ||
|
|
||
| # Use processor.tokenizer.apply_chat_template for video inputs. | ||
| # processor.apply_chat_template rewrites image_url to image before the | ||
| # template runs, which breaks HCX's extension-based video detection. | ||
| text = processor.tokenizer.apply_chat_template( | ||
| messages, | ||
| add_generation_prompt=True, | ||
| tokenize=False, | ||
| ) | ||
| inputs = processor( | ||
| text=text, | ||
| videos=["/path/to/video.mp4"], | ||
| return_tensors="pt", | ||
| ).to(model.device) | ||
|
|
||
| generated_ids = model.generate(**inputs, max_new_tokens=256) | ||
| generated_ids_trimmed = [ | ||
| out_ids[len(in_ids):] for in_ids, out_ids in zip(inputs.input_ids, generated_ids) | ||
| ] | ||
| output_text = processor.batch_decode( | ||
| generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False | ||
| ) | ||
| print(output_text) | ||
| ``` | ||
|
|
||
| </hfoption> | ||
| </hfoptions> | ||
|
|
||
| Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. | ||
|
|
||
| The example below uses [bitsandbytes](../quantization/bitsandbytes) to load the model in 4-bit. | ||
|
|
||
| ```python | ||
| from transformers import BitsAndBytesConfig, HyperCLOVAXVisionV2ForConditionalGeneration, HyperCLOVAXVisionV2Processor | ||
|
|
||
| quantization_config = BitsAndBytesConfig(load_in_4bit=True) | ||
| model = HyperCLOVAXVisionV2ForConditionalGeneration.from_pretrained( | ||
| "naver-hyperclovax/HyperCLOVAX-SEED-Think-32B", | ||
| device_map="auto", | ||
| quantization_config=quantization_config, | ||
| ) | ||
| processor = HyperCLOVAXVisionV2Processor.from_pretrained("naver-hyperclovax/HyperCLOVAX-SEED-Think-32B") | ||
| ``` | ||
|
|
||
| ## Notes | ||
|
|
||
| - HyperCLOVAX Vision V2 uses a unique media input format. Both images and videos are specified using `{"type": "image_url", "image_url": {"url": "..."}}`. The processor and chat template distinguish images from videos by file extension (`.mp4`, `.avi`, `.mov`, `.mkv`, `.webm`, `.flv`, `.wmv`, `.m4v` are treated as video; everything else is treated as image). | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah ok this is the explicit change, imo would maybe make sense to have a different chat template if possible. This really is weird |
||
|
|
||
| ```python | ||
| # Image input | ||
| {"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}} | ||
|
|
||
| # Video input (identified by file extension) | ||
| {"type": "image_url", "image_url": {"url": "/path/to/video.mp4"}} | ||
| ``` | ||
|
|
||
| > [!WARNING] | ||
| > Video input via `processor.apply_chat_template` is currently broken. Recent Transformers versions rewrite `image_url` entries to `image` before the chat template runs, so the video-detection branch in HCX's template never triggers and video inputs are silently dropped. As a workaround, use `processor.tokenizer.apply_chat_template` to render the prompt text, then pass the video path separately to `processor(...)`. See [this review comment](https://github.com/huggingface/transformers/pull/44314#discussion_r3008382827) for details. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the review comment is closed, cant load via url it seems
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've reopened the comment. |
||
|
|
||
| - The model supports chain-of-thought reasoning. By default, the generation prompt prepends an empty `<think>\n\n</think>` block. To generate an explicit reasoning trace inside `<think>...</think>` tags, pass `thinking=True` to `apply_chat_template` (image/text inputs only): | ||
|
|
||
| ```python | ||
| inputs = processor.apply_chat_template( | ||
| messages, | ||
| add_generation_prompt=True, | ||
| tokenize=True, | ||
| return_dict=True, | ||
| return_tensors="pt", | ||
| thinking=True, | ||
| ).to(model.device) | ||
| ``` | ||
|
|
||
| - The model supports multi-turn conversations with mixed media. Images and videos can appear across multiple turns. For turns containing video, use the `processor.tokenizer.apply_chat_template` workaround described above. | ||
|
|
||
| ```python | ||
| messages = [ | ||
| { | ||
| "role": "user", | ||
| "content": [ | ||
| {"type": "image_url", "image_url": {"url": "https://example.com/image1.jpg"}}, | ||
| {"type": "text", "text": "What do you see in this image?"}, | ||
| ], | ||
| }, | ||
| { | ||
| "role": "assistant", | ||
| "content": "I see a cat sitting on a couch.", | ||
| }, | ||
| { | ||
| "role": "user", | ||
| "content": [ | ||
| {"type": "image_url", "image_url": {"url": "https://example.com/image2.jpg"}}, | ||
| {"type": "text", "text": "How does this compare to the first image?"}, | ||
| ], | ||
| }, | ||
| ] | ||
| ``` | ||
|
|
||
| - The model supports function/tool calling. Pass tools using the `tools` parameter in `apply_chat_template`: | ||
|
|
||
| ```python | ||
| tools = [ | ||
| { | ||
| "type": "function", | ||
| "function": { | ||
| "name": "get_weather", | ||
| "description": "Get the current weather for a location.", | ||
| "parameters": { | ||
| "type": "object", | ||
| "properties": { | ||
| "location": {"type": "string", "description": "City name"}, | ||
| }, | ||
| "required": ["location"], | ||
| }, | ||
| }, | ||
| } | ||
| ] | ||
|
|
||
| messages = [ | ||
| {"role": "user", "content": "What is the weather in Seoul?"} | ||
| ] | ||
|
|
||
| inputs = processor.apply_chat_template( | ||
| messages, | ||
| tools=tools, | ||
| add_generation_prompt=True, | ||
| tokenize=True, | ||
| return_dict=True, | ||
| return_tensors="pt", | ||
| ).to(model.device) | ||
| ``` | ||
|
|
||
| ## HyperCLOVAXVisionV2Config | ||
|
|
||
| [[autodoc]] HyperCLOVAXVisionV2Config | ||
|
|
||
| ## HyperCLOVAXVisionV2Processor | ||
|
|
||
| [[autodoc]] HyperCLOVAXVisionV2Processor | ||
| - __call__ | ||
|
|
||
| ## HyperCLOVAXVisionV2Model | ||
|
|
||
| [[autodoc]] HyperCLOVAXVisionV2Model | ||
| - forward | ||
| - get_image_features | ||
| - get_video_features | ||
|
|
||
| ## HyperCLOVAXVisionV2ForConditionalGeneration | ||
|
|
||
| [[autodoc]] HyperCLOVAXVisionV2ForConditionalGeneration | ||
| - forward | ||
| - get_image_features | ||
| - get_video_features | ||
|
|
||
| ## HyperCLOVAXVisionV2ForSequenceClassification | ||
|
|
||
| [[autodoc]] HyperCLOVAXVisionV2ForSequenceClassification | ||
| - forward | ||
|
jp1924 marked this conversation as resolved.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is weird, why are we even using image url --> shouldnt it be video url to properly distinguish between img/video? cc @zucchini-nlp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh, didn't see it. I believe related ti how the jinja template is saved on the hub
This indeed looks weird, lets' ping the Naver team to change model-type/jinja/etc or ask them to host a non-remote version. @jp1924 , when you are done passing over comments, could you list the things we need to change on the hub and ping @ (bigshanedogg). We need to either push directly to the existing repo or upload a new repo with
{{MODELNAME}}-hfsuffixThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#44314 (comment)
You can check the details via this link.
Sharing the text below as well since the link is dead.