A QLoRA adapter for Ministral 3 3B Instruct (2512) specialized in e-commerce catalog tasks with Magento 2 conventions: attribute extraction to JSON, product Q&A, search-relevance classification, and product ranking. Sibling model to gtstadeu/qwen3.5-4b-ec-magento — same frozen data, same recipe, same eval harness — for cross-family comparison.
transformers/peft/unsloth on top of the base model
gguf/
Merged + quantized Q4_K_M + Ollama Modelfile
2.0GB
llama.cpp / Ollama, CPU+GPU serving (text-only)
What it does
Trained on 56,253 instruction samples: 70% ECInstruct (generic e-commerce) + 30% synthetic Magento-schema data generated from the Magento Luma sample catalog (products fully disjoint between train and eval). Four task shapes:
Attribute extraction — product text (or a raw Magento custom_attributes payload) → JSON:
Absent attributes are reported as "None" rather than hallucinated.
Product QA — a question answered strictly from given product data.
Relevance classification — query + product → graded relevance option (ESCI-style A–D).
Relevance ranking — query + lettered product list → ranked letters (B,A,C).
Usage — adapter (unsloth / peft)
python
1from unsloth import FastLanguageModel
23model, tokenizer = FastLanguageModel.from_pretrained(4"gabrielgts/ministral3-3b-ec-magento", max_seq_length=2048, load_in_4bit=True)5FastLanguageModel.for_inference(model)67# An EXPLICIT EMPTY system message is REQUIRED: without one, the Ministral 38# chat template injects Mistral's ~520-token default system prompt, which the9# adapter was not trained with. The multimodal Processor also requires10# tokenizer(text=...), never a positional string.11messages =[12{"role":"system","content":""},13{"role":"user","content":14"Extract the value of the target attribute from the given product information "15"and output it as JSON. If the attribute is not present, output None as the value.\n\n"16"target attribute: size\nproduct title: Puma Suede green sneakers size 43"},17]18text = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)19inputs = tokenizer(text=text, return_tensors="pt").to("cuda")20out = model.generate(**inputs, max_new_tokens=64, do_sample=False)# greedy recommended21print(tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))22# [{"attribute": "size", "value": "43"}]
Plain peft also works: PeftModel.from_pretrained(base_model, "gabrielgts/ministral3-3b-ec-magento").
The bundled Modelfile renders the trained prompt format ([SYSTEM_PROMPT][/SYSTEM_PROMPT][INST]…[/INST]) with temperature 0. If your Ollama version ships a built-in Ministral 3 renderer, pass an explicit empty system prompt per request so Mistral's default one is not injected.
Training recipe
Parameter
Value
Method
QLoRA (4-bit NF4 base, bf16 compute) via Unsloth
LoRA
r=8, alpha=16, targets q/k/v/o/gate/up/down_proj (language model only; vision tower frozen)
explicit empty system message at train and eval (suppresses the template default)
Evaluation
Greedy decoding, identical prompts and chat template across all models; base model evaluated zero-shot with the same harness. The Qwen column is the same-data, same-recipe sibling qwen3.5-4b-ec-magento (4.55B params vs 3.85B text params here — mind the ~15% size gap when comparing).
Magento held-out set (2,969 samples, 475 products never seen in training):
Task · metric
Base
this model
qwen3.5-4b-ec-magento
Attribute extraction · F1
0.000
0.945
0.938
Attribute extraction · parse failures
100%
0.1%
0%
Product QA · token-F1
0.039
0.954
0.943
Relevance classification · accuracy
0.132
0.972
0.962
Relevance rank · top-1
0.299
0.793
0.799
ECInstruct held-out set (2,000 samples):
Task · metric
Base
this model
qwen3.5-4b-ec-magento
Attribute extraction · F1
0.000
0.654
0.646
Query→product rank · top-1
0.000
0.632
0.650
Relevance classification · accuracy
0.013
0.655
0.685
Answerability · accuracy
0.507
0.735
0.780
Limitations — read before relying on the numbers
The Magento eval is synthetic-on-synthetic. Eval tasks were generated with the same templates as training data (products fully disjoint). It validly measures schema adherence — JSON format, Magento attribute vocabularies, the None-when-absent rule — but overstates production quality on real catalogs and real user queries.
The base model's near-zero extraction scores are dominated by format non-adherence (it answers in prose); they understate its underlying capability, though prose output is itself a blocker for programmatic use.
Fine-tuned on English-only structured data: expect degraded multilingual and general-chat ability versus the base model (drop the adapter to recover it). The vision tower is untouched, but this repo's GGUF is text-only.
Free-form generation is weak (trained r=8, extraction-focused); use it for structured tasks, not copywriting.
Use greedy decoding (do_sample=False / temperature 0) — that's how it was evaluated.