Skip to content

fix(verl): file image URIs fail to load and drop valid training rows #637

Description

Problem

Readable local images supplied as standard Path.as_uri() URLs fail to load in the VERL rollout adapter. The loader passes the percent-encoded URI path to Pillow without converting it to a filesystem path. Spaces, Unicode and literal percent signs therefore break image loading; native Windows drive paths also require conversion.

This affects the resulting training data: RolloutAdapter.get_train_data_batch() marks the row for dropping when image processing fails, so an otherwise valid multimodal rollout is removed by the training-row filter.

Minimal reproduction

At d381995396274039f2bb1cbe5ff42ac8067f4e47, with the frozen dev and verl-cpu environment:

from pathlib import Path
from tempfile import TemporaryDirectory

from PIL import Image
from agentlightning.verl.rollout_adapter import _load_pil_image

with TemporaryDirectory() as directory:
    path = Path(directory) / "frame 50% 中文.png"
    Image.new("RGB", (2, 2), "red").save(path)
    with Image.open(path) as image:
        assert image.size == (2, 2)  # The local file is valid and readable.
    image = _load_pil_image(path.as_uri())  # Fails on the encoded/native path.
    assert image.size == (2, 2)

I also reproduced the downstream effect through the actual RolloutAdapter.get_train_data_batch() entry point, using Torch CPU, VERL DataProto, and a real Transformers CLIPProcessor with a locally constructed tokenizer and image processor. The same PNG bytes were used for both inputs:

Input is_drop_mask Retained rollout IDs Pixel tensor shape
Base64 data URL [false] ["uri-probe"] [1, 3, 2, 2]
path.as_uri() [true] [] No image input

No model download, network image request, fake dependency or monkeypatch was used in that comparison.

Expected behavior

Decode the file URI into the platform's native path exactly once before opening the image. The file-URI input should retain the same rollout and image pixels as the data-URL control. Literal encoded-looking filenames such as frame%20.png must not accidentally select a different file named frame .png.

Environment and scope

  • Native Windows, Python 3.12.14.
  • Agent Lightning 1.0.2 at the commit above; VERL 0.8.0; Torch 2.13.0+cpu; Transformers 5.10.4; Pillow 12.3.0.
  • The reproduction exercises the CPU batch adapter, not the local rollout controller or GPU training.

The affected branch is in _load_pil_image. A focused fix with regression tests is in preparation. Investigation and reporting used Codex assistance.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions