SDXL 四款 GPU 實測比較:RTX A6000、L40S、RTX 5090 與 H100 的生成速度及成本
SDXL images per dollar on four GPUs: RTX A6000, L40S, RTX 5090 and H100, eager vs torch.compile
Runcrate 團隊以相同 SDXL 設定實測四款 GPU,測試中每 1,000 張圖像的最低成本分別為 RTX A6000 $0.91、RTX 5090 $0.93、L40S $1.01 及 H100 PCIe $1.80。
How many SDXL images does a dollar buy on a rented GPU? It depends on the card, the batch size and whether you pay for torch.compile, so I measured it. Today (2026-10-27) I rented four single-GPU machines on Runcrate, ran the same SDXL script on each, and terminated them as soon as the numbers were on disk.
Short version: an RTX A6000 made 1,000 images for $0.91, an RTX 5090 for $0.93, an L40S for $1.01 and an H100 for $1.80. The H100 was the fastest by far, 1.67 s per image against 4.94 s on the A6000, and the most expensive per image.
Setup
-
Model:
stabilityai/stable-diffusion-xl-base-1.0, fp16 weights, with themadebyollin/sdxl-vae-fp16-fixVAE. Base model only, no refiner. - Image: 1024 x 1024, 30 steps, the pipeline's default scheduler and guidance, one fixed prompt ("a photo of an astronaut riding a horse on a beach at sunset, detailed, 35mm").
- Software: diffusers 0.42.1, torch 2.8.0+cu128, Python 3.12.
-
Four configurations per GPU: batch 1 and batch 4 (
num_images_per_prompt), each in eager mode and withtorch.compile(pipe.unet, fullgraph=True)plus channels-last memory format. One warm-up generation before each timed run; 8 images timed at batch 1, 16 at batch 4. - Machines (on-demand price at launch time):
| Runcrate GPU | VRAM | Region | $/hour |
|---|---|---|---|
| RTX A6000 | 48 GB | US Midwest | 0.66 |
| L40S | 48 GB | Des Moines, US | 1.14 |
| RTX 5090 | 32 GB | Gdansk, PL | 1.33 |
| H100 PCIe | 80 GB | Des Moines, US | 3.88 |
Cost per 1,000 images is hourly price / images per hour x 1,000, with the GPU kept busy. It does not include setup time; that is below.
The commands
Launch (one call per GPU; the instance_type_id comes from GET /api/v1/instances/types):
curl -s https://www.runcrate.ai/api/v1/instances \
-H "Authorization: Bearer $RUNCRATE_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"sdxl-a6000","instance_type_id":"<id from /instances/types>",
"ssh_key_id":"<your key id>","max_runtime_minutes":50}'
On the machine:
curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=$HOME/.local/bin:$PATH
uv venv --python 3.12 /opt/env && . /opt/env/bin/activate
uv pip install torch diffusers transformers accelerate safetensors --torch-backend=cu128
python sdxl_bench.py
The core of sdxl_bench.py:
vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16)
pipe = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", vae=vae,
torch_dtype=torch.float16, variant="fp16", use_safetensors=True).to("cuda")
def run(batch, n_batches):
pipe(PROMPT, num_inference_steps=30, height=1024, width=1024, num_images_per_prompt=batch) # warm-up
torch.cuda.synchronize(); t = time.time()
for _ in range(n_batches):
pipe(PROMPT, num_inference_steps=30, height=1024, width=1024, num_images_per_prompt=batch)
torch.cuda.synchronize()
return (time.time() - t) / (batch * n_batches) # seconds per image
run(1, 8); run(4, 4) # eager
pipe.unet.to(memory_format=torch.channels_last)
pipe.unet = torch.compile(pipe.unet, fullgraph=True)
run(1, 8); run(4, 4) # compiled
Then DELETE /api/v1/instances/<id> and a check that the instance list is empty.
Results
| GPU | Config | Seconds per image | Images per hour | $ per 1,000 images | Peak VRAM |
|---|---|---|---|---|---|
| RTX A6000 | eager, batch 1 | 5.79 | 622 | 1.06 | 9.0 GB |
| RTX A6000 | eager, batch 4 | 5.65 | 637 | 1.04 | 14.6 GB |
| RTX A6000 | compiled, batch 1 | 4.94 | 728 | 0.91 | 9.0 GB |
| RTX A6000 | compiled, batch 4 | 5.13 | 701 | 0.94 | 14.6 GB |
| L40S | eager, batch 1 | 3.48 | 1,034 | 1.10 | 9.0 GB |
| L40S | eager, batch 4 | 3.39 | 1,064 | 1.07 | 14.6 GB |
| L40S | compiled, batch 1 | 3.21 | 1,121 | 1.02 | 9.0 GB |
| L40S | compiled, batch 4 | 3.19 | 1,130 | 1.01 | 14.6 GB |
| RTX 5090 | eager, batch 1 | 2.77 | 1,301 | 1.02 | 9.0 GB |
| RTX 5090 | eager, batch 4 | 2.66 | 1,355 | 0.98 | 14.6 GB |
| RTX 5090 | compiled, batch 1 | 2.53 | 1,424 | 0.93 | 9.0 GB |
| RTX 5090 | compiled, batch 4 | 2.53 | 1,421 | 0.94 | 14.6 GB |
| H100 PCIe | eager, batch 1 | 2.25 | 1,603 | 2.42 | 9.0 GB |
| H100 PCIe | eager, batch 4 | 1.94 | 1,853 | 2.09 | 14.6 GB |
| H100 PCIe | compiled, batch 1 | 1.80 | 2,003 | 1.94 | 9.0 GB |
| H100 PCIe | compiled, batch 4 | 1.67 | 2,156 | 1.80 | 14.6 GB |
What torch.compile costs up front (the first compiled call, measured on the machine) and how many images it takes to earn that back at batch 1:
| GPU | Compile, batch 1 | Compile, batch 4 | Saved per image (batch 1) | Break-even |
|---|---|---|---|---|
| RTX A6000 | 188 s | 255 s | 0.85 s | about 220 images |
| L40S | 82 s | 121 s | 0.27 s | about 300 images |
| RTX 5090 | 96 s | 133 s | 0.24 s | about 400 images |
| H100 PCIe | 94 s | 130 s | 0.45 s | about 210 images |
Batch 4 recompiles (new input shape), so a server that mixes batch sizes pays both.
Setup on each machine, before the first image:
| GPU | Launch to SSH | diffusers install | Model download (about 7 GB) | Pipeline load |
|---|---|---|---|---|
| RTX A6000 | 288 s | 29 s | 73 s | 3.9 s |
| L40S | 190 s | under 1 s | 24 s | 2.0 s |
| RTX 5090 | 122 s | 15 s | 25 s | 2.8 s |
| H100 PCIe | 307 s | 7 s | 27 s | 2.5 s |
What surprised me
- Three of the four cards were within 11% of each other per image, and the H100 cost about twice as much per image. The A6000, RTX 5090 and L40S landed between $0.91 and $1.01 per 1,000 images. The H100 was 3x faster than the A6000 and cost 5.9x more per hour.
- Batch 4 barely helped, except on the H100. SDXL at 1024 x 1024 already fills these GPUs with one image: batch 4 changed throughput by -4% to +4% on the A6000, L40S and 5090. Only the H100 gained (16% eager, 8% compiled). Batching mostly adds latency for the person waiting for the first image.
-
torch.compilecut the time per image by 8% to 20%, if you generate a few hundred images per process. The biggest gain was on the A6000 (5.79 to 4.94 s), which also had the slowest compile (188 s). For a one-off batch of 50 images, eager mode is the better deal. - Peak memory was 9.0 GB at batch 1 and 14.6 GB at batch 4, so SDXL base fits on any of these cards with room to spare. VRAM size did not matter for this workload; compute did.
- The model download varied 3x between machines (24 s to 73 s for the same 7 GB). For short jobs, keep the weights on a volume.
Caveats
- One run per GPU, 8 to 16 timed images per configuration. Treat differences under about 5% as noise.
- One prompt, one resolution, one scheduler, 30 steps. Fewer steps, a distilled model (SDXL Turbo, Lightning) or a different scheduler change the absolute numbers; rerun before relying on them.
- No refiner, no ControlNet, no LoRA, no xFormers or other attention kernels beyond PyTorch's built-in SDPA, no TensorRT.
- Prices are the on-demand prices at launch time on 2026-10-27 and move daily.
Reproduce it
- Create an API key and add an SSH key (
POST /api/v1/ssh-keys). - Pick a GPU from
GET /api/v1/instances/typesand launch with the curl above,max_runtime_minutesset as a safety net. - Run the block above, copy
results/back, delete the instance.
The four machines, including setup time and compile warm-ups, were billed $1.02 together ($0.17 for the A6000, $0.15 for the L40S, $0.19 for the RTX 5090, $0.50 for the H100).
If you want to run it yourself: runcrate.ai
Written by the Runcrate team, with AI assistance. The numbers come from the run described above; raw logs are kept with the post.
來源:DEV Community · dev.to