Skip to content

Enhance image type handling and add embedding converter - #837

Merged
cristian-tamblay merged 5 commits into
developfrom
feat/image-embedding-converter
Aug 25, 2026
Merged

Enhance image type handling and add embedding converter#837
cristian-tamblay merged 5 commits into
developfrom
feat/image-embedding-converter

Conversation

@Irozuku

@Irozuku Irozuku commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds an image embedding converter that turns a DashAIImage column into plain Float columns using a pretrained vision encoder. This lets image data reach the existing tabular tasks and models with no new task and no new model.

It also fixes a naming mismatch that made any image typed component unusable: converters and explorers advertised their accepted types with the Python class name, so DashAIImage reached the frontend as DashAIImage while dataset columns report their type as Image. Nothing ever matched, and selecting an image dataset failed with "This dataset does not have any columns with the required types (DashAIImage)". No existing converter hit this because every other one uses Text, Float or Categorical, where the class name and the display name happen to be identical.


Type of Change

  • Backend change
  • Frontend change
  • CI / Workflow change
  • Build / Packaging change
  • Bug fix
  • Documentation

Changes (by file)

  • DashAI/back/types/dashai_data_type.py: adds DISPLAY_NAME and display_name(), so a type whose class name differs from the name users see declares it itself instead of a caller translating it.
  • DashAI/back/types/dashai_image.py: declares DISPLAY_NAME = "Image", and to_string() now reads it, so one constant per class drives both directions.
  • DashAI/back/converters/base_converter.py: serialises allowed_types through display_name() instead of __name__.
  • DashAI/back/exploration/base_explorer.py: same fix, same defect.
  • DashAI/back/tasks/base_task.py: drops its private _CLASS_NAME_TO_DISPLAY dict in favour of the type's own display_name().
  • DashAI/back/converters/hugging_face/image_embedding.py: the new converter. model_name is an enum over three permissively licensed encoders, device reuses DEVICE_ENUM from the models package so the form lists real GPUs, and keep_source_column defaults to true so a later stage can still reach the original pixels.
  • DashAI/back/initial_components.py: registers the converter.
  • tests/back/converters/test_image_column_roundtrip.py: documents that dashai_types metadata is lost through a pandas round trip, which is why a converter that rebuilds a dataset must pass types= explicitly.

Testing

  • Select an image dataset and confirm the converter is offered.
  • Run it with DINOv2 small and verify it returns the embedding columns.

Notes

Encoder choices are DINOv2 base, DINOv2 small and ResNet 50, all Apache 2.0, which is compatible with this project's MIT licence.

@Irozuku Irozuku added bug Something isn't working back Backend work labels Aug 24, 2026
Converters and explorers advertised allowed_types with the Python class
name, so DashAIImage reached the frontend as DashAIImage while columns
report their type as Image. Nothing matched and an image dataset was
rejected naming a type no column can have.

Types now carry their own DISPLAY_NAME and expose display_name(), which
to_string() also reads, so one constant per class drives both directions
and a new type with the same mismatch needs no change outside itself.
Turns a DashAIImage column into plain Float columns named
emb_{column}_{i} using a HuggingFace vision encoder, so image data can
be consumed by the existing tabular tasks and models with no new task
and no new model.

Unlike the text embedding converter it is modelled on, the source column
is retained by default through keep_source_column, so a later stage can
still reach the original pixels.

The round trip test documents that dashai_types metadata is lost through
a pandas round trip, which is why a converter rebuilding a dataset must
pass types explicitly.
… enum

model_name was free text, which let a user name any repository including
weights whose licence is not compatible with this project. It is now an
enum over IMAGE_ENCODERS, three permissively licensed vision encoders,
with the friendly name resolved to a repository id at construction. An
unrecognised value still passes through so an API payload naming a
repository directly keeps working.

device now reuses DEVICE_ENUM, DEVICE_PLACEHOLDER and DEVICE_TO_IDX from
the models package, so the form lists the machine's actual GPUs instead
of a hardcoded cpu and cuda pair, and the label is mapped to a torch
device string.
ResNet returns a spatially pooled pooler_output of shape
(batch, channels, 1, 1) while a vision transformer such as DINOv2
returns (batch, hidden). The column builder indexed the second axis and
handed pyarrow a nested list, failing with 'Could not convert
[[0.057...]] with type list: tried to convert to float32'.

Collapse every dimension after the batch axis, and reject a non two
dimensional result with a message naming the column, so an injected
encoder of the wrong shape does not surface as an opaque pyarrow error.
The switch to display_name() assumed every entry in inputs_types,
outputs_types and allowed_types is a DashAIDataType. They are not: the
component API tests register tasks whose types are HuggingFace dataset
features, and a plugin can legitimately declare its own classes. The
previous t.__name__ worked on any class, so this raised AttributeError
for ClassLabel and errored 34 tests in CI.

Ask the type for its own name when it can answer and fall back to the
class name otherwise.
@cristian-tamblay
cristian-tamblay force-pushed the feat/image-embedding-converter branch from 114deb1 to 37e35b3 Compare August 25, 2026 14:06
@cristian-tamblay
cristian-tamblay merged commit a1a95e7 into develop Aug 25, 2026
20 checks passed
@cristian-tamblay
cristian-tamblay deleted the feat/image-embedding-converter branch August 25, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

back Backend work bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants