Instructions to use opdullah/bertturk-product-matcher with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use opdullah/bertturk-product-matcher with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="opdullah/bertturk-product-matcher")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForSequenceClassification tokenizer = AutoTokenizer.from_pretrained("opdullah/bertturk-product-matcher") model = AutoModelForSequenceClassification.from_pretrained("opdullah/bertturk-product-matcher", device_map="auto") - Notebooks
- Google Colab
- Kaggle
BERTturk Product Matcher
By opdullah. A Turkish BERT pair classifier for research on whether two
product titles describe the same product. Label 1 means same; label 0 means
different. This is a fine-tune of dbmdz/bert-base-turkish-cased.
The default weights are the checkpoint after two complete epochs.
Training
| Setting | Value |
|---|---|
| Training pairs | 1,803,494 |
| Dataset | opdullah/turkish-product-matching-706k, matching configuration |
| Dataset revision | 2c515bdbb63eac04343eb6df628b4a7fe961fc51 |
| Epochs | 2 |
| Optimizer updates | 56,360 |
| Hardware | 1 NVIDIA A100 SXM 80 GB |
| Batch size / gradient accumulation | 64 / 1 |
| Maximum combined pair length | 512 tokens, including special tokens |
| Learning rate | 0.00002 |
| Precision | BF16 mixed precision |
| Seed | 42 |
Training pairs are shuffled each epoch. Product title order is randomly swapped during training. Evaluation and inference average both title orders.
Evaluation of the two-epoch checkpoint
Validation contains 224,850 pairs and uses decision threshold 0.5.
| Metric | Value |
|---|---|
| Accuracy | 96.2224% |
| Precision (same product) | 98.1639% |
| Recall (same product) | 94.2068% |
| F1 (same product) | 96.1447% |
| ROC AUC | 0.995083 |
| Average precision | 0.994994 |
Inference
Install the libraries:
pip install "torch>=2.6" "transformers>=4.57,<5" "huggingface_hub>=0.36,<1"
Run this setup once. It is shown in full so no helper script needs to be downloaded.
CPU is supported; CUDA is selected automatically when available. You can pass
device="mps" on a supported Apple computer. revision can be a commit ID for
reproducible research.
import json
import torch
from huggingface_hub import hf_hub_download
from transformers import AutoTokenizer, AutoModelForSequenceClassification
class ProductMatcher:
def __init__(self, model_id="opdullah/bertturk-product-matcher",
revision="main", device=None):
self.device = torch.device(device or ("cuda" if torch.cuda.is_available() else "cpu"))
self.tokenizer = AutoTokenizer.from_pretrained(model_id, revision=revision)
self.model = AutoModelForSequenceClassification.from_pretrained(
model_id, revision=revision).to(self.device).eval()
decision_path = hf_hub_download(model_id, "decision.json", revision=revision)
self.decision = json.loads(open(decision_path).read())
self.positive_id = int(self.model.config.label2id["same"])
@torch.inference_mode()
def predict_batch(self, pairs, batch_size=32, threshold=None):
if batch_size < 1:
raise ValueError("batch_size must be positive")
pairs = list(pairs)
if any(not isinstance(pair, (tuple, list)) or len(pair) != 2
or any(not isinstance(text, str) or not text.strip() for text in pair)
for pair in pairs):
raise ValueError("Each pair must contain two non-empty title strings")
threshold = float(self.decision["threshold"] if threshold is None else threshold)
if not 0 <= threshold <= 1:
raise ValueError("threshold must be between 0 and 1")
results = []
for start in range(0, len(pairs), batch_size):
chunk = pairs[start:start + batch_size]
first = [title for a, b in chunk for title in (a, b)]
second = [title for a, b in chunk for title in (b, a)]
inputs = self.tokenizer(first, second, padding=True,
truncation="longest_first", max_length=self.decision["max_length"],
return_tensors="pt").to(self.device)
scores = self.model(**inputs).logits.float().softmax(-1)[:, self.positive_id]
scores = scores.reshape(-1, 2).mean(-1).cpu().tolist()
for score in scores:
same = score >= threshold
results.append({"label": "same" if same else "different",
"is_match": same, "probability_same": score, "threshold": threshold})
return results
def predict(self, first, second, threshold=None):
return self.predict_batch([(first, second)], threshold=threshold)[0]
matcher = ProductMatcher()
Single pair
result = matcher.predict(
"Samsung Galaxy A55 128 GB Siyah",
"Samsung A55 Siyah 128GB",
)
print(result)
Example output (rounded):
{"label": "same", "is_match": True, "probability_same": 0.999120, "threshold": 0.5}
Batch inference
pairs = [
("Samsung Galaxy A55 128 GB Siyah", "Samsung A55 Siyah 128GB"),
("Samsung Galaxy A55 128 GB Siyah", "Samsung Galaxy A55 256 GB Siyah"),
("Apple iPhone 15 128 GB Mavi", "iPhone 15 Mavi 128GB"),
]
results = matcher.predict_batch(pairs, batch_size=32)
for pair, result in zip(pairs, results):
print(pair, result)
For the three pairs above, the verified outputs are:
| Pair | Label | Same-product score |
|---|---|---|
| A55 128 GB / A55 128 GB | same | 0.999120 |
| A55 128 GB / A55 256 GB | different | 0.001304 |
| iPhone 15 128 GB / iPhone 15 128 GB | same | 0.998722 |
Scores are rounded; small floating-point differences across devices are expected.
Results are returned in input order with label (same or different),
is_match, probability_same, and threshold. An empty batch returns an empty
list. Each pair is evaluated in both directions and the two same-product scores
are averaged before thresholding. batch_size=32 evaluates up to 64 ordered
sequences per model forward pass; reduce it if device memory is limited.
The combined input is truncated at 512 tokens. Scores are model outputs and
have not been probability-calibrated. Set threshold only when justified by
your own research validation data.
Limitations
The model compares title text; it does not use images, reviews, specifications, or seller information. Ambiguous titles, missing model codes and subtle variant differences can cause errors. It is intended for noncommercial research only.
Base model notice
BERTurk was released by the MDZ Digital Library team (dbmdz) at the Bavarian State Library under the MIT license. Its original license and notices remain applicable. The research-only terms apply to the contributions distributed here and do not replace the base model's license.
Research-only use and attribution
Released under the Research-Only Attribution License 1.0 in LICENSE.md. Use is limited to noncommercial scientific research. Commercial use, production deployment, and non-research uses require separate written permission. Research derivatives and redistributed copies must retain these terms and credit.
Credit opdullah and cite the dataset in any publication or research output that uses it. When using the fine-tuned model, cite the model as well as the dataset. Include the exact revision used for reproducibility.
@misc{opdullah2026turkishproductmatchingdata,
author = {{opdullah}},
title = {Turkish Product Matching 706K},
year = {2026},
howpublished = {Hugging Face dataset: opdullah/turkish-product-matching-706k}
}
@misc{opdullah2026turkishproductmatchingbert,
author = {{opdullah}},
title = {BERTturk Product Matcher},
year = {2026},
howpublished = {Hugging Face model: opdullah/bertturk-product-matcher}
}
- Downloads last month
- 11
Model tree for opdullah/bertturk-product-matcher
Base model
dbmdz/bert-base-turkish-cased