cbx-bfs-banking-intent-classifier-68M

Detects the intent of a banking customer's message: one of the 77 BANKING77 intents, such as card_arrival, pending_transfer, exchange_rate or lost_or_stolen_card. English. Fine-tuned from Ettin encoder 68m (68.4M parameters). 93.7% accuracy on the BANKING77 test set, about 12 ms per message on a CPU.

Current version: v0.1 (use revision="v0.1" to pin it). Also available in 17M.

Licence: Apache-2.0, free for commercial use.

Quick start

pip install -r requirements.txt
python example.py
from cbx_intent import IntentClassifier

clf = IntentClassifier(".")          # folder with the model files
clf.classify("My new card was posted ten days ago and it still hasn't shown up")
# {'text': '...', 'intent': 'card_arrival', 'description': '...', 'confidence': ..., 'top': [...]}

Or with plain transformers:

from transformers import pipeline

clf = pipeline("text-classification", model="CobuildX-AI/cbx-bfs-banking-intent-classifier-68M", revision="v0.1")
clf("Can I add money to my account using Google Pay?")

Input. One customer message, at most 128 tokens (every BANKING77 message fits).

Output. The intent, its one-line description, a confidence and the top 3 intents. The model was trained with label smoothing 0.1, so the top confidence rarely goes above about 0.9; set any review or hand-off threshold on this model's own scores.

Intents (77)

The intents are the BANKING77 labels, unchanged, with the same ids as PolyAI/banking77 on Hugging Face. A one-line description of each is in intent_config.json.

All 77 intents

activate_my_card, age_limit, apple_pay_or_google_pay, atm_support, automatic_top_up, balance_not_updated_after_bank_transfer, balance_not_updated_after_cheque_or_cash_deposit, beneficiary_not_allowed, cancel_transfer, card_about_to_expire, card_acceptance, card_arrival, card_delivery_estimate, card_linking, card_not_working, card_payment_fee_charged, card_payment_not_recognised, card_payment_wrong_exchange_rate, card_swallowed, cash_withdrawal_charge, cash_withdrawal_not_recognised, change_pin, compromised_card, contactless_not_working, country_support, declined_card_payment, declined_cash_withdrawal, declined_transfer, direct_debit_payment_not_recognised, disposable_card_limits, edit_personal_details, exchange_charge, exchange_rate, exchange_via_app, extra_charge_on_statement, failed_transfer, fiat_currency_support, get_disposable_virtual_card, get_physical_card, getting_spare_card, getting_virtual_card, lost_or_stolen_card, lost_or_stolen_phone, order_physical_card, passcode_forgotten, pending_card_payment, pending_cash_withdrawal, pending_top_up, pending_transfer, pin_blocked, receiving_money, Refund_not_showing_up, request_refund, reverted_card_payment?, supported_cards_and_currencies, terminate_account, top_up_by_bank_transfer_charge, top_up_by_card_charge, top_up_by_cash_or_cheque, top_up_failed, top_up_limits, top_up_reverted, topping_up_by_card, transaction_charged_twice, transfer_fee_charged, transfer_into_account, transfer_not_received_by_recipient, transfer_timing, unable_to_verify_identity, verify_my_identity, verify_source_of_funds, verify_top_up, virtual_card_not_working, visa_or_mastercard, why_verify_identity, wrong_amount_of_cash_received, wrong_exchange_rate_for_cash_withdrawal

Evaluation

BANKING77 test set (3,080 messages, 40 per intent). Accuracy and macro F1 over the 77 intents.

Model Accuracy Macro F1 Latency per message Price per 1,000 messages
cbx-bfs-banking-intent-classifier-68M (this model) 93.7% 0.937 12 ms (CPU, local) none (runs on your hardware)
cbx-bfs-banking-intent-classifier-17M 92.3% 0.923 3 ms (CPU, local) none (runs on your hardware)
Jev (decision model API) + 3 retrieved examples 91.9% 0.919 296 ms (API) about $0.10
TF-IDF + logistic regression 91.0% 0.911 under 1 ms (CPU, local) none
Claude Opus 5, zero-shot (published by OpenRouter) 84.4% 0.836 2,266 ms (API) about $2.40
Jev (decision model API), zero-shot 81.5% 0.810 290 ms (API) about $0.09
  • Our runs (CobuildX, 2026-11-13): both CBX models, TF-IDF + logistic regression, and Jev through TypeSafe's System One API (jev-latest requested; jev-1.14.0 answered every call).
    • Jev zero-shot: each intent had a one-line description written from its label name only, plus one fixed instruction, following the setup of the OpenRouter post below.
    • Jev + 3 retrieved examples: the same prompt plus the 3 BANKING77 training messages most similar to the message (TF-IDF cosine), each with its intent. These are the same training messages the CBX models learned from.
    • Price is Jev's published input-token price; its output tokens are free.
  • Claude Opus 5 is OpenRouter's published result, from Jev vs Claude Opus 5 on classification, with OpenRouter's own prompt. We did not rerun it; its price is their reported cost for the full test set, divided per 1,000 messages.
  • Latency is not measured the same way for every row:
    • CBX and TF-IDF: one message on a CPU with 8 threads, on our machine.
    • API models: the full round trip, median; Jev ran 8 requests in parallel.
  • Speed of this model (one message; CPU with 8 threads / GPU): 12.11 / 7.82 ms. A batch of 32: 214.86 / 15.89 ms.
  • For reference, the BANKING77 paper reports 93.66% for a fine-tuned BERT-base (110M parameters).

Training data

  • BANKING77 (Casanueva et al., 2020, CC BY 4.0): online-banking customer questions labelled with 77 intents.
    • Training: 90% of the official training split.
    • Model selection: the other 10% (split per intent).
    • Score: the official test split was used only for the final score above.
  • No other data was used.

Limitations

  • BANKING77's world only. The intents come from a card-and-app digital bank: cards, top-ups, transfers, currency exchange, identity checks. Loans, mortgages, branches, investments and many other banking topics are not covered.
  • Every message gets one of the 77 intents. The model has no "out of scope" answer: a message about something else still gets the closest intent. Use the confidence to send uncertain messages to a person or a fallback.
  • English only. The test set is clean English questions; typos, slang, very long messages and multi-intent messages are less well tested.
  • Label conventions. Some BANKING77 intents overlap, for example transfer_timing vs balance_not_updated_after_bank_transfer, or card_arrival vs card_delivery_estimate. Most remaining errors are between such pairs, and some test labels are themselves debatable.
  • Not for decisions about people. Use it to route and understand messages, not to decide on credit, fraud, accounts or similar matters.

Files

File
model.safetensors, config.json, tokenizer.json, tokenizer_config.json the model
intent_config.json the 77 intents with descriptions, input limit, base model, scores
cbx_intent.py, example.py, requirements.txt loader and example
LICENSE, NOTICE Apache-2.0 licence, third-party notices (Ettin, BANKING77)
checksums.sha256 SHA-256 of every file

Licence

Apache-2.0 for the model weights and code (see LICENSE). The base model, Ettin, is MIT. The training data, BANKING77, is CC BY 4.0 and is credited in NOTICE; the data itself is not included.

Contact

Questions: hello@cobuildx.ai. Release v0.1 (2026-11-13).

Downloads last month
15
Safetensors
Model size
68.4M params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for CobuildX-AI/cbx-bfs-banking-intent-classifier-68M

Finetuned
(40)
this model

Dataset used to train CobuildX-AI/cbx-bfs-banking-intent-classifier-68M

Collection including CobuildX-AI/cbx-bfs-banking-intent-classifier-68M

Paper for CobuildX-AI/cbx-bfs-banking-intent-classifier-68M