Normalize multimodal input keys in AnyToAnyPipeline - #47074
Conversation
zucchini-nlp
left a comment
There was a problem hiding this comment.
Can we add tests pls, for ex take a vlm with videos support and enable pipeline tester mixing on it
LKM if you have a tiny ckpt that has to be moved to testing hub repo!
| if "image" in inputs: | ||
| inputs.setdefault("images", inputs.pop("image")) | ||
| if "video" in inputs: | ||
| inputs.setdefault("videos", inputs.pop("video")) |
There was a problem hiding this comment.
i think we can assume now that the keys will be correct, this is usually not called outside pipe
|
Thanks @zucchini-nlp. The follow-up narrows this to the direct It adds a focused regression with the tiny Qwen2.5-Omni processor plus a fake generate model, and extends the shared pipeline tester path to exercise I also tried enabling the real Qwen2.5-Omni pipeline tester directly. It enters the long Omni generation path on CPU, so I kept this at the pipeline/processor boundary. |
| class Qwen2_5OmniForConditionalGeneration(torch.nn.Module): | ||
| input_modalities = ("image", "video", "audio", "text") | ||
| output_modalities = ("text", "audio") | ||
|
|
||
| def __init__(self): | ||
| super().__init__() | ||
| self.config = type("Config", (), {"_commit_hash": None, "model_type": "qwen2_5_omni"})() | ||
| self.generation_config = GenerationConfig(max_new_tokens=1) | ||
| self.generate_kwargs = None | ||
|
|
||
| @property | ||
| def device(self): | ||
| return torch.device("cpu") | ||
|
|
||
| def can_generate(self): | ||
| return True | ||
|
|
||
| def generate(self, input_ids=None, **kwargs): | ||
| self.generate_kwargs = kwargs | ||
| token = torch.full((input_ids.shape[0], 1), 42, dtype=input_ids.dtype) | ||
| return torch.cat([input_ids, token], dim=1) |
There was a problem hiding this comment.
why is this, lets import an existing model and use it
There was a problem hiding this comment.
Thanks @zucchini-nlp, good point. I updated the test to load the tiny Qwen2_5OmniForConditionalGeneration.
I still stub generate on that loaded instance so the test stays focused and does not enter the slow Omni generation path.
There was a problem hiding this comment.
tbh I dont understand why we need the override in general. Calling a pipe on model should work ideally without any workarounds
There was a problem hiding this comment.
Thanks @zucchini-nlp, agreed. I removed the generate override entirely; the test now calls the tiny Qwen2.5-Omni model through the pipeline with its real generate.
I only pass public Qwen generation kwargs to keep the real call short.
Signed-off-by: Ting Sun <suntcrick@gmail.com>
Signed-off-by: Ting Sun <suntcrick@gmail.com>
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
|
Thank you for your contribution 🤗! CI Security Gate — automatic approval blockedThis PR was not automatically approved for CI because the security gate failed. Possible reasons:
See the workflow run for the exact violations. A maintainer can review and manually approve CI if a finding is a false positive. |
|
@bot /style |
|
Style fix is beginning .... View the workflow run here. |
CI recapDashboard: View test results in Grafana |
* Keep AnyToAnyPipeline video inputs plural Signed-off-by: Ting Sun <suntcrick@gmail.com> * Run AnyToAnyPipeline video test with real model generate Signed-off-by: Ting Sun <suntcrick@gmail.com> * style --------- Signed-off-by: Ting Sun <suntcrick@gmail.com> Co-authored-by: Raushan Turganbay <raushan@huggingface.co>
* Keep AnyToAnyPipeline video inputs plural Signed-off-by: Ting Sun <suntcrick@gmail.com> * Run AnyToAnyPipeline video test with real model generate Signed-off-by: Ting Sun <suntcrick@gmail.com> * style --------- Signed-off-by: Ting Sun <suntcrick@gmail.com> Co-authored-by: Raushan Turganbay <raushan@huggingface.co>
What does this PR do?
AnyToAnyPipelineaccepts multimodal inputs through both direct keyword arguments and dict/dataset samples, but two of those paths used singular keys before calling the processor.videos=was repacked asvideo, and dict inputs like{"image": ..., "video": ...}were forwarded unchanged. Qwen Omni processors expectimages=andvideos=, so video inputs could be ignored and image inputs could crash when an image placeholder was expanded without an image grid.This normalizes pipeline inputs before the processor call. Direct
videos=stays plural, dictimage/videoaliases are converted toimages/videos, and explicit plural dict values keep precedence.End-to-end pipeline repro (real AnyToAnyPipeline + real Qwen3-Omni processor)
Environment:
I did not add a dedicated unit test for this small key-normalization change. The repro above exercises the real pipeline plus real Qwen3-Omni processor path before and after the patch.
Touched-file checks
Checks:
Code Agent Policy
Before submitting
Pull Request checks?
to it if that's the case.
Who can review?
cc @Rocketknight1 @zucchini-nlp