메뉴
HN
Hacker News • 17일 전

OUI-1: 세계 최초의 생성형 UI 모델

IMP
7/10
핵심 요약

OUI-1은 DiffusionGemma를 파인튜닝한 오픈 웨이트 모델로, openui-lang으로 UI를 생성하며 소비자용 GPU(RTX 5090, FP8)에서 실행 가능합니다. 베이스 모델의 Generative UI 벤치마크 13.0%에서 LoRA 파인튜닝만으로 28.8%까지 향상시켰으나, 스키마 오류와 와이어링 오류가 시소처럼 반대로 움직이는 트레이드오프에 직면했습니다. 에이전트 기반 인터페이스의 미래를 향해 로컬 하드웨어에서 1초 미만으로 신뢰할 수 있는 UI를 생성하는 것이 목표입니다.

번역된 본문

OUI-1은 openui-lang으로 사용자 인터페이스를 작성하는, 파인튜닝된 DiffusionGemma 모델입니다. 총 26B 파라미터 중 활성화 파라미터 4B(26BA4B) 규모의 모델로, 소비자용 GPU(RTX 5090, FP8 기준)에서 실행할 수 있으며, 웨이트는 Gemma 이용약관에 따라 Hugging Face에 공개되어 있습니다.

우리가 OUI-1을 만든 이유

에이전트 기반 인터페이스는 소프트웨어의 미래입니다. 하지만 그곳에 도달하려면 세 가지 제약을 해결해야 합니다. 인터페이스는 1초 미만에 생성되어야 하고, 실제 소프트웨어로 사용할 수 있을 만큼 신뢰성이 있어야 하며, 모델은 소비자용 하드웨어에서 로컬로 실행할 수 있을 만큼 작아야 합니다.

AppLess에서 우리는 Cerebras 위의 Gemma 4로 그 경험을 탐구했습니다. 하지만 이는 클라우드의 특수 하드웨어에 의존하는 것이었습니다. 이것을 기기로 옮기는 것은 더 어려운 문제를 푸는 것을 의미했습니다. 계산량을 극적으로 줄이면서도 품질과 정확성을 희생하지 않고 반응성을 유지하는 것입니다. OUI-1은 이 문제 해결을 향한 우리의 첫걸음입니다. 소비자용 하드웨어에서 신뢰할 수 있는 인터페이스를 생성하도록 만들어진 오픈 웨이트 모델입니다. 우리의 목표는 기존 소프트웨어의 속도로 로컬에서 생성되는, 신뢰할 수 있는 에이전트 기반 인터페이스입니다.

제약에 맞는 모델 찾기

프로토콜은 이미 준비되어 있었습니다. OpenUI Lang은 JSON보다 최대 67% 적은 토큰을 사용하며 스트리밍이 가능해서, 모델이 생성을 끝내기 전에 인터페이스가 나타나기 시작합니다.

더 어려운 부분은 속도와 하드웨어 요구사항이 맞는 모델을 찾는 것이었습니다. 그래서 우리는 DiffusionGemma를 선택했습니다. 자기회귀(autoregressive) 모델은 한 번에 토큰 하나씩 생성해 메모리 대역폭에 병목이 생기지만, DiffusionGemma는 노이즈에서 시작해 확신이 드는 순간 각 토큰을 확정하면서 256 토큰 블록을 한 번에 작성합니다. Google은 단일 H100에서 초당 1,000 토큰 이상, RTX 5090에서 700 토큰 이상을 보고했습니다[1].

DiffusionGemma는 우리가 원하던 속도를 제공했습니다. 하지만 속도만으로는 소프트웨어가 되지 않습니다. 인터페이스도 실제로 동작해야 했습니다. 그것이 우리가 메워야 했던 격차였습니다.

격차가 북극성이 되다

벤치마크가 그 격차를 구체적으로 만들었습니다. DiffusionGemma는 Generative UI Benchmark에서 13.0%를 기록했습니다. 우리가 원하던 속도와 하드웨어 프로파일은 갖췄지만 신뢰성은 없었습니다.

OpenUI Lang 파서 덕분에 실패 원인을 쉽게 파악할 수 있었습니다. 스키마 오류는 잘못된 enum, 필수 prop 누락, 존재하지 않는 컴포넌트 사용입니다. 와이어링 오류는 정의되지 않은 이름을 사용하거나, 정의했지만 루트에 연결되지 않은 섹션입니다.

header = CardHeader("Spending", "last 7 days")
total = Heading("$24,180", "h9") // 스키마: h9는 유효한 제목 수준이 아님
chart = AreaChart(days, [spend], "wavy") // 스키마: "wavy"는 유효한 곡선 타입이 아님
footer = TextContent("Updated today")
root = Card([header, total, chart, summary]) // 와이어링: summary가 정의되지 않음

이것이 우리의 북극성이 되었습니다. 속도를 포기하지 않으면서 두 종류의 오류를 모두 줄이는 것입니다.

학습 방법

학습은 두 단계로 진행되었습니다. 먼저 지도 파인튜닝(SFT)으로 DiffusionGemma에게 OpenUI Lang을 작성하도록 가르쳤습니다. 그다음 자기증류(self-distillation)를 사용해 속도를 회복하고 신뢰성을 개선했습니다. 하나의 컴포넌트 라이브러리에서 이것이 작동하자, 27개 라이브러리에서 과정을 반복했습니다.

1단계: 지도 파인튜닝(Supervised Fine Tuning)

우리는 더 큰 모델이 작성한 약 700개의 OpenUI Lang 예제로 시작했으며, 이는 일곱 개의 컴포넌트 라이브러리에 걸쳐 있었습니다. 단일 A100에서 LoRA 파인튜닝을 진행했습니다. 손실은 내려갔습니다. 하지만 벤치마크 점수도 함께 내려갔습니다. 모델은 더 길고 조밀한 프로그램을 작성하는 법을 배웠지만, 파싱이 깨끗하게 되는 경우가 거의 없었습니다.

우리는 문제를 단일 컴포넌트 라이브러리, 즉 벤치마크가 사용하는 라이브러리로 좁혔습니다. 점수는 13.0%에서 28.8%로 올라갔지만, 진전에는 트레이드오프가 따랐습니다. 어떤 실행은 와이어링 오류를 줄이는 대신 스키마 오류를 늘렸고, 다음 실행은 그 반대였습니다:

실행       스키마 오류   고아 섹션
n          78           66
n + 1      112          40
n + 2      51           65

두 오류 유형은 시소처럼 움직였습니다. 우리는 베이스 모델보다 크게 앞서 있었지만, 어떤 실행도 두 오류를 함께 줄이지는 못했습니다. 우리는 LoRA의 용량 한계에 도달했다고 판단했습니다. 한 번에 하나의 규율만 학습할 수 있었고, 전체 파인튜닝이 나중에 이 트레이드오프를 해결할 것이라고 생각했습니다.

원문 보기
원문 보기 (영어)
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: run schema errors orphaned sections n 78 66 n + 1 112 40 n + 2 51 65 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. 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. 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. 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. 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. 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 Ge