Runtime Labs

One Model. Hundreds of Specializations.

TL;DRWe discovered which 2% of a vision-language model actually needs to change, turned that 2% into an 80 MB executable artifact, and built a custom inference engine on top of vLLM that serves hundreds of those specializations against one shared model.
Runtime LabsSeptember 15, 2026Computer use

Ask a frontier model to click a button in a CRM and it will usually get close. Close is the problem.

We put nine frontier models on 139 held-out screens from a live customer-service CRM and asked each one where to click. To count as correct, the box a model predicted had to genuinely overlap the target, which is the standard object detection has used for a decade. The strongest model in the field, OpenAI's newest at the time, got 44.6% of them right.

Our 4B model got 92.09%.

Twice the accuracy of the best frontier model money can buy, on a task that amounts to clicking the right thing in a business application. It was trained on fewer than a thousand datapoints.

This is not LoRA.The training strategy behind that number is our own custom, novel method, developed in-house, and it is what makes everything below possible.

The score is not the part we are proudest of, though. The customer running that model does not train a four-billion-parameter model, does not store one, and does not serve one. They train a small, specific set of weights inside a base model that already exists, and what they end up owning is an 80 MB file. We call it a slice.

Working out which weights belong in that file, and building something a production server can actually run, took three problems worth of work:

Solve all three and a customer's model goes from 8.88 GB to 80 MB, and a hundred of them run on one GPU at once. That is the business.

92.09%Correct, against 44.6% for the best rival
<1,000Labeled screenshots in the training set
80 MBA customer's entire specialization, as one file
100Customer slices resident on one 46 GB GPU

Problem one: which layers actually matter

A 4B vision-language model has hundreds of weight tensors. Fine-tuning all of them gives you a second 8.88 GB model per customer, which is exactly the thing we are trying to avoid. So the first question is simple: which tensors actually need to change?

There is no principled answer in the literature, and the intuitive answers are wrong. Retraining the vision encoder, the conventional prescription for a new visual domain, is close to redundant: the encoder already sees what it needs to. Retraining the language side moves nine tenths of the weights and makes the model worse. The parameters that matter sit in a narrow band where the visual representation crosses into the language model, and you cannot find that band by reasoning about it. We found it by defining a taxonomy of candidate placements and training every one of them, on multiple tasks, across two model families, then measuring which held up.

The answer is a set of layers we call the junction set, between 1.5% and 2% of the model's parameters. We do not repeat that search per customer. Every new specialization trains the same known set of layers, which is why onboarding a customer is a training run rather than a research project.

Where the cut sits matters as much as how big it is. Cut at the junction and the expensive majority of the model remains identical across every customer. Cut a few layers deeper and that shared computation disappears. That placement is not just a training result; it is the architectural decision our inference engine is built around. Find the right 2%, and suddenly hundreds of specialized models can share the other 98%.

Problem two: cutting it out without breaking the model

Knowing which tensors to take is half of it. Getting them out, and back in, without perturbing the model is the other half, and it is a correctness problem rather than a performance one.

A slice is not a compressed approximation of a fine-tune, and it is not a patch applied on top of the base at inference time. It is the actual trained tensors, extracted directly from the PyTorch model state. Applying one writes those tensors directly into the corresponding parameter buffers with identical shape and dtype: no merge, no reconstruction, no arithmetic. The 8.88 GB base never moves. The ~80 MB specialization does. Restore the original tensors and the model returns bit-for-bit identical to the untouched base. We verify this at the tensor level and across a full base → slice → base decoding cycle.

That invariant is what makes our inference engine possible. The base model stays permanently resident on the GPU; switching customers means swapping ~80 MB of specialization state instead of loading another 4B model. One customer's slice leaves nothing behind for the next, and rolling back a customer means changing an artifact, not redeploying a model.

We test the opposite direction too: a swap must actually change behaviour. Slices trained on deliberately different objectives produce different answers to identical inputs, while restoring the base reproduces its original behaviour. Apply changes behaviour. Restore recovers the base exactly. Either direction takes 16 ms.

Problem three: building an inference engine for slices

This is where most of the engineering went.

Existing inference engines are built to serve one set of model weights extremely efficiently. We needed an engine that could serve hundreds of specialized models as if they were one. So we built our own inference engine on top of vLLM, keeping its high-performance CUDA execution, continuous batching and KV-cache machinery, but changing the fundamental unit of model state from a checkpoint to a slice.

The 8.88 GB base is loaded once and stays resident. Each customer's ~80 MB slice is a versioned, self-describing artifact containing the tensor payload and a manifest pinning its base revision, placement, shapes, dtypes and content hash. Our runtime validates and stages these slices, while a slice-aware scheduler decides which specialization needs to be active for each request. We swap specialization state, not models.

That changes the economics completely. A normal serving stack sees a hundred fine-tunes and thinks a hundred models. Our engine sees one model and a hundred 80 MB pieces of state. The expensive weights, execution engine and GPU memory are shared; only the tiny part that makes the model customer-specific moves.

That is the payoff of building the engine ourselves on top of vLLM: specialization becomes a runtime primitive rather than a deployment primitive. The base stays hot. The slices move. And adding another customer starts looking less like deploying another model and more like scheduling another request.

The task

The benchmark is UI grounding on a real product: the ticket-disposition workflow of a customer-service CRM, captured live while agents worked. One sample is one decision point. The input is a screenshot of the page as it looked immediately before the agent acted, plus an instruction like "open 'Assign To' and pick an agent option" or "type into 'Search sub folder' to filter L2/L3 suggestions". The model answers with JSON: an action, click or fill, and a bounding box on a 0–1000 scale.

These are not big obvious buttons. Twelve distinct intents span 269 distinct selectors, and the held-out set alone contains 42 distinct target boxes across 18 tickets: suggestion chips inside a three-level disposition folder tree, an autocomplete field that only exists after a parent selection, a callback checkbox, the tab that reveals a conversation's email body. Several targets are roughly 29 by 56 units in a 1000-unit space. Landing a cursor somewhere in the right neighbourhood of one is easy to do by accident, which is why we do not score it that way. A prediction counts only if the box it names substantially covers the element it is supposed to hit.

We split by ticket rather than by sample, smallest ticket first, so that no screenshot from a training flow leaks into evaluation as a near-duplicate.

What the field actually scored

Correct UI targets on the first attempt

139 held-out screens, same 1024px images, same prompt convention. A prediction counts only if its box overlaps the true target by at least half (IoU≥0.5).

Runtime Labs SVLM scores 92.09 percent. The best competitor, gpt-6-astra, scores 44.60. GLM-5.3-Flash 30.22, Kimi-K3 28.78, Claude Fable 5.1 28.06, GPT-5.6-sol 25.90, Gemini 3.1 Pro Preview 21.58. Runtime Labs SVLM gpt-6-astra GLM-5.3-Flash Kimi-K3 Claude Fable 5.1 GPT-5.6-sol Gemini 3.1 Pro Preview 92.1%44.6%30.2% 28.8%28.1%25.9% 21.6% 020 4060 80100 Percent of 139 held-out screens hit correctly
Runtime Labs SVLM (4B, self-hosted) Frontier and open-weight models
Data table
ModelCorrect (IoU≥0.5)
Runtime Labs SVLM92.09%
gpt-6-astra44.60%
GLM-5.3-Flash30.22%
Kimi-K328.78%
Claude Fable 5.128.06%
GPT-5.6-sol25.90%
Gemini 3.1 Pro Preview21.58%
Figure 1. A 47.5 point lead over the best model in the field, and better than three times the score of most of it. Our model is predicting the element. The rest are predicting its neighbourhood.

The rest of the picture, and it is consistent:

The full field. 139 held-out screens. Action precision is click-vs-fill correctness among responses that parsed.
ModelCorrect (IoU≥0.5)Mean IoUTight fit (IoU≥0.75)Action prec.
Runtime Labs SVLM (4B, self-hosted)92.09%0.88279.86%100.0%
gpt-6-astra44.60%0.52934.53%82.6%
GLM-5.3-Flash30.22%0.29812.95%80.6%
Kimi-K328.78%0.25111.51%79.3%
Claude Fable 5.128.06%0.36313.67%81.3%
GPT-5.6-sol25.90%0.37422.30%82.0%
Gemini 3.1 Pro Preview21.58%0.34116.55%85.3%
Claude Opus 4.8, Gemini 2.5 Computer Use and DeepSeek-V4-Flash-0731 could not be scored on overlap: the first two return a click point rather than a box, and the third rejects image input entirely.

Mean overlap is the number we find most telling. Ours is 0.882, so when our model names a box it is essentially the right box. The best competitor manages 0.529 and most of the field sits between 0.25 and 0.37. A figure around 0.3 describes a model that knows roughly which region of the screen you mean and has no idea where the element ends. For a demo that is fine. For an agent that has to click twenty-three times in a row with nobody watching, it is not.

Action precision points the same way. Ours is 100%: on every response that parsed, the model correctly told "click this" apart from "type into this". The field ran 79% to 85%. One in five actions being the wrong kind is not a rounding error in a workflow that has to run to completion.

Fewer than a thousand screens

The training set is under a thousand labeled screens. That is the whole thing. No synthetic augmentation, no contractor pipeline, no reinforcement learning stage. It is the byproduct of instrumenting a workflow that agents were already performing, captured as a side effect of the product running.

What more data bought

Same model, same training setup, same scoring. Training set scaled roughly 8×.

Training on roughly a hundred screenshots gives 62.5 percent correct; training on just under a thousand gives 92.09 percent. 025 5075 100 % 62.5% 92.1% ~100 screenshots under 1,000 screenshots Labeled training examples
Data table
Training examplesCorrect (IoU≥0.5)
~10062.50%
under 1,00092.09%
Figure 2. Scaling the training set about 8× took us from 62.5% to 92.1% correct. The early checkpoint was scored on a much smaller test set, so treat the left-hand bar as directional; the right-hand bar is the 139-screen result reported throughout.

Two things stand out. A few hundred examples already beat every hosted model in Figure 1, which means the bar for onboarding a customer is a dataset they can produce in a week of ordinary operation rather than a labeling project. And accuracy was still climbing when we stopped adding data, so we are limited by how many screens we have and not by the size of the model. The fix for the next customer is more of their screens, not a bigger model.

What this buys on one GPU

A 4B base sits in 8.88 GB resident. Each customer's slice adds about 80 MB. The base loads once and is never duplicated, so the fleet's memory footprint is set by the model, not by how many customers you have. This is the entire commercial argument, and it only works because the cut is in the right place.

GPU memory as the slice fleet grows

One shared base plus per-customer slices, against one independent fine-tuned model per customer.

A shared base plus specializations stays near 9 GB from one to ten customers, while independent models grow to 88.8 GB and exceed a single 46 GB GPU past five customers. 025 5075 100 GB Capacity of one 46 GB GPU 88.8 GB 9.68 GB 13 57 9 Customer-specific models served
Shared base + slices Independent models One-GPU capacity
Data table
CustomersShared base + slicesIndependent models
18.96 GB8.88 GB
109.68 GB88.8 GB
5012.9 GB444 GB
10016.9 GB888 GB
Figure 3. Independent models run out of card at the fifth customer. The shared-base fleet is still under 17 GB at the hundredth, with another thousand slices stageable in host memory and swapped in on demand.

Co-residency would be worth having on its own. What makes it fast is the shared remainder: because every slice is cut above the language model, the expensive part of the computation is identical for all of them and runs once for the whole batch. Different customers, different screens, different slices, one pass, different answers. Verified end to end, with nothing swapped between requests.

That is also where the latency goes. Served one at a time, each specialist costs about 1,430 ms. Batched over the shared base, total time barely moves as the batch grows, so per-request latency falls to 156 ms at a batch of ten. Nine customers get served in the time the tenth would have taken alone.

Cost and speed

A real disposition task runs about 23 steps. Priced at published rates from token counts captured off live API responses, that is what each model costs and how long it takes.

Cost of one 23-step workflow

Token usage captured from live responses, priced at each provider's published September 2026 rate.

A 23-step workflow costs about two hundredths of a cent on our own GPU, against 1.0 cents for GLM-5.3-Flash, 6.0 cents for Gemini 2.5 Computer Use, 11.7 cents for Gemini 3.1 Pro, 26 cents for Claude Opus 4.8, 28.2 cents for Kimi-K3, 31 cents for gpt-6-astra, 51 cents for Claude Fable 5.1 and 52.1 cents for GPT-5.6-sol. GPT-5.6-sol Claude Fable 5.1 gpt-6-astra Kimi-K3 Claude Opus 4.8 Gemini 3.1 Pro Preview Gemini 2.5 Computer Use GLM-5.3-Flash Runtime Labs SVLM $0.521$0.510$0.310 $0.282$0.260$0.117 $0.060$0.010$0.0002 $0$0.10 $0.20$0.30 $0.40$0.50 $0.60 Cost per 23-step workflow
Runtime Labs SVLM (self-hosted) Hosted API
Data table
Model$ / call$ / 23-step run
Runtime Labs SVLM$0.0000094$0.00022
GLM-5.3-Flash$0.00042$0.010
Gemini 2.5 Computer Use$0.0026$0.060
Gemini 3.1 Pro Preview$0.0051$0.117
Claude Opus 4.8$0.0113$0.260
Kimi-K3$0.0123$0.282
gpt-6-astra$0.0135$0.310
Claude Fable 5.1$0.0222$0.510
GPT-5.6-sol$0.0226$0.521
Figure 4. Our bar is a hairline because the number is $0.00022, derived from a sustained 32.7 requests per second on one 46 GB GPU at $1.10 an hour. Against the most accurate competitor that is 1,400× cheaper, and against the cheapest model in the field, which scores 50.36%, it is still 47× cheaper.

Speed follows the same shape, for a different reason. Hosted models burn wall-clock on reasoning tokens: GPT-5.6-sol averages 620 output tokens for a bounding box, GLM 1,517, Kimi 2,028. Ours emits a short JSON object and stops.

Average wall-clock per call, and the same figure scaled to a 23-step workflow.
ModelAvg output tokensLatency / call23-step flow
Runtime Labs SVLM~300.40 s9.2 s
gpt-6-astra1084.07 s1 min 33 s
Gemini 2.5 Computer Use245.78 s2 min 12 s
Claude Fable 5.11466.15 s2 min 21 s
Gemini 3.1 Pro Preview22711.83 s4 min 32 s
GPT-5.6-sol62016.44 s6 min 18 s
GLM-5.3-Flash1,51725.2 s9 min 40 s
Kimi-K32,02838.9 s14 min 55 s

Nine seconds against a minute and a half is the difference between an agent a human can supervise and a batch job. The two open-weight reasoning models are also wildly variable, with single calls of 58 to 82 seconds sitting next to others under ten.

Because the base is shared, the fixed cost divides across the fleet. This is the one thing per-token pricing structurally cannot do.

Serving cost per customer-specific model, one GPU at $803 per month.
Customers on one cardGPU memoryCost / customer / month
18.96 GB$803
109.68 GB$80
5012.9 GB$16
10016.9 GB$8

A hundred customers as independent fine-tuned models would need 888 GB of weights, so twenty cards before anyone gets an answer, or roughly $161 per customer per month against our $8. And that is only the memory bill, with none of the batching economics.