What we do · expertise

Artificial intelligence

Your models on your side, your data never leaves.

Inference and fine-tuning on your infrastructure: GPU sizing, serving architecture, agents and the MCP protocol. We favour sourced answers — an answer that does not cite its document is unusable in a regulated business.

vLLMTritonKServeKubeflowMCPpgvector
Engagement models
Audit & architecture · Embedded
Inference chain
KServe · LeaderWorkerSet · vLLM
Accelerators
NVIDIA GPU Operator, on your own hardware
Model weights
Staged into an internal volume, mounted read-only
Service egress
None, by default
Foundation models
We do not train them

Method

Sizing decides how many machines you buy.

Sizing is calculated before a model is chosen, and it decides the hardware budget. Weights have to fit in accelerator memory next to the attention cache, which grows with the number of concurrent sessions and the context length. As long as the weights fit on one GPU, a replica is one pod and one card. When they no longer do, they are sharded across several cards in one machine. When they no longer fit in one machine, it takes several machines to serve a single model.

That is where Kubernetes alone stops being enough. A Deployment does not know that four pods are one model: it schedules them separately, restarts one without the others, and a half-placed group serves nothing at all. LeaderWorkerSet treats the group as the unit — one leader, its workers, placed, restarted and scaled together. It is the piece that makes a multi-node replica genuinely operable, and that is why it is installed in the platform before it is needed.

The chain we run is this one: KServe for the service declaration, LeaderWorkerSet for distributed replicas, the NVIDIA GPU Operator for drivers, device plugin and DCGM metrics, vLLM as the inference engine, an Envoy gateway at the front with a tokenizer-aware scheduler. It runs on a client's infrastructure, described in GitOps, alongside Ceph storage, PostgreSQL operated by CloudNativePG and OpenBao.

The manifest opposite is taken from it, and one of its details carries the point: the checkpoint is already FP8-quantised when we stage it. That is not a quality footnote, it is a sizing decision. The on-disk and in-memory footprint falls by roughly half, startup no longer includes a quantisation pass, and the chosen scheme — eight-bit float weights channel by channel, per-token dynamic activations — is tighter than the one the engine would apply on its own. The weights arrive through a download job into an internal volume, then mounted read-only: at startup, the service fetches nothing from the internet.

What this produces is hard to measure, and we measure it anyway. On a document-exploitation engagement, the client team estimated 1 h (1) given back to each equipped employee. It is a self-reported estimate, at a single client, and it does not generalise.

platform-apps/kserve/model-serving/… KServe · LLMInferenceService · YAML
apiVersion: serving.kserve.io/v1alpha2
kind: LLMInferenceService
metadata:
  name: …
spec:
  model:
    # Local copy staged by the download Job (avoids the presets' 1Gi
    # storage-initializer cap). Mounted at /mnt/models by the controller.
    #
    # Pre-quantized FP8 build rather than the BF16 repo quantized at load:
    # 8-bit float weights (channel-wise, static) with per-token dynamic
    # activations, which is a tighter scheme than the per-tensor default
    # vLLM applies for --quantization fp8. And no quantization pass
    # during startup.
    uri: pvc://…
    name: …
  replicas: 1
  # Managed gateway + route + EPP scheduler (the llm-d data path via the
  # envoy GatewayClass installed by platform-apps/envoy-gateway).
  router:
    gateway: {}
    route: {}
  template:
    containers:
      - name: main
        image: vllm/vllm-openai:v0.24.0
        resources:
          limits:
            nvidia.com/gpu: "1"
        # Injected via the llmd preset's VLLM_ADDITIONAL_ARGS launch-script hook.
        env:
          - name: VLLM_ADDITIONAL_ARGS
            value: "--kv-cache-dtype fp8 --enable-auto-tool-choice …"
An inference service manifest taken from a GitOps repository we operate. Redacted before publication: host, cluster, volume and served-model names removed, CPU and memory requests and limits removed. The comments are the repository's own. One operational detail does not fit in the excerpt: the scheduler that routes by tokenizer mounts the same weights volume, and that volume accepts only one node at a time — so the scheduler has to be placed on the workload's node, or it deadlocks on mount. That kind of constraint only shows up in production.

Scope

What we do, and what we do not do.

Everything starts from the hardware you have and from what your documents actually are.

What we do

  • Size it: model, card count, memory, attention cache, target throughput — with the arithmetic and its assumptions written out, not a range.
  • Deploy the chain on your hardware: KServe, vLLM, LeaderWorkerSet for distributed replicas, the GPU Operator, queues and per-team quotas.
  • Choose and apply a quantisation scheme, and measure what it costs in quality on your own documents.
  • Fine-tune an open model on your data, on your infrastructure, without the training set leaving your perimeter.
  • Build sourced answers: every answer cites the document it came from, a precondition for use in a regulated business.
  • Expose tools over MCP, under the same access control and the same audit trail as the rest of the platform.

What we do not do

  • We do not train foundation models. We start from open models published by others, and we tell you which ones and under what licence.
  • We do not resell a third-party API under our own name, and we do not route your data through a service whose jurisdiction we do not carry.
  • We do not judge a model on a public leaderboard: evaluation happens on your documents, with your business teams, and the protocol is written down.

Engagements

Two comparable engagements.

Described by the setup that was put in place and by what it produced.

Data & AI · fixed-term engagement

Industrial group

An ingestion pipeline that takes documents as they come, a base of open tables queried in SQL, semantic indexing — and one rule on the answering side: an answer without a source document is not an answer.

TrinoApache IcebergOCRpgvectorMCP

Sovereign cloud · ongoing

Montpellier Métropole

An internal cloud for data and inference, deployed under public control: the models run on the authority's own infrastructure, and the logs stay on its side.

KubernetesvLLMKeycloakPostgreSQLMinIO

See all four engagements

Get in touch

Start from the hardware and the documents.

Before talking about a model, we look at three things: the hardware you have, what your documents actually are, and what your logging policy permits. Sizing is calculated; it is not guessed, and it is not copied from another client.