Financial Fraud Detection — Conceptual Overview#

1. Conceptual Overview — What Is a GNN?#

1.1 The Limits of Traditional Machine Learning for Fraud#

In a conventional fraud detection system, you train a model on a table where each row represents one transaction and each column is a feature: transaction amount, time of day, merchant category, whether the card was present, and so on. This approach works reasonably well, but it has a fundamental blind spot: it evaluates every transaction as if it happened in isolation.

Consider the following scenario:

  • A merchant has processed 200 transactions this month. Fifty of them resulted in chargebacks, meaning customers disputed the charges as fraudulent.

  • A new transaction arrives at that merchant from a customer who has never been flagged before.

A traditional model, looking only at the new transaction’s own features, might score this as low-risk because the customer’s history is clean. It has no way to know the merchant is compromised. This is exactly how fraud rings exploit standard systems.

1.2 Graphs as a Natural Representation of Financial Networks#

A graph is a data structure consisting of nodes (entities) and edges (relationships between entities). Financial transaction data is naturally graph-shaped:

[Customer 7] ──holds──► [Account 42] ──transacts──► [Merchant 19]
                              │                            │
                              └──uses──► [Terminal 88] ◄──serves──┘

                         ──initiated by──► [Device 34]

In this graph:

  • Nodes are real-world entities: customers, accounts, merchants, devices, terminals.

  • Edges capture relationships: “account 42 sent a transaction to merchant 19,” “device 34 initiated a session on account 42.”

  • Each node carries a feature vector describing its attributes (balance, account age, merchant category, device OS, etc.).

  • Each transaction edge can carry its own features (amount, time of day, payment channel).

The prediction task is an edge classification problem: given a transaction edge between an account and a merchant, is it fraudulent?

1.3 How a GNN Aggregates Context#

A Graph Neural Network learns by iteratively passing messages between connected nodes. The number of hops is configurable (default: 2). The computation for a single query transaction with 2 hops proceeds as follows:

Hop 2 (outermost): Every node in the sampled neighbourhood gathers feature vectors from its own immediate neighbours — across all edge types connected to it — and aggregates them into a compact summary.

Merchant 19 ← gathers info from ← [Accounts 3, 17, 42, 55, 91, ...] + [Terminals 88, 102, ...]
Account 42  ← gathers info from ← [Merchants 7, 19, 44, ...] + [Customer 7] + [Device 34] + [Terminal 88]

The graph is heterogeneous, not bipartite. Each node type aggregates from all node types it is directly connected to through any edge relation. All those relations contribute signal in each hop.

Hop 1: Each node updates its own representation using the aggregated summaries from Hop 2.

Final step: The edge embedding for the transaction between Account 42 and Merchant 19 is formed by combining the updated representations of both endpoint nodes. This embedding encodes everything the GNN has learned about the local neighbourhood — including the fraud history of the merchant’s other transactions, the behavioral patterns of the account’s other merchants, device and terminal context, and the topological structure connecting them.

This is why a GNN can flag a transaction from a clean customer to a compromised merchant, even if the customer’s own history is pristine: the merchant’s neighbourhood is carrying the fraud signal.

1.4 The Two-Stage Architecture — GNN + XGBoost#

This pipeline uses a two-stage approach that combines the structural reasoning of GNNs with the predictive precision of gradient-boosted trees:

                         ┌─────────────────────────────────┐
Raw Graph Data           │          Stage 1: GNN           │
(nodes + edges)   ──────►│                                 │
                         │  For each query edge:           │
                         │  1. Sample N-hop neighbourhood  │
                         │     (N configurable, default 2) │
                         │  2. Aggregate node features     │
                         │  3. Output dense embedding      │
                         │     (captures graph context)    │
                         └───────────────┬─────────────────┘
                                         │  edge embedding
                                         │  [2·hidden_channels + raw_node_feat_dim]

                         ┌─────────────────────────────────┐
                         │          Stage 2: XGBoost       │
                         │                                 │
                         │  Gradient-boosted forest        │
                         │  classifies each embedding      │
                         │  as fraud (1) or legitimate (0) │
                         └───────────────┬─────────────────┘


                              Fraud Probability  [0.0 – 1.0]

Why not train the GNN end-to-end as a classifier?
End-to-end GNN classifiers are technically possible, but for fraud detection specifically, the two-stage approach offers decisive practical advantages:

Concern

End-to-End GNN

GNN + XGBoost

Training time for tabular patterns

Very long (deep net)

Fast (boosted trees)

Handling class imbalance (1–5% fraud)

Difficult; requires careful loss tuning

Natural; XGBoost supports scale_pos_weight

Explainability

Black-box

Shapley values available from XGBoost

Incremental retraining

Must retrain full network

Can retrain XGBoost on new embeddings alone

Model size

Large

Compact

1.5 The Explainability Layer#

Because the pipeline uses XGBoost as the final classifier, we have access to principled feature attribution methods. The xgb_explainer Triton backend computes Shapley Value Sampling (SVS) attributions using Captum — a game-theoretic measure that fairly distributes the prediction credit across all feature groups.

Feature groups are defined during training based on the semantic meaning of each block of dimensions in the embedding vector (GNN embedding of the account, GNN embedding of the merchant, raw account features, raw merchant features, transaction amount, payment channel, etc.). The top contributors are surfaced to the LLM, which generates a human-readable explanation.


2. System Architecture — Deep Dive#

2.1 Full Pipeline Diagram#

┌──────────────────────────────────────────────────────────────────┐
│                        Training Phase                            │
│                                                                  │
│  your-data/                                                      │
│  ├── nodes/  ──► Data Discovery & Validation                     │
│  └── edges/                                                      │
│                          │                                       │
│                          ▼                                       │
│                 WholeGraph Partitioning                          │
│                 (distributes graph across GPUs)                  │
│                          │                                       │
│             ┌────────────┴────────────┐                          │
│         GPU 0                      GPU 1  ...                    │
│         GNN training               GNN training                  │
│         (cuGraph-PyG)              (cuGraph-PyG)                 │
│         Gradient sync using NCCL ◄──►                            │
│             └────────────┬────────────┘                          │
│                          │  model_final.pt (rank 0 saves)        │
│                          ▼                                       │
│              GNN Embedding Extraction                            │
│              (full graph inference, all edges)                   │
│                          │  edge embeddings [N × feat_dim]       │
│                          ▼                                       │
│              XGBoost Distributed Training                        │
│              (RabitTracker, all GPUs collaborate)                │
│                          │  xgboost_fraud.json                   │
│                          ▼                                       │
│              Triton Artifact Export                              │
│              output/infer/triton/  ←── ready to deploy           │
└──────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│                    Inference Phase (Triton)                      │
│                                                                  │
│  Client sends graph tensors using gRPC                           │
│          │                                                       │
│          ▼                                                       │
│  ┌───────────────────────────────────────────┐                   │
│  │  fraud_pipeline  (ensemble)               │                   │
│  │                                           │                   │
│  │  gnn_embedder ──────────────────────────► │                   │
│  │  (Python backend: torch + torch_geometric)│                   │
│  │       │  edge embedding                   │                   │
│  │       ▼                                   │                   │
│  │  xgb_fraud ─────────────────────────────► │ fraud_probability │
│  │  (FIL backend: RAPIDS)                    │  [N, 1]           │
│  └───────────────────────────────────────────┘                   │
│                                                                  │
│  ┌────────────────────────────────────────────────────────────┐  │
│  │  fraud_pipeline_explained  (ensemble)                      │  │
│  │                                                            │  │
│  │  gnn_embedder ──────────────────────────────────────────►  │  │
│  │       │  edge embedding                                    │  │
│  │       ▼                                                    │  │
│  │  xgb_explainer ─────────────────────────────────────────►  │  │
│  │  (XGBoost + Captum SVS)                                    │  │
│  │       │  fraud_prob + svs_attrs + edge_embedding           │  │
│  │       ▼                                                    │  │
│  │  llm_explainer ─────────────────────────────────────────►  │  │
│  │  (OpenAI-compatible LLM)                                   │  │
│  │                                         fraud_prob         │  │
│  │                                         explanation (text) │  │
│  └────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────┘

2.2 Training Technology Stack#

Component

Technology

Role

GNN framework

cuGraph-PyG (NVIDIA)

Distributed heterogeneous GNN with GPU-accelerated sampling

Graph storage

WholeGraph (NVIDIA)

Distributed graph feature store; nodes partitioned across GPUs with transparent remote access

GNN training

PyTorch DDP + torchrun

Gradient synchronisation across processes using NCCL

GNN model

GNNEncoder

Heterogeneous multi-layer convolution (SAGE / GAT / Transformer / General)

XGBoost training

XGBoost + RabitTracker

Distributed gradient boosted trees; data sharded across GPUs

Orchestration

torchrun

Spawns one process per GPU; sets LOCAL_RANK, RANK, WORLD_SIZE

2.3 Inference Technology Stack#

Component

Technology

Role

Serving runtime

NVIDIA Triton Inference Server

Production model server with ensemble support

GNN inference

Triton Python backend (torch + torch_geometric)

Runs the saved GNN model on CPU/GPU tensors

XGBoost inference

Triton FIL backend (RAPIDS FIL)

Hardware-accelerated forest inference on GPU

Explainability

Triton Python backend (XGBoost + Captum)

Shapley Value Sampling feature attributions

LLM narrative

Triton Python backend (OpenAI SDK)

Calls OpenAI-compatible API; thread pool for parallel requests