/
06.09.2026 at 08:20 am
Cuttings

Fitting LLMs and Image Generation Models Onto One RTX 4090

Concurrently running Qwen 3.8-27B (with 262K context) plus InvokeAI.
Table of Contents

I like having two things simultaneously loaded in memory at all times:

Unfortunately, having both loaded on the same GPU often turns into a VRAM budgeting exercise.

Yes, my RTX 4090 has substantial VRAM for one card - 24 GB. But a modern 27B-class LLM model - and I'm now using Qwen 3.8 - can consume most of that delicious VRAM, before the image model even starts loading.

FINAL RESULTS

But a recent round of tuning LM Studio on a Ryzen 9 7950X3D system with an RTX 4090 produced a surprisingly effective compromise:

And best of all? No need to reduce GPU model offload.

The key for me was to decide which parts of inference actually deserved precious GPU memory. Here's how I went about it.


My Starting Problem: VRAM Gobbled Up

GPU utilization and VRAM allocation are separate problems. (A model can sit at 1% GPU utilization while still holding nearly all available VRAM.)

My initial configuration used roughly 22 GB of VRAM for LM Studio alone. That left barely more than 1 GB free on a nominally 24 GB card.

That meant InvokeAI had nowhere useful to load Z-Image Turbo.

My first instinct was to reduce GPU offload, and push transformer layers onto the CPU. That does free memory. But it also attacks inference speed, which I'm trying to prioritize.

Moving the KV Cache Out of VRAM

LM Studio exposes a setting called:

Offload KV Cache to GPU Memory

Turning that off moved the KV cache into system RAM. I didn't really know what that was, but I clicked it.

The effect was immediate: LM Studio's VRAM consumption dropped by roughly 4.5 GB, from around 22 GB to about 17.5-18 GB.

Wow. Now model weights and transformer computation could remain on the RTX 4090, while the growing attention cache lived in ordinary RAM. (And I had room to spare, with 64 GB RAM mostly unused.)

The architecture effectively became:

RTX 4090
├── Qwen 3.8 - 27B
└── InvokeAI / Z-Image Turbo

System RAM
└── KV cache

This was a good start.

The Surprising Result: I Could Now Reach 262K Context

Initially, my model was configured for about 16K context, because the KV cache was on GPU.

Once the KV cache was moved out of VRAM, it became possible to increase the configured context all the way to 262,144 tokens.

Yes. I maxed it out. While still running InvokeAI alongside it.

I then kept testing. The final practical result was better than my original configuration in every useful sense:

BEFORE:

- 16K context
- ~23 GB LM Studio VRAM use
- InvokeAI effectively excluded

AFTER:

- 262K context
- ~19-20 tok/s
- ~20 GB LM Studio VRAM use
- InvokeAI running simultaneously
- GPU model offload retained

Speculative Decoding Was Not Necessarily Better

LM Studio supports speculative decoding through MTP, so I tested it:

MTP setting Generation speed
Off 17-20 tok/s
2 draft tokens ~19-21 tok/s
3 draft tokens ~18-19 tok/s
5 draft tokens ~14 tok/s


At 2x draft tokens, I got a small 'win' - +1 token.

But then I encountered something I didn't like: lack of smoothness. With MTP disabled, generation felt less jerky and more consistent. There were fewer 'bursts'.

(Arguably this doesn't matter if you're not staring while generation is going on. But I now realize that in local inference tuning, the highest reported token rate is not always the best interactive experience. Hmm.)

I still use MTP with my other models, but I eventually disabled MTP for this config.

Batch Size Affects Waiting Before Generation

Another useful discovery was with Evaluation Batch Size and Physical Batch Size.

Increasing batch size can make the first prefill phase much faster.

Larger evaluation batches let the GPU process more prompt tokens in larger chunks during prefill. (Which is kind of important for agentic workloads.) And so we can reduce time to first token.

I tested successfully with:

Evaluation Batch Size: 4096
Physical Batch Size:   2048

I've looked it up, and my config seems more aggressive than many default configurations. But on my RTX 4090 setup, it worked. And it didn't destabilize my other GPU workload with InvokeAI.

CPU Thread Count Didn't Feel Different

My machine uses an AMD Ryzen 9 7950X3D, with 16 physical cores and 32 threads.

Since the KV cache was now living in system RAM, I wondered if CPU thread tuning would matter substantially. It didn't (for me).

I tested several thread counts. 16 threads performed best, but I felt no real difference.

KV Cache Quantization: Q4 Versus Q8

I also tested KV-cache precision.

I found no obvious speed difference between Q4 and Q8 in my testing. Since I had enough system RAM and wasn't gaining anything noticeable from the lower precision, I preferred to keep Q8_0 for both K and V cache, rather than trade away precision unnecessarily.

My final configuration in the end was this:

K cache: Q8_0
V cache: Q8_0

The Final Configuration

My resulting LM Studio configuration was approximately this - which I deem optimal for my needs:

Context Length              262144
GPU Offload                 65

CPU Thread Pool Size        16

Evaluation Batch Size       4096
Physical Batch Size         2048

Unified KV Cache            ON
Context Checkpoints         8

Offload KV Cache to GPU     OFF

Keep Model in Memory        ON
Try mmap()                  ON

Speculative Decoding        OFF

Flash Attention             ON

K Cache Quantization        Q8_0
V Cache Quantization        Q8_0

My Tradeoffs (Why I Avoided Reducing Gpu offload)

I am looking for maximum useful work from the whole machine. As such:

  1. Reasonable inference speed matters more to me, even if reducing GPU offload would have freed additional VRAM. As long as the LLM weight and loaded InvokeAI models fit comfortably enough on one GPU, and perform reasonably speedily (and they do), I'm happy with the arrangement.

  2. I'm not obsessing over using every last gigabyte of VRAM. I observed peak VRAM usage of around 20-22 GB with both Qwen and Z-Image Turbo active. That leaves me with about 2-3 GB of usable VRAM, which is tempting. But workloads can spike or need transient allocations, and I'd rather have room to breathe with a mixed load.

  3. Now my system RAM absorbs the expandable context cache, while the RTX 4090 handles what it is exceptionally good at: smarter models, and image generation. My tuned system delivers:

    • roughly 20 tok/s;

    • a 262K context window;

    • simultaneous image generation;

    • fast large-context prefill;

    • and a smoother interactive experience.

Even if a narrowly configured LLM-only benchmark could produce a higher number, I've reached an 'optimal' machine setup in practical terms. And so I'm staying with this setup for now.

Filed under:
#
#
Words: 1229 words approx.
Time to read: 4.92 mins (at 250 wpm)
Keywords:
, , , , , , , , ,

Latest Comments

© Wan Zafran. See disclaimer.