Downloads · 30 days
16
21% of all-time downloads
fport/issue-writer-gemma4-lora
issue-writer-gemma4-lora is a text generation model from fport. 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.
Turns raw product input — a Slack message, a support ticket, a Sentry alert — into a structured issue tracker entry. Output is always a single JSON object.
Downloads · 30 days
16
21% of all-time downloads
All-time downloads
77
Public
Repo size
652 MB
Likes
0
Public
Click a slice to open those files.
.safetensors294 MB · 90%
From the Hugging Face model README
Turns raw product input — a Slack message, a support ticket, a Sentry alert — into a structured issue tracker entry. Output is always a single JSON object.
Works in English and Turkish; the language of the output follows the input.
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
base = AutoModelForCausalLM.from_pretrained(
"unsloth/gemma-4-E4B-it", dtype=torch.bfloat16, device_map="auto")
model = PeftModel.from_pretrained(base, "fport/issue-writer-gemma4-lora")
tok = AutoTokenizer.from_pretrained("fport/issue-writer-gemma4-lora")
SYSTEM = ("You are a senior agile delivery assistant. You turn raw product input "
"into well-formed Jira issues. Reply with a single valid JSON object and "
"nothing else. Follow INVEST, write testable Given/When/Then acceptance "
"criteria, and never invent facts: anything the input does not state goes "
"into `assumptions` or `clarifying_questions`.")
msgs = [{"role": "system", "content": SYSTEM},
{"role": "user", "content": "Turn this into a Jira issue.\n\n---\n"
"hey team, users keep asking to export their invoice history as one PDF "
"instead of opening each invoice\n---"}]
# The rendered template already carries <bos>; letting the tokenizer add another
# measurably degrades Gemma output.
text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
enc = tok(text, return_tensors="pt", add_special_tokens=False).to(model.device)
out = model.generate(**enc, max_new_tokens=1400, do_sample=False)
print(tok.decode(out[0][enc["input_ids"].shape[1]:], skip_special_tokens=True))
Use the system prompt verbatim. It is one of the three the model was trained on; rewording it — even to drop a vendor name — moves the model off-distribution and costs output quality. The Turkish equivalent is in the dataset.
Greedy decoding (do_sample=False) is deliberate. The output is a schema, not prose;
sampling only produces malformed JSON.
{
"issue_type": "Story",
"summary": "Add bulk PDF export to invoice history",
"description": "h2. User Story\nAs a customer …\n\nh2. Context\n…\n\nh2. Acceptance Criteria\n…",
"priority": "Medium",
"severity": null,
"labels": ["export", "self-service"],
"components": ["Billing"],
"story_points": 5,
"acceptance_criteria": [
{"id": "AC1", "given": "…", "when": "…", "then": "…"}
],
"assumptions": ["Assumed the export covers the selected date range …"],
"clarifying_questions": ["What is the widest range that can be exported?"],
"dor_check": {"ready": false, "missing": ["acceptance detail"]}
}
The schema is defined in
schema/issue.schema.json,
generated from a pydantic model so the two cannot drift.
assumptions and clarifying_questions carry most of the value. The model is
trained to put anything the input did not state there, rather than inventing a
plausible detail in the body. On thin input those fields should be populated — if
they come back empty, treat the output with suspicion.
| Base | unsloth/gemma-4-E4B-it (~4.5B effective, 8B total) |
| Method | LoRA, r=32, alpha=64, no dropout |
| Targets | attention + MLP projections, text layers only |
| Trainable | ~73M parameters, 0.9% of the model |
| Data | 13,000 examples, 50% English / 50% Turkish |
| Objective | supervised, loss on assistant turns only |
| Optimiser | adamw_8bit, lr 1e-4, cosine, warmup 3% |
The dataset covers ten domains and ten task types — drafting issues, classifying type with the rejected alternative, splitting epics, adding acceptance criteria, triage, estimation and Definition of Ready review. Splits hold out whole content cores, so the test set measures generalisation rather than recall.
Apache-2.0, same as the base model.