• Stefy Lanza (nextime / spora )'s avatar
    take the size the caller asked for, and the words they trained (v0.4.90) · 03169236
    Stefy Lanza (nextime / spora ) authored
    Three things the image endpoints accepted and then quietly did something else
    with.
    
    size. A size that did not parse fell through to the default, so "1024" or
    "1k x 1k" generated a square nobody asked for and the response looked like a
    success. A side that was not a multiple of 8 went to the pipeline as-is, where
    the VAE cannot represent it. Nothing capped it either, so 4096x4096 was
    accepted and came back as a CUDA OOM -- which reads like a busy GPU rather
    than a size the caller chose. Now: a 400 quoting what was sent, a 400 for a
    zero dimension (snapping it up would answer an uninitialised client variable
    with an 8x8 image), snapping to the grid with a log line, and a 400 naming
    image.max_side / image.max_pixels when it is over the ceiling. "auto" is
    accepted as in the OpenAI API, and the dead `width != width` NaN guard on a
    value that was already an int is gone. The archive records the size actually
    generated alongside the one requested.
    
    /v1/images/inpaint no longer defaults to 1024x1024, which squashed every
    non-square photo and pulled the mask out of alignment with it -- worse than
    the same default on /v1/images/edits, where it was fixed in 0.4.86. Omitted
    now keeps the source's shape.
    
    Textual inversions. easynegative, bad-hands-5 and the rest are vectors living
    in CLIP's embedding table under a word of their own, and until the file is
    loaded that word is an ordinary unknown token -- so a large part of the
    ecosystem's negative prompting asked for nothing at all. They load from the
    request (embeddings: [...]), from the model's config (textual_inversion), or
    by filename from image.embeddings_dir, which is how A1111 works and what a
    prompt copied off a model card assumes. Two details decide whether this works
    at all: an SDXL-format embedding holds a clip_l and a clip_g tensor that must
    go into the matching tokenizer/encoder pair, and a multi-vector embedding
    occupies several tokens (tok, tok_1, tok_2...) that the prompt has to be
    expanded into -- without it an eight-vector embedding contributes one vector
    and appears inert. A name the caller gave that will not load is a 400; a bad
    file in the directory is a line in the log, because one file should not break
    every request.
    
    /v1/images/outfit goes through the same encoder now, so the weight grammar and
    clip_skip reach it too. Its per-frame video path encodes the prompt once for
    the clip instead of once per frame.
    
    And a 400 is no longer reported as a failed backend. On the first request for
    a model that is not loaded yet, the generate call sits inside the try that
    falls back from diffusers to sd.cpp, so a rejected request was caught as a
    load failure and answered with a report about which backends failed. The three
    edit endpoints did the same through their catch-alls. All four re-raise
    HTTPException untouched.
    
    Found by the tests while writing them: the embeddings directory was searched
    by the renamed trigger word rather than the filename, so "easynegative:myneg"
    never resolved, and "768X512" did not parse.
    
    64 new tests; full suite 4475 passed with the same 15 pre-existing failures as
    0.4.89 (diff empty).
    Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01S8LAP3ueNzQJtwzhgVbq66
    03169236
Name
Last commit
Last update
..
admin Loading commit data...
api Loading commit data...
backends Loading commit data...
broker Loading commit data...
cluster Loading commit data...
compose Loading commit data...
frontproxy Loading commit data...
models Loading commit data...
ocr Loading commit data...
openai Loading commit data...
pydantic Loading commit data...
queue Loading commit data...
tasks Loading commit data...
util Loading commit data...
__init__.py Loading commit data...
cli.py Loading commit data...
config.py Loading commit data...
hf_cache.py Loading commit data...
main.py Loading commit data...
ocr_fleet_workers.py Loading commit data...
platform_paths.py Loading commit data...
system_app.py Loading commit data...