OpenPanguVL's custom `image_processor`/`processor` remote code breaks on current `transformers` (3 stacked bugs)
This repo's custom trust_remote_code=True processor files — imageprocessor_openpangu_vl.py and processor_openpangu_vl.py — were written against transformers==4.52.4 (pinned in this repo's own config.json's transformers_version field) and no longer work on current transformers releases. Loading the processor and preprocessing any image raises three separate, sequential exceptions — each one only becomes visible after the previous one is patched, since the code never gets far enough to hit the next bug otherwise.
Confirmed as still present and unfixed by pulling imageprocessor_openpangu_vl.py/processor_openpangu_vl.py directly from main today. Also checked the repo's one open discussion/PR (#2, "Don't make all kwargs required in OpenPanguVLVideoProcessor.__init__") — it's an unrelated one-line fix to a different file (videoprocessor_openpangu_vl.py) and doesn't touch either file below (diffed byte-for-byte against main, identical except for that file).
Reproduction
from transformers import AutoProcessor
from PIL import Image
processor = AutoProcessor.from_pretrained(
"FreedomIntelligence/openPangu-VL-7B", trust_remote_code=True
)
processor(text="describe this image", images=[Image.new("RGB", (64, 64))], return_tensors="pt")
Bug 1 — AttributeError: ... object has no attribute 'min_pixels'
OpenPanguVLImageProcessorFast._resolve_preprocess_params (subclasses Qwen2VLImageProcessorFast) does:
def _resolve_preprocess_params(self, **kwargs):
params = SimpleNamespace()
for key, value in kwargs.items():
setattr(params, key, value if value is not None else getattr(self, key))
...
The hard getattr(self, key) (no default) assumes every kwarg the caller didn't override is still a stored instance attribute. On current transformers, Qwen2VLImageProcessorFast.__init__ no longer stores min_pixels/max_pixels as instance attributes — they're folded into self.size["shortest_edge"/"longest_edge"] instead — so this raises AttributeError: 'OpenPanguVLImageProcessorFast' object has no attribute 'min_pixels' immediately.
Fix: soft fallback, getattr(self, key, None). The if params.size is None: params.size = {...} branch just below already handles a None min_pixels/max_pixels correctly — no other change needed.
Bug 2 — TypeError: SizeDict() argument after ** must be a mapping, not SizeDict
Once bug 1 is patched, this line is reached:
params.size = SizeDict(**params.size)
params.size (falling back to self.size when the caller didn't override size) is now, on current transformers, already a SizeDict instance, not a plain dict as this code assumes. SizeDict.__init__ doesn't implement Mapping's **-unpacking protocol the way a plain dict does, so this raises TypeError.
Fix: convert via dict(...) first when params.size is already a SizeDict:
if isinstance(params.size, SizeDict):
params.size = SizeDict(**dict(params.size))
else:
params.size = SizeDict(**params.size)
Bug 3 — AttributeError: ... object has no attribute '_process_image'
Once bug 2 is patched, _prepare_input_images calls self._process_image (private, leading underscore):
process_image_fn = partial(
self._process_image,
do_convert_rgb=do_convert_rgb,
...
)
Current transformers' Qwen2VLImageProcessorFast (the actual parent class) renamed this to the public process_image (no underscore) — the private name no longer exists on the class.
Fix: call self.process_image instead.
Bug 4 — NameError: name 'np' is not defined (in processor_openpangu_vl.py, not a transformers-version issue)
Separately, processor_openpangu_vl.py's __call__ uses np.array(...)/np.zeros_like(...) (around line 108) but the file never imports numpy anywhere. This is a plain bug in this repo's own code, not a transformers API change — it always would have raised NameError regardless of transformers version, unless a caller happened to import numpy as np into global scope first (making np visible via some other coincidental import ordering).
Fix: add import numpy as np near the top of the file.
Why this matters, and why it's a repo-side fix (not a transformers bug)
trust_remote_code=True model repos pin their behavior to the transformers version available at authoring time. This repo subclasses Qwen2VLImageProcessorFast, whose internals (the _process_image/min_pixels/SizeDict details bugs 1–3 depend on) have since been intentionally redesigned in transformers v5 — this is a documented breaking change, not accidental drift: see transformers' own MIGRATION_GUIDE_V5.md, "Image processors" section — the old slow/fast dual-file design (FooImageProcessor + FooImageProcessorFast) was replaced by a named-backend architecture (TorchvisionBackend/PilBackend), which is exactly what moved min_pixels/max_pixels into self.size and changed the process_image method contract. Because this is intentional, versioned, upstream behavior — not a transformers bug — the fix belongs in this repo's own remote code, not a transformers GitHub issue.
Any environment running a transformers release that has adopted this redesign hits all three bugs above, in order, on the very first image processed — this repo is currently unusable for multimodal (image) inference on any such install.
Suggested fix (all in this repo, not upstream transformers)
Apply the 4 fixes above to imageprocessor_openpangu_vl.py (bugs 1–3) and processor_openpangu_vl.py (bug 4). Happy to open a PR with the diff if that's preferred over a discussion — let me know.