Text Classification
Transformers
Safetensors
English
modernbert
commitment-detection
decision-detection
experimental
vela
text-embeddings-inference
Instructions to use TwilightTechie/vela-commitment-classifier-307m with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use TwilightTechie/vela-commitment-classifier-307m with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="TwilightTechie/vela-commitment-classifier-307m")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForSequenceClassification tokenizer = AutoTokenizer.from_pretrained("TwilightTechie/vela-commitment-classifier-307m") model = AutoModelForSequenceClassification.from_pretrained("TwilightTechie/vela-commitment-classifier-307m", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Download reproducibility/sequence_repair/evaluate.py from TwilightTechie/vela-commitment-classifier-307m: direct link, hf CLI and curl.
- Browser
- Download file 5.52 kB
-
https://huggingface.co/TwilightTechie/vela-commitment-classifier-307m/resolve/main/reproducibility/sequence_repair/evaluate.py
- Command line
-
hf download hf://TwilightTechie/vela-commitment-classifier-307m/reproducibility/sequence_repair/evaluate.py
-
curl -L -o evaluate.py https://huggingface.co/TwilightTechie/vela-commitment-classifier-307m/resolve/main/reproducibility/sequence_repair/evaluate.py
5.52 kB
| """Explicit streaming evaluation; never invoked on test data during training.""" | |
| # ruff: noqa: PLC0415 | |
| import argparse | |
| import json | |
| import time | |
| from pathlib import Path | |
| from .data import classification_metrics, file_receipts, read_records | |
| from .model import load_model | |
| LONG_BATCH_THRESHOLD = 2048 | |
| def evaluate_records( | |
| model, | |
| tokenizer, | |
| records, | |
| label_to_id, | |
| id_to_label, | |
| max_length, | |
| batch_size=16, | |
| dtype="bfloat16", | |
| ): | |
| import torch | |
| device = next(model.parameters()).device | |
| if model.config.problem_type != "single_label_classification": | |
| raise ValueError("Softmax evaluation requires a single-label classifier") | |
| was_training = model.training | |
| model.eval() | |
| encoded = [ | |
| tokenizer(row["text"], truncation=False, padding=False) for row in records | |
| ] | |
| lengths = [len(row["input_ids"]) for row in encoded] | |
| if max(lengths) > max_length: | |
| raise ValueError( | |
| "Evaluation input exceeds the explicit budget; truncation is forbidden" | |
| ) | |
| order = sorted(range(len(records)), key=lengths.__getitem__) | |
| results, timings, cursor = [None] * len(records), [], 0 | |
| while cursor < len(order): | |
| size = 1 if lengths[order[cursor]] > LONG_BATCH_THRESHOLD else batch_size | |
| indices = order[cursor : cursor + size] | |
| if any(lengths[index] > LONG_BATCH_THRESHOLD for index in indices): | |
| indices = indices[:1] | |
| cursor += len(indices) | |
| batch = tokenizer.pad( | |
| [encoded[index] for index in indices], padding=True, return_tensors="pt" | |
| ) | |
| batch = {key: value.to(device) for key, value in batch.items()} | |
| if device.type == "cuda": | |
| torch.cuda.synchronize() | |
| start = time.perf_counter() | |
| with torch.inference_mode(), torch.autocast( | |
| device_type=device.type, | |
| dtype=getattr(torch, dtype), | |
| enabled=device.type == "cuda" and dtype != "float32", | |
| ): | |
| logits = model(**batch).logits.float() | |
| if not bool(torch.isfinite(logits).all()): | |
| raise ValueError("Non-finite evaluation logits") | |
| probabilities = logits.softmax(-1).cpu().tolist() | |
| if device.type == "cuda": | |
| torch.cuda.synchronize() | |
| timings.append((time.perf_counter() - start) * 1000) | |
| for position, index in enumerate(indices): | |
| scores = probabilities[position] | |
| results[index] = { | |
| "id": records[index]["id"], | |
| "prediction": max(range(len(scores)), key=scores.__getitem__), | |
| "probabilities": scores, | |
| "tokens": lengths[index], | |
| } | |
| gold = [label_to_id[row["label"]] for row in records] | |
| predicted = [row["prediction"] for row in results] | |
| metrics = classification_metrics(gold, predicted, id_to_label) | |
| metrics["breakdowns"] = {} | |
| for field in ["source", "language", "length_bucket", "position"]: | |
| metrics["breakdowns"][field] = {} | |
| for group in sorted({str(row.get(field, "unspecified")) for row in records}): | |
| indices = [ | |
| i | |
| for i, row in enumerate(records) | |
| if str(row.get(field, "unspecified")) == group | |
| ] | |
| metrics["breakdowns"][field][group] = classification_metrics( | |
| [gold[i] for i in indices], [predicted[i] for i in indices], id_to_label | |
| ) | |
| metrics["actual_tokens"] = {"min": min(lengths), "max": max(lengths)} | |
| metrics["forward_batches_ms"] = timings | |
| metrics["precision"] = { | |
| "parameters": "float32", | |
| "forward_autocast": ( | |
| dtype if device.type == "cuda" and dtype != "float32" else None | |
| ), | |
| "device_type": device.type, | |
| } | |
| if was_training: | |
| model.train() | |
| return metrics, results | |
| def main(): | |
| import torch | |
| torch.set_num_threads(8) | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--base", required=True) | |
| parser.add_argument("--adapter") | |
| parser.add_argument("--contract", required=True) | |
| parser.add_argument("--data", nargs="+", required=True) | |
| parser.add_argument("--output", type=Path, required=True) | |
| parser.add_argument("--max-length", type=int, default=32768) | |
| parser.add_argument("--device", default="cuda") | |
| parser.add_argument("--dtype", choices=["float32", "bfloat16"], default="bfloat16") | |
| args = parser.parse_args() | |
| if args.output.exists(): | |
| raise ValueError("Refusing to overwrite evaluation evidence") | |
| model, tokenizer, labels, ids = load_model(args.base, args.contract, args.adapter) | |
| if args.max_length > model.config.max_position_embeddings: | |
| raise ValueError("Evaluation budget exceeds checkpoint position capacity") | |
| model.to(args.device) | |
| rows = read_records(args.data, labels) | |
| metrics, predictions = evaluate_records( | |
| model, tokenizer, rows, labels, ids, args.max_length, dtype=args.dtype | |
| ) | |
| metrics["data_files"] = file_receipts(args.data) | |
| args.output.parent.mkdir(parents=True, exist_ok=True) | |
| args.output.write_text(json.dumps(metrics, indent=2) + "\n") | |
| args.output.with_suffix(".predictions.jsonl").write_text( | |
| "".join(json.dumps(row) + "\n" for row in predictions) | |
| ) | |
| print( | |
| json.dumps( | |
| { | |
| key: metrics[key] | |
| for key in ["rows", "accuracy", "macro_f1", "actual_tokens"] | |
| } | |
| ), | |
| flush=True, | |
| ) | |
| if __name__ == "__main__": | |
| main() | |