OUI-1: 세계 최초의 생성형 UI 모델
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의 용량 한계에 도달했다고 판단했습니다. 한 번에 하나의 규율만 학습할 수 있었고, 전체 파인튜닝이 나중에 이 트레이드오프를 해결할 것이라고 생각했습니다.