TurkExtract — Türkçe Bilgi Çıkarımı · Turkish Information Extraction
TurkExtract, Türkçe bir metinden sizin tanımladığınız şemaya göre yapılandırılmış bilgi çıkarır: varlıklar (kişi, kurum, tarih, ilaç, sorun …), aralarındaki ilişkiler ("kurucusu", "çalıştığı kurum", "yol açtığı sonuç" …), varlıkların öznitelikleri (ör. duygu), form/kayıt alanları (randevu, dava, sipariş …) ve sınıflandırma (konu, niyet, duygu). Etiketleri istediğiniz gibi yazarsınız; yeni bir tür için modeli yeniden eğitmek gerekmez. 287M parametre, CPU'da kısa bir metin için ~0,2–0,3 saniye.
English version below.
Görseller projenin demosundan alınmış gerçek çıktılardır (demo eşiği 0,5). Kusurları da görünüyor: ilk örnekte soyut ilişkiler ("yol açtığı sonuç", "çözümü") bu eşikte çıkmıyor; ikincide kayıttaki branş ve doktor alanları boş kalıyor.
Ne çıkarır?
| Görev | Siz verirsiniz | Model döndürür |
|---|---|---|
| Varlıklar | tür adları, isterseniz açıklamalarıyla ("ilaç": "etken madde ya da ticari ad") |
metindeki her varlık: tür, metin, karakter konumu, güven |
| İlişkiler | ilişki adı ve iki tarafın türü ("kurucusu": {"head": "şirket", "tail": "kişi"}) |
(baş, ilişki, kuyruk) üçlüleri ve güven |
| Öznitelikler | varlıklara bağlı değer grupları (duygu: olumlu / olumsuz / nötr) |
her varlık için seçilen değer |
| Kayıtlar | form türü ve alanları (randevu: tarih, saat, yer · durum = onaylı / iptal) |
doldurulmuş alanlar ve seçimler |
| Sınıflandırma | görev ve etiketler (niyet: randevu alma, iptal, bilgi) |
seçilen etiket(ler) ve güven |
Hızlı başlangıç
# pip install gliner2==2.0.0 torch "transformers>=4.57,<5" huggingface_hub
import sys
from huggingface_hub import snapshot_download
path = snapshot_download("furkanbekmezci/turkextract-turkish-information-extraction")
sys.path.insert(0, path) # modelin yanındaki küçük `turkextract` paketi
from turkextract import TurkExtract
m = TurkExtract.from_pretrained(path, device="cpu")
sonuc = m.extract(
"NovaSoft'un kurucusu Ahmet Yılmaz, şirketin yeni genel müdürü olarak Elif Şahin'i atadığını açıkladı.",
entities=["kişi", "şirket"],
relations={"kurucusu": {"head": "şirket", "tail": "kişi"}, "genel müdürü": {"head": "şirket", "tail": "kişi"}},
)
print(sonuc["entities"]) # [{'label': 'şirket', 'text': 'NovaSoft', ...}, {'label': 'kişi', 'text': 'Ahmet Yılmaz', ...}, ...]
print(sonuc["relations"]) # [{'label': 'kurucusu', 'head': {'text': 'NovaSoft', ...}, 'tail': {'text': 'Ahmet Yılmaz', ...}, ...}, ...]
Kayıt, öznitelik ve sınıflandırma örnekleri: m.extract(metin, entities=..., records={"randevu": {"fields": ["tarih", "saat"], "choices": {"durum": ["onaylı", "iptal"]}}}, classification={"niyet": ["randevu alma", "iptal", "bilgi"]}). Görev başına karar eşikleri
doğrulama verisiyle ayarlandı (thresholds.json); threshold= ile hepsini birden değiştirebilirsiniz. Uzun metinler (350 kelimeden
fazla) parçalara bölünerek işlenir.
Model ve eğitim
- Temel model:
fastino/gliner2.5-multi-v1(GLiNER2 sınır tabanlı mimari, Apache-2.0). - Veri: 295.784 Türkçe eğitim örneği:
- 11 açık veri seti (insan etiketli, yarı otomatik ya da sentetik; lisansları
NOTICE.md'de): Türkçe WikiNER, MultiCoNER, TWNERTC (kaba ve ince), MASSIVE, kişisel veri (PII) setleri, e-ticaret ve vitamin-takviye NER, konu ve niyet sınıflandırma; - şablonla üretilmiş sentetik örnekler (~200 bin; tüm görev türleri, Türkçe ek ve biçim çeşitliliği);
- Gemma 4 31B ile şeması serbestçe önerilip etiketlenen açık şemalı örnekler (Vikipedi paragrafları ve ~120 alanda üretilmiş metinler);
- son turda ilişki yoğun veri: her metni iki bağımsız Gemma çağrısı etiketledi, ilişki kümeleri yeterince uyuşan (F1 ≥ 0,8) 2.558 metin tutuldu.
- 11 açık veri seti (insan etiketli, yarı otomatik ya da sentetik; lisansları
- İlişki sorgularında, ilişki açıklaması ve tanımladığınız iki tarafın türleri (
[şirket → kişi]) modele birlikte verilir. - Model seçimi, eşikler ve güven kalibrasyonu yalnızca doğrulama verisiyle yapıldı.
Değerlendirme
Açık şemalı test (505 metin; eğitimde görülmeyen alanlar ve şemalar, etiketler Gemma 4 31B ile üretildi):
| Görev (F1) | TurkExtract | GLiNER2.5-multi (sıfır-atış) |
|---|---|---|
| Varlıklar (tam eşleşme) | 67,7 | 55,4 |
| İlişkiler (tam eşleşme) | 43,4 | 16,5 |
| İlişkiler (gevşek eşleşme) | 57,2 | 23,4 |
| Kayıt alanları | 50,0 | 34,8 |
| Sınıflandırma (micro-F1) | 71,5 | 56,2 |
Genel test (17.973 metin; 16 kaynağın test bölümleri): varlıklar 78,9 · ilişkiler 63,2 · kayıt alanları 47,2 · sınıflandırma 72,6 · öznitelikler (uçtan uca) 28,4. İlişki yoğun test (134 metin, görülmemiş alanlar, iki geçişli etiket): ilişkiler 40,9 (gevşek eşleşmede 63,6); bir önceki sürüm 34,0.
Sınırlılıklar
- İlişkiler en zayıf görev: adlandırılmış varlıklar arası ilişkiler (kurucusu, çalıştığı kurum, merkezi …) iyi çalışırken, soyut ifadeler arası ilişkiler (neden, sonuç, çözüm) sıklıkla kaçırılıyor.
- Öznitelik ve kayıt alanlarında uçtan uca doğruluk düşük; kayıtların tümünü eksiksiz doldurma oranı düşük.
- Açık şemalı ve ilişki yoğun testlerin etiketleri LLM ile üretildi; bu sayılar insan etiketli bir ölçüm değildir.
- Varlık sınırları kelime düzeyinde: kesme işareti olmadan yazılmış eklerde ek de varlığa dahil olabilir ("İstanbulda").
- Tıbbi, hukuki ya da finansal kararlarda tek başına kullanılmamalı.
Lisans
Model ağırlıkları ve kod: Apache-2.0. Temel model fastino/gliner2.5-multi-v1: Apache-2.0. Eğitim verisinin kaynakları ve lisansları
(CC BY 4.0, CC BY-SA 4.0, Apache-2.0, MIT, CC0): NOTICE.md.
English
TurkExtract extracts structured information from Turkish text following a schema you define at inference time: entities, typed relations between them, entity attributes (e.g. sentiment), records / form fields and text classification. Labels are free text; new types need no retraining. 287M parameters, ~0.2–0.3 s for a short text on CPU. The images above are real outputs of the project's demo (threshold 0.5), imperfections included.
Usage: see the quick-start above (TurkExtract.from_pretrained(path).extract(text, entities=..., relations=..., records=..., classification=..., attributes=...)). Requirements: gliner2==2.0.0, torch, transformers>=4.57,<5.
Model and training. Fine-tuned from fastino/gliner2.5-multi-v1 (GLiNER2 boundary architecture) on 295,784 Turkish examples: 11
public datasets (WikiNER, MultiCoNER, TWNERTC, MASSIVE, PII, e-commerce and supplement NER, topic and intent classification; licenses
in NOTICE.md), ~200k template-generated examples covering every task, open-schema examples whose schemas were proposed and labelled
by Gemma 4 31B (Wikipedia paragraphs and generated texts across ~120 domains), and in the last round 2,558 relation-dense texts labelled
by two independent Gemma passes (kept at relation-set agreement F1 ≥ 0.8). Relation queries carry the relation description and the
declared argument types. Checkpoint, thresholds and calibration were chosen on validation data only.
Evaluation. Open-schema test (505 texts, unseen domains and schemas, Gemma-labelled), TurkExtract vs GLiNER2.5-multi zero-shot: entities 67.7 vs 55.4, relations strict 43.4 vs 16.5 (relaxed 57.2 vs 23.4), record fields 50.0 vs 34.8, classification micro-F1 71.5 vs 56.2. Full test (17,973 texts, 16 sources): entities 78.9, relations 63.2, record fields 47.2, classification 72.6, attributes end-to-end 28.4. Relation-dense test (134 texts): relations 40.9 (previous version 34.0).
Limitations. Relations are the weakest task (relations between named entities work well; relations between abstract phrases such as cause, effect or solution are often missed); attribute and record extraction end-to-end scores are low; the open-schema and relation-dense test labels were produced by an LLM, not by humans; entity boundaries are word-level, so suffixes written without an apostrophe can be included. Do not use as the sole basis for medical, legal or financial decisions.
License. Weights and code: Apache-2.0. Base model: Apache-2.0. Training data sources and licenses (CC BY 4.0, CC BY-SA 4.0,
Apache-2.0, MIT, CC0): NOTICE.md.