L3 Contrastive ONNX — prompt-armor
Contrastive fine-tuned embedding model for prompt injection detection. Exported to ONNX INT8 for fast inference without PyTorch.
Model Details
- Base model: paraphrase-multilingual-MiniLM-L12-v2 (Apache 2.0)
- Fine-tuning: TripletLoss contrastive learning on 5K+ attack/benign pairs
- Export: ONNX with INT8 dynamic quantization
- Embedding dimension: 384
- Max sequence length: 128
- Pooling: Mean tokens + L2 normalization
Key Improvement
The base model matches by topic — "how does DAN jailbreak work?" (benign research) gets similar embeddings to "do anything now" (actual attack). After contrastive fine-tuning, the model matches by intent:
| Metric | Base Model | Fine-tuned |
|---|---|---|
| Cross-similarity (attack↔benign) | 0.053 | -0.021 |
| Attack self-similarity | 0.229 | 0.858 |
| Separation gap | 0.176 | 0.879 |
Usage
import onnxruntime as ort
from tokenizers import Tokenizer
import numpy as np
session = ort.InferenceSession("model_quant.onnx")
tokenizer = Tokenizer.from_file("tokenizer.json")
tokenizer.enable_padding(pad_id=1, pad_token="<pad>")
tokenizer.enable_truncation(max_length=128)
encoding = tokenizer.encode("your text here")
input_ids = np.array([encoding.ids], dtype=np.int64)
attention_mask = np.array([encoding.attention_mask], dtype=np.int64)
outputs = session.run(None, {"input_ids": input_ids, "attention_mask": attention_mask})
# Mean pooling + L2 normalize
token_emb = outputs[0]
mask = attention_mask[..., np.newaxis].astype(np.float32)
pooled = (token_emb * mask).sum(axis=1) / mask.sum(axis=1).clip(min=1e-9)
embedding = pooled / np.linalg.norm(pooled, axis=1, keepdims=True)
Part of prompt-armor
This model is used by prompt-armor — an open-source prompt injection detector. Auto-downloaded on first use.
License
Apache 2.0 (same as base model)
Credits
Base model: sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 by Nils Reimers and Iryna Gurevych.