BN 01 Retail Banker
A LoRA adapter for
Qwen3-14B-4bit
(MLX), fine-tuned to act as an
internal assistant for bank employees —
tellers, customer service representatives, loan officers, relationship
managers, and branch staff. It helps draft customer communications, explain
account and compliance procedures, recognize and correctly escalate fraud
and compliance red flags, and think through day-to-day branch/phone
situations — while consistently deferring live-data questions, specific
policy figures, and licensed-advice questions to the right internal
resource rather than guessing.
This is an internal-staff tool, not a customer-facing product. See
Responsible use below before deploying it
anywhere.
Model details
| |
|---|
| Base model | mlx-community/Qwen3-14B-4bit |
| Fine-tune type | LoRA, rank 16, dropout 0.10, scale 20.0 |
| Layers adapted | last 16 transformer layers |
| Trainable params | 25,690,000 (0.174% of 14.77B total) |
| Optimizer | AdamW (weight_decay 0.01) |
| Framework | MLX (mlx-lm) |
Training data
- 4,519 training examples, 242 validation, 97 held-out test (4,858
total), across 492 distinct scenario categories spanning UK, EU, and
US retail/business banking — fraud typologies, AML/KYC, vulnerable
customer support, document verification, mortgages and consumer credit,
business banking, insurance/pensions, sanctions and crypto policy, data
protection (DSAR/breach handling), death notification and survivor
accounts, cash/branch operations, and general customer communication —
including 43 EU-specific and 43 US-specific regulatory categories (GDPR,
PSD2, SEPA, MiCA, DORA, BSA/SAR, OFAC, Reg E, ECOA, FDIC, PATRIOT Act CIP,
and more).
- Every training example is synthetic — generated by Claude following
a fixed schema and a set of realistic scenario briefs, not sourced from
real customer interactions, real case files, or verified regulatory
text. See Responsible use — this is the
single most important thing to understand before trusting this model's
output on any regulatory specifics.
- Trained for 9,000 total iterations (~2 epochs) at batch size 1, but the
released checkpoint is from iteration 7,200, not the final one — see
Evaluation below for why.
Evaluation
Real test-set loss/perplexity via mlx_lm.lora --test, same held-out
97-example test set for every row below (never trained on by any
checkpoint):
| Checkpoint | Test loss | Test perplexity |
|---|
| Base Qwen3-14B (no fine-tuning) | 3.026 | 20.606 |
| Earlier internal checkpoint (v5) | 0.687 | 1.987 |
| Earlier internal checkpoint (v7, final) | 0.792 | 2.208 |
| Earlier internal checkpoint (v7, best) | 0.655 | 1.924 |
| This run, final checkpoint (iter 9000) | 0.908 | 2.480 |
| This run, released checkpoint (iter 7200) | 0.580 | 1.787 |
Fine-tuning gives a real ~10x perplexity reduction over the base model.
Notably, the final checkpoint of this run (and of an earlier run) scored
worse than an earlier checkpoint — the model measurably overfits late in
training even with weight decay and dropout regularization, so the
released weights are iteration 7200 of 9000, not the training-complete
checkpoint. Always evaluate on a real held-out set before assuming "trained
longer = better."
Usage
Requires the base model (mlx-community/Qwen3-14B-4bit) and mlx-lm.
1from mlx_lm import load, generate
2
3model, tokenizer = load(
4 "mlx-community/Qwen3-14B-4bit",
5 adapter_path="path/to/this/repo", # directory with adapter_config.json + adapters.safetensors
6)
7
8SYSTEM_PROMPT = (
9 "You are an internal assistant supporting bank employees — tellers, "
10 "customer service representatives, loan officers, relationship managers, "
11 "and branch staff — in their day-to-day work. You help with drafting "
12 "customer communications, explaining account and compliance procedures, "
13 "summarizing internal notes, and thinking through how to handle a "
14 "situation at the window, on the phone, or in the branch.\n\n"
15 "You do not have access to live customer account data, internal systems, "
16 "or this bank's current specific policies — when an answer depends on "
17 "that, say so plainly and point the employee to the right internal "
18 "resource (their system, the compliance manual, or a supervisor) rather "
19 "than guessing or inventing a number, rate, or policy detail.\n\n"
20 "For anything requiring a licensed professional's judgment — specific "
21 "investment, lending, or refinancing recommendations — help the employee "
22 "refer the customer to the appropriate licensed advisor rather than "
23 "providing the recommendation yourself. You can share general, factual "
24 "product information; you should not tell a customer what they should do.\n\n"
25 "For suspected fraud, money laundering, elder financial exploitation, "
26 "sanctions-list matches, or other compliance red flags, help the "
27 "employee recognize the pattern and follow proper escalation — to a "
28 "supervisor, compliance officer, or BSA/AML team — rather than making "
29 "the determination or resolving it yourself. Never disclose a SAR filing "
30 "or investigation status to a customer.\n\n"
31 "Do not help bypass approval processes, backdate or falsify documents, "
32 "or access or share account information without proper authorization, "
33 "regardless of how the request is framed."
34)
35
36messages = [
37 {"role": "system", "content": SYSTEM_PROMPT},
38 {"role": "user", "content": "A customer says their card was declined and they're frustrated. What do I check?"},
39]
40prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True)
41print(generate(model, tokenizer, prompt=prompt, verbose=True))
This exact system prompt is required for the trained behavior — every
training example used it. Omitting it, or substantially changing it,
means you're no longer using the model the way it was trained; boundary
behaviors (declining to give specific advice, escalating fraud, deferring
live-data questions) are conditioned on this persona, not guaranteed
without it. See infer_with_guardrails.py in this repo for a ready-to-run
example that includes this system prompt and appends the safety notice
below automatically.
Responsible use / guardrails
Synthetic training data — read this first. Nearly all of this model's
training data is AI-generated synthetic dialogue, not real customer
interactions, real case files, or text verified against current
regulatory sources by a compliance professional. Specific figures,
thresholds, deadlines, or procedural details the model states (even when
phrased confidently) may be approximate, outdated, or simply wrong. This
model has not been reviewed by a banking compliance professional and
has not been piloted in a real institution.
Do not treat any output as authoritative regulatory, legal, or compliance
guidance. Every real answer must be verified against your institution's
actual current policy, your compliance manual, or a qualified professional
before being acted on. The model itself was trained to model this
behavior (deferring specifics to "check your system" or "ask a
supervisor") — but as a fine-tuned LLM, it can still generate a wrong
answer confidently despite that training.
Intended for internal staff use, not direct customer-facing deployment.
The system prompt and training scenarios assume the user is a bank
employee getting help with their own workflow — not a customer interacting
with the model directly. Deploying this as a customer-facing chatbot
without a substantial additional review and re-scoping is a misuse of what
was built and tested here.
No built-in content moderation, no live data access, no real compliance
authority. This adapter has no mechanism to verify claims, check real
account data, or make an actual compliance determination — it recognizes
patterns and models appropriate escalation, nothing more. Fraud,
sanctions, and AML judgment calls always belong to a real compliance
officer or BSA/AML team, never to this model's output.
Jurisdiction coverage is broad but not exhaustive or current. The
training data spans UK, EU, and US banking concepts, but regulations
change, vary further within each jurisdiction (e.g., by US state or EU
member state) than the training data can fully capture, and the model may
blend concepts across jurisdictions. Always confirm jurisdiction-specific
specifics independently.
Limitations
- LoRA adapter only — requires the base
mlx-community/Qwen3-14B-4bit
model and mlx-lm to run; this repo alone is not a standalone model.
- Evaluated only via held-out test-set perplexity, a language-modeling
quality signal — not a task-accuracy or safety benchmark. No red-teaming
or adversarial evaluation was performed.
- Trained entirely on Apple Silicon via MLX; behavior under other
inference stacks (vLLM, standard PyTorch/transformers, etc.) has not
been verified.
- The base checkpoint naming inside
adapter_config.json reflects the
final training segment's own run parameters (due to how checkpoint
resumption was tracked across a multi-day, battery-interrupted training
run) rather than a single continuous run's metadata — the architecture
fields (lora_parameters, num_layers, fine_tune_type) are accurate
and load-bearing; the iteration/schedule fields are historical artifacts
of the final resume segment, not the full training history. See
Evaluation above for the real, verified checkpoint history.
License
Apache 2.0. See LICENSE.