File size: 3,513 Bytes
f376c84
65f8346
 
 
 
 
 
 
 
af8f15a
65f8346
 
3ec3806
892903c
 
 
f376c84
 
af8f15a
f376c84
af8f15a
f376c84
af8f15a
f376c84
65f8346
f376c84
af8f15a
f376c84
af8f15a
 
65f8346
 
f376c84
65f8346
f376c84
af8f15a
65f8346
af8f15a
65f8346
 
 
 
f98fe27
65f8346
 
f98fe27
65f8346
84df194
65f8346
 
 
 
 
 
84df194
 
65f8346
 
 
 
 
f98fe27
 
65f8346
 
 
 
 
 
 
 
 
 
 
 
 
af8f15a
f98fe27
65f8346
 
 
 
af8f15a
 
f98fe27
65f8346
 
 
 
 
 
f98fe27
 
 
 
 
 
 
 
 
 
 
 
 
 
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
---
language:
- en
license: apache-2.0
tags:
- zero-shot-classification
- nli
- cross-encoder
- intent-routing
- modernbert
pipeline_tag: zero-shot-classification
widget:
- text: Generate a formal project proposal in Word format.
  candidate_labels: a Word document creation request, an Excel spreadsheet creation
    request, a PowerPoint presentation deck creation request, a PDF document analysis
    query, general chitchat
---

# MarkOne

**MarkOne** is a high-precision, zero-shot NLI cross-encoder model powered by **ModernBERT** designed for dynamic intent routing and query classification within modular AI architectures.

It evaluates user prompts against arbitrary numbers of candidate choice labels (N = 3, 6, 8,..) by computing sequence pair entailment probabilities using modern attention mechanics and an expanded context window.

---

## Key Features

- **ModernBERT Backbone:** Built on ModernBERT architecture featuring FlashAttention, unpadded processing, and Rotary Positional Embeddings (RoPE) for blazing-fast inference.
- **Extended Context Window:** Natively supports up to 8,192 tokens, allowing for rich, detailed candidate descriptions and long-form document inputs.
- **Dynamic Choice Counts:** Handles variable numbers of candidate labels on the fly across different routing domains.
- **Cross-Encoder Accuracy:** Outperforms single-text classifiers by evaluating joint attention over `(Premise, Hypothesis)` pairs.

---

## Quickstart & Usage

MarkOne operates as an NLI cross-encoder, evaluating candidate choices by pairing the input prompt as a Premise with a set of generated candidate Hypotheses.

### Zero-Shot NLI Classification (Python)

```python
import json
import torch
import torch.nn.functional as F
from transformers import AutoModelForSequenceClassification, AutoTokenizer

MODEL_ID = "ChandruK/MarkOne"
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
model = AutoModelForSequenceClassification.from_pretrained(MODEL_ID).to(device)
model.eval()

ENTAILMENT_IDX = 1

CANDIDATE_LABELS = [
    "a Word document creation request",
    "an Excel spreadsheet creation request",
    "a PowerPoint presentation deck creation request",
    "a PDF document analysis or extraction query",
    "general chitchat or off-topic conversation",
    "a Question answer related",
]
HYPOTHESIS_TEMPLATE = "This user prompt is {}."

prompt = "Generate a formal project proposal in Word format."

hypotheses = [HYPOTHESIS_TEMPLATE.format(label) for label in CANDIDATE_LABELS]
premises = [prompt] * len(CANDIDATE_LABELS)

inputs = tokenizer(
    text=premises,
    text_pair=hypotheses,
    padding=True,
    truncation=True,
    max_length=1024,
    return_tensors="pt",
).to(device)

with torch.no_grad():
    outputs = model(**inputs)
    logits = outputs.logits
    entailment_logits = logits[:, ENTAILMENT_IDX] if logits.shape[-1] >= 3 else logits[:, 1]

    probabilities = F.softmax(entailment_logits / 0.5, dim=-1)
    top_prob, top_idx = torch.max(probabilities, dim=-1)

predicted_label = CANDIDATE_LABELS[top_idx.item()]
confidence = top_prob.item() * 100

label_scores = {
    label: round(prob.item() * 100, 2)
    for label, prob in zip(CANDIDATE_LABELS, probabilities)
}

output_json_data = {
    "prompt": prompt,
    "predicted_label": predicted_label,
    "confidence": round(confidence, 2),
    "all_scores": label_scores,
}

json_output = json.dumps(output_json_data, indent=2)
print(json_output)