Elafnawaf / gliner2-arabic-multitask

huggingface.co
Total runs: 56
24-hour runs: -2
7-day runs: -8
30-day runs: -77
Model's Last Updated: September 08 2026
token-classification

Introduction of gliner2-arabic-multitask

Model Details of gliner2-arabic-multitask

GLiNER2 Arabic Multi-Task — entities, classification, structured records, relations

One encoder, four heads, all fine-tuned for Arabic. This is a GLiNER2 checkpoint (boundary architecture, 287M parameters, mDeBERTa-v3 encoder) built on fastino/gliner2.5-multi-v1 . The base model's extraction heads were trained on English and other European languages; the encoder had seen Arabic, the heads had not. This checkpoint trains all four heads on Arabic supervision so that a single model can, from one forward pass and with no task-specific code:

head what you ask what you get
entities a list of entity types every span of each type
classification one or more tasks, each with its label set one label per task (single-label) or several (multi-label)
structured extraction a record schema (field names) a JSON record whose values are substrings of the text
relations a list of relation types (head, tail) pairs for each type

The schema is part of the input. GLiNER2 reads the task names and label names as text, so the model has to have seen Arabic schemas to answer them. Half of the training examples carried an Arabic schema ( المشاعر → إيجابي / سلبي / محايد ) and half the English equivalent, with the same gold answer, so the finished model answers either language . Everything is zero-shot in principle — you can ask for types it never saw — but the tables below list what it was actually tuned on.

Architecture note. The boundary architecture pairs start and end positions directly, so any span length that fits the encoded window is reachable — unlike the span architecture, which is capped at max_width: 8 tokens. Record metadata ( occurrence_policy , field cardinality, anchored records) is live here.

Quick start
pip install "gliner2[local]"
from gliner2.auto import AutoExtractor

# AutoExtractor reads the architecture field in config.json and picks the right
# class. Plain GLiNER2.from_pretrained is span-only and refuses this checkpoint.
model = AutoExtractor.from_pretrained("Elafnawaf/gliner2-arabic-multitask")
Normalise first — this is not optional

GLiNER's word splitter is \w+(?:[-_]\w+)*|\S , and Python's \w does not match Arabic diacritics. A diacritised word shatters into one token per character and every span offset after it is meaningless. Tatweel ( ـ ) fails the other way: it does match \w , so it survives glued to a real word. Strip both before inference:

import re, unicodedata

_DIACRITICS = re.compile(r"[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06ED]")
_INVISIBLE  = re.compile(r"[\u200B-\u200F\u202A-\u202E\u2066-\u2069\uFEFF]")

def normalise(text: str) -> str:
    text = unicodedata.normalize("NFC", text)
    text = _DIACRITICS.sub("", text)       # حركات
    text = text.replace("\u0640", "")      # tatweel ـ
    text = _INVISIBLE.sub("", text)        # ZWJ / RLM / BOM ...
    return text
1 · Entities
text = normalise("أعلنت شركة أرامكو السعودية في الظهران يوم 5 مارس 2024 عن أرباح بلغت "
                 "121 مليار دولار، ويمكن التواصل عبر الرقم 0501234567.")

model.extract_entities(text, ["منظمة / organization", "مكان / place",
                              "مبلغ مالي / money", "رقم جوال / mobile number"])
# {'entities': {'منظمة / organization': ['أرامكو السعودية'],
#               'مكان / place': ['الظهران'],
#               'مبلغ مالي / money': ['121 مليار دولار'],
#               'رقم جوال / mobile number': ['0501234567']}}

# character offsets and confidence, e.g. for redaction
model.extract_entities(text, ["منظمة / organization"],
                       include_spans=True, include_confidence=True)
# {'entities': {'منظمة / organization': [
#     {'text': 'أرامكو السعودية', 'confidence': 0.866, 'start': 11, 'end': 26}]}}

The entity head was trained with bilingual label names of the form عربي / english (full list below). Use those exact strings for the best precision; plain منظمة or organization also work.

2 · Classification
review = normalise("الخدمة كانت ممتازة والتوصيل وصل قبل الموعد، شكراً لكم")

model.classify_text(review, {
    "المشاعر":    ["إيجابي", "سلبي", "محايد"],
    "نوع الخطاب": ["سؤال", "طلب", "شكوى", "تعبير", "إعلان", "أخرى"],
})
# {'المشاعر': 'إيجابي', 'نوع الخطاب': 'تعبير'}

# the same task, asked in English, with confidence
model.classify_text(review, {"sentiment": ["positive", "negative", "neutral"]},
                    include_confidence=True)
# {'sentiment': {'label': 'positive', 'confidence': 0.998}}

model.classify_text(normalise("والله الجو اليوم يجنن، بس الزحمة تقتل"),
                    {"اللهجة": ["خليجي", "مصري", "شامي", "مغاربي", "فصحى"]})
# {'اللهجة': 'فصحى'}
3 · Structured records (JSON)
news = normalise("تأسست شركة الاتصالات السعودية عام 1998 ومقرها الرياض، "
                 "ويرأسها المهندس عليان الوتيد.")

model.extract_json(news, {"شركة": ["الاسم", "المقر", "سنة التأسيس", "الرئيس"]})
# {'شركة': [{'الاسم': ['الاتصالات السعودية'], 'المقر': ['الرياض'],
#            'سنة التأسيس': ['1998'], 'الرئيس': ['عليان الوتيد']}]}

Field values are lists (a field may occur more than once) and extraction is extractive : every value should be a substring of the input. A value that is not is a hallucination — log it. Richer schemas from the gliner2 API ( ChoiceField for a classification inside a record, list-valued fields, several records of the same name under an occurrence_policy ) are supported and were part of training.

4 · Relations
model.extract_relations(news, ["المقر", "تاريخ التأسيس", "المهنة"])
# {'relation_extraction': {'المقر': [['شركة الاتصالات السعودية', 'الرياض']],
#                          'تاريخ التأسيس': [['شركة الاتصالات السعودية', '1998']],
#                          'المهنة': []}}

model.extract_relations(news, ["headquarters location", "inception"])
# {'relation_extraction': {'headquarters location': [['شركة الاتصالات السعودية', 'الرياض']],
#                          'inception': [['شركة الاتصالات السعودية', '1998']]}}
Everything at once
from gliner2 import Schema

schema = (Schema()
          .entities(["شخص / person", "منظمة / organization", "مكان / place"])
          .classification("المشاعر", ["إيجابي", "سلبي", "محايد"])
          .structure("شركة").field("الاسم").field("المقر")
          .relations(["المقر"]))
model.extract(news, schema)
# {'entities': {'شخص / person': ['عليان الوتيد'],
#               'منظمة / organization': ['شركة الاتصالات السعودية'],
#               'مكان / place': ['الرياض']},
#  'المشاعر': 'محايد',
#  'شركة': [{'الاسم': ['شركة الاتصالات السعودية'], 'المقر': ['الرياض']}],
#  'relation_extraction': {'المقر': [['شركة الاتصالات السعودية', 'الرياض']]}}
5 · Multi-label classification

One task, several true labels. Ask with multi_label=True through the schema builder:

from gliner2 import Schema

ticket = normalise("تواصل معنا العميل سعود الدوسري، رقم الهوية 1098765432، عبر الجوال 0551234567 "
                   "بخصوص فاتورة بقيمة 450 ريالاً صادرة بتاريخ 3 مايو 2024 من فرع الرياض.")
TYPES = ["شخص / person", "منظمة / organization", "مكان / place", "تاريخ / date",
         "مبلغ مالي / money", "رقم جوال / mobile number", "رقم الهوية الوطنية / national id number"]

model.extract(ticket, Schema().classification("أنواع الكيانات", TYPES, multi_label=True))
# {'أنواع الكيانات': ['شخص / person', 'مكان / place', 'تاريخ / date',
#                    'رقم جوال / mobile number', 'رقم الهوية الوطنية / national id number']}

On held-out data this returns the exact label set 77% of the time (per-label F1 0.94). It is a cheap first pass before running the entity head on a large corpus.

6 · Records with choice fields and list fields

A choices=[...] field is a classification inside a record: its value comes from the list, not from the text. dtype="list" lets a field hold several values. Together they give you an extracted record plus a decision in one call, which is the shape a PDPL redaction log needs.

record = (Schema().structure("سجل")
          .field("شخص / person", dtype="list")
          .field("رقم الهوية الوطنية / national id number")
          .field("نوع السجل", choices=TYPES)
          .field("يحتوي بيانات شخصية", choices=["نعم", "لا"]))

model.extract(ticket, record)
# {'سجل': [{'شخص / person': ['سعود الدوسري'],
#           'رقم الهوية الوطنية / national id number': ['1098765432'],
#           'نوع السجل': ['شخص / person', 'رقم الهوية الوطنية / national id number'],
#           'يحتوي بيانات شخصية': ['لا']}]}

Read the last line carefully. On the held-out set the record-type field is right 96% of the time and the personal-data flag 100%, but on fresh support text the flag under-fires, as above, where an ID number is present and the answer should be نعم . Do not let the model's flag be the only gate: derive it from the extracted fields ( bool(record["شخص / person"] or record["رقم الهوية الوطنية / national id number"]) ) and keep the choice field as a second opinion.

7 · Several records of one name from one text

Records were trained with mode / occurrence_policy metadata so that one text can yield a list of records. This is the weakest shape in the current checkpoint:

meeting = normalise("حضر الاجتماع المهندس فهد العتيبي من شركة أرامكو، والدكتورة ريم الشهري من "
                    "جامعة الملك سعود، والأستاذ ماجد القحطاني من هيئة الاتصالات.")

model.extract(meeting, Schema().structure("مشارك", mode="natural", occurrence_policy="all")
                                .field("الاسم").field("الجهة"))
# {'مشارك': [{'الاسم': 'فهد العتيبي', 'الجهة': ['أرامكو']}]}      <- one of three

Held-out pair F1 is 0.68 with recall as the limit (about one record returned per two or three in gold). When you need every participant, ask the entity head, which does return them all, and pair by proximity yourself:

model.extract_entities(meeting, ["شخص / person", "منظمة / organization"])
# {'entities': {'شخص / person': ['فهد العتيبي', 'ريم الشهري'],
#               'منظمة / organization': ['أرامكو', 'جامعة الملك سعود', 'هيئة الاتصالات']}}
8 · New labels, explained rather than named

The schema is text, so a label the model never saw can carry a description. Pass a dict instead of a list, for entity types and for classification labels alike:

model.extract(ticket, Schema().entities({
    "رقم مرجعي": "رقم يعرّف عميلاً أو وثيقة، مثل رقم الهوية أو رقم الفاتورة",
    "مبلغ":      "قيمة مالية مع عملتها",
}))
# {'entities': {'رقم مرجعي': ['1098765432'], 'مبلغ': ['450 ريالاً']}}

model.extract(ticket, Schema().classification("نوع الطلب", {
    "شكوى":     "العميل غير راضٍ عن خدمة أو فاتورة",
    "استفسار":  "العميل يسأل عن معلومة",
    "طلب خدمة": "العميل يريد تفعيل أو إلغاء خدمة",
}))
# {'نوع الطلب': 'استفسار'}

Relation descriptions are accepted by the API but did not help this checkpoint on business relations ( شراكة , استحواذ came back empty); the relation head knows the 32 Wikidata predicates listed below.

9 · Batches and long documents

Every extract_* call has a batch_* twin that takes a list of texts, and a *_long twin that chunks a document (default 384 tokens with 64 of overlap) and merges the spans:

model.batch_extract_entities([ticket, meeting], ["شخص / person", "منظمة / organization"],
                             batch_size=8, threshold=0.3)
# [{'entities': {'شخص / person': ['سعود الدوسري'], 'منظمة / organization': []}},
#  {'entities': {'شخص / person': ['فهد العتيبي', 'ريم الشهري'],
#                'منظمة / organization': ['أرامكو', 'جامعة الملك سعود', 'هيئة الاتصالات']}}]

model.extract_entities_long(long_document, ["شخص / person", "رقم جوال / mobile number"],
                            chunk_size=384, chunk_overlap=64, include_spans=True)

Batching sorts by length internally; on one L4 the entity head scores about 200 sentences per second at batch 8.

threshold (default 0.5) is accepted by every call; lower it for recall, raise it for precision. Per-label entity thresholds tuned on the dev set are in inference_config.json , together with every task name and label set the model was trained on, in both languages.

What it was trained to answer
Entity types (17)

تاريخ / date , ترتيب / ordinal , رقم الهوية الوطنية / national id number , رقم جوال / mobile number , شخص / person , عدد / cardinal number , عملة / currency , عنوان / address , كمية / quantity , مبلغ مالي / money , مطار / airport , مكان / place , منظمة / organization , موقع إلكتروني / website , نسبة مئوية / percentage , وحدة قياس / unit of measurement , وقت / time

Classification tasks
task (ar) task (en) labels
اللهجة dialect مصري (egypt), خليجي (gulf), شامي (levant), مغاربي (magreb), فصحى (msa)
السخرية sarcasm غير ساخر (non-sarcastic), ساخر (sarcastic)
المشاعر sentiment سلبي (negative), محايد (neutral), إيجابي (positive), سلبي (Negative), محايد (Neutral), إيجابي (Positive), مختلط (Mixed)
نوع الخطاب speech act تأكيد (Assertion), توصية (Recommendation), تعبير (Expression), سؤال (Question), طلب (Request), أخرى (Miscellaneous)
الموضوع topic تقنية (Tech), اقتصاد (Finance), سياسة (Politics), دين (Religion), طب (Medical), ثقافة (Culture), رياضة (Sports)
Relation types (32, Wikidata predicates from REDFM)
English Arabic
author المؤلف
capital العاصمة
cast member من طاقم العمل
characters الشخصيات
child الابن
country الدولة
country of citizenship بلد الجنسية
director المخرج
follows يتبع
founded by أسسها
genre النوع
headquarters location المقر
inception تاريخ التأسيس
instance of نوع من
league الدوري
located in or next to body of water يقع على مسطح مائي
location الموقع
manufacturer الشركة المصنعة
member of عضو في
mouth of the watercourse مصب النهر
named after سمي نسبة إلى
notable work عمل بارز
occupation المهنة
owned by مملوك لـ
part of جزء من
participant مشارك
place of birth مكان الميلاد
replaces يحل محل
shares border with يحد
sibling شقيق
sport الرياضة
spouse الزوج
Results

Measured on held-out Arabic before and after the multi-task fine-tune. "Before" is the base checkpoint fastino/gliner2.5-multi-v1 answering the same Arabic schemas.

head metric before after
entities span-exact micro-F1 (1,500 test sentences, 17 types) 0.352 0.693
structure field-level F1 (600 held-out records) 0.242 0.791
relations triple F1 on REDFM Arabic, human-revised (344 sentences) 0.171 0.406
Classification accuracy (600 held-out examples, per task)
task before after
dialect 0.265 0.618
entity types present 0.438 0.625
sarcasm 0.264 0.806
sentiment 0.588 0.758
speech act 0.168 0.814
topic 0.657 0.971
أنواع الكيانات 0.538 0.692
السخرية 0.712 0.797
اللهجة 0.222 0.571
المشاعر 0.639 0.732
الموضوع 0.768 0.970
نوع الخطاب 0.319 0.782

Relations are scored on Babelscape/REDFM Arabic, which is human-revised and has no Arabic train split. Training used Babelscape/SREDFM Arabic, which is automatically annotated — so the relation number is measured against people, not against the annotator the model learned from. evaluation.json in this repo holds the full gate report.

The four extra shapes were scored separately on held-out dev examples (before → after): multi-label per-label F1 0.58 → 0.94, choice-field record type 0.01 → 0.96 and personal-data flag 0.04 → 1.00, several-records-per-text pair F1 0.53 → 0.68, named-role relations triple F1 0.32 → 0.51 (identical when asked as plain head/tail, so treat it as an ordinary relation result).

Training data

All supervision is public and Arabic. Each source is capped so that no head dominates the summed loss; the caps below are the number of examples drawn per source.

source used for examples link
WikiANN + IAHLT + Wojood sample + synthetic Saudi PII entities 40,000 entities
ArSarcasm sentiment, sarcasm, dialect 12,000 sarcasm
ArSAS speech act, sentiment 14,000 arsas
SANAD news topic 14,000 sanad
SREDFM (ar) relations + free structure records 22,000 sredfm
entity gold → records structured extraction 14,000 —
derived multi-label classification 10,000 —
derived records with ChoiceField / list fields 14,000 —
derived several records per text 7,000 —
derived relations with named roles 7,000 —

Entity corpus (64,365 MSA sentences, converted to character offsets, 17 bilingual labels): wikiann 32,600, iahlt-mafat 26,449, synthetic-pii 4,380, wojood-sample 936. The synthetic PII sentences add Saudi national IDs, mobile numbers, addresses and websites, which none of the public corpora annotate.

The ner_struct , multilabel , rich_records , multi_instance and named_roles sets are derived from the entity gold spans and from SREDFM's typed entities: the same text re-expressed as a record, a multi-label task, a record with a ChoiceField , several records of one name, and relations with named roles. They teach capabilities the plain form does not exercise. Schema language was Arabic for 50% of examples and English for the rest, always with the same gold answer.

Training details
base checkpoint fastino/gliner2.5-multi-v1
trainable parameters 287,355,159 (full fine-tune, no LoRA)
examples 113,003 train / 7,215 dev after dropping 33 examples longer than 384 tokens
epochs 2 (14,126 optimizer steps)
batch 2 × gradient accumulation 8 = effective 16
learning rates encoder 1e-5, task heads 5e-4, linear schedule, 10% warm-up
regularisation weight decay 0.01, gradient clipping 1.0
precision fp32 — with bf16 autocast this model's boundary head overflows within ~300 steps and every weight becomes NaN; fp32 was both stable and faster on an L4
hardware 1 × NVIDIA L4 (24 GB), 4.6 h
checkpoint selection lowest dev loss (evaluated every 1,766 steps)
Intended use and limitations

Built for Arabic text analytics on customer-service, social and news text: PII detection and redaction, intent/sentiment/dialect tagging, pulling structured records out of messages, and light knowledge-graph population.

  • Dialects. The entity corpus is Modern Standard Arabic. Dialect supervision comes only from ArSarcasm's five-way dialect label; Gulf coverage beyond that is untested.
  • Relation predicates come from Wikipedia/Wikidata ( المهنة , العاصمة , الزوج ). They are not domain relations for customer service or media monitoring; asking for such types works zero-shot but is not what the head was tuned on.
  • Ask for dates, amounts and percentages in short type lists. On natural prose the entity head drops تاريخ / date , مبلغ مالي / money and نسبة مئوية / percentage when they are requested together with the full 8-type list, yet finds them (0.7–0.9 confidence) when asked with three or four types. Training passed all 17 labels as explicit negatives on WikiANN/IAHLT sentences, which taught "long list + prose = no numbers"; those types are also 57–100% synthetic in training, so their held-out scores measure the template. Until the next round, call the entity head twice: once for person/organization/place, once for the numeric types.
  • Structured extraction is extractive. A returned value that is not a substring of the input is a hallucination; the evaluation counted zero on the held-out set, but check in production.
  • Classification collapse and overconfidence. Dialect, sarcasm and sentiment lean heavily on the majority label ( فصحى , غير ساخر , محايد ), and the reported confidence is near 1.0 even when wrong, so it is not a usable signal for those tasks. Topic, speech act and message type are reliable.
  • Not a replacement for a rules layer on identifiers: pair the رقم الهوية الوطنية and رقم جوال types with a regex validator (Arabic-Indic digits included).
Files
file purpose
model.safetensors , config.json , encoder_config/ weights and architecture
tokenizer.json , tokenizer_config.json , special_tokens_map.json mDeBERTa tokenizer
inference_config.json every trained task name / label set (ar + en), per-label entity thresholds, normaliser note
evaluation.json the before/after gate report the numbers above come from
Credits

GLiNER2 by Fastino AI ( fastino/gliner2.5-multi-v1 , Apache-2.0). Data: WikiANN (Pan et al.), IAHLT Arabic NER, ArSarcasm (Abu Farha & Magdy), ArSAS (Elmadany et al.), SANAD (Einea et al.), REDFM / SREDFM (Huguet Cabot et al.). Licence of this checkpoint follows the most restrictive source, CC BY-SA 4.0.

Runs of Elafnawaf gliner2-arabic-multitask on huggingface.co

56
Total runs
-2
24-hour runs
-6
3-day runs
-8
7-day runs
-77
30-day runs

More Information About gliner2-arabic-multitask huggingface.co Model

More gliner2-arabic-multitask license Visit here:

https://choosealicense.com/licenses/cc-by-sa-4.0

gliner2-arabic-multitask huggingface.co

gliner2-arabic-multitask huggingface.co is an AI model on huggingface.co that provides gliner2-arabic-multitask's model effect (), which can be used instantly with this Elafnawaf gliner2-arabic-multitask model. huggingface.co supports a free trial of the gliner2-arabic-multitask model, and also provides paid use of the gliner2-arabic-multitask. Support call gliner2-arabic-multitask model through api, including Node.js, Python, http.

gliner2-arabic-multitask huggingface.co Url

https://huggingface.co/Elafnawaf/gliner2-arabic-multitask

Elafnawaf gliner2-arabic-multitask online free

gliner2-arabic-multitask huggingface.co is an online trial and call api platform, which integrates gliner2-arabic-multitask's modeling effects, including api services, and provides a free online trial of gliner2-arabic-multitask, you can try gliner2-arabic-multitask online for free by clicking the link below.

Elafnawaf gliner2-arabic-multitask online free url in huggingface.co:

https://huggingface.co/Elafnawaf/gliner2-arabic-multitask

gliner2-arabic-multitask install

gliner2-arabic-multitask is an open source model from GitHub that offers a free installation service, and any user can find gliner2-arabic-multitask on GitHub to install. At the same time, huggingface.co provides the effect of gliner2-arabic-multitask install, users can directly use gliner2-arabic-multitask installed effect in huggingface.co for debugging and trial. It also supports api for free installation.

gliner2-arabic-multitask install url in huggingface.co:

https://huggingface.co/Elafnawaf/gliner2-arabic-multitask

Url of gliner2-arabic-multitask

gliner2-arabic-multitask huggingface.co Url

Provider of gliner2-arabic-multitask huggingface.co

Elafnawaf
ORGANIZATIONS

Other API from Elafnawaf