Live demo · Transaction enrichment

From raw memo
to a clean ledger.

Bank feeds arrive as cryptic strings like SQ *BLUE BOTTLE COFFE. A ModernBERT extractor tags every part of the memo, and an open decision model picks the merchant and the category, with a probability for every option. Both run on one GPU that Chalk deploys from a single Python file.

Enrich a month of transactions

Each batch is synthetic, generated in a typical bank-feed format. Press New batch for another, or paste a memo from your own statement. Every row shows what the extractor tagged and what the decision model chose.

clef-flash + modern-glinerOpen in new tab

How it works

A small extractor is good at finding the pieces of a memo. A decision model is good at choosing between options. Each does the part it is good at, and neither has to generate text.

Tag the memo

A ModernBERT-based GLiNER model marks every part of the raw memo: the company, the payment processor, the city and state, and the reference, phone and store-number noise around them.

Propose merchants

Those spans become a short list of candidate names, with processor codes, store numbers and boilerplate stripped away. For a transfer, the person named in the memo is a candidate too.

Decide

Clef-Flash reads the memo and the candidates and, in one forward pass, picks the merchant and answers typed questions: one of 16 categories, whether it recurs, and how essential it is.

The models are Clef-Flash, a 9B decision model, and modern-gliner-bi-large, a zero-shot entity extractor with a ModernBERT-large encoder. Both are Apache-2.0.

Getting started

Deploy your own in three commands

Clone the example, log in, and run the deploy script. Chalk builds the image, provisions an L40S, and prints a URL that serves this exact demo. The evaluator then scores your deployment against labeled synthetic transactions.

The API takes and returns transactions in a typical bank-feed shape and fills in merchant_name and personal_finance_category, so it can sit behind a feature resolver, a nightly backfill, or a review queue.

chalk-ai/bank-transaction-enrichment
git clone https://github.com/chalk-ai/bank-transaction-enrichment
cd bank-transaction-enrichment

# Or export CHALK_CLIENT_ID and CHALK_CLIENT_SECRET.
chalk login

# Builds the image, provisions an L40S, prints your demo's URL.
./deploy.py --gpu nvidia-l40s

# Score it against the synthetic generator's labels.
./evaluate.py https://<web_url> --seeds 3

What Chalk handles

The models are the interesting part. Everything around them is the part Chalk does for you.

Measured on labeled data

On 153 synthetic transactions the merchant matched the label 95% of the time and the category 93%. The evaluation script ships with the code, so you can rerun it.

Calibrated, not generated

Every category gets a probability, so low-confidence transactions can go to review instead of being guessed. The decision model never writes free text, so there is nothing to parse.

Two models, one GPU

GLiNER and the 9B decision model share one L40S in a single scaling group. Ten transactions take about two seconds, batched in one forward pass.

Any open model

Both models load straight from Hugging Face into a stock PyTorch image. Swap in a larger Clef, your own fine-tune, or a different extractor and redeploy.

Runs in your cloud

The replica runs in your Chalk environment, next to the ledger it enriches. Account data never passes through a third-party API.

Open source

The server, page, transaction generator, evaluator and deploy script are Apache-2.0 on GitHub.

Turn transactions into features

Underwriting, fraud, and personal finance all start from a clean ledger. Talk to an engineer about enriching transactions on GPUs in your cloud.