Skip to content

Studio: cache Edit-mode text encoding by reference image content - #13683

Merged
danielhanchen merged 3 commits into
unslothai:mainfrom
kevin9327:studio-prompt-cache-edit-images
Oct 15, 2026
Merged

danielhanchen merged 3 commits into
unslothai:mainfrom
kevin9327:studio-prompt-cache-edit-images

Conversation

@kevin9327

Copy link
Copy Markdown
Contributor

Refs #13638 (prompt-cache half; the CUBLAS init failure on the render thread needs a GPU and is not addressed here).

Problem

In Images → Edit, encode_prompt receives PIL reference images. _plain() raises TypeError: Image on them, so:

  1. every Edit render bypasses the prompt cache and re-runs the (large, VL) text encoder even for the same prompt + same image;
  2. the fallback encode(...) runs inside the except TypeError block, so any real encoder error (e.g. the CUBLAS one in [Bug]: TypeError: Image in diffusion_prompt_cache.py causes CUBLAS error during Image Edit (Qwen-Image-2.1) #13638) is reported as "During handling of the above exception … TypeError: Image", which sends debugging in the wrong direction.

Change

  • _plain() keys PIL images as ["PIL.Image", mode, size, sha256(pixels)]. Content-based, so an in-place edit of the same object misses, and a reloaded identical image hits. Only real PIL.* objects qualify; other duck-typed objects still bypass.
  • The bypass path in cached_encode_prompt and the MiniMax-H3 shim now calls the encoder after leaving the handler, so encoder errors are no longer chained onto the key error.

Tests (CPU, studio/backend/tests/test_diffusion_prompt_cache.py)

New: same-image hit (also via list), miss on different pixel / size / mode, miss after in-place putpixel, non-PIL lookalike still bypasses, bypassed encoder error has __context__ is None.

  • this branch: 25 passed (incl. safetensors test), 1 skipped (needs CUDA)
  • main: the two behavioural tests fail (image bypassed; RuntimeError chained onto TypeError)
  • test_diffusion_cond_cache.py has 8 failures on main in my env, unchanged by this PR.

Cost

Fingerprinting is one sha256 over raw pixels: ~3.1 ms for 1184x896 RGB, ~3.3 ms for 1024x1024 (CPU, mean of 20), versus a full Qwen3-VL encode on a hit. Not measured end-to-end on GPU.

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 14, 2026
@danielhanchen

Copy link
Copy Markdown
Member

@codex review

1 similar comment
@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T14:30:17.143351Z 7cb84cb Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7cb84cb91e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

module = type(value).__module__ or ""
if not module.startswith("PIL."):
return None
digest = hashlib.sha256(value.tobytes()).hexdigest()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include palette colors in image fingerprints

When a wrapped encoder receives a valid paletted (P/PA) PIL reference image, Image.tobytes() contains palette indices but not the palette or palette transparency. Two images with identical indices, size, and mode but different colors therefore produce the same cache key, so the second render reuses embeddings computed from a visually different image; hash the encoder-visible converted pixels or add palette/transparency data to the fingerprint.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not reachable from Studio: every image that reaches encode_prompt goes through decode_b64_image, which converts to RGB (or the family's condition_image_mode, RGB/RGBA), so a palette (P/PA) image never gets fingerprinted here.

@danielhanchen

Copy link
Copy Markdown
Member

@codex review

1 similar comment
@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 7cb84cb91e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants