tr-factbench-electra-lora / inference_example.py
angeldust007's picture
Upload inference_example.py with huggingface_hub
41504b2 verified
Raw
History Blame Contribute Delete
4.85 kB
"""
Inference example for engin-dalga/tr-factbench-electra-lora
Loads the LoRA adapter on top of the exact base-model revision used during training
and runs factuality verification on a short example.
Requirements:
pip install torch transformers peft
Usage:
python inference_example.py
"""
import json
import torch
from pathlib import Path
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from peft import PeftModel
# ── Configuration ─────────────────────────────────────────────────────────────
BASE_MODEL = "dbmdz/electra-base-turkish-cased-discriminator"
BASE_MODEL_REVISION = "44ba696463e4d853078f3094cec76ba4e924cfd1"
ADAPTER_REPO = "engin-dalga/tr-factbench-electra-lora" # Hugging Face Hub ID
LABEL_MAPPING = {
0: "supported",
1: "partially_supported",
2: "contradicted",
3: "unverifiable",
}
MAX_LENGTH = 512
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# ── Example input ──────────────────────────────────────────────────────────────
EXAMPLE = {
"context": (
"TΓΌrkiye'de lisanslΔ± hekimlerin tΔ±p fakΓΌltesinden mezun olmasΔ± zorunludur. "
"Tıp fakülteleri en az altı yıllık eğitim vermektedir."
),
"question": "Türkiye'de hekim olmak için ne kadar eğitim gereklidir?",
"claim": "Türkiye'de hekim olmak için en az altı yıllık tıp eğitimi zorunludur.",
}
def load_model(adapter_path: str | None = None):
"""
Load base model + LoRA adapter.
Args:
adapter_path: Local path to adapter directory (optional).
If None, loads from Hugging Face Hub.
"""
print(f"Loading tokenizer from: {adapter_path or ADAPTER_REPO}")
tokenizer = AutoTokenizer.from_pretrained(
adapter_path or ADAPTER_REPO,
revision=None, # adapter repo, not base model
)
print(f"Loading base model: {BASE_MODEL}@{BASE_MODEL_REVISION}")
base_model = AutoModelForSequenceClassification.from_pretrained(
BASE_MODEL,
revision=BASE_MODEL_REVISION,
num_labels=len(LABEL_MAPPING),
ignore_mismatched_sizes=True,
)
print(f"Loading LoRA adapter from: {adapter_path or ADAPTER_REPO}")
model = PeftModel.from_pretrained(base_model, adapter_path or ADAPTER_REPO)
model.eval().to(DEVICE)
return model, tokenizer
def format_input(context: str, question: str, claim: str) -> tuple[str, str]:
"""Format context and question+claim into the two text_a / text_b strings used during training."""
text_a = f"[CONTEXT] {context}"
text_b = f"[QUESTION] {question} [CLAIM] {claim}"
return text_a, text_b
def predict(model, tokenizer, context: str, question: str, claim: str) -> dict:
text_a, text_b = format_input(context, question, claim)
enc = tokenizer(
text_a, text_b,
max_length=MAX_LENGTH,
truncation=True,
padding=True,
return_tensors="pt",
)
enc = {k: v.to(DEVICE) for k, v in enc.items()}
with torch.no_grad():
logits = model(**enc).logits
probs = torch.softmax(logits, dim=-1).squeeze().cpu().tolist()
pred_id = int(torch.argmax(logits, dim=-1).item())
return {
"predicted_label": LABEL_MAPPING[pred_id],
"probabilities": {LABEL_MAPPING[i]: round(p, 4) for i, p in enumerate(probs)},
}
def verify_classifier_head(model) -> None:
"""Quick sanity check: confirm the classifier head is inside the adapter (modules_to_save)."""
classifier_params = [
n for n, _ in model.named_parameters()
if "classifier" in n or "modules_to_save" in n
]
if not classifier_params:
raise RuntimeError(
"Classifier head not found in adapter parameters. "
"The adapter may be incomplete β€” retrain with modules_to_save=['classifier', 'score']."
)
print(f"[OK] Classifier head found in adapter ({len(classifier_params)} parameters).")
if __name__ == "__main__":
model, tokenizer = load_model()
verify_classifier_head(model)
result = predict(model, tokenizer, **EXAMPLE)
print("\n── Inference result ──────────────────────────────────────────────────")
print(f"Context : {EXAMPLE['context'][:80]}...")
print(f"Question: {EXAMPLE['question']}")
print(f"Claim : {EXAMPLE['claim']}")
print(f"\nPredicted label : {result['predicted_label']}")
print("Probabilities:")
for label, prob in result["probabilities"].items():
print(f" {label:<22}: {prob:.4f}")