LoRA adapter for Trendyol/Trendyol-LLM-Asure-12B, trained with GRPO (RLVR) on a custom Turkish e-commerce attribute-extraction reward function.
Headline result
On an out-of-distribution test set of 578 Trendyol products drawn from 18 categories (swimwear, underwear, sportswear, scarves, hats, slippers, maternity, bedding, towels, bathrobes, curtains, belts, wallets, men's bags) that were never seen during GRPO training, this adapter brings the base 12B Asure model above the frontier-LLM bar with statistical significance:
model
macro F1 (OOD, 578 rows)
95% CI
Renk
Materyal
Kalıp
Desen
Asure-12B base + v3 prompt
0.305
[0.274, 0.335]
0.448
0.187
0.169
0.418
Claude Opus 4.7 v3 (frontier reference)
0.338
[0.311, 0.365]
0.409
0.176
0.145
0.624
Asure-12B + this adapter (step 250)
0.364
[0.336, 0.391]
0.456
0.195
0.161
0.644
Δ vs Claude on OOD: +0.026 macro F1, paired-bootstrap 95% CI [+0.011, +0.041], P(no improvement) = 0.001 — significant at 99.9% confidence.
The trained adapter wins on all 4 fields OOD (not just Desen). Confidence intervals are computed via paired bootstrap (N=2000 resamples, same indices across models so per-prompt difficulty cancels — see eval/bootstrap_ci.py).
In-distribution test (200 rows, held-out from training)
For the original held-out test split:
model
macro F1 (in-dist, 200 rows)
95% CI
Renk
Materyal
Kalıp
Desen
Asure-12B base + v3 prompt
0.338
[0.294, 0.383]
0.452
0.188
0.269
0.447
Claude Opus 4.7 v3 (frontier reference)
0.366
[0.325, 0.406]
0.457
0.158
0.278
0.572
Asure-12B + this adapter (step 250)
0.380
[0.338, 0.421]
0.465
0.195
0.278
0.583
In-dist Δ vs Claude: +0.014 macro F1, 95% CI [−0.008, +0.036], P=0.11 — directionally above Claude, but the 200-row sample is too small to reach 95% significance. The OOD result above is the more rigorous test.
The biggest single contributor to the gain is the Desen (pattern) field: recall jumped from 0.41 → 0.71 because the policy fully internalized the catalog-default rule (Desen → "Düz" when no explicit pattern keyword is in the title — the modal value at ~65% in-dist and ~75% OOD).
Intended use
Given a Turkish product title (and optionally a brand), produce a strict JSON object with up to four catalog attributes:
Renk (color) — canonical colors, e.g. "Beyaz", "Siyah", "Lacivert", ...
Then call the OpenAI-compatible endpoint with model="asure-12b-grpo". See the prompt template below for the exact system+user shape we trained on.
With transformers + PEFT (research / single-call)
python
1from peft import PeftModel
2from transformers import AutoModelForCausalLM, AutoTokenizer
3import torch
45base = AutoModelForCausalLM.from_pretrained(6"Trendyol/Trendyol-LLM-Asure-12B",7 torch_dtype=torch.bfloat16,8 device_map="auto",9)10model = PeftModel.from_pretrained(base,"KocKaankk/asure-12b-tr-attr-grpo")11tok = AutoTokenizer.from_pretrained("KocKaankk/asure-12b-tr-attr-grpo")1213# See "Prompt template" below for SYSTEM and USER strings.14messages =[15{"role":"system","content": SYSTEM},16*FEW_SHOTS,17{"role":"user","content": USER.format(title="Erkek Slim Fit %100 Pamuk Basic Tişört Beyaz", brand_line="Marka: Mavi\n")},18]19prompt = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)20out = model.generate(21**tok(prompt, return_tensors="pt").to(model.device),22 max_new_tokens=128, do_sample=False,23)24print(tok.decode(out[0], skip_special_tokens=True))
Prompt template (v3, the one we trained on)
The model is sensitive to the prompt format. The system text sets per-field canonical vocabulary and the Desen → "Düz" default rule; the user template is a tight Marka:/Ürün adı:/JSON: shape with three Turkish few-shot examples between system and user.
The complete system prompt is ~280 tokens — too long to paste here. The exact text used in training is in eval/prompts.py (V3 constant). If serving in production, copy that file verbatim — there is no other supported prompt for this adapter.
We saved checkpoints every 50 steps and evaluated each on the held-out test set:
step
macro F1 on test
Δ vs base
base
0.339
ref
50
0.369
+0.030
100
0.374
+0.035
150
0.375
+0.036
200
0.376
+0.037
250
0.380
+0.041 (peak — this checkpoint)
300
0.376
+0.037 (slight overshoot — cosine LR tail)
Distribution shape (best-of-8 at T=0.8 on the held-out test set)
metric
base
this adapter (step 250)
Δ
mean-of-8
0.319
0.369
+0.050 (low-reward tail lifted)
best-of-8
0.457
0.463
+0.006 (ceiling held — no sacrifice)
RL headroom (best − mean)
+0.137
+0.094
−0.043 (−31%)
Distribution narrowed by ~31% with no ceiling sacrifice — textbook successful RLVR signature.
Limitations
Domain-specific. Trained on a 1,278-title slice of 36 Trendyol categories. Out-of-distribution categories (luxury, perishables, electronics with very different attribute schemas) have not been evaluated.
4 fields only. Trendyol pages have 8-12 attributes per product; this model is good only at the 4 most common ones.
Capability narrowing. RL on a narrow reward function reduces the model's general-Turkish capabilities. This is fine for a specialized attribute-extraction model and a known cost of RLVR; do not use this adapter for free-form Turkish chat.
Prompt-locked. The model only works well with the v3 prompt above. Other prompts (especially zero-shot) will significantly underperform.
JSON output is regex-parsed downstream. The model produces well-formed JSON in 200/200 test cases, but a robust serving pipeline should still validate.
Statistical robustness. The in-distribution +0.014 over Claude (on 200 rows) is not statistically significant (95% CI [−0.008, +0.036], P=0.11). The out-of-distribution +0.026 (on 578 rows) is significant (95% CI [+0.011, +0.041], P=0.001). When citing this model, prefer the OOD number — it's both larger and more rigorous. See notes/v0.6.2-ood-eval.md in the source repo for full methodology.
Reproducibility
Full code, dataset scrapers, training script, eval pipeline, and Terraform infra: github.com/KocKaankk/tr-rl(repo link will be live once published).
The training run that produced this adapter is documented end-to-end in notes/v0.6-grpo.md of that repo.