Serving the Trained Model
Starting the Triton Server
Training writes everything you need to serve alongside the trained weights. Assume your training output is at /path/to/output (the value you passed as output_dir in your config). The structure you will find there is:
Step 1 — Install the client dependencies (host, once)
The inference client runs on the host (outside Docker). Install its dependencies once:
Step 2 — Start the Triton Server
serve.sh mounts the Triton model repository into the official nvcr.io/nvidia/tritonserver:26.04-py3 container and installs the Python backend dependencies at startup:
Run this in a dedicated terminal (it stays in the foreground). You will see a stream of startup logs as Triton loads each model.
What serve.sh executes internally:
Key design choices:
- Python dependencies (
torch_geometric,xgboost,captum,openai) are installed inside the container at every startup (torchis already in the Triton base image) — the model repository itself stays clean and portable. stub-timeout-seconds=120allows the Python backend models up to 2 minutes to initialise. This is necessary on first startup when PyTorch and the GNN architecture are loaded for the first time.- LLM API key environment variables are forwarded from the host shell into the container automatically — no secrets need to be baked into images or files.
Exposed ports:
Step 3 — Wait for the Server to Become Ready
The server takes 30–90 seconds on the first startup (pip install + model loading). Poll the health endpoint in a separate terminal:
The server is ready when the container logs show:
Verify all six models are loaded:
Expected: all of gnn_embedder, xgb_fraud, xgb_explainer, llm_explainer, fraud_pipeline, fraud_pipeline_explained show "state": "READY".
You can also check a specific model:
LLM Explainability at Serve Time
The LLM explainer calls an external OpenAI-compatible API. The API key must be set as an environment variable in the host shell before running serve.sh — the key is forwarded into the container automatically; you never need to write it to disk.
Option A — NVIDIA NIM (default, no LLM_BASE_URL needed):
Default endpoint: https://inference-api.nvidia.com
Default model: nvidia/meta/llama-3.2-1b-instruct
Option B — OpenAI or any compatible API endpoint:
Option C — Any other OpenAI-compatible endpoint:
Confirm the LLM backend connected successfully by checking the Triton startup logs for:
Running without an API key:
The server starts normally. fraud_pipeline (scoring only) works fully. fraud_pipeline_explained also starts, but llm_explainer disables itself gracefully — it logs a warning and returns a placeholder string ([LLM explanation disabled: set LLM_API_KEY to enable]) in place of a real explanation. This is not an error state; scoring is unaffected.
Production Deployment Checklist
Before routing production traffic to the server:
Multi-GPU Inference — Horizontal Scaling
By default, all models load on GPU 0 with 1 instance. To spread load across multiple GPUs, use the NUM_GPUS and INSTANCES_PER_GPU environment variables when calling serve.sh. The script automatically patches the config.pbtxt files before starting Triton — no manual file editing required. Training and deployment typically happen on different machines, so GPU count is set at serve time, not at training time.
Usage:
Triton load-balances incoming requests across all instances automatically.
Which models are patched:
Node prediction pipeline (GNN_XGBoost_NP):
Edge prediction pipeline (GNN_XGBoost):
What serve.sh writes to each patched config:
count is per GPU, not total. gpus: [0, 1] count: 3 creates 6 instances total (3 per GPU).
Startup time with many instances: torch.compile warmup runs once per GNN embedder instance (gnn_embedder for EP, np_gnn_embedder for NP). With 8 GPUs × 3 instances = 24 instances, startup can take several minutes. The default stub-timeout-seconds=120 may need increasing — set it in serve.sh if models fail to load: