Instructions to use FluidInference/jeff-coreml with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- GLiFormer
How to use FluidInference/jeff-coreml with GLiFormer:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
File size: 3,154 Bytes
0deb31c | 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 | """Standalone Jeff classification inference from the Core ML package.
No original PyTorch checkpoint is loaded. Tokenization and the classification
prompt formatting use the pinned GLiFormer processor and tokenizer files.
"""
from __future__ import annotations
import json
from pathlib import Path
import coremltools as ct
import numpy as np
from gliformer.config import GLiFormerConfig
from gliformer.processing.collator import resolve_gliformer_collator_class
from gliformer.processing.processor import resolve_gliformer_processor_class
from gliner.data_processing.tokenizer import WordsSplitter
from transformers import AutoTokenizer
from jeff_decision import marker_positions
class JeffCoreML:
"""One-group, one-text Jeff classifier for 1–8 labels and at most 128 tokens."""
def __init__(self, asset_dir: str | Path, package: str | Path, compute_units=ct.ComputeUnit.ALL):
asset_dir = Path(asset_dir)
config = GLiFormerConfig(**json.loads((asset_dir / "gliner_config.json").read_text()))
tokenizer = AutoTokenizer.from_pretrained(asset_dir, local_files_only=True)
splitter = WordsSplitter(config.words_splitter_type)
processor_cls = resolve_gliformer_processor_class(config)
processor = processor_cls(config, tokenizer, splitter)
collator_cls = resolve_gliformer_collator_class(config)
self.collator = collator_cls(config, data_processor=processor, return_tokens=True, prepare_labels=False)
self.splitter = splitter
self.config = config
self.model = ct.models.MLModel(str(package), compute_units=compute_units)
self.output_name = self.model.get_spec().description.output[0].name
def score(self, text: str, labels: list[str], name: str = "", description: str = "") -> list[float]:
if not 1 <= len(labels) <= 8:
raise ValueError("JeffCoreML accepts 1 to 8 labels")
tokens = [word for word, _, _ in self.splitter(text)]
batch = self.collator([{
"tokenized_text": tokens,
"classification": [{
"name": name,
"description": description,
"all_labels": labels,
"true_labels": [],
}],
}])
ids = batch["input_ids"]
mask = batch["attention_mask"]
if ids.shape[1] > 128:
raise ValueError(f"JeffCoreML L128 bucket cannot fit {ids.shape[1]} tokens")
parent, children, count = marker_positions(ids, self.config, 8)
if count != len(labels):
raise ValueError("tokenizer label markers disagree with the supplied label count")
inputs = {
"input_ids": np.pad(ids.numpy().astype(np.int32), ((0, 0), (0, 128 - ids.shape[1]))),
"attention_mask": np.pad(mask.numpy().astype(np.int32), ((0, 0), (0, 128 - mask.shape[1]))),
"parent_position": parent.numpy(),
"category_positions": children.numpy(),
}
logits = self.model.predict(inputs)[self.output_name][0, :count].astype(np.float32)
probabilities = 1.0 / (1.0 + np.exp(-logits))
return probabilities.tolist()
|