fix(diffusers,vllm-omni,tinygrad): save generated images as PNG explicitly#10729
Merged
Conversation
…citly The image backends call PIL Image.save(request.dst) without a format, so Pillow infers the encoder from the file extension. The core passes an absolute staging path ending in .tmp (e.g. /staging/localai-output-*.tmp), which Pillow can't map to a format, raising "unknown file extension: .tmp" and crashing the worker right after a successful GPU inference. Pass format="PNG" explicitly. LocalAI serves generated images as PNG regardless of the temporary path, so this is always correct and no longer depends on the extension of the destination the core happens to allocate. diffusers is the reported backend (#10727); vllm-omni and tinygrad carry the identical latent crash for any .tmp staging destination. Closes #10727 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:claude-opus-4-8 [Claude Code]
mudler
approved these changes
Jul 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Image generation completes GPU inference but crashes at the file-save step. The Python image backends call
PIL Image.save(request.dst)without a format, so Pillow infers the encoder from the file extension. The core passes an absolute staging path ending in.tmp(e.g./staging/localai-output-*.tmp, fromcore/services/nodes/file_transfer_server.go), which Pillow can't map to a format:The worker dies right after a successful inference, so the image never reaches the UI.
Fix
Pass
format="PNG"explicitly. LocalAI serves generated images as PNG regardless of the temp path (core/http/endpoints/openai/image.goappends.png), so this is always correct and no longer depends on the destination extension the core happens to allocate.Fixed in all three image backends that had the identical pattern:
backend/python/diffusers/backend.py— the reported backend (bug(diffusers): Python backend crashes saving image to .tmp path without explicit format #10727)backend/python/vllm-omni/backend.py— identical latent crash on any.tmpdstbackend/python/tinygrad/backend.py— same(
mlx-vlmalready passesformat='JPEG';chatterboxusestorchaudio— both fine.)Testing
All three files pass
python -m py_compile. Full runtime verification requires the backend images + GPU + models (CI/backend-image territory); the change is a one-argument PIL usage fix.Closes #10727
🤖 Generated with Claude Code