CoolFace
Modelpublic

sammiset/finops-fail-triage

sourceHugging Faceapache-2.0updated 5mo agoView on Hugging Face
0likes17downloads
Model Card

finops-fail-triage

A QLoRA fine-tuned Qwen3.5-9B model for post-trade settlement fail triage and prioritization. Given a structured fail record, the model outputs a JSON object containing a priority score (0–100), priority tier, lifecycle state, score components, resolution action, escalation level, and regulatory flags.

This is Stage 1 of a two-model FinOps pipeline. Stage 2 (finops-resolver, in development) takes this model's output and recommends an ordered resolution sequence.


Model Details

FieldValue
Base modelQwen/Qwen3.5-9B (post-trained instruct)
Fine-tuning methodQLoRA (4-bit NF4 + LoRA adapters)
FrameworkUnsloth + TRL SFTTrainer
QuantizationGGUF Q4KM
File size5.3 GB
Trainable parameters3,932,160 of 9,413,745,984 (0.04%)
LoRA rankr=16, alpha=32
Target modulesqproj, kproj, vproj, oproj
Training hardwareNVIDIA RTX 5070 Ti (16GB GDDR7)
Training time~4.2 hours (3,000 steps)
Final train loss0.1453

Intended Use

This model is designed for post-trade settlement operations in a broker-dealer or clearing firm context. It triages fail records by:

  • Classifying the fail category (CNS, DVP, B2B, Correspondent, DK)
  • Calculating a weighted priority score using a multi-factor formula
  • Applying regulatory override rules (Reg SHO, threshold securities, close-out deadlines)
  • Distinguishing CNS FTD (fail to deliver) from FTR (fail to receive)
  • Recommending an action and escalation level

This is a research and portfolio demonstration project. It is not intended for production use in live trading or settlement systems.


Priority Scoring Model

The model was trained on a deterministic scoring formula derived from post-trade settlement domain knowledge:

Final Score (0–100) = Base Score × Inventory Modifier × Concentration Modifier

Base Score = (Age × 0.30) + (Value × 0.25) + (Regulatory × 0.35) + (CP History × 0.10)

Factor Tables

Age Factor | Days Aged | Score | |-----------|-------| | 1–3 | 10 | | 4–6 | 30 | | 7–9 | 60 | | 10–12 | 80 | | 13+ | 100 |

Value Factor | Market Value | Score | |--------------|-------| | < $100K | 10 | | $100K–$500K | 30 | | $500K–$1M | 50 | | $1M–$5M | 70 | | > $5M | 100 |

Regulatory Factor | Condition | Score | |-----------|-------| | No concern | 0 | | Approaching Reg SHO | 50 | | Threshold security | 80 | | Close-out required | 100 |

Counterparty History Factor | 15-day Fail Rate | Score | |-----------------|-------| | < 1% | 10 | | 1–3% | 30 | | 3–5% | 60 | | > 5% | 100 |

Inventory Modifier (0.50–1.00) | Coverage | Modifier | |----------|----------| | ≥ 100% | 0.50 | | 75–99% | 0.65 | | 50–74% | 0.80 | | 25–49% | 0.90 | | < 25% | 1.00 |

Concentration Modifier (1.00–1.50, capped) | Condition | Modifier | |-----------|----------| | Normal | 1.00 | | Threshold list security | 1.20 | | Non-CNS eligible | 1.15 | | Security fail rate > 2% ADV | 1.15 | | Broker fail rate > 5% (15-day) | 1.15 | | Multiple conditions | Multiplicative, max 1.50 |

Priority Tiers

ScoreTierEscalation
0–25LOWNone
26–50MEDIUML1 Ops Associate
51–75HIGHL2 Senior Ops
76–100CRITICALL3 Management / L4 Compliance

Category Override Rules

CNS_FAIL is always minimum MEDIUM regardless of calculated score — NSCC systemic risk requires active management. Score is reported as calculated; only the tier is overridden.


Training Data

Training data was synthetically generated using a deterministic Python pipeline with no API calls. All examples were mathematically verified against the scoring formula before training.

MetricValue
Total examples10,000
Train split8,000 (80%)
Eval split2,000 (20%)
Generation methodDeterministic Python (no LLM API)
Validation100% formula-verified before training

Category Distribution

Category%
CNS_FAIL30%
DVP_FAIL30%
B2B_PENDING20%
CA_EVENT10%
DK_DISPUTE10%

Coverage

  • All 5 age bands × all 5 value tiers × all 4 regulatory states
  • All inventory modifier tiers (0.50, 0.65, 0.80, 0.90, 1.00)
  • All concentration modifier stacking combinations including cap at 1.50
  • FTD and FTR across all age bands and value tiers
  • Realistic DTC participant number distribution: 15 high-volume counterparties (~39% of assignments, uncapped) + general pool (1–1999, max 3 uses each)

Training Configuration

python
# Model loading
model_name = "unsloth/Qwen3.5-9B"
load_in_4bit = True           # NF4 quantization
double_quant = True           # Double quantization for memory efficiency

# LoRA
r = 16
lora_alpha = 32
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj"]
lora_dropout = 0.05
bias = "none"
use_gradient_checkpointing = "unsloth"

# Training
per_device_train_batch_size = 2
gradient_accumulation_steps = 4   # effective batch size = 8
max_seq_length = 1024
num_train_epochs = 3
learning_rate = 2e-4
warmup_ratio = 0.03
lr_scheduler_type = "cosine"
bf16 = True

Loss Curve

The model converged rapidly — loss dropped from 2.299 at step 1 to approximately 0.13 by epoch 0.10, reflecting the structured and deterministic nature of the synthetic training data.

EpochApprox Loss
0.10~0.185
0.25~0.130
1.00~0.100
3.000.1453 (final)

Output Schema

json
{
  "category": "CNS_FAIL | DVP_FAIL | B2B_PENDING | CA_EVENT | DK_DISPUTE",
  "cns_direction": "FTD | FTR | N_A",
  "lifecycle_state": "OPEN | ESCALATED | BUYIN | OFFSET",
  "priority_score": 88.2,
  "priority_tier": "LOW | MEDIUM | HIGH | CRITICAL",
  "category_priority_override": false,
  "score_components": {
    "age_factor": 60,
    "value_factor": 70,
    "regulatory_factor": 80,
    "cp_history_factor": 30,
    "base_score": 73.5,
    "inventory_modifier": 1.0,
    "concentration_modifier": 1.20
  },
  "reason": "Plain English explanation of score drivers",
  "action": "LOCATE_AND_DELIVER | SEND_DK_NOTICE | MONITOR_PENDING_RECEIPT | ESCALATE | CONTACT_COUNTERPARTY | INITIATE_BUYIN | NO_ACTION",
  "escalation_level": "NONE | L1 | L2 | L3 | L4",
  "deadline": "T+N or null",
  "flags": ["THRESHOLD_SECURITY", "REG_SHO_CLOSEOUT", "PROBLEM_CP", "HIGH_VALUE", "AGED_FAIL"]
}

Usage

Ollama (recommended)

bash
# Pull the model
ollama pull sammiset/finops-fail-triage

# Run inference
ollama run finops-fail-triage "Triage this fail record:
CUSIP: 594918104 | Side: Sell | Qty: 5000 | Counterparty: DTC-0005 | 
Age: 7 days | Market Value: $2.1M | CNS Position: -5000 | 
CNS Direction: FTD | Reg SHO Threshold: Yes | 
Inventory Coverage: 10% | CP 15-day Fail Rate: 4%"

llama.cpp

bash
./llama-cli -m finops-triage-qwen3.5-9b-q4_k_m.gguf \
  --temp 0.1 \
  --top-p 0.9 \
  -p "You are a post-trade settlement triage assistant. Output JSON only.\n\nTriage this fail record:\nCUSIP: 594918104 | Side: Sell | Qty: 5000 | Counterparty: DTC-0005 | Age: 7 days | Market Value: \$2.1M | CNS Direction: FTD | Reg SHO Threshold: Yes | Inventory Coverage: 10% | CP 15-day Fail Rate: 4%"

Python (Transformers)

python
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

model_id = "sammiset/finops-fail-triage"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id, 
    torch_dtype=torch.bfloat16,
    device_map="auto"
)

messages = [
    {
        "role": "system",
        "content": "You are a post-trade settlement triage assistant. Output JSON only — no explanation, no markdown, no preamble."
    },
    {
        "role": "user", 
        "content": "Triage this fail record:\nCUSIP: 594918104 | Side: Sell | Qty: 5000 | Counterparty: DTC-0005 | Age: 7 days | Market Value: $2.1M | CNS Direction: FTD | Reg SHO Threshold: Yes | Inventory Coverage: 10% | CP 15-day Fail Rate: 4%"
    }
]

input_ids = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt=True,
    return_tensors="pt"
).to(model.device)

output = model.generate(input_ids, max_new_tokens=512, temperature=0.1)
print(tokenizer.decode(output[0][input_ids.shape[-1]:], skip_special_tokens=True))

Input Field Reference

FieldDescriptionExample
CUSIP9-character security identifier594918104
SideBuy or SellSell
QtyShare quantity5000
CounterpartyDTC participant numberDTC-0005
AgeDays since settlement date7 days
Market ValueCurrent market value of position$2.1M
CNS PositionNet CNS position (negative = short)-5000
CNS DirectionFTD (owe shares) or FTR (owed shares)FTD
Reg SHO ThresholdWhether security is on threshold listYes
Inventory Coverage% of fail covered by available inventory10%
CP 15-day Fail RateCounterparty fail rate over 15 days4%
Security Fail RateOptional: security fail rate vs ADV>2% ADV

Known Limitations

  • Trained on synthetic data — real-world fail records may have edge cases not represented in training
  • Score arithmetic shows occasional small drift on inventory modifier boundary conditions
  • Category classification can drift on DVP/B2B fails where CNS Direction is N/A — a v1.1 retrain with targeted examples is planned
  • Thinking mode must be disabled at inference for clean JSON output (already handled in Modelfile)
  • Not validated against live production settlement data

Domain Glossary

TermDefinition
CNSContinuous Net Settlement — NSCC's multilateral netting system
FTDFail to Deliver — short position at CNS, shares owed
FTRFail to Receive — long position at CNS, shares owed to you
DVPDelivery vs Payment — bilateral institutional settlement
RVPReceipt vs Payment — bilateral institutional settlement (buy side)
B2BBack-to-back — obligation contingent on street-side receipt
Reg SHOSEC regulation governing short sale delivery requirements
Threshold SecuritySecurity on Reg SHO threshold list — mandatory close-out applies
DTCDepository Trust Company — central securities depository
NSCCNational Securities Clearing Corporation — CCP for US equities
DKDon't Know — trade comparison dispute
Close-outMandatory buy-in triggered by Reg SHO Rule 204

Citation

bibtex
@misc{sammiset2026finopstriage,
  author = {sammiset},
  title = {finops-fail-triage: A Fine-tuned LLM for Post-Trade Settlement Triage},
  year = {2026},
  publisher = {HuggingFace},
  url = {https://huggingface.co/sammiset/finops-fail-triage}
}

License

Apache 2.0 — inherited from Qwen3.5-9B base model.


Related

  • Base model: Qwen/Qwen3.5-9B
  • Fine-tuning framework: Unsloth
  • Stage 2 (in development): sammiset/finops-resolver