Downloads · 30 days
15
11% of all-time downloads
david-di-castro/didibert-enforcement116-he-cls
didibert-enforcement116-he-cls is a text classification model from david-di-castro. Use it when you need a label for a piece of text. It is set up for transformers. The card lists the license as apache-2.0.
A Hebrew classifier that routes free-form queries to single legal section IDs from Israel’s Planning & Building Law (Amendment 116). This model exposes legal sections through free-form Hebrew queries for two primary a…
Downloads · 30 days
15
11% of all-time downloads
All-time downloads
138
Public
Parameters
110M
438 MB on disk
Likes
1
Public
Click a slice to open those files.
.safetensors438 MB · 100%
From the Hugging Face model README
A Hebrew classifier that routes free-form queries to single legal section IDs from Israel’s Planning & Building Law (Amendment 116). | This model exposes legal sections through free-form Hebrew queries for two primary actors:
243, 239, general, neutral) via id2label.BertForSequenceClassificationmax_position_embeddings=512).safetensors), config.json (with label mapping), tokenizer files, license.The model was trained through intensive supervised fine-tuning across multiple iterations.
Each round of training was carefully monitored and validated.
The Hebrew legal dataset was manipulated and expanded between training rounds:
This iterative process ensured that the model’s weights became progressively stronger.
After every training cycle:
The model outputs a deterministic section ID (e.g., 216).
For production use, it is recommended to pair this classifier with RAG (Retrieval-Augmented Generation):
The outcome is a powerful NLP classification tool:
This classifier is a central component in constructing a large Hebrew corpus for LLM training.
It provides deterministic routing to canonical section IDs, supports de-duplication and curriculum design, and mitigates Hebrew tokenization pitfalls (RTL marks, zero-width chars, niqqud, clitics) via consistent normalization and section-aware segmentation.
Use with Retrieval-Augmented Generation (RAG).
For consistent answers and to avoid hallucinations:
section_id with this model.section_id as a hard filter.Why this works: stable routing, Hebrew-aware normalization, and section-aware segmentation reduce noise and keep answers aligned with the law text.
config.json:
id2label, label2id, and num_labels.r = 8–16, alpha = 16–32, dropout ≈ 0.05, LR 2e-4…5e-4, batch 16–64, max seq length 512.general / neutral as catch-all classes for out-of-scope inputs.config.json.The examples below demonstrate the model’s routing power from its pretrained weights. Adapting it to broader Israeli enforcement domains is straightforward with PEFT or light finetuning.
This work builds upon the open-source HeBERT model. Huge thanks to the HeBERT team and community 🙏. This repository is not affiliated with the HeBERT authors; any mistakes are mine. HeBERT is released under Apache-2.0, and I keep the same license here. If you extend or fine-tune this model, please retain this acknowledgement.
from transformers import pipeline
REPO = "david-di-castro/didibert-enforcement116-he-cls"
clf = pipeline("text-classification", model=REPO, truncation=True)
out = clf("מפקח נתן לי צו הפסקת עבודה. מה זה אומר?", max_length=512)[0]
print(out["label"], out["score"]) # section id + confidence






from transformers import pipeline
clf = pipeline("text-classification",
model="david-di-castro/didibert-enforcement116-he-cls",
token="hf_...",
truncation=True)
out = clf("מפקח נתן לי צו הפסקת עבודה. מה זה אומר?")[0]
print(out["label"], out["score"])
from transformers import pipeline
REPO = "david-di-castro/didibert-enforcement116-he-cls"
clf = pipeline("text-classification", model=REPO, truncation=True)
out = clf("בניה בחוף הים זה חמור?")[0]
section = out["label"]
score = out["score"]
print(f"section: {section}, score: {score:.4f}")
from transformers import pipeline
REPO = "david-di-castro/didibert-enforcement116-he-cls"
clf = pipeline("text-classification", model=REPO, truncation=True)
out = clf("בניתי ללא היתר וקיבלתי צו הריסה הפרתי אותו והמשכתי לבנות הרשות הרסה לי גם את תוספת הבניה,זה חוקי?")[0]
section = out["label"]
score = out["score"]
print(f"section: {section}, score: {score:.4f}")
A) Continue training (single-label)
from transformers import AutoModelForSequenceClassification, AutoTokenizer
REPO = "david-di-castro/didibert-enforcement116-he-cls"
tok = AutoTokenizer.from_pretrained(REPO)
model = AutoModelForSequenceClassification.from_pretrained(REPO) # 53 labels as shipped
# Train with HF Trainer as usual (labels are integer class ids)
B) Multi-label training (one example can map to multiple sections)
Use binary targets (one-hot vector) and enable the built-in BCE loss:
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(
"david-di-castro/didibert-enforcement116-he-cls",
problem_type="multi_label_classification",
)
# Provide labels as float32 vectors of length num_labels (0/1).
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained( "david-di-castro/didibert-enforcement116-he-cls", problem_type="multi_label_classification", ) #Provide labels as float32 vectors of length num_labels (0/1).
Multi-label inference:
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
REPO = "david-di-castro/didibert-enforcement116-he-cls"
tok = AutoTokenizer.from_pretrained(REPO)
mdl = AutoModelForSequenceClassification.from_pretrained(REPO).eval()
text = "טקסט בעברית…"
with torch.inference_mode():
b = tok(text, return_tensors="pt", truncation=True, padding=True, max_length=512)
probs = mdl(**b).logits.sigmoid()[0]
idxs = (probs >= 0.5).nonzero().flatten().tolist()
labels = [mdl.config.id2label[str(i)] for i in idxs]
print(labels, probs[idxs].tolist())
C) Change the label set size (add/remove classes)
Keep the pretrained encoder; re-init a new classification head:
from transformers import AutoModelForSequenceClassification
NEW_NUM = 80 # your new class count
model = AutoModelForSequenceClassification.from_pretrained(
"david-di-castro/didibert-enforcement116-he-cls",
num_labels=NEW_NUM,
ignore_mismatched_sizes=True, # preserves encoder weights, re-inits head
)
# Update mapping for transparency
id2label = {i: f"CLASS_{i}"} # replace with your real names
label2id = {v: k for k, v in id2label.items()}
model.config.id2label = id2label
model.config.label2id = label2id
LoRA is usually enough to adapt to new enforcement domains while keeping the base stable.
Install:
pip install -U peft transformers accelerate
Wrap the model with LoRA (example targets BERT attention projections):
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForSequenceClassification, AutoTokenizer
REPO = "david-di-castro/didibert-enforcement116-he-cls"
tok = AutoTokenizer.from_pretrained(REPO)
model = AutoModelForSequenceClassification.from_pretrained(REPO)
lora_cfg = LoraConfig(
r=16, lora_alpha=32, lora_dropout=0.05, bias="none",
target_modules=["query","key","value","dense"] # typical for BERT
)
model = get_peft_model(model, lora_cfg)
# Train with Trainer as usual. Keep seq length 512; batch 16–64; LR 2e-4..5e-4; a few epochs.
Export mapping after training :
model.config.id2label = {i: name_i for i, name_i in enumerate(your_label_names)}
model.config.label2id = {v: k for k, v in model.config.id2label.items()}
model.config.save_pretrained("./your-finetuned-repo")
--Single-label: accuracy, macro/micro F1.
--Multi-label: example-based F1, macro/micro F1, average precision (mAP). Tune the decision threshold (e.g., 0.3–0.6) on a validation set.