Instructions to use FluidInference/gliner2-5-small-coreml with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- GLiNER2
How to use FluidInference/gliner2-5-small-coreml with GLiNER2:
from gliner2 import AutoExtractor extractor = AutoExtractor.from_pretrained("FluidInference/gliner2-5-small-coreml") # Extract entities text = "Apple CEO Tim Cook announced iPhone 15 in Cupertino yesterday." result = extractor.extract_entities(text, ["company", "person", "product", "location"]) print(result) - Notebooks
- Google Colab
- Kaggle
File size: 3,707 Bytes
4e12f7c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | """Compare the pinned GLiNER2 native classifier with its Core ML export."""
import argparse
import json
import statistics
import time
from pathlib import Path
import coremltools as ct
import numpy as np
import torch
from gliner2 import AutoExtractor
from preprocessing import prepare_classification
MODEL_ID = "fastino/gliner2.5-small-v1"
MODEL_REVISION = "7e6f537f10337497069276892a5ef435028252ce"
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--package", default="build/gliner2_small_classification_fp16_L128_K8.mlpackage")
parser.add_argument("--suite", required=True)
parser.add_argument("--limit", type=int, default=100)
parser.add_argument("--length", type=int, default=128)
parser.add_argument("--max-options", type=int, default=8)
parser.add_argument("--out", default="build/verify.json")
args = parser.parse_args()
torch.set_num_threads(4)
source = Path.home() / ".cache/huggingface/hub/models--fastino--gliner2.5-small-v1/snapshots" / MODEL_REVISION
native = AutoExtractor.from_pretrained(str(source), map_location="cpu").eval()
model = ct.models.MLModel(args.package, compute_units=ct.ComputeUnit.ALL)
counts = {"checked": 0, "too_many_options": 0, "too_long": 0, "duplicate_labels": 0, "mismatches": 0}
errors = []
latencies = []
failures = []
for line in Path(args.suite).open():
row = json.loads(line)
options = row.get("options") or []
if len(options) > args.max_options or not options:
counts["too_many_options"] += 1
continue
labels = [(description or key).strip() for key, description in options]
if len(set(labels)) != len(labels):
counts["duplicate_labels"] += 1
continue
text = row["state"]
task = "decision"
try:
arrays = prepare_classification(native, text, task, labels, args.length, args.max_options)
except ValueError:
counts["too_long"] += 1
continue
expected = native.classify_text(text, {task: labels}, include_confidence=True, max_len=args.length)[task]
start = time.perf_counter()
prediction = model.predict(arrays)
latencies.append((time.perf_counter() - start) * 1000)
probabilities = np.asarray(prediction["probabilities"])[0, : len(labels)]
chosen = labels[int(probabilities.argmax())]
error = abs(float(probabilities.max()) - float(expected["confidence"]))
errors.append(error)
counts["checked"] += 1
if chosen != expected["label"]:
counts["mismatches"] += 1
failures.append({"suite": row["suite"], "index": row["index"], "native": expected, "coreml": chosen})
if counts["checked"] >= args.limit:
break
result = {
"model": MODEL_ID, "revision": MODEL_REVISION, "package": args.package,
"selected_manifest": "first eligible rows in source suite order; no gold labels used",
"counts": counts, "maximum_confidence_error": max(errors, default=None),
"mean_confidence_error": statistics.mean(errors) if errors else None,
"model_call_p50_ms": statistics.median(latencies[1:]) if len(latencies) > 1 else None,
"model_call_p95_ms": sorted(latencies[1:])[int(0.95 * (len(latencies) - 1))] if len(latencies) > 1 else None,
"failures": failures[:20],
}
Path(args.out).parent.mkdir(parents=True, exist_ok=True)
Path(args.out).write_text(json.dumps(result, indent=2) + "\n")
print(json.dumps(result, indent=2))
if counts["checked"] == 0 or counts["mismatches"]:
raise SystemExit(1)
if __name__ == "__main__":
main()
|