Introducing OUI-1: world's first model for Generative UI

A DiffusionGemma finetune at 71.7% on the Generative UI Benchmark, 5.5x its base.

Thesys Engineering Team·

OUI-1 is a finetuned DiffusionGemma model that writes user interfaces in openui-lang. It is 26BA4B model that can run on consumer grade GPU (RTX 5090, at FP8), and the weights are on Hugging Face under the Gemma Terms of Use.

Why we built OUI-1

Agent-driven interfaces are the future of software. But getting there comes down to three constraints. Interfaces must be generated in under a second. They must be reliable enough to use as software. And the models must be small enough to run locally on consumer hardware.

With AppLess, we explored that experience using Gemma 4 on Cerebras. But it depended on specialized hardware in the cloud. Moving it onto the device means solving a harder problem: preserving responsiveness with dramatically less compute, without sacrificing the quality or correctness of the generated interface.

OUI-1 is our first step toward solving that problem: an open-weight model built to generate reliable interfaces on consumer hardware. The ambition is reliable, agent-driven interfaces generated locally at the speed of traditional software.

Finding a model that fit the constraints

The protocol was already in place. OpenUI Lang costs up to 67% fewer tokens than JSON and streams, so the interface starts appearing before the model has finished generating it. The harder part was finding a model with the right speed and hardware profile.

That is why we chose DiffusionGemma. Autoregressive models generate one token at a time and are bottlenecked on memory bandwidth. DiffusionGemma writes a 256-token block at once, starting from noise and committing each token the moment it is sure of it. Google reports over 1,000 tokens per second on a single H100 and over 700 on an RTX 5090[1].

DiffusionGemma gave us the speed we were looking for. But speed alone does not make software: the interfaces also have to work. That was the gap we needed to close.

The gap became the north star

The benchmark made the gap concrete. DiffusionGemma scored 13.0% on the Generative UI Benchmark. It had the speed and hardware profile we wanted, but not the reliability.

The OpenUI Lang parser made those failures easy to see. A schema error is a wrong enum, a missing required prop, or an invented component. A wiring error is a name used but never defined, or a section defined but never attached to the root.

header = CardHeader("Spending", "last 7 days")
total = Heading("$24,180", "h9")// schema: h9 is not a heading level
chart = AreaChart(days, [spend], "wavy")// schema: "wavy" is not a curve type
footer = TextContent("Updated today")// wiring: defined, never attached to root
root = Card([header, total, chart, summary])// wiring: summary is never defined

That became our north star: bring both kinds of error down without giving up speed.

How we trained it

The training unfolded in two stages. First, we taught DiffusionGemma to write OpenUI Lang through supervised fine tuning. Then we used self-distillation to recover its speed and improve its reliability. Once that worked on one component library, we repeated the process across 27.

Phase 1: Supervised Fine Tuning

We started with about 700 OpenUI Lang examples written by larger models, spread across seven component libraries, and ran a LoRA fine-tune on one A100. The loss went down. But the benchmark score went down with it. The model had learned to write longer, denser programs, and almost none of them parsed cleanly.

We narrowed the problem to a single component library: the one used by the benchmark. The score rose from 13.0% to 28.8%, but progress came with a tradeoff. One run reduced wiring errors while increasing schema errors; the next did the reverse:

runschema errorsorphaned sections
n7866
n + 111240
n + 25165

The two error types moved like a see-saw. We were well ahead of the base model, but no run brought both down together. We assumed we had reached a capacity limit of the LoRA: it could learn one discipline at a time, and a full fine-tune would resolve the tradeoff later.

Where the errors went

2802
DiffusionGemma24/184 runs complete
35.3 defects per 100 statements
1263
after supervised finetuning53/184 runs complete
16.4 defects per 100 statements
20313.8× fewer
OUI-1132/184 runs complete
3.8 defects per 100 statements
schema errorswiring errors: undefined names and orphaned sections

Then we found a second problem: the model had become slower. We had expected fine tuning to make it faster. The sampler commits a token once its entropy falls below a bound, so a model that knows the language should become certain sooner. Instead, on the same 20 light briefs, generation time rose from 1.6 seconds per output to 4.3.

The base model was fast because its outputs were short and generic, averaging 22 tokens per statement. The fine-tuned model wrote real names and values, averaging 32 tokens per statement, and needed about twice as many denoising steps to commit each token. We had taught it to produce more useful interfaces, but lost the speed that made DiffusionGemma interesting in the first place.

Seconds per output, before and after supervised finetuning

Same 20 light briefs, one request at a time, same serving settings for both rows: vLLM, FP8, one A100.

DiffusionGemma1.6s
after supervised finetuning4.3s

The finetuned model writes longer outputs and needs about twice the denoising steps per token: it is committing real names and values where DiffusionGemma commits short, generic ones.

Phase 2: Self-distillation

The breakthrough was realizing that OpenUI Lang has a verifiable reward. The parser can tell us whether an interface is structurally valid and identify the exact schema or wiring errors when it is not. That meant the model could become its own teacher: generate programs, keep or repair them using the parser's feedback, and learn from the result. Self-distillation also offered a path to recovering speed because it is a known way to reduce the denoising steps used by diffusion language models[2][3].

Our version uses rejection-sampled self-training with repair. The model writes a few hundred OpenUI Lang programs, and the parser keeps the ones it accepts. Near-misses go through a repair pass that fixes only the defects reported by the parser; we reject any edit that rewrites or invents. The median repair changes one statement. A judge then checks whether each surviving program matches its brief. Those programs become the training set for the next run: 500 steps, taking an hour or two on one A100. The resulting model generates the next batch, and the loop begins again.

Self-distillation: generate, verify, retrain

1 · generatethe model writes a few hundred openui-lang programs
2 · verifythe parser keeps the ones that pass clean; a judge checks each against its brief
3 · repairnear-misses fixed by an LLM, listed defects only, rewrites rejected
4 · retrainthe survivors become the next training set
each pass trains the model that writes the next batch

The speed came back: on the same 20 light briefs, generation time fell from 4.3 seconds per output to 1.9, even though the outputs contained 28% more tokens than DiffusionGemma's. Then the see-saw stopped. The benchmark score reached 57.1%, schema errors fell from 292 to 76, and wiring errors fell from 971 to 484 in the same model. Every earlier run had traded one error type for the other; self-distillation improved both.

In effect, this is reinforcement learning in its simplest form: rejection sampling with the parser as the reward. Our hypothesis—which we have not isolated—is that training on the model's own text keeps the loss low almost everywhere, concentrating the gradient on the few things that changed: repaired statements and sampled choices pushed toward the mode. The first teaches the wiring fix; the second sharpens the model so the entropy bound can commit tokens earlier. Teacher-written data spreads that gradient across an entirely different writing style.

Phase 3: Generalizing across 27 component libraries

The one-library result left us with another question: had the model learned to generate interfaces, or had it learned one component library? We applied the same recipe—supervised fine tuning followed by self-distillation—across 27 component libraries.

Results

The result was OUI-1. On the Generative UI Benchmark, it scored 71.7%, up from DiffusionGemma's 13.0%. Every open model with up to 31B active parameters scored lower, including Gemma 4 31B at 46.7%, with one exception: Qwen3.8 27B at 78.8%. Qwen3.8 is a dense model that uses 27B parameters on every token, compared with OUI-1's 4B active parameters. Nothing at 4B active parameters or below scored higher; the next step up in score required a dense 27B.

Generative UI Benchmark, open-weight models up to 31B active

frontier models, open and closed · 90 to 99.5%02040608010031B14B8B4B2Bfewer active parameters →OUI-171.7% · 5.5x the base modelDiffusionGemma · 13%Qwen3.8 27B · 78.8%Qwen3.6 27B · 68.5%Qwen3.6 35B-A3B · 61.4%Gemma 4 31B · 46.7%Phi-4 14B · 44%Gemma 4 26B-A4B · 29.9%Ministral 8B · 27.2%Granite 4.1 8B · 14.7%LFM 2.5 2.6B · 3.3%
View data
modelactive paramsOpenUI score
OUI-1 (DiffusionGemma, finetuned)4B71.7%
DiffusionGemma4B13%
Qwen3.8 27B27B78.8%
Qwen3.6 27B27B68.5%
Qwen3.6 35B-A3B3B61.4%
Gemma 4 31B31B46.7%
Phi-4 14B14B44%
Gemma 4 26B-A4B4B29.9%
Ministral 8B8B27.2%
Granite 4.1 8B8B14.7%
LFM 2.5 2.6B2.6B3.3%

The gain also generalized beyond the benchmark library. On the AppLess library, we tested 60 asks that the model had never seen during training. OUI-1 produced 55 valid outputs; DiffusionGemma produced 23.

Valid outputs on the appless phone library

60 asks written independently of every training file, one output each, counted valid when it parses clean: no schema errors, every name defined, at least three statements.

DiffusionGemma23 / 60
OUI-155 / 60

A different component library from the benchmark's, with its own signatures in the system prompt. None of these asks or outputs were trained on.

OUI-1 did more than bring us back to where we began. AppLess had relied on Gemma 4 running on Cerebras; it now runs on OUI-1. On the benchmark, OUI-1's 71.7% surpassed both Gemma 4 31B at 46.7% and Gemma 4 26B-A4B at 29.9%. The experience that first required specialized inference hardware can now be powered by an open-weight, 4B-active model built to run on consumer hardware.

Model release

Get OUI-1

Download the open-weight model from Hugging Face.

26B parameters · 4B active · FP8View model weights
Open evaluation

Explore the benchmark

Review the scoring code and raw generations on GitHub.

71.7% Generative UI BenchmarkView benchmark

Directions from here

Three directions matter from here:

  • Personal devices. Run models like OUI-1 closer to the person, keeping more of their context on the device.
  • OpenUI Lang 0.5. Generate interfaces with their own state, queries and mutations, so the runtime—not the model—handles each interaction.
  • Lower latency. Move toward reliable, locally generated interfaces that arrive in under a second.

References

  1. Google, DiffusionGemma: faster text generation

  2. Deschenaux and Gulcehre, Beyond Autoregression: Fast LLMs via Self-Distillation Through Time

  3. Zhang et al., T3D: Few-Step Diffusion Language Models via Trajectory Self-Distillation with Direct Discriminative Optimization