stefans71/frontend-design-expert-8b
<p align="center"> <img src="hero.png" alt="Frontend Design Expert โ Fine-tuned Qwen3-VL that asks before it builds" width="800"/> </p>
<p align="center"> <a href="https://huggingface.co/stefans71/frontend-design-lite-4b"><img src="https://img.shields.io/badge/๐ค-4BLite(8GBGPU)-blue" alt="4B Lite"/></a> <a href="https://github.com/stefans71/frontend-design-dataset"><img src="https://img.shields.io/badge/GitHub-DatasetPipeline-green" alt="GitHub"/></a> <img src="https://img.shields.io/badge/Base-Qwen3--VL--8B-4b8bbf" alt="Base model"/> <img src="https://img.shields.io/badge/License-Apache_2.0-gray" alt="License"/> </p>
[!IMPORTANT] Vision critique trigger: Use exactly "Critique this UI design." when sending a screenshot. The model learned this specific phrase during training โ other phrasings may not reliably activate the critique behavior.The Problem
Base models are RLHF-tuned to be immediately helpful โ they build immediately regardless of how vague the request is. You can't fix this with a system prompt. It has to be trained into the weights.
<p align="center"> <img src="terminal.png" alt="Base Model vs Fine-tuned: qualifying question behavior" width="800"/> </p>
1/10 โ 10/10 on qualifying questions. All 10 tested vague prompts triggered clarifying questions from the fine-tuned model; only 1/10 from the base model.
Before / After
<p align="center"> <img src="hero-comparison.png" alt="Before vs After: Base Model vs Fine-tuned on FitTrack login prompt" width="800"/> </p>
Left: base Qwen3-VL-8B ignores the brand name and defaults to blue. Right: fine-tuned model applies FitTrack branding and green accent across every interactive element.
<p align="center"> <img src="qwen-8B-vs-fine-tuned.png" alt="Before vs After: Base vs Fine-tuned pricing card with design critique scores" width="800"/> </p>
Base model scores 5/10 โ fine-tuned scores 6/10 (+1.0). Notice the improved typography hierarchy, gradient background, and "MOST POPULAR" badge treatment.
[!IMPORTANT] Live demo & full dataset explorer: <a href="https://qwen.data-analytics.space" style="color: #F97316; font-weight: bold;">qwen.data-analytics.space</a>
Fine-tuned vs. base Qwen3-VL-8B on the same prompts:
Training Pipeline
<p align="center"> <img src="pipeline.png" alt="Training pipeline: Natural Prompt โ Qwen3.6-27B โ Playwright โ GPT-5.4 โ 3,090 Records โ Fine-tuned 8B" width="800"/> </p>
Teacher-student distillation:
- Qwen3.6-27B generates HTML components from natural language prompts
- Playwright renders each component to desktop (1280ร900) and mobile (390ร844) screenshots
- GPT-5.4 critiques each screenshot and rewrites the HTML with expert design improvements โ hover states, WCAG contrast, color consistency, layout hierarchy
- Training pairs:
[screenshot + original HTML + critique] โ [expert improved HTML]
The gap between Qwen's output and GPT-5.4's rewrite is the training signal. 3,090 records across 8 types:
Validated Behaviors
Head-to-Head Design Quality
Head-to-head test: base Qwen3-VL-8B vs fine-tuned, same 10 prompts, same hardware (RTX 3080 Ti 12GB), GPT-5.4 judge using the same critique rubric as training.
- Fine-tuned wins: 6/10 components
- Tied: 3/10
- Base wins: 1/10 (dark navbar only)
- Biggest improvement: mobile dark bottom sheet +5 (base scored 1, fine-tuned scored 6)
Note: Scores reflect first-pass generation without the improvement step. The model was trained on critique+improvement pairs โ ask it to critique and improve its own output for higher quality results.
[!TIP] Thinking mode: Always disable thinking mode in your inference server. Add"chat_template_kwargs": {"enable_thinking": false}to API requests, or use--no-thinkflag with llama-server.
Quick Start
Text-only (Ollama)
ollama pull stefans71/frontend-design-expert-8b
ollama run stefans71/frontend-design-expert-8b \
"make me a pricing card for my SaaS called TaskFlow, dark theme, purple accent"Vision + Text (llama-server)
Ollama does not currently support separate mmproj files for vision. Use llama-server:
llama-server \
-m frontend-design-expert-Q4_K_M.gguf \
--mmproj mmproj-F16.gguf \
-c 8192 \
--host 0.0.0.0 \
--port 8080Send requests via the OpenAI-compatible API:
import base64, requests
with open("screenshot.png", "rb") as f:
img = base64.b64encode(f.read()).decode()
response = requests.post("http://localhost:8080/v1/chat/completions", json={
"model": "frontend-design-expert",
"messages": [{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img}"}},
{"type": "text", "text": "Critique this UI design."}
]
}],
"max_tokens": 1024
})
print(response.json()["choices"][0]["message"]["content"])Inference tips
- Vision critique trigger: Use exactly
"Critique this UI design."โ other phrasings may trigger thinking-mode EOS - Disable thinking mode: Add
"chat_template_kwargs": {"enable_thinking": false}to API requests - Screenshot resolution: Max 1024ร1024 to avoid VRAM OOM on 12GB GPUs
- Context window: 8192 tokens; increase to 32768 for full-page builds
Files
Training Details
Limitations
- Vision critique requires the exact phrase
"Critique this UI design."โ other phrasings may not reliably activate the behavior - Ollama does not currently support separate mmproj files โ use llama-server for vision tasks
- Generated HTML uses inline CSS only (no Tailwind CDN) โ intentional for offline compatibility
- Complex HTML outputs may be truncated at 4096 tokens โ increase
max_tokensfor full-page builds
Related
- [stefans71/frontend-design-lite-4b](https://huggingface.co/stefans71/frontend-design-lite-4b) โ 4B version for 8GB GPUs
- [stefans71/frontend-design-dataset](https://github.com/stefans71/frontend-design-dataset) โ training pipeline (Bun + TypeScript + Playwright)
- Base model: [Qwen/Qwen3-VL-8B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct)
@misc{stefan2026frontenddesign,
title={Frontend Design Expert: Fine-tuning Qwen3-VL-8B for UI Generation via Teacher-Student Distillation},
author={Stefan, Scott},
year={2026},
url={https://huggingface.co/stefans71/frontend-design-expert-8b}
}