Reject native batch seeds outside the JSON-safe range
This commit is contained in:
parent
499bada598
commit
5a17614b51
2 changed files with 35 additions and 0 deletions
|
|
@ -2069,6 +2069,21 @@ class DiffusionGenerateRequest(BaseModel):
|
|||
raise ValueError("must be a multiple of 16")
|
||||
return value
|
||||
|
||||
@model_validator(mode = "after")
|
||||
def _batch_seeds_json_safe(self) -> "DiffusionGenerateRequest":
|
||||
# A batch derives per-image seeds as seed, seed+1, ... seed+batch_size-1 (sd.cpp and
|
||||
# diffusers both advance the seed per image). The base seed is bounded to 2**53-1 so it
|
||||
# round-trips through the JSON gallery recipe, but the derived top-of-batch seed is not:
|
||||
# with an explicit seed near the cap it can exceed Number.MAX_SAFE_INTEGER, where the
|
||||
# frontend rounds it and a restored recipe replays a different image. Reject at the
|
||||
# boundary so an API client can't persist an unreplayable seed.
|
||||
if self.seed is not None and self.seed + self.batch_size - 1 > 2**53 - 1:
|
||||
raise ValueError(
|
||||
"seed + batch_size - 1 must not exceed 2**53 - 1 so every per-image seed "
|
||||
"stays JSON-safe (lower the seed or the batch_size)"
|
||||
)
|
||||
return self
|
||||
|
||||
|
||||
class GalleryImage(BaseModel):
|
||||
"""A persisted image's full generation recipe (embedded in the PNG too)."""
|
||||
|
|
|
|||
|
|
@ -340,6 +340,26 @@ def test_generate_rejects_non_multiple_of_16(client):
|
|||
assert ok.status_code == 200
|
||||
|
||||
|
||||
def test_generate_rejects_batch_seed_past_json_safe_range(client):
|
||||
client.post(
|
||||
"/api/inference/images/load", json = {"model_path": "x/z-image", "gguf_filename": "q.gguf"}
|
||||
)
|
||||
# An explicit seed at the JS-safe cap with a batch derives per-image seeds
|
||||
# (seed+1 ...) that exceed Number.MAX_SAFE_INTEGER and no longer round-trip
|
||||
# through the gallery JSON recipe, so the request is rejected at the boundary.
|
||||
over = client.post(
|
||||
"/api/inference/images/generate",
|
||||
json = {"prompt": "p", "seed": 2**53 - 1, "batch_size": 2},
|
||||
)
|
||||
assert over.status_code == 422
|
||||
# The top-of-batch seed lands exactly on the cap: still JSON-safe, so accepted.
|
||||
ok = client.post(
|
||||
"/api/inference/images/generate",
|
||||
json = {"prompt": "p", "seed": 2**53 - 2, "batch_size": 2},
|
||||
)
|
||||
assert ok.status_code == 200
|
||||
|
||||
|
||||
def test_non_gguf_load_restricted_to_unsloth(client):
|
||||
# gguf_filename is optional now; with none, the load is a full-pipeline kind, which
|
||||
# is gated to unsloth/* repos. A non-unsloth repo (no filename) is rejected -> 400.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue