andhakanoon commited on
Commit
d380b91
·
verified ·
1 Parent(s): 533d988

card: how to run (vLLM, OpenAI client, function calling, transformers)

Browse files
Files changed (1) hide show
  1. README.md +91 -20
README.md CHANGED
@@ -85,33 +85,104 @@ teacher-written answer to them. The training set is not released.
85
 
86
  ## How to use
87
 
88
- Serve with vLLM 0.24 or newer. The sampler settings come from the checkpoint's own
89
- `generation_config.json` (entropy-bound sampler, entropy bound 0.1, 48 denoising steps, 256-token
90
- canvas); every number above was measured with them. To change the step cap use
91
- `--diffusion-config '{"canvas_length":256,"max_denoising_steps":N}'`; note that `--hf-overrides`
92
- keys such as `diffusion_max_denoising_steps` are not read by vLLM.
 
 
 
 
 
 
 
93
 
94
  ```bash
 
95
  vllm serve thesysdev/OUI-1 --trust-remote-code --max-model-len 16384 --quantization fp8 \
96
  --served-model-name oui-1 --max-num-seqs 4 \
97
  --enable-auto-tool-choice --tool-call-parser gemma4
98
  ```
99
 
100
- Function calling: the model keeps Gemma 4's native tool-call format, so with the `gemma4` parser
101
- it returns standard OpenAI `tool_calls` for tools you pass in the request, then writes the screen
102
- from the tool result on the next turn. It needs one instruction in the system prompt to prefer the
103
- tool over inventing data, e.g.: "When the user asks about the weather or a stock price you MUST
104
- call the matching tool first and output nothing else in that turn; write the screen from the
105
- returned values on the next turn." In our test (weather, stock price tools) it called the right
106
- tool with the right arguments on 9 of 9 asks, never called one on 3 unrelated asks, and used the
107
- returned numbers verbatim. `tool_choice: "required"` is not available (vLLM has no structured
108
- outputs for diffusion models yet).
109
-
110
- Then call it as an OpenAI-compatible chat model. The system prompt must carry the component
111
- library: use `@openuidev/cli`'s prompt generator for your library, or the benchmark's
112
- `protocols/openui/prompt.ts` for the reference library. Recommended: `max_tokens` 4096 (the
113
- `temperature` and `seed` fields are ignored by DiffusionGemma), briefs in the form the model was
114
- trained on:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
  ```
117
  A fitness app's daily summary. Build a single screen for this. It must show:
 
85
 
86
  ## How to use
87
 
88
+ The model reads the component library from the system prompt and answers with an openui-lang
89
+ program. Build the system prompt for your own component library with `@openuidev/cli`
90
+ (`npx @openuidev/cli generate <library.ts> --out system-prompt.txt`), or use the benchmark's
91
+ reference prompt (`protocols/openui/prompt.ts` in generative-ui-bench) to try it as is. Render
92
+ the output with `@openuidev/react-lang` (or the Vue and Svelte renderers) and validate it with
93
+ `@openuidev/lang-core`.
94
+
95
+ ### vLLM (recommended)
96
+
97
+ vLLM 0.24 or newer. The sampler settings come from the checkpoint's own `generation_config.json`
98
+ (entropy-bound sampler, entropy bound 0.1, 48 denoising steps, 256-token canvas); every number
99
+ above was measured with them. About 26 GB of VRAM at FP8.
100
 
101
  ```bash
102
+ pip install "vllm>=0.24"
103
  vllm serve thesysdev/OUI-1 --trust-remote-code --max-model-len 16384 --quantization fp8 \
104
  --served-model-name oui-1 --max-num-seqs 4 \
105
  --enable-auto-tool-choice --tool-call-parser gemma4
106
  ```
107
 
108
+ Then call it as an OpenAI-compatible chat model. `temperature` and `seed` are ignored (diffusion
109
+ models use a fixed internal schedule); keep `max_tokens` at 4096 or below.
110
+
111
+ ```python
112
+ from openai import OpenAI
113
+
114
+ client = OpenAI(base_url="http://localhost:8000/v1", api_key="local")
115
+ system = open("system-prompt.txt").read() # your component library, from @openuidev/cli
116
+ brief = """A fitness app's daily summary. Build a single screen for this. It must show:
117
+ 1. step count today against the daily goal
118
+ 2. calories burned
119
+ 3. a way to log a new workout
120
+ Cover every numbered item."""
121
+ r = client.chat.completions.create(
122
+ model="oui-1",
123
+ messages=[{"role": "system", "content": system}, {"role": "user", "content": brief}],
124
+ max_tokens=4096,
125
+ stream=False,
126
+ )
127
+ print(r.choices[0].message.content) # openui-lang: one component per line, wired into root
128
+ ```
129
+
130
+ Streaming works the same way (`stream=True`); tokens arrive one 256-token canvas at a time.
131
+
132
+ To change the step cap use `--diffusion-config '{"canvas_length":256,"max_denoising_steps":N}'`
133
+ (32 and 48 score the same on the benchmark, 16 breaks the reference graph). `--hf-overrides` keys
134
+ such as `diffusion_max_denoising_steps` are not read by vLLM.
135
+
136
+ ### Function calling
137
+
138
+ The model keeps Gemma 4's native tool-call format. With `--tool-call-parser gemma4` it returns
139
+ standard OpenAI `tool_calls` for tools you pass in the request, then writes the screen from the
140
+ tool result on the next turn. It needs one instruction in the system prompt to prefer the tool
141
+ over inventing data, e.g.: "When the user asks about the weather or a stock price you MUST call the
142
+ matching tool first and output nothing else in that turn; write the screen from the returned
143
+ values on the next turn." In our test (weather, stock price tools) it called the right tool with
144
+ the right arguments on 9 of 9 asks, never called one on 3 unrelated asks, and used the returned
145
+ numbers verbatim. `tool_choice: "required"` is not available (vLLM has no structured outputs for
146
+ diffusion models yet).
147
+
148
+ ```python
149
+ tools = [{"type": "function", "function": {"name": "get_weather",
150
+ "description": "Current weather for a city",
151
+ "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}}]
152
+ r = client.chat.completions.create(model="oui-1", tools=tools, max_tokens=4096,
153
+ messages=[{"role": "system", "content": system + TOOL_RULE}, {"role": "user", "content": "weather in Goa this weekend"}])
154
+ call = r.choices[0].message.tool_calls[0] # get_weather({"city": "Goa"})
155
+ # run the tool, then append the assistant message and a {"role": "tool", ...} result and call again
156
+ ```
157
+
158
+ ### Transformers
159
+
160
+ Transformers 5.11 or newer with the DiffusionGemma model class; bf16 needs about 52 GB of GPU
161
+ memory (one A100 80GB or H100). `generate` chains 256-token canvases internally and stops at EOS.
162
+
163
+ ```python
164
+ import torch
165
+ from transformers import AutoModelForCausalLM, AutoProcessor
166
+
167
+ model_id = "thesysdev/OUI-1"
168
+ processor = AutoProcessor.from_pretrained(model_id)
169
+ model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.bfloat16, device_map="cuda")
170
+
171
+ messages = [{"role": "system", "content": open("system-prompt.txt").read()},
172
+ {"role": "user", "content": brief}]
173
+ ids = processor.apply_chat_template(messages, tokenize=True, add_generation_prompt=True, return_tensors="pt").to("cuda")
174
+ gc = model.generation_config # entropy-bound sampler, 48 steps, from the checkpoint
175
+ gc.max_new_tokens = 256 * 16 # up to 16 canvases; EOS stops earlier
176
+ out = model.generate(input_ids=ids, generation_config=gc)
177
+ print(processor.decode(out.sequences[0, ids.shape[1]:], skip_special_tokens=True))
178
+ ```
179
+
180
+ The LoRA adapter that produced these weights is in `adapter/` (PEFT format, base
181
+ `google/diffusiongemma-26B-A4B-it`), for anyone who prefers to load base plus adapter.
182
+
183
+ ### Briefs
184
+
185
+ Briefs in the form the model was trained on work best:
186
 
187
  ```
188
  A fitness app's daily summary. Build a single screen for this. It must show: