Downloads · 30 days
184
16% of all-time downloads
bbidpa/Qwen2.5-Coder-0.5B-Flutter-direct
Qwen2.5-Coder-0.5B-Flutter-direct is a text generation model from bbidpa. Use it when you need the model to write or continue text. It is set up for transformers. The card lists the license as mit.
Qwen2.5-Coder-0.5B, fine-tuned to generate a complete Flutter/Dart file in one shot from a natural-language goal. Fine-tuned on 5M tokens of flat goal → complete-file examples (bbidpa/flutter-full-examples-v1).
Downloads · 30 days
184
16% of all-time downloads
All-time downloads
1.1K
Public
Parameters
494M
999 MB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors988 MB · 98%
From the Hugging Face model README
Qwen2.5-Coder-0.5B, fine-tuned to generate a complete Flutter/Dart file in one shot from a natural-language goal. Fine-tuned on 5M tokens of flat goal → complete-file examples (bbidpa/flutter-full-examples-v1).
This model is part of a paired comparison studying whether small models benefit more from learning to emit a whole file at once, or from learning to build code up iteratively via small diffs. Its companion on the same base model is Qwen2.5-Coder-0.5B-Flutter-steps. The same comparison is also run on a 100M-parameter model trained fully from scratch: Rainbow-Pony-100M-Flutter-direct / -steps.
Full methodology and results are in the accompanying paper, Diffs vs. Whole Files: An Empirical Comparison of Iterative Edit-Based and Direct Generation for Flutter/Dart Code Models (arXiv:2609.05779, cs.SE).
🤗 Space - Diffs vs. Whole Files
Since Qwen2.5-Coder is a standard, already-registered transformers architecture, plain AutoModel loading works with no custom code:
from transformers import AutoModelForCausalLM, AutoTokenizer
REPO = "bbidpa/Qwen2.5-Coder-0.5B-Flutter-direct"
tokenizer = AutoTokenizer.from_pretrained(REPO)
model = AutoModelForCausalLM.from_pretrained(REPO)
For the exact calling convention used in the examples below (and shared with the from-scratch TinyGPT models in this collection), wrap it with these two small adapters instead:
import torch
import torch.nn as nn
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModelForCausalLM
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
class QwenTokenizerAdapter:
def __init__(self, model_id):
self.hf = AutoTokenizer.from_pretrained(model_id)
self.eos_id = self.hf.eos_token_id
self.bos_id = self.hf.bos_token_id if self.hf.bos_token_id is not None else self.eos_id
self.pad_id = self.hf.pad_token_id if self.hf.pad_token_id is not None else self.eos_id
self.vocab_size = len(self.hf)
self.tokenizer = self
def encode(self, text, add_special_tokens=False):
return self.hf.encode(text, add_special_tokens=add_special_tokens)
def decode(self, ids, skip_special_tokens=False):
return self.hf.decode(ids, skip_special_tokens=skip_special_tokens)
def id_to_token(self, idx):
return self.hf.convert_ids_to_tokens([int(idx)])[0]
def tokens(self, text):
return self.hf.tokenize(text)
class HFModelWrapper(nn.Module):
"""Matches TinyGPT's call convention -- model(xb, yb) -> (logits, loss),
model.generate(idx, max_new_tokens=, eos_id=, top_k=) -> full sequence."""
def __init__(self, hf_model):
super().__init__()
self.hf_model = hf_model
def forward(self, xb, yb=None):
logits = self.hf_model(input_ids=xb).logits
loss = None
if yb is not None:
loss = F.cross_entropy(
logits.view(-1, logits.size(-1)),
yb.view(-1),
ignore_index=-100,
)
return logits, loss
def generate(self, idx, max_new_tokens, eos_id=None, top_k=None, temperature=None, do_sample=None):
return self.hf_model.generate(
input_ids=idx,
max_new_tokens=max_new_tokens,
eos_token_id=eos_id,
pad_token_id=eos_id,
top_k=top_k,
do_sample=do_sample if do_sample is not None else (top_k is not None or temperature is not None),
temperature=temperature if temperature is not None else 1.0,
)
@property
def vocab_size(self):
return self.hf_model.config.vocab_size
def load_hf_checkpoint(path, device):
hf_model = AutoModelForCausalLM.from_pretrained(
path,
torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
attn_implementation="sdpa",
).to(device)
return HFModelWrapper(hf_model).to(device)
tokenizer = QwenTokenizerAdapter(REPO)
model = load_hf_checkpoint(REPO, DEVICE).eval()
Same tag vocabulary as the rest of this collection. <CODE> holds the current file contents (empty for a from-scratch generation), <HISTORY> holds prior steps (unused for this model's typical single-step usage), and the model completes everything after <OUTPUT>:
<GOAL>
Write a widget that displays a select button with months in it
</GOAL>
<CODE>
</CODE>
<HISTORY>
</HISTORY>
<OUTPUT>
def render_step_prompt_from_data(
goal: str,
code: str = "",
history: list[dict] | None = None,
action_type: str = "",
action_desc: str = "",
changes: list[dict] | None = None,
is_last_step: bool = False,
include_output: bool = False,
) -> str:
history = history or []
changes = changes or []
history_text = "\n".join(
f"<ACTION><TYPE>{h['type']}</TYPE><DESC>{h['desc']}</DESC></ACTION>"
for h in history
)
text = f"""<GOAL>
{goal}
</GOAL>
<CODE>
{code}
</CODE>
<HISTORY>
{history_text}
</HISTORY>
<OUTPUT>
"""
if include_output:
hunks = "\n".join(
f"<HUNK>\n<SEARCH>\n{h['search']}\n</SEARCH>\n<REPLACE>\n{h['replace']}\n</REPLACE>\n</HUNK>"
for h in changes
)
output = f"<ACTION><TYPE>{action_type}</TYPE><DESC>{action_desc}</DESC></ACTION>\n<CHANGES>\n{hunks}\n</CHANGES>"
if is_last_step:
output += "\n<DONE></DONE>"
text += output + "\n</OUTPUT>"
return text
def generate_output(model, tokenizer, device, prompt, max_new_tokens=300, **generate_kwargs):
prompt_ids = tokenizer.encode(prompt, add_special_tokens=False)
idx = torch.tensor([[tokenizer.bos_id] + prompt_ids], dtype=torch.long).to(device)
generated = model.generate(idx, max_new_tokens=max_new_tokens, eos_id=tokenizer.eos_id, **generate_kwargs)
text = tokenizer.decode(generated[0].tolist(), skip_special_tokens=False)
output = text.split("<OUTPUT>")[-1].split("</OUTPUT>")[0].strip()
return output
prompt = render_step_prompt_from_data(
goal="Write a widget that displays a select button with months in it",
)
text = generate_output(model, tokenizer, DEVICE, prompt, max_new_tokens=1024)
print(text)
Input goal: Write a widget that displays a select button with months in it
test_row = {
"goal": "Write a widget that displays a select button with months in it",
"code": """""",
"history": [],
"action_type": "",
"action_desc": "",
"is_last_step": False,
"changes": [],
}
prompt = render_step_prompt_from_data(
goal=test_row['goal'],
code=test_row['code'],
history=test_row['history'],
action_type=test_row['action_type'],
action_desc=test_row['action_desc'],
changes=test_row['changes'],
is_last_step=test_row['is_last_step'],
include_output=False
)
text = generate_output(model, tokenizer, DEVICE, prompt, max_new_tokens=300)
print(text)
Output:
import 'package:flutter/material.dart';
class SelectMonth extends StatefulWidget {
@override
_SelectMonthState createState() => _SelectMonthState();
}
class _SelectMonthState extends State<SelectMonth> {
String? selectedMonth;
final List<String> monthNames = ['January', 'February', 'March', 'April', 'May', 'June'];
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
DropdownButton<String>(
value: selectedMonth,
items: monthNames
.map((month) => DropdownMenuItem(value: month, child: Text(month)))
.toList(),
onChanged: (val) => setState(() => selectedMonth = val),
),
Text('Selected month: ${selectedMonth ?? 'None'}'),
],
);
}
}
| Base model | Qwen/Qwen2.5-Coder-0.5B (~0.5B params, pretrained by Alibaba/Qwen) |
| Fine-tuning | 5M tokens, flat goal → complete-file examples |
| Tokenizer | Qwen's native BPE tokenizer, extended with structural special tokens |
@misc{andrejev2026diffs,
title = {Diffs vs. Whole Files: An Empirical Comparison of Iterative Edit-Based and Direct Generation for Flutter/Dart Code Models},
author = {Andrejev, Andrej},
year = {2026},
eprint = {2609.05779},
archivePrefix = {arXiv},
primaryClass = {cs.SE},
url = {https://arxiv.org/abs/2609.05779}
}