Downloads · 30 days
4
21% of all-time downloads
mangiis/cca-qwen2.5-3b-lora
cca-qwen2.5-3b-lora is a text classification model from mangiis. Use it when you need a label for a piece of text. It is set up for peft. The card lists the license as mit.
A rank-32 LoRA adapter that decides whether two options from different facets of one scenario can coexist.
Downloads · 30 days
4
21% of all-time downloads
All-time downloads
19
Public
Repo size
251 MB
Likes
0
Public
Click a slice to open those files.
.safetensors240 MB · 95%
From the Hugging Face model README
A rank-32 LoRA adapter that decides whether two options from different facets of one scenario can coexist.
Given two values with what each requires of a scenario and what each provides to one, it answers a single question: could one real configuration contain both? The verdict is read from one token's logits — no generation.
Trained during an internship at the Institute for Systems Studies & Analyses (ISSA), Defence Research & Development Organisation (DRDO).
Code, corpus and the Java deployment: https://github.com/Onecombatboot/morphological-analyzer
Measured on 1,191 held-out cells from 10 domains never seen in training, with the decision threshold fitted leave-one-domain-out.
| AUC | F1 (full coverage) | F1 @ 50% coverage | |
|---|---|---|---|
| This adapter (4-bit NF4 base) | 0.878 | 0.589 | 0.805 |
| After 4-bit ONNX quantisation | 0.876 | 0.583 | 0.811 |
| Second human analyst, same criterion | — | — | 0.807 |
Inter-annotator agreement from a blind re-labelling of 289 cells: 88.9%, Cohen's κ = 0.730. At its operating point the adapter reproduces the corpus judgements at a rate comparable to an independent human analyst.
Intended to be used with a coverage threshold — deciding the cells it is confident about and referring the rest, which is the normal mode for decision support.
| Coverage | 100% | 90% | 80% | 70% | 60% | 50% | 40% |
|---|---|---|---|---|---|---|---|
| F1 | 0.583 | 0.582 | 0.630 | 0.693 | 0.754 | 0.811 | 0.827 |
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import PeftModel
BASE = "Qwen/Qwen2.5-3B"
ADAPTER = "mangiis/cca-qwen2.5-3b-lora"
tok = AutoTokenizer.from_pretrained(BASE)
model = AutoModelForCausalLM.from_pretrained(
BASE,
quantization_config=BitsAndBytesConfig(
load_in_4bit=True, bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_use_double_quant=True),
dtype=torch.bfloat16, device_map={"": 0})
model = PeftModel.from_pretrained(model, ADAPTER).eval()
SYSTEM = (
"You are a defence and security analyst carrying out cross-consistency "
"assessment for General Morphological Analysis. You are given two options "
"from different facets of ONE scenario, with what each requires and "
"provides. Decide whether a single real scenario could contain both. "
"Answer N only when you can name the clause that makes it impossible or "
"means it never occurs; ineffective or unwise is still Y.")
PREFIX = "VERDICT:"
# the verdict must be exactly one token past the prefix, or the logits are
# being read at the wrong position
y_id = tok(PREFIX + " Y", add_special_tokens=False)["input_ids"][-1]
n_id = tok(PREFIX + " N", add_special_tokens=False)["input_ids"][-1]
def score_one(pa, a, a_req, a_prov, pb, b, b_req, b_prov):
"""P(inconsistent) for one presentation order."""
user = (f"Facet A — {pa}\n{a} | REQUIRES: {a_req} | PROVIDES: {a_prov}\n\n"
f"Facet B — {pb}\n{b} | REQUIRES: {b_req} | PROVIDES: {b_prov}\n\n"
"Can one scenario contain both?")
msgs = [{"role": "system", "content": SYSTEM},
{"role": "user", "content": user}]
prompt = tok.apply_chat_template(
msgs, tokenize=False, add_generation_prompt=True) + PREFIX
enc = tok(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
lg = model(**enc, logits_to_keep=1).logits[0, -1, :]
pair = torch.stack([lg[y_id], lg[n_id]]).float()
return torch.softmax(pair, dim=-1)[1].item()
def score(pa, a, a_req, a_prov, pb, b, b_req, b_prov):
"""Both presentation orders averaged. Do not skip this -- see below."""
return 0.5 * (score_one(pa, a, a_req, a_prov, pb, b, b_req, b_prov)
+ score_one(pb, b, b_req, b_prov, pa, a, a_req, a_prov))
p = score("OPERATOR", "Private security contractor",
"a commercial engagement", "personnel without sovereign powers",
"LEGAL BASIS", "Territorial waters enforcement",
"exercise of sovereign enforcement authority",
"jurisdiction inside the territorial sea")
print(p) # ~0.99 -- the contractor has no sovereign authority
Supply the premises. This model judges from REQUIRES and PROVIDES. Given bare value names it scores at chance. An early formulation asked the model to generate its own characterisations before judging and failed for exactly this reason: under teacher forcing it learns to condition on reference premises, and at inference it conditions on its own generated text, ~250 tokens of drift away.
The prompt wording is not editable. The template above, including the em dash
in Facet A —, is byte-identical to the training format. Drift degrades the
model silently — verdicts stay fluent and plausible while the numbers stop
meaning what they used to.
Average both presentation orders. Cross-consistency is symmetric and this is not an optional refinement. Dropping it collapses the selective-prediction curve to F1 0.000 at 50% coverage: ranking survives, but the confidence signal inverts, so the model becomes least reliable exactly where it is most certain.
| Base | Qwen2.5-3B, 4-bit NF4, frozen |
| Adapter | rank 32, α 64, dropout 0.05 |
| Targets | all seven projections (q, k, v, o, gate, up, down) |
| Trainable | 59.9M parameters — 1.90% of the model |
| Budget | 6 GB VRAM |
Two departures from a default QLoRA recipe were necessary, not optional:
Data. 96 morphological domains, 648 parameter pairs, 10,286 assessed cells, 1,419 exclusions — each carrying a typed reason code and two verbatim citations, re-verified against source text on every build. Domains span far beyond defence (organ transplant allocation, patent litigation, coastal erosion, microfinance) so the only consistently predictive feature is the structure of the conflict itself rather than any field's vocabulary.
Split by domain, never by cell. Cells within a box share characterisations, so a cell-level split leaks premises and inflates every figure.
@misc{cca-qwen-lora,
title = {Automated Cross-Consistency Assessment for General Morphological Analysis},
author = {Shourya, Aditya},
year = {2026},
note = {QLoRA adapter on Qwen2.5-3B. ISSA, DRDO.}
}
MIT. The base model carries its own licence (Qwen).