Quick start
vLLM (works on bf16, FP8, or AWQ base — all tested):
vllm serve Qwen/Qwen3.6-27B-FP8 \
--enable-lora --max-lora-rank 32 \
--lora-modules fresh-paint=loktar00/Qwen3.6-27B-fresh-paint
Then request "model": "fresh-paint". System prompt used for all evals: "You generate a single, self-contained HTML document that fully answers the user's request." Sampling: temperature 0.7, top_p 0.95.
llama.cpp: stock convert_lora_to_gguf.py crashes on this hybrid-attention architecture (V-head reorder). Either use a patched converter that dispatches input-dim reorders to lora_A / output-dim to lora_B, or build merged GGUFs via llama-export-lora from a base GGUF + this adapter. Serving with --lora <converted>.gguf on a Q4_K_M base is well-tested.
Merging note: merge under a healthy transformers — a known save bug in 5.14.1 inflates merged saves of this architecture ~4x.
Evaluation
Headless-Chromium runtime audit (uncaught exceptions + blank-render detection), 94 prompts, served FP8+LoRA. fresh-paint = SFT epoch-2 + DPO (this release); e1 = SFT-only sibling:
Table with columns: slice, fresh-paint, SFT-only (e1), base| slice | fresh-paint | SFT-only (e1) | base |
|---|
| styled incl. held-out styles (60) | 60/60 | 54/60 | 54/60 |
| general, no style named (16) | 14/16 | 14/16 | 15/16 |
| games (10) | 10/10 | 9/10 | 10/10 |
| rare trained styles (8) | 8/8 | 8/8 |
Blind human preference (same 94 prompts, 3-way, position-randomized panels): fresh-paint 36 · e1 26 · base 20 (12 skips). On styled prompts the tuned pair took 85% of votes.
The honest paragraph. In a later blind against its own SFT parent (e2) at Q4, fresh-paint won the styled category (8-6) but the parent won overall (22-16), driven by games and general prompts — and a human playability pass found more of fresh-paint's game pages broken-in-play than the parent's, a defect class automated audits largely miss. Net: the DPO stage bought style fidelity and killed a fence artifact (below) at some cost to game robustness relative to its immediate parent. If your use case is games-first, benchmark both; the SFT parent adapter may be released separately.
- Paraphrase robustness (casually-worded requests vs the template-phrased main eval, 14 prompts): 14/14 CLEAN for both fresh-paint and base — casual, vaguely-worded phrasing broke nothing that the template-phrased main eval didn't already handle. (Runtime-only signal — doesn't measure style fidelity; see the honest paragraph above for that caveat.)
Known behaviors
- No doubled-fence artifact: the SFT-only sibling opens with two
```html fences on 39% of outputs (a trained-in teacher habit); the DPO in this release eliminated it — 0/94. If you parse outputs from any model in this family, prefer document-anchored extraction (find <!doctype → </html>) over fence regexes.
- Hybrid thinking model: reasoning can run long on ambitious prompts; serve without tight
max_tokens caps. /no_think soft switch works as in base.
- The base is multimodal; this adapter includes vision-tower LoRA tensors. Text-only serving works fine and an lm-only stripped variant exists.
Training
- SFT: LoRA r=32 α=64, 2 epochs, 5,676 rows (~59.5M tokens), completion-only loss, 32k packing. Teacher outputs distilled from commercial frontier models (thinking on). Includes a plain-prompt "default taste" lane so unstyled prompts get better output too.
- DPO: from the SFT epoch-2 checkpoint, β=0.1, 1,200 preference pairs (teacher-working-page vs own-draft), seq 12288.
- Both SFT epoch checkpoints were runtime-audited before choosing the DPO parent. ~14 GPU-hours total on 2×B200.
Provenance & license
Apache-2.0, inheriting the base license. Training data is teacher-distilled synthetic output from commercial frontier models plus preference pairs from the model's own drafts; no benchmark content. Trained and evaluated by loktar.