Iris-3B: an open image model that draws its own pixels, about two seconds a picture

Iris-3B is an open image model that draws pixels itself. We ran its fast Turbo version on InferenceKey: about 2 seconds a picture on an A40.

On 5 October Sperid Labs released Iris-3B on Hugging Face and GitHub, an open image model that draws every pixel of the picture itself. The models it compares itself with, FLUX and Qwen-Image among them, do not: they sketch a compressed version and a separate decoder turns it into pixels.

Their paper also built two extra tools on the model, one that estimates depth and one that restores photos, and its abstract says that working in pixels gave no clear gain on either.

On 12 October they added a fast "Turbo" version that finishes a picture in 4 passes instead of 100 (these models start from random noise and clean it up a little on each pass). We spotted it in the AI Search news video of 11 October, read the sources and ran Turbo ourselves on a rented GPU, served through InferenceKey. Here is what a reader can take away before the details:

Iris-3B Turbo
LicenseApache-2.0 for code and weights: you can use it commercially, change it and redistribute it
Size3 billion parameters (the learned numbers inside the model, a rough measure of its size), plus a 4-billion-parameter model that reads the prompt
Download you needabout 6 GB for Turbo, plus about 9 GB for the prompt reader. Not the whole 42 GB repo
GPU memory, measuredabout 21 GB loaded, about 23 GB at peak: just under a 24 GB gaming card (untested), comfortable on the 48 GB card we used
Time per 1024x1024 picture, measured on an NVIDIA A401.96 s on the GPU, about 2.9 s end to end through the API
Same picture with the 100-pass base modelabout 90 s
First start, from "deploy" to ready for the first picture (GPU machine already online)about 2 minutes (130 s)
Where it falls short in our testa menu with four prices, extra hands on a pianist, a cat that did not show up

Here is why I care. The common way to put generated pictures in a product is a hosted API that charges per picture. An Apache-2.0 model this small is one you can run on a rented GPU yourself: you keep the weights, you choose when the version changes, you know where the prompts and pictures go, and you pay for the card's time instead of per picture. It is not the best open image model on quality, and we say where it falls short below, but it is a real option if you want to own the model rather than rent pictures from someone else.

Most image models work on an MP3 of the picture

The usual recipe goes like this. A small helper network squeezes each image into a compact code, a bit like an MP3 squeezes a recording. The big model learns to draw in that code, which is much cheaper than drawing every pixel, and the helper expands the result back into a full picture at the end. Call them compressed-image models: those are the ones Sperid Labs compares Iris against.

Sperid Labs' research page argues against the MP3. Compression loses detail, they write, and the compressed code is "biased" and "texture-focused": it is tuned to the look of surfaces more than to exact detail. Their target is tasks where fine detail matters, such as estimating depth from a photo or restoring a low-resolution one. So Iris-3B skips the MP3 and works on the master: it cuts the picture into tiles of 16 by 16 pixels, works on those tiles directly, and a small final stage turns each tile back into real pixels. The authors borrowed the design of that last step from another research group (credited below). There is no separate decoder and no compressed space.

The prompt is read by a separate model, Qwen3-VL-4B-Instruct from Alibaba's Qwen team, also Apache-2.0, which Iris downloads on its first run.

The authors' own verdict: no clear gain from pixels

The paper's abstract states its finding plainly: "We find no significant improvement from using a pixel-space generative prior." In plain words: building the depth and photo-restoration tools on a pixel model did not make them any better than building them on a compressed-image model. They tested it on two jobs against FLUX.2 Klein, a compressed-image model of similar size (4 billion parameters). On depth the two tied. On enlarging photos 4 times, Iris-3B did not beat FLUX.2 Klein.

For plain picture-making, the paper says Iris-3B scores level with Qwen-Image, a model about seven times its size (20 billion parameters), on a general test of how well pictures follow their prompts (OneIG in the table below). The other column, LongText, scores how well the model writes a sentence or more into the picture.

ModelLongText (EN)OneIG (EN)
Iris-3B (base)0.8570.540
Iris-3B Turbo0.8040.516
Qwen-Image (20B)0.9430.539
Z-Image (6B, prompt rewriting)0.9350.546
FLUX.1-dev (12B)0.6070.434

Scores run from 0 to 1, higher is better. "Prompt rewriting": Z-Image's score was measured after an assistant rewrote each prompt in more detail, which helps it. The Iris rows were measured by Sperid Labs. The other rows are quoted on their research page from the Qwen-Image and Z-Image reports. None of it was reproduced by us. More rows and two more columns are in the engineers' section.

Look at the LongText column: Iris-3B gets 0.857 where Qwen-Image gets 0.943. Iris-3B is clearly behind Qwen-Image and Z-Image there, and Turbo is a little behind its own base model. That matches what we saw with a price menu further down. The AI Search reviewer put it more bluntly: quality "not as good as the leading open models out there", but "a decent lightweight alternative". We did not run a compressed-image model on the same prompts, so this quality comparison is the vendor's tables and one reviewer's opinion, not our pictures.

One network, three jobs

The same Iris network, retrained a little for each job, also ships as two other tools in the same download. One estimates depth from a single photo (how far each point is, relative to the others, not in metres). The other, a photo enlarger, enlarges a photo 4 times and restores its detail, working tile by tile. Both run in a single pass with no prompt and no text model. Sperid Labs reports scores for both on standard test sets, listed in the engineers' section. We did not test either of them.

Turbo: four passes instead of a hundred

The base Iris-3B uses 100 passes, and each pass runs the model twice (once with your prompt and once without, so it can push the picture toward the prompt), which makes it slower still. Turbo is the whole model retrained to finish in 4 passes of one run each. Sperid Labs says Turbo makes a 1024x1024 picture in about 0.7 seconds on an H100, Nvidia's top data-centre GPU, when it makes four at a time. We did not test that card. The trade, by their own list of limits: Turbo is weaker than the base model on dense or long text, gives less variety when you ask for the same prompt several times, and can leave a faint grain on flat backgrounds.

Sperid Labs was not first to make Iris fast. Their own model card thanks pentacoxian-dev, who built iris-3b-turbo-lora, a 4-pass version packaged as a small 460 MB add-on and trained on a single consumer GPU. It has its own row in the benchmark table on Sperid Labs' model card. We ran Sperid Labs' Turbo, not this one.

The 42 GB trap

If you clone the Hugging Face repo you get four models: the base model (about 12 GB), Turbo (about 6 GB), the depth model (about 12 GB) and the photo enlarger (about 12 GB). That is 41.9 GB in total. To make pictures fast you only need Turbo:

hf download speridlabs/iris-3b --include "turbo/*" --local-dir iris-3b

The prompt reader, Qwen3-VL-4B-Instruct, comes on top: another 8.88 GB, fetched automatically the first time the code runs.

Running it on InferenceKey

Turbo was serving pictures through the InferenceKey API about two minutes after the deploy call (on a GPU machine that was already online), at about 2 seconds of GPU per 1024x1024 image. Here is how, and what went wrong on the way.

The GPU and why that one

We rented an NVIDIA A40 with 48 GB of memory on RunPod, in an EU data centre. The obvious choice for a "3B" model would be a cheaper 24 GB gaming card such as an RTX 4090. We skipped it because of how the authors' code loads the model: it stores every number of the 3B network at double the size the file ships in, which takes about 12 GB, and the prompt reader adds about 8 GB more. Turbo alone measured about 21 GB loaded and about 23 GB at peak. We have not tried a 24 GB card, so whether Turbo fits on one in practice is open. The 48 GB card also let us load the 100-pass base model next to Turbo for a side-by-side.

For your own economics: at the A40's RunPod list price, a thousand Turbo pictures made four at a time is about 29 minutes of the card, roughly 30 US cents, not counting start-up and idle time. You pay for the card's time instead of paying per picture, and you pick the model, not a provider.

Why a custom backend

A backend is the piece of code that loads a model once and then answers requests. InferenceKey ships ready-made backends for the usual ways image and text models are packaged, but Iris-3B comes in its own format, so none of them can run it. So we wrote our own in Python, which InferenceKey lets you bring. Ours is about 5 KB, no weights inside. On start-up it downloads a fixed version of the authors' code, fetches only the Turbo folder from Hugging Face, and loads the model the same way the authors do. It answers the same /v1/images/generations request shape that OpenAI's image API uses, so any client that speaks that format can call it.

We ran it on a private test copy of InferenceKey, with the rented GPU connecting back to it, so nothing here touched our production service. The company name you see in the video, Lumenframe Studio, is a made-up demo account.

The steps

Everything is in the SDK example iris3b-text2image-custom-backend-private-nvidia. You need an InferenceKey account with an NVIDIA worker (a GPU machine connected to your project). The example's .env file lists the keys it reads. You can also upload the backend by hand in the dashboard. The SDK is built locally from the repo, so the README's setup steps come first:

cp .env.example .env        # SDK token, API key, project, worker id, tenant id, dashboard session token
python -m venv .venv && . .venv/bin/activate
pip install maturin requests
( cd ../../bindings/python && maturin develop --release )
python publish.py           # packages backend.py and registers it as "iris3b-text2image"
python main.py              # deploy, wait until ready, generate two images, clean up

main.py asks InferenceKey for one always-on copy of the model on your worker, waits until it is serving, sends two pictures' worth of requests, saves the PNGs and deletes the running model (the workload) on exit (set IK_KEEP_ALIVE=1 to keep it). For the 100-pass base model, python publish.py --variant base and then IRIS_VARIANT=base python main.py. Below is the same request shape we sent to our local copy of InferenceKey, with the bee's prompt and seed from the pictures further down. On the hosted service it has the same shape, though we did not call it there:

curl https://cloud.inferencekey.com/endpoint/$INFERENCEKEY_PROJECT/iris3b-turbo/v1/images/generations \
  -H "Authorization: Bearer $INFERENCEKEY_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "default", "prompt": "Macro photograph of a honeybee covered in pollen on a lavender flower, shallow depth of field", "size": "1024x1024", "seed": 110, "n": 1}'

What we measured

The first start took 130 seconds from the deploy call to ready. Setting up the Python environment took 16 seconds and downloading Turbo's 6 GB model file took 12. Most of the rest was the prompt reader: about 72 seconds to download it, then about 27 seconds to load both models onto the GPU.

Once it was running, a 1024x1024 picture took 1.96 seconds on the GPU every time, and 2.8 to 2.9 seconds from request to finished PNG back at the caller. Larger, non-square sizes such as 1344x896 took 2.2 to 2.9 seconds of GPU. Four pictures in one request took 7.0 seconds, 1.75 seconds each. The vendor quotes 0.7 seconds each on an H100. We did not run that like-for-like test. The image tester in the InferenceKey panel showed 2.9 seconds per picture.

The base model, with its 100 passes, took about 90 seconds per 1024x1024 picture and 106 at 1344x896. That is about 46 times slower than Turbo. With both loaded on the same card, they used nearly all of its 48 GB at peak.

The pictures

Turbo did well on photos, styles and short text. These are straight from the API, 4 passes each:

Macro photograph of a honeybee covered in pollen on a lavender flower, generated by Iris-3B Turbo

"Macro photograph of a honeybee covered in pollen on a lavender flower, shallow depth of field". 1024x1024, 1.96 s on the GPU.

Flat vector travel poster of a yellow Lisbon tram climbing a steep street, with the word LISBOA at the top, generated by Iris-3B Turbo

A flat vector travel poster. The word LISBOA came out spelled right. 896x1344, 2.65 s.

Studio portrait of an elderly fisherman with a thick grey beard and deep wrinkles, generated by Iris-3B Turbo

An elderly fisherman, film-photo style. 896x1200, 2.77 s.

It also got "OPEN LATE" right on an enamel sign, and drew exactly seven apples when asked for seven. Three prompts went wrong. In the panel, "a lighthouse keeper's cat asleep on a windowsill, stormy sea outside, oil painting" gave the window and the lighthouse but no cat that we could see. We asked for "two hands of a pianist" and got the two on the right, plus a third hand at the lower left and part of another at the top-left edge (that one may be a reflection in the black lacquer).

Close-up of a pianist's hands on a grand piano, with a third hand at the lower left and part of another at the top-left edge, generated by Iris-3B Turbo

"Close-up of two hands of a pianist playing a grand piano". Look at the lower left. 1344x896, 2.83 s.

And a chalkboard menu with four prices was too much. Turbo dropped the decimal points ("Cappuccino 320", "Daily soup 550"). The base model, in 90 seconds instead of 2, put the decimal point in three of the four prices. Cappuccino still came out as 320, and it wrote the espresso price and the croissant line twice.

Side by side chalkboard menus. Left, Turbo in 4 steps and 2.0 s: Cappuccino 320 and Daily soup 550. Right, base in 100 steps and 90 s: Espresso 2.50 and Daily soup 5.50 right, but Cappuccino 320, a repeated 2.50 and a repeated Croissant 2.00 line

Same prompt and seed, Turbo on the left, base on the right. The prompt asked for "Espresso 2.50, Cappuccino 3.20, Croissant 2.00, Daily soup 5.50".

On a photo without text, the two are hard to tell apart at a glance, which is the point of Turbo:

A red fox asleep in fresh snow, Turbo in 4 steps and 2.0 s on the left, base in 100 steps and 90 s on the right

Same prompt and seed. 2 seconds against 90.

The demo

The 72-second recording below is the InferenceKey panel during the test: both Iris workloads running on the A40 (named a40-render-01), the image tester making the bee and the "OPEN LATE" sign in 2.9 seconds each, and the live view with eight requests going through.

InferenceKey panel image tester showing the honeybee picture generated by Iris-3B Turbo. Click to play the demo video

Click the image to play the MP4 (72.5 s, 7.4 MB).

What went wrong, and one thing that went right

Turbo ran end to end, and the panel's image tester and live view worked with our backend unchanged. On the way we hit four rough edges on the InferenceKey side, none of them fatal. Numbers 1, 3 and 4 are how the platform works today, so they will happen again. Number 2 we saw once, in one run:

  1. A too-big answer became a five-minute wait. Two PNG pictures in one request added up to 9.1 MB, more than the 8 MB limit for a single message inside InferenceKey. The worker knew at once and dropped the result, but the caller only got a generic timeout after about 5 minutes. Our example now refuses that case straight away with a clear error and offers JPEG or WebP, where four pictures fit in 688 KB.
  2. "Ready" came 50 seconds early. With two models on one worker, the SDK's wait-until-ready reported the base model ready after 10 seconds. The "ready" it saw actually came from Turbo, which was restarting with our updated code on the same GPU. No request was lost: the first one waited in the queue until the base model was up.
  3. No settings per workload. A custom backend cannot be told "run the base model this time" from the workload's settings. We published the base model as a second backend under its own name instead.
  4. A fixed start-up limit. A custom backend gets 300 seconds to become ready, and on a rented GPU machine that InferenceKey sets up for you, there is no way to raise it. Ours took 113 seconds, but a slower download could hit the limit.

The thing that went right: when we fixed problem 1 and published the backend again, InferenceKey noticed the change and restarted the running model with the new code by itself, in 23 seconds, with no manual step.

Who did what

Iris-3B is Sperid Labs' work: the model, the Turbo version, the depth and photo-enlarging versions, the training scripts, the public demo and the paper by Hanqiu Li Cai and Chema Garabito. The first fast, 4-pass Iris came from the community: pentacoxian-dev built iris-3b-turbo-lora on a single consumer GPU. Qwen3-VL-4B-Instruct, the model that reads the prompt, is from Alibaba's Qwen team. The stage that turns each tile into pixels follows the design of PixelDiT, another group's model (the authors wrote their own code for it). The training also builds on published methods from other groups, including an image model from Meta (DINOv2) used as a guide early in training. The full list is in the engineers' section. AI Search's news video is where we first heard of it.

Our part: reading the sources, writing the custom backend and the SDK example, running it on InferenceKey, measuring it and recording the demo.

What to take away

If you need an open image model that you can use commercially and that makes a 1024x1024 picture in about 2 seconds on a rented 48 GB A40, Iris-3B Turbo is worth a test. Download the Turbo folder, not the repo. Keep your expectations honest on long text and on hands, and try your own prompts before you commit: the vendor's benchmarks and the AI Search review both put it behind the best open models, and we did not run one of those side by side. The pixel-space idea is interesting research, and the authors are the first to tell you it did not win the comparison they set up.

The question we left open is the cheap card. Turbo peaked at about 23 GB on the A40. Whether it runs on a 24 GB RTX 4090 is one python main.py away on a worker that has one.

For engineers

Model (GitHub README, research page, paper). 3B diffusion transformer working in pixel space: no VAE and no latent space (the "helper network" and "compressed code" of the narrative). 24 blocks at width 2560 (8 dual-stream + 16 single-stream), GQA 20 query / 5 KV heads, patch size 16, a 4-block pixel-transformer (PiT) head that follows the design of PixelDiT's (an independent implementation, no PixelDiT code) decodes each patch token to pixels. Rectified flow, v-prediction, logit-normal timesteps. 2D RoPE, so one set of weights runs at any aspect ratio up to about 1 MP. Text encoder: frozen Qwen3-VL-4B-Instruct, 12 hidden layers combined by a learned layer-attention adapter. Paper: "Iris-3B: Going Beyond the Latent with Pixel-Space Diffusion Training, Conversion and Fine-Tuning", arXiv 2610.09450 v1, 7 October 2026, 19 pages (we read the abstract, not the full text).

Training. From scratch, 256 -> 512 -> 1024 px, then SFT at 1024: 665K steps (stage 1 to 365K at batch 1024 with REPA on DINOv2-B/14, stage 2 to 530K, stage 3 to 625K at batch 512, SFT 625K-665K). Muon + AdamW, bf16, FSDP2, torchrun --nproc_per_node=8. Training scripts are released. GPU hours are not stated (the research page only says "a fraction" of latent models' compute).

Base sampling. 1024x1024, 100 DPM-Solver++ (order 2) steps, CFG 3. python scripts/sample.py --checkpoint iris-3b --prompt "...", flags --steps --seed --negative-prompt --txt-file --cfg-scale.

Turbo. Full fine-tune of all 3B parameters (not a LoRA) with Trajectory Distribution Matching, data-free, two stages (6 steps for 1,600 updates, then 4 steps for 500). CFG 3.5 baked in from the teacher, no CFG or negative prompt at inference, fixed sigmas 1, 0.938, 0.833, 0.625. Seven aspect buckets around 1 MP: 1024x1024, 752x1344, 896x1344, 896x1200 and their transposes. Weights exported in bf16, upcast to FP32, run under BF16 autocast. Python API iris3b.sampling.generate_few_step. Community alternative: iris-3b-turbo-lora by pentacoxian-dev, a 4-step DMD2 distillation as a rank-64 LoRA (460 MB), not tested by us. Vendor-listed limits: weaker on dense or long text than base, less seed variety, possible faint grain on flat vector backgrounds, fixed 4 steps. In general, text rendering and exact counts are not always reliable.

Credits for methods. The DiT architecture, the design of PixelDiT's PiT head for decoding patches to pixels, the Muon optimizer through Microsoft's Dion, REPA with Meta's DINOv2-B/14 features in base training stage 1, the DPM-Solver++ sampler for the base model, Trajectory Distribution Matching for Turbo, the HYPIR recipe for the upscaler and the Marigold V2 protocol for scoring depth.

Benchmark table (selected rows). Iris rows run by Sperid Labs with official evaluators at 1024², no prompt rewriting, no best-of-N. The other rows are quoted on the research page as references from the Qwen-Image and Z-Image reports. The research page also lists SDXL, SD3 Medium, SD3.5 Large and Lumina-Image 2.0, not copied here. The community LoRA row is from the HF card and GitHub README.

ModelGenEvalDPGLongText ENOneIG EN
Iris-3B0.79886.520.8570.540
Iris-3B Turbo0.82086.680.8040.516
iris-3b-turbo-lora r2-1000 (community)0.76085.050.7330.486
Qwen-Image 20B0.8788.30.9430.539
Z-Image 6B (prompt rewriting)0.8488.10.9350.546
HiDream-I1-Full0.8385.890.5430.477
Janus-Pro-7B0.8084.190.0190.267
FLUX.1-dev 12B0.6683.80.6070.434

Fine-tunes (vendor numbers, not tested by us). Depth (depth/, about 12 GB): relative log depth, affine-invariant, 10K steps, AbsRel 0.071 and delta1 0.946 averaged zero-shot over NYUv2, KITTI, ETH3D, ScanNet and DIODE (Marigold V2 protocol), scripts/depth.py photo.jpg --out depth_out. Upscaler (upscaler/, about 12 GB): one-step adversarial restoration (HYPIR recipe), 10K steps, 4x, LPIPS 0.292 and PSNR 20.68 on DIV2K val, 1024x1024 tiles at stride 512 with Gaussian blending, output capped at 2048x4096 (21 tiles) by default, scripts/upscale.py photo.jpg --out upscaled. Both run one forward pass with an empty prompt and no text encoder. The Gradio demo with all three models needs about 45 GB, about 20 GB at peak with IRIS_OFFLOAD=1. The HF Space runs on ZeroGPU.

Files (HF API, 2026-10-12): root model.safetensors 11,950,112,680 B (fp32 base), turbo/model.safetensors 5,975,089,200 B, depth/model.safetensors 11,952,738,184 B, upscaler/model.safetensors 11,950,112,680 B, whole repo 41,911,753,317 B. Qwen3-VL-4B-Instruct safetensors 8.88 GB. Requirements: Python 3.11+, PyTorch 2.7.1+, NVIDIA GPU with CUDA.

Our setup. RunPod NVIDIA A40 48 GB, SECURE, EU-SE-1, 0.59 USD/h with 100 GB disk, image runpod/pytorch:1.0.2-cu1281-torch280-ubuntu2404, driver 580.159.03 (CUDA 13.0). Worker bootstrapped by a local InferenceKey manager over HTTP + TCP tunnels. RTX 4090 COMMUNITY listed at 0.34 USD/h at the time. Pod created 21:07:30Z (worker online about 21:08:40Z), deleted 21:33:35Z. Backend venv: Python 3.12.3, torch 2.14.1+cu130, transformers 5.19.0, installed by uv. Upstream code pinned at 73bcdf59 (a later docs commit, cee0c13, landed the same day and was not tested).

Backend (backend.py). A custom backend because Iris-3B is neither a Diffusers pipeline nor a GGUF file, the formats the built-in backends load. Slugs iris3b-text2image (Turbo) and iris3b-base-text2image (base), package 5,209 to 5,800 bytes. setup() downloads the upstream tarball at the pinned commit (about 1 MB), snapshot_download of turbo/* (or config.yaml + model.safetensors for base), builds IrisDiT on the meta device, loads weights, upcasts to fp32, builds the Qwen3-VL encoder. process() accepts native input or the OpenAI images JSON, snaps Turbo sizes to the 7 buckets, draws the noise on the CPU from the seed (the same starting noise on any GPU), runs generate_few_step (Turbo) or generate (base, 100 steps, CFG 3) under bf16 autocast, returns {data: [{b64_json}]}. n 1 to 4, output_format png, jpeg or webp, PNG with n > 1 answers 400. SDK example commit 05869ee on main.

Measurements (GPU time = backend-measured with cuda.synchronize(), round trip = HTTP client to the manager, including encoding and NATS):

CaseGPU sRound trip s
Turbo cold start, ensure() to ready130 (venv 16, upstream code + Turbo download 12.2, encoder download ~72, loading both models ~27)
Turbo first two calls, 1024x1024 / 1344x7523.45 / 2.755.80 / 3.73
Turbo 1024x1024, 5 prompts1.956 to 1.9612.83 to 2.92
Turbo 1344x7521.912.79 to 2.83
Turbo 1344x8962.21 / 2.833.46 / 3.84
Turbo 896x1200 / 1200x896 / 896x13442.77 / 2.87 / 2.653.76 / 3.83 / 3.71
Turbo n=4, 1024x1024, JPEG7.02 (1.75 per image)7.41 (688 KB)
Turbo, 8 sequential JPEG requests2.10 to 2.25
Turbo, panel image tester2.86 and 2.92
Base 1024x1024, 100 steps, CFG 389.8 / 90.0
Base 1344x896106.1

Base start-up with the encoder cached: ready 60 s after ensure() (weights 42.7 s, load 11.4 s). VRAM from nvidia-smi every 0.5 s: Turbo 20,384 MiB loaded, 21,831 MiB peak (19.9 / 21.3 GiB, or 21.4 / 22.9 GB). Turbo + base 40,455 MiB loaded, 44,890 MiB peak (39.5 / 43.8 GiB). Max board power 308.8 W against a 300 W limit.

Platform issues, exact.

  1. n=2 PNG at 1024x1024 = 9,097,397 bytes, over the 8,388,608 byte NATS max payload. Worker: job result refused by JetStream for good (code max_payload: ...); the result is given up and the job is acked. Client: HTTP 504 inference_timeout after about 300 s. The worker knows at once, the gateway only finds out by timing out. Mitigated in the example (400 in 0.08 s).
  2. wait_until_ready("iris3b-base") returned at +10 s while the base backend became ready at 21:19:52. The event it saw was Turbo's hot recycle on the same worker. First base round trip 141 s (about 50 s in queue + 90 s generation).
  3. The worker spawns python -m inferencekey.backend.serve --port N --backend <entrypoint> with no --config-json, so a custom backend gets no per-workload config. Workaround: a second entrypoint class, Iris3BBaseText2ImageBackend, under its own slug.
  4. INFERENCEKEY_CUSTOM_BACKEND_READY_TIMEOUT_SECS defaults to 300 s and cannot be set on manager-provisioned RunPod pods. This setup took 113 s.

Positive: re-publishing the backend hot-recycled the running workload in 23 s (custom backend artifact changed for a running workload; recycling its backend).

Limits.

  • One GPU model (A40), one run, one seed per prompt.
  • One client sending requests one after another (the 8 "live" requests were sequential), and one workload serving traffic at a time. No concurrency or throughput-under-load test. We did not test a 24 GB card, so whether Turbo fits on an RTX 4090 or A5000 in practice is open.
  • The vendor's 0.7 s per image on an H100 at batch 4 was not reproduced. Our 1.75 s per image at batch 4 is on an A40 and is not a like-for-like check.
  • Quality judgments are ours, from looking at every image we made, one seed per prompt. We did not run a compressed-image (latent) model such as FLUX, Z-Image or Qwen-Image on the same prompts, so the quality comparison with them is the vendor's tables and one reviewer's opinion. Seed variety and grain on flat backgrounds were not evaluated.
  • Depth and upscaler scores, benchmark scores and the paper's findings are Sperid Labs' claims. We read the abstract of the paper, not the full text.
  • The AI Search review said the 12 GB base model "should fit on most consumer GPUs". With the authors' fp32 upcast and the text encoder, Turbo alone measured 20,384 MiB (19.9 GiB) loaded, so plan for more than the file size.

Sources: Iris-3B model card, GitHub repo, paper, research page, HF Space, SDK example, AI Search video (chapter at 36:35).