MarkOne / README.md
ChandruK's picture
updated the output format
f98fe27 verified
|
Raw History Blame Contribute Delete
3.94 kB
metadata
language:
  - en
license: apache-2.0
tags:
  - zero-shot-classification
  - nli
  - cross-encoder
  - intent-routing
  - debberta
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 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 without requiring dedicated single-label classification fine-tuning for every domain.


🌟 Key Features

  • 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.
  • DocGeniee Native: Pre-configured for routing document generation workflows (Word, Excel, PowerPoint), PDF RAG queries, and chitchat/out-of-scope filtering.

πŸš€ Quickstart & Usage

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

Zero-Shot NLI Classification (Python)

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

# Load model and tokenizer
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 label index (Index 2 for standard DeBERTa MNLI architecture)
ENTAILMENT_IDX = 2

# 1. Define Candidate Labels and Hypothesis Template
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 {}."

# 2. Input Prompt
prompt = "Generate a formal project proposal in Word format."

# 3. Construct Premise-Hypothesis Pairs
hypotheses = [HYPOTHESIS_TEMPLATE.format(label) for label in CANDIDATE_LABELS]
premises = [prompt] * len(CANDIDATE_LABELS)

# 4. Tokenize Pairs
inputs = tokenizer(
    text=premises,
    text_pair=hypotheses,
    padding=True,
    truncation=True,
    return_tensors="pt",
).to(device)

# 5. Model Inference
with torch.no_grad():
    outputs = model(**inputs)
    # Extract Entailment logits vector across all dynamic candidates
    entailment_logits = outputs.logits[:, ENTAILMENT_IDX]

    # Softmax probability normalization
    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

# =====================================================================
# MODIFICATION FOR JSON OUTPUT
# =====================================================================

# Build dictionary containing key details and all category probabilities
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,
}

# Output as formatted JSON string
json_output = json.dumps(output_json_data, indent=2)
print(json_output)