---
description: Documentation for Belfort's compilation-as-a-service platform for encrypted inference.
---

# Introduction

Belfort runs your PyTorch model on data that stays encrypted. Your end client
encrypts an input on their own machine, a Belfort GPU runs the model on the
ciphertext, and the end client decrypts the result. The secret key never leaves
the end client, so neither you nor Belfort can read the input or the result.

The encryption is fully homomorphic encryption (FHE) in the CKKS scheme, which
computes additions and multiplications on encrypted real numbers. Any other
operation, such as a ReLU, is replaced by a polynomial approximation, which
costs time and some accuracy.

## Who it is for

Model providers whose end clients cannot hand over their raw data, such as
health records, financial transactions or sensor readings, but want the
provider's predictions on it. You never hold the end client's data, and the
model runs on Belfort's GPUs.

## Which models compile

A trained `nn.Module` with one encrypted input of a fixed shape, built from
linear layers, convolutions, average pooling, batch normalization and
elementwise activations. Depthwise convolutions compile. Max pooling, other
grouped convolutions and softmax are not supported yet.
[What compiles](concepts/compilation-pipeline.md#what-compiles) lists the
supported and unsupported operations and what each costs.
<!-- TODO: say whether attention works once it has been validated. -->

## The path from a model to an encrypted inference

1. Compile locally: `belfort_ml.compile` traces your `nn.Module` and writes
   it out as MLIR, without a network call.
2. Upload and compile for FHE:
   `provider.models.get(name=..., create_from=artifacts)` uploads the MLIR, or
   returns the model already compiled from it.
   Belfort's compiler chooses encryption parameters and generates GPU code for
   the server and C++ for the Belfort ML client (key generation, encryption,
   decryption).
3. Mint a client token: `model.create_client` returns a token that lets one
   end client use this model through the Belfort gateway. Belfort does not
   deliver it: you pass it to the end client yourself, the same way you
   already exchange data with them.
4. Deploy: `model.deploy` starts a GPU instance with your model.
5. Infer: your end client runs the Belfort ML client on the token, as the
   `belfort-ml-client infer` command or `belfort_ml_client.Client` in Python. It
   downloads the client-side C++ for your model, builds it, generates a key
   pair, and uploads the public evaluation keys, which the gateway loads onto
   your deploy. It then encrypts, sends the ciphertext to the deploy, and
   decrypts the answer. The secret key stays in that process, and neither the
   input nor the answer passes through your code.

The [Quickstart](getting-started/quickstart.md) walks through all five steps
with a pretrained MNIST classifier, running the Belfort ML client yourself in place of an end client.

A coding agent such as Claude Code can follow these steps once you install the
[Belfort skill](getting-started/coding-agents.md).

## Two packages

| Package | Who runs it | What it does |
|---|---|---|
| `belfort-ml` | You, the model provider | Compiles models, and drives the Belfort gateway: models, client tokens, deploys, credits |
| `belfort-ml-client` | Your end client | Holds the secret key: on a client token from you, builds the client code, generates keys, encrypts, decrypts |

[Model providers and end clients](concepts/providers-and-end-clients.md)
explains what crosses between them.
