Downloads · 30 days
16
19% of all-time downloads
milwright/cloze-reader-qwen3.5-0.8b-lora
cloze-reader-qwen3.5-0.8b-lora is a text generation model from milwright. Use it when you need the model to write or continue text. It is set up for peft. The card lists the license as apache-2.0.
A rank-16 LoRA adapter over Qwen/Qwen3.5-0.8B that replaces a ~33× larger teacher (Gemma-3-27B-IT) as the language-model backend for the Cloze Reader reading-comprehension app (source).
Downloads · 30 days
16
19% of all-time downloads
All-time downloads
83
Public
Repo size
71.2 MB
Likes
0
Public
Click a slice to open those files.
.safetensors25.6 MB · 56%
From the Hugging Face model README
A rank-16 LoRA adapter over Qwen/Qwen3.5-0.8B that replaces a ~33× larger teacher (Gemma-3-27B-IT) as the language-model backend for the Cloze Reader reading-comprehension app (source).
On a 200-example held-out test set, the fine-tuned 0.8B student matches or exceeds the 27B teacher on 4 of 5 metric categories, with perfect format-constraint compliance on two tasks. The full model at bf16 is ~1.7 GB; at Q4_K_M it runs in ~2.5–3 GB of VRAM.
| This LoRA over Qwen3.5-0.8B | Baseline Gemma-3-27B-IT | |
|---|---|---|
| Word Selection — JSON valid | 100.0% | 94.0% |
| Batch Selection — all metrics | 100.0% | 96.0% |
| Hints — word safety | 98.0% | 100.0% |
| Contextualization — all metrics | 100.0% | 96.0–98.0% |
| Params (total) | 0.8B + 25 MB adapter | 27B |
| VRAM at Q4_K_M | ~2.5–3 GB | ~16 GB |
Update (2026-07): the live adapter has since had 6 additional continued-PEFT cycles of Gemini-distilled data on top of the original Gemma-only run. Training loss fell from 0.625 (original, 3 epochs) to 0.4304 (after cycle 6, ~20.3k examples). The tables below report the original n=200 Gemma-vs-student eval; the honest hint-safety figure under a 9-layer leak detector is ~72.5% no-leak (vs. the 98% a cheap exact-match check reports) — see Evaluation → Hint-leakage note. This adapter is the intended per-app LoRA for the shared inference-arcade vLLM host.
The Cloze Reader app uses a single LM for four tightly-constrained text-generation tasks. The adapter was trained on examples of all four and produces the exact JSON / plaintext shapes the front-end expects.
["laboratory", "synthesis"]. Constraints: lowercase only, 4–14 letters, must appear verbatim in the passage, no proper nouns.Exact prompt templates match aiService.js / conversationManager.js in the cloze-reader repo.
peft + transformersfrom transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel
import torch
BASE = "Qwen/Qwen3.5-0.8B"
ADAPTER = "milwright/cloze-reader-qwen3.5-0.8b-lora"
tokenizer = AutoTokenizer.from_pretrained(ADAPTER)
base = AutoModelForCausalLM.from_pretrained(BASE, torch_dtype=torch.bfloat16, device_map="auto")
model = PeftModel.from_pretrained(base, ADAPTER)
messages = [
{"role": "system", "content": "Select words for a cloze exercise. Return ONLY a JSON array of words, nothing else."},
{"role": "user", "content": "Select 1 challenging words (4-14 letters) from this passage.\n\nPassage: \"...\""},
]
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
out = model.generate(**tokenizer(prompt, return_tensors="pt").to(model.device), max_new_tokens=64)
print(tokenizer.decode(out[0], skip_special_tokens=True))
from unsloth import FastLanguageModel
model, tokenizer = FastLanguageModel.from_pretrained(
"milwright/cloze-reader-qwen3.5-0.8b-lora",
max_seq_length=2048,
load_in_4bit=True,
)
FastLanguageModel.for_inference(model)
A merged GGUF build of this adapter fits ~2.5–3 GB at Q4_K_M and runs with:
ollama create cloze-reader -f Modelfile
ollama run cloze-reader
(The GGUF + Modelfile are not bundled here — see the project repo for the export pipeline.)
Standalone — serve the merged build (milwright/cloze-reader-qwen3.5-0.8b) directly:
vllm serve milwright/cloze-reader-qwen3.5-0.8b \
--served-model-name cloze-reader \
--host 127.0.0.1 --port 1234 \
--dtype bfloat16 --max-model-len 2048
Shared base + adapter (multi-LoRA) — load this adapter on top of the base so one
0.8B model in VRAM can serve several app-specific adapters, each selected per request
via the OpenAI model field:
vllm serve Qwen/Qwen3.5-0.8B \
--enable-lora --max-lora-rank 16 \
--lora-modules cloze-reader=milwright/cloze-reader-qwen3.5-0.8b-lora \
--host 127.0.0.1 --port 1234 --max-model-len 2048
Then POST OpenAI-shape chat completions with "model": "cloze-reader". This is the
serving mode used by the inference-arcade host,
which attaches multiple sibling adapters to the same base.
google/gemma-3-27b-it serving the production cloze-reader endpoint.manu/project_gutenberg corpus (61k books on the Hub).{"conversations": [{"role": ..., "content": ...}, …]}, rendered through Qwen-3 ChatML (<|im_start|> / <|im_end|>).Supervised fine-tuning with TRL + Unsloth's FastLanguageModel, loss masked to assistant turns via train_on_responses_only().
| Setting | Value |
|---|---|
| LoRA rank / alpha / dropout | 16 / 16 / 0.05 |
| Target modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
| Base load precision | 4-bit (bnb, nf4) via load_in_4bit=True |
| Training precision | bfloat16 |
| Optimizer | adamw_8bit |
| Learning rate | 2e-4, cosine schedule, 5% warmup |
| Weight decay | 0.01 |
| Per-device batch | 4 |
| Gradient accumulation | 4 |
| Max sequence length | 2048 |
| Epochs | 3 |
| Seed | 42 |
| Final training loss | 0.625 |
| Chat template | qwen-3 |
checkpoint-1311, -2622, -3933).After the original Gemma-only run, the adapter was refined with 6 additive continued-PEFT cycles (--resume-from, lr=5e-5, 1 epoch each). Each cycle adds +500/task of fresh data distilled from google/gemini-3.1-flash-lite-preview and merges it with the legacy corpus:
| Cycle | Train loss | Train set |
|---|---|---|
| orig (Gemma, 3 ep) | 0.625 | 15,981 |
| 1 | 0.5152 | 16,942 |
| 2 | 0.5145 | 18,303 |
| 3 | 0.4936 | 18,861 |
| 4 | 0.4724 | 19,344 |
| 5 | 0.4508 | 19,820 |
| 6 | 0.4304 | 20,310 |
Loss kept falling ~linearly (no asymptote), but a 4-cell prompt × adapter matrix eval showed the structural metrics were already saturated and hint-leak safety did not move — the ceiling is structural to giving meaningful hints about content words, not a data-volume problem.
200 held-out examples (50 per task, seed 42, removed from training data pre-split) scored against the live Gemma-3-27B endpoint as baseline.
| Metric | This LoRA | Gemma-3-27B | Δ |
|---|---|---|---|
| JSON valid | 100.0% | 94.0% | +6.0 |
| Format OK | 100.0% | 94.0% | +6.0 |
| Words valid | 88.0% | 90.0% | −2.0 |
| Valid ratio | 96.85% | 98.72% | −1.87 |
| Metric | This LoRA | Gemma-3-27B | Δ |
|---|---|---|---|
| JSON valid | 100.0% | 96.0% | +4.0 |
| Structure OK | 100.0% | 96.0% | +4.0 |
| Words present | 100.0% | 96.0% | +4.0 |
| Metric | This LoRA | Gemma-3-27B | Δ |
|---|---|---|---|
| Non-empty | 100.0% | 100.0% | — |
| Word safe (no leak) | 98.0% | 100.0% | −2.0 |
| Length OK (15–25w) | 90.0% | 94.0% | −4.0 |
| Mean word count | 23.2 | 20.8 | +2.4 |
| Metric | This LoRA | Gemma-3-27B | Δ |
|---|---|---|---|
| Non-empty | 100.0% | 98.0% | +2.0 |
| Length OK (≤25w) | 100.0% | 98.0% | +2.0 |
| No em-dashes | 100.0% | 98.0% | +2.0 |
| No preamble | 100.0% | 96.0% | +4.0 |
| Mean word count | 19.0 | 16.9 | +2.1 |
The 98% "word safe" figure above comes from a cheap exact/substring match. A 9-layer detector (exact → normalized → substring → phonetic → lemma → synonym → hypernym → gloss-overlap → definition) that catches inflection, synonym, hypernym, and dictionary-gloss leaks measures ~72.5% no-leak on the n=40 holdout. The 22.5-point gap is dominated by gloss_overlap + hypernym events (≈75% of all leaks) and is structural: a hint that meaningfully describes a content-rich word tends to borrow words from its definition. Keep a heuristic safety filter downstream regardless of which number you quote.
Full per-metric JSON is at evaluation_results.json in the training project repo.
In-scope. Serving the four cloze-reader tasks in the Cloze Reader app or a comparable vocabulary-practice / guided-reading UI, where inputs are short English prose passages (classical or modern) and outputs are JSON arrays / objects or tightly-length-bounded sentences.
Out of scope.
gemma-3-27b-it on the 4 task prompts are inherited. If the teacher has a blind spot on certain passages (e.g., archaic or dialect text from Gutenberg), the student has the same one.This adapter is released under Apache 2.0, inheriting from the base model Qwen/Qwen3.5-0.8B. Training data includes public-domain passages from Project Gutenberg and AI-generated outputs from google/gemma-3-27b-it; redistribution of the adapter weights themselves carries no Gutenberg restriction, but downstream users should honor Gemma's terms if they redistribute teacher generations separately.
This is the production LM for Cloze Reader, a reading-comprehension web app for practicing vocabulary through contextual word-blanking. Originally the app called a hosted Gemma-3-27B endpoint; this adapter was trained to bring inference on-device and retire the API dependency.
Developed as part of milwright/quimbot, a broader fine-tuning and evaluation project for small English-language models. See the repo's CLAUDE.md and fine-tuning/ for the larger pipeline.
Base model — Qwen Team, Qwen3.5-0.8B (2026), huggingface.co/Qwen/Qwen3.5-0.8B.
Teacher (training data) — Google DeepMind, Gemma 3 27B Instruct (2025), huggingface.co/google/gemma-3-27b-it.
Passage corpus — manu/project_gutenberg.
TRL
@misc{vonwerra2022trl,
title = {{TRL: Transformer Reinforcement Learning}},
author = {Leandro von Werra and Younes Belkada and Lewis Tunstall and Edward Beeching and Tristan Thrush and Nathan Lambert and Shengyi Huang and Kashif Rasul and Quentin Galloué́́dec},
year = 2020,
journal = {GitHub repository},
howpublished = {\url{https://github.com/huggingface/trl}}
}
Unsloth — github.com/unslothai/unsloth.
PEFT — Mangrulkar et al., PEFT: State-of-the-art Parameter-Efficient Fine-Tuning, github.com/huggingface/peft.