antflydb/termite

Termite ML inference service for embeddings, chunking, and reranking

28

stars

438

commits

Go

primary language

Apr 21, 2026

updated

README

Termite

Build status Docs

ML inference service for embeddings, chunking, reranking, classification, NER, OCR, transcription, text generation, and more — with two-tier caching (memory + singleflight).

Termite is the companion ML service for Antfly, the distributed search engine. It runs automatically in Antfly's swarm mode and can also be used standalone. If you're new, the Antfly quickstart is the fastest way to see everything working together.

Documentation | Discord

Features

  • Embeddings — dense and sparse vectors, multimodal (text, images, audio)
  • Chunking — semantic text segmentation
  • Reranking — cross-encoder relevance scoring
  • Classification — zero-shot text classification (NLI-based, 100+ languages)
  • Recognition (NER) — named entity recognition, zero-shot labels, relation extraction
  • Reading (OCR) — document understanding, OCR, visual question answering
  • Transcription — speech-to-text (Whisper, Wav2Vec2)
  • Extraction — schema-based structured data extraction
  • Rewriting — paraphrasing, question generation (Seq2Seq)
  • Generation — text generation with tool calling (OpenAI-compatible)
  • Multiple backends — ONNX Runtime, XLA (TPU/CUDA), pure Go
  • SIMD / SME acceleration — vector math uses hardware intrinsics via go-highway on x86 and ARM
  • Native Go ML — XLA backend powered by GoMLX and GoLLMX, working toward making native Go ML/LLM inference a reality
  • Kubernetes operator — autoscaling with TermitePool and TermiteRoute CRDs

Running

# Standalone server
go run ./cmd/termite run

Inference Backends

Termite supports multiple inference backends, selected via build tags. The omni build includes everything so you can pick at runtime.

BuildTagsDescriptionUse Case
Pure Go(none)No CGO, always worksDevelopment, testing
ONNXonnx,ORTFast CPU/GPU via ONNX RuntimeProduction (recommended)
XLAxla,XLATPU/CUDA via GoMLXCloud TPU, NVIDIA GPU
Omnionnx,ORT,xla,XLAAll backendsMaximum flexibility

Includes both ONNX and XLA backends — pick which one to use at runtime without recompiling.

# Download dependencies for all platforms
./scripts/download-onnxruntime.sh
./scripts/download-pjrt.sh

# Build omni binary
CGO_ENABLED=1 go build -tags="onnx,ORT,xla,XLA" -o termite ./pkg/termite/cmd

# Run with backend priority (tries in order until one works)
./termite run --backend-priority="onnx:cuda,xla:tpu,onnx:cpu,go"

ONNX Runtime

Dependencies:

  • ONNX Runtime - download for your platform or install with homebrew
  • Tokenizers - HuggingFace tokenizers bindings
# Download dependencies
./scripts/download-onnxruntime.sh

# Or manually (macOS with homebrew)
CGO_ENABLED=1 \
DYLD_LIBRARY_PATH=/opt/homebrew/opt/onnxruntime/lib \
CGO_LDFLAGS="-L$(pwd) -ltokenizers" \
go run -tags="onnx,ORT" ./pkg/termite/cmd run

XLA Runtime (TPU/GPU)

For TPU or CUDA GPU acceleration via GoMLX XLA backend. Hardware is autodetected.

Dependencies:

# Download dependencies
./scripts/download-pjrt.sh

# Build with XLA support
go build -tags="xla,XLA" -o termite ./pkg/termite/cmd

# Run with autodetection (TPU > CUDA > CPU)
./termite run

Autodetection:

  • TPU: Detected via libtpu.so, /dev/accel* devices, or GKE TPU node metadata
  • CUDA: Detected via nvidia-smi or libcudart.so in library path

Installing Additional PJRT Plugins:

The omni and XLA builds bundle a CPU PJRT plugin that's auto-discovered from lib/ next to the binary. For TPU or CUDA, install the right plugin:

# Install TPU plugin (for Google Cloud TPU)
go run github.com/gomlx/go-xla/cmd/pjrt_installer@latest -plugin=tpu

# Install CUDA plugin (for NVIDIA GPU)
go run github.com/gomlx/go-xla/cmd/pjrt_installer@latest -plugin=cuda

# Install to a specific location
go run github.com/gomlx/go-xla/cmd/pjrt_installer@latest -plugin=tpu -path=/usr/local/lib/go-xla

Installed plugins are found automatically via standard go-xla search paths. To override, set PJRT_PLUGIN_LIBRARY_PATH.

Platform Availability:

PlatformPJRT CPUNotes
linux-amd64Yes
linux-arm64Yes
darwin-arm64YesApple Silicon
darwin-amd64NoIntel Mac not supported upstream

Models

Pull from registry:

termite pull bge-small-en-v1.5
termite pull mxbai-rerank-base-v1
termite pull chonky-mmbert-small-multilingual-1

# List available models
termite list --remote

Models auto-discovered from chunker_models_dir, embedder_models_dir, reranker_models_dir.

Available Models

Embedders

ModelSizeDimsVariantsNotes
bge-small-en-v1.5128MB384f16, i8Fast English embeddings
all-MiniLM-L6-v287MB384f32, f16, i8Fastest, good quality
all-mpnet-base-v2418MB768f32, f16, i8Best sentence-transformers accuracy
nomic-embed-text-v1.5548MB768f16, i88K context, Matryoshka dims
bge-m32.2GB1024f16, i8100+ languages, 8K context
gte-Qwen2-1.5B-instruct6GB1536f1632K context, instruction-following
snowflake-arctic-embed-l-v2.01.3GB1024f16, i8Retrieval-optimized, Matryoshka
stella_en_1.5B_v56GB1024f16Premium English, top MTEB scores
embeddinggemma-300m-ONNX1.2GB768f16, q4, q4f16Multilingual, edge-optimized
splade-cocondenser-ensembledistilsparsef32Sparse embeddings (SPLADE)

Multimodal Embedders

ModelSizeDimsVariantsNotes
clip-vit-base-patch32584MB512f16, i8Text + image embeddings (CLIP)
clipclap512Text + image (CLIP variant)
clap-htsat-unfused512Audio + text embeddings (CLAP)

Rerankers

ModelSizeVariants
mxbai-rerank-base-v1713MBf16, i8

Chunkers

ModelSizeVariants
chonky-mmbert-small-multilingual-1570MBf16, i8

Classifiers

ModelSizeVariantsNotes
mDeBERTa-v3-base-mnli-xnlif32, f16, i8Zero-shot, 100+ languages
bart-large-mnlif32, f16, i8Zero-shot, English

Recognizers (NER)

ModelSizeVariantsCapabilities
bert-base-NER413MBf32, f16, i8labels
bert-large-NER1.3GBf32, f16, i8labels
gliner_small-v2.1199MBf32, f16, i8labels, zeroshot
gliner2-base-v1f32, f16, i8labels, zeroshot (improved)
gliner-multitask-large-v0.51.3GBf32, f16, i8labels, zeroshot, relations, answers
rebel-large3.0GB-relations

Readers (OCR / Document Understanding)

ModelSizeVariantsNotes
trocr-base-printedPrinted text OCR
donut-base-finetuned-cord-v2Receipt/form parsing
donut-base-finetuned-docvqaDocument question answering
moondream2General vision understanding

Transcribers (Speech-to-Text)

ModelSizeVariantsNotes
whisper-tiny.enOpenAI Whisper, English

Extractors

ModelSizeVariantsNotes
gliner2-base-v1f32, f16, i8Schema-based field extraction

Rewriters

ModelSizeVariants
flan-t5-small-squad-qg569MB-
pegasus_paraphrase4.5GB-

Generators

ModelSizeVariants
functiongemma-270m-it1.1GB-
gemma-3-1b-it3.7GB-

Model Variants

Models come in multiple precision variants, trading off size and speed for accuracy:

VariantFileDescription
(default)model.onnxFP32 baseline - highest accuracy
f16model_f16.onnxFP16 - ~50% smaller, recommended for ARM64/M-series
i8model_i8.onnxINT8 dynamic quantization - smallest, fastest CPU inference

Pull specific variants:

# Pull using variant suffix (recommended)
termite pull bge-small-en-v1.5-i8

# Or use --variants flag
termite pull --variants i8 bge-small-en-v1.5

# Pull multiple models with same variant
termite pull bge-small-en-v1.5-i8 mxbai-rerank-base-v1-i8

# Pull multiple variants for one model
termite pull --variants f16,i8 bge-small-en-v1.5

Use variants in config:

embedder:
  provider: termite
  model: bge-small-en-v1.5-f16  # Use FP16 variant

Termite auto-selects the best available variant if not specified.

API

All endpoints accept JSON. See openapi.yaml for full schema details.

EndpointMethodDescription
/api/embedPOSTGenerate dense and sparse embeddings (text, image, audio)
/api/chunkPOSTChunk text into semantic segments
/api/rerankPOSTRerank documents by relevance
/api/classifyPOSTZero-shot text classification
/api/recognizePOSTNamed entity recognition
/api/readPOSTOCR and document understanding
/api/transcribePOSTSpeech-to-text transcription
/api/extractPOSTSchema-based structured data extraction
/api/rewritePOSTText rewriting (paraphrase, question generation)
/api/generatePOSTText generation (OpenAI-compatible)
/api/modelsGETList available models
/api/versionGETVersion info

Multimodal Input

The /api/embed endpoint supports multimodal input using the OpenAI content format:

{
  "model": "clip-vit-base-patch32",
  "input": [
    {
      "content": [
        {"type": "text", "text": "a photo of a cat"},
        {"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}
      ]
    }
  ]
}

Configuration

Config via file (termite.yaml), flags, or environment variables (TERMITE_ prefix):

api_url: "http://localhost:11433"
models_dir: "./models"

# Backend priority with optional device specifiers
# Format: "backend" or "backend:device"
# Devices: auto (default), cuda, coreml, tpu, cpu
backend_priority:
  - onnx:cuda      # Try ONNX with CUDA first
  - xla:tpu        # Then XLA with TPU
  - onnx:cpu       # Fall back to ONNX CPU
  - go             # Pure Go fallback (always works)

keep_alive: "5m"
max_loaded_models: 3
allow_downloads: false
log:
  level: info
  style: terminal

Backend Priority

The backend_priority setting controls which backends Termite tries, in order. Each entry can be:

  • Backend only: onnx, xla, go - uses auto device detection
  • Backend with device: onnx:cuda, xla:tpu, onnx:coreml - explicit device

Available backends (depend on build tags):

BackendBuild TagsDevices Supported
onnxonnx,ORTcuda, coreml (macOS), cpu
xlaxla,XLAtpu, cuda, cpu
go(none)cpu only

Example configurations:

# GPU-first with CPU fallback
backend_priority: ["onnx:cuda", "xla:cuda", "onnx:cpu", "go"]

# macOS with CoreML acceleration
backend_priority: ["onnx:coreml", "go"]

# Cloud TPU deployment
backend_priority: ["xla:tpu", "xla:cpu"]

# Simple auto-detection (default)
backend_priority: ["onnx", "xla", "go"]

Kubernetes Operator

Deploy on GKE with TPU support using the Termite Operator.

Custom Resources

TermitePool: manages a pool of Termite replicas with autoscaling.

apiVersion: termite.antfly.io/v1alpha1
kind: TermitePool
metadata:
  name: embeddings-pool
spec:
  workloadType: read-heavy
  models:
    preload:
      - name: bge-small-en-v1.5
        variant: i8
        priority: high
        strategy: eager    # Always loaded, never evicted
      - name: mxbai-rerank-base-v1
        variant: i8
        priority: high
        # strategy defaults to loadingStrategy (lazy)
    loadingStrategy: lazy  # Default for models without explicit strategy
    keepAlive: 5m          # Idle timeout for lazy models
  replicas:
    min: 2
    max: 10
  hardware:
    accelerator: tpu-v5-lite-podslice
    topology: "2x2"
  autoscaling:
    enabled: true
    metrics:
      - type: queue-depth
        target: "50"

TermiteRoute: routes traffic to pools based on model or endpoint.

Running the Operator

# Build operator
go build -o termite-operator ./cmd/termite-operator

# Generate CRDs and RBAC manifests
make generate

See pkg/operator/ for CRD definitions and controller implementation. The model registry protocol is formally specified in TLA+.

Community

Discord for questions, discussion, and updates.

License

Apache License 2.0

Contributors

ajroetker

372 commits

timkaye11

47 commits

dovinmu

14 commits

claude

2 commits

antflydb/termite

Termite ML inference service for embeddings, chunking, and reranking

28

stars

438

commits

Go

primary language

Apr 21, 2026

updated

README

Termite

Build status Docs

ML inference service for embeddings, chunking, reranking, classification, NER, OCR, transcription, text generation, and more — with two-tier caching (memory + singleflight).

Termite is the companion ML service for Antfly, the distributed search engine. It runs automatically in Antfly's swarm mode and can also be used standalone. If you're new, the Antfly quickstart is the fastest way to see everything working together.

Documentation | Discord

Features

  • Embeddings — dense and sparse vectors, multimodal (text, images, audio)
  • Chunking — semantic text segmentation
  • Reranking — cross-encoder relevance scoring
  • Classification — zero-shot text classification (NLI-based, 100+ languages)
  • Recognition (NER) — named entity recognition, zero-shot labels, relation extraction
  • Reading (OCR) — document understanding, OCR, visual question answering
  • Transcription — speech-to-text (Whisper, Wav2Vec2)
  • Extraction — schema-based structured data extraction
  • Rewriting — paraphrasing, question generation (Seq2Seq)
  • Generation — text generation with tool calling (OpenAI-compatible)
  • Multiple backends — ONNX Runtime, XLA (TPU/CUDA), pure Go
  • SIMD / SME acceleration — vector math uses hardware intrinsics via go-highway on x86 and ARM
  • Native Go ML — XLA backend powered by GoMLX and GoLLMX, working toward making native Go ML/LLM inference a reality
  • Kubernetes operator — autoscaling with TermitePool and TermiteRoute CRDs

Running

# Standalone server
go run ./cmd/termite run

Inference Backends

Termite supports multiple inference backends, selected via build tags. The omni build includes everything so you can pick at runtime.

BuildTagsDescriptionUse Case
Pure Go(none)No CGO, always worksDevelopment, testing
ONNXonnx,ORTFast CPU/GPU via ONNX RuntimeProduction (recommended)
XLAxla,XLATPU/CUDA via GoMLXCloud TPU, NVIDIA GPU
Omnionnx,ORT,xla,XLAAll backendsMaximum flexibility

Includes both ONNX and XLA backends — pick which one to use at runtime without recompiling.

# Download dependencies for all platforms
./scripts/download-onnxruntime.sh
./scripts/download-pjrt.sh

# Build omni binary
CGO_ENABLED=1 go build -tags="onnx,ORT,xla,XLA" -o termite ./pkg/termite/cmd

# Run with backend priority (tries in order until one works)
./termite run --backend-priority="onnx:cuda,xla:tpu,onnx:cpu,go"

ONNX Runtime

Dependencies:

  • ONNX Runtime - download for your platform or install with homebrew
  • Tokenizers - HuggingFace tokenizers bindings
# Download dependencies
./scripts/download-onnxruntime.sh

# Or manually (macOS with homebrew)
CGO_ENABLED=1 \
DYLD_LIBRARY_PATH=/opt/homebrew/opt/onnxruntime/lib \
CGO_LDFLAGS="-L$(pwd) -ltokenizers" \
go run -tags="onnx,ORT" ./pkg/termite/cmd run

XLA Runtime (TPU/GPU)

For TPU or CUDA GPU acceleration via GoMLX XLA backend. Hardware is autodetected.

Dependencies:

# Download dependencies
./scripts/download-pjrt.sh

# Build with XLA support
go build -tags="xla,XLA" -o termite ./pkg/termite/cmd

# Run with autodetection (TPU > CUDA > CPU)
./termite run

Autodetection:

  • TPU: Detected via libtpu.so, /dev/accel* devices, or GKE TPU node metadata
  • CUDA: Detected via nvidia-smi or libcudart.so in library path

Installing Additional PJRT Plugins:

The omni and XLA builds bundle a CPU PJRT plugin that's auto-discovered from lib/ next to the binary. For TPU or CUDA, install the right plugin:

# Install TPU plugin (for Google Cloud TPU)
go run github.com/gomlx/go-xla/cmd/pjrt_installer@latest -plugin=tpu

# Install CUDA plugin (for NVIDIA GPU)
go run github.com/gomlx/go-xla/cmd/pjrt_installer@latest -plugin=cuda

# Install to a specific location
go run github.com/gomlx/go-xla/cmd/pjrt_installer@latest -plugin=tpu -path=/usr/local/lib/go-xla

Installed plugins are found automatically via standard go-xla search paths. To override, set PJRT_PLUGIN_LIBRARY_PATH.

Platform Availability:

PlatformPJRT CPUNotes
linux-amd64Yes
linux-arm64Yes
darwin-arm64YesApple Silicon
darwin-amd64NoIntel Mac not supported upstream

Models

Pull from registry:

termite pull bge-small-en-v1.5
termite pull mxbai-rerank-base-v1
termite pull chonky-mmbert-small-multilingual-1

# List available models
termite list --remote

Models auto-discovered from chunker_models_dir, embedder_models_dir, reranker_models_dir.

Available Models

Embedders

ModelSizeDimsVariantsNotes
bge-small-en-v1.5128MB384f16, i8Fast English embeddings
all-MiniLM-L6-v287MB384f32, f16, i8Fastest, good quality
all-mpnet-base-v2418MB768f32, f16, i8Best sentence-transformers accuracy
nomic-embed-text-v1.5548MB768f16, i88K context, Matryoshka dims
bge-m32.2GB1024f16, i8100+ languages, 8K context
gte-Qwen2-1.5B-instruct6GB1536f1632K context, instruction-following
snowflake-arctic-embed-l-v2.01.3GB1024f16, i8Retrieval-optimized, Matryoshka
stella_en_1.5B_v56GB1024f16Premium English, top MTEB scores
embeddinggemma-300m-ONNX1.2GB768f16, q4, q4f16Multilingual, edge-optimized
splade-cocondenser-ensembledistilsparsef32Sparse embeddings (SPLADE)

Multimodal Embedders

ModelSizeDimsVariantsNotes
clip-vit-base-patch32584MB512f16, i8Text + image embeddings (CLIP)
clipclap512Text + image (CLIP variant)
clap-htsat-unfused512Audio + text embeddings (CLAP)

Rerankers

ModelSizeVariants
mxbai-rerank-base-v1713MBf16, i8

Chunkers

ModelSizeVariants
chonky-mmbert-small-multilingual-1570MBf16, i8

Classifiers

ModelSizeVariantsNotes
mDeBERTa-v3-base-mnli-xnlif32, f16, i8Zero-shot, 100+ languages
bart-large-mnlif32, f16, i8Zero-shot, English

Recognizers (NER)

ModelSizeVariantsCapabilities
bert-base-NER413MBf32, f16, i8labels
bert-large-NER1.3GBf32, f16, i8labels
gliner_small-v2.1199MBf32, f16, i8labels, zeroshot
gliner2-base-v1f32, f16, i8labels, zeroshot (improved)
gliner-multitask-large-v0.51.3GBf32, f16, i8labels, zeroshot, relations, answers
rebel-large3.0GB-relations

Readers (OCR / Document Understanding)

ModelSizeVariantsNotes
trocr-base-printedPrinted text OCR
donut-base-finetuned-cord-v2Receipt/form parsing
donut-base-finetuned-docvqaDocument question answering
moondream2General vision understanding

Transcribers (Speech-to-Text)

ModelSizeVariantsNotes
whisper-tiny.enOpenAI Whisper, English

Extractors

ModelSizeVariantsNotes
gliner2-base-v1f32, f16, i8Schema-based field extraction

Rewriters

ModelSizeVariants
flan-t5-small-squad-qg569MB-
pegasus_paraphrase4.5GB-

Generators

ModelSizeVariants
functiongemma-270m-it1.1GB-
gemma-3-1b-it3.7GB-

Model Variants

Models come in multiple precision variants, trading off size and speed for accuracy:

VariantFileDescription
(default)model.onnxFP32 baseline - highest accuracy
f16model_f16.onnxFP16 - ~50% smaller, recommended for ARM64/M-series
i8model_i8.onnxINT8 dynamic quantization - smallest, fastest CPU inference

Pull specific variants:

# Pull using variant suffix (recommended)
termite pull bge-small-en-v1.5-i8

# Or use --variants flag
termite pull --variants i8 bge-small-en-v1.5

# Pull multiple models with same variant
termite pull bge-small-en-v1.5-i8 mxbai-rerank-base-v1-i8

# Pull multiple variants for one model
termite pull --variants f16,i8 bge-small-en-v1.5

Use variants in config:

embedder:
  provider: termite
  model: bge-small-en-v1.5-f16  # Use FP16 variant

Termite auto-selects the best available variant if not specified.

API

All endpoints accept JSON. See openapi.yaml for full schema details.

EndpointMethodDescription
/api/embedPOSTGenerate dense and sparse embeddings (text, image, audio)
/api/chunkPOSTChunk text into semantic segments
/api/rerankPOSTRerank documents by relevance
/api/classifyPOSTZero-shot text classification
/api/recognizePOSTNamed entity recognition
/api/readPOSTOCR and document understanding
/api/transcribePOSTSpeech-to-text transcription
/api/extractPOSTSchema-based structured data extraction
/api/rewritePOSTText rewriting (paraphrase, question generation)
/api/generatePOSTText generation (OpenAI-compatible)
/api/modelsGETList available models
/api/versionGETVersion info

Multimodal Input

The /api/embed endpoint supports multimodal input using the OpenAI content format:

{
  "model": "clip-vit-base-patch32",
  "input": [
    {
      "content": [
        {"type": "text", "text": "a photo of a cat"},
        {"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}
      ]
    }
  ]
}

Configuration

Config via file (termite.yaml), flags, or environment variables (TERMITE_ prefix):

api_url: "http://localhost:11433"
models_dir: "./models"

# Backend priority with optional device specifiers
# Format: "backend" or "backend:device"
# Devices: auto (default), cuda, coreml, tpu, cpu
backend_priority:
  - onnx:cuda      # Try ONNX with CUDA first
  - xla:tpu        # Then XLA with TPU
  - onnx:cpu       # Fall back to ONNX CPU
  - go             # Pure Go fallback (always works)

keep_alive: "5m"
max_loaded_models: 3
allow_downloads: false
log:
  level: info
  style: terminal

Backend Priority

The backend_priority setting controls which backends Termite tries, in order. Each entry can be:

  • Backend only: onnx, xla, go - uses auto device detection
  • Backend with device: onnx:cuda, xla:tpu, onnx:coreml - explicit device

Available backends (depend on build tags):

BackendBuild TagsDevices Supported
onnxonnx,ORTcuda, coreml (macOS), cpu
xlaxla,XLAtpu, cuda, cpu
go(none)cpu only

Example configurations:

# GPU-first with CPU fallback
backend_priority: ["onnx:cuda", "xla:cuda", "onnx:cpu", "go"]

# macOS with CoreML acceleration
backend_priority: ["onnx:coreml", "go"]

# Cloud TPU deployment
backend_priority: ["xla:tpu", "xla:cpu"]

# Simple auto-detection (default)
backend_priority: ["onnx", "xla", "go"]

Kubernetes Operator

Deploy on GKE with TPU support using the Termite Operator.

Custom Resources

TermitePool: manages a pool of Termite replicas with autoscaling.

apiVersion: termite.antfly.io/v1alpha1
kind: TermitePool
metadata:
  name: embeddings-pool
spec:
  workloadType: read-heavy
  models:
    preload:
      - name: bge-small-en-v1.5
        variant: i8
        priority: high
        strategy: eager    # Always loaded, never evicted
      - name: mxbai-rerank-base-v1
        variant: i8
        priority: high
        # strategy defaults to loadingStrategy (lazy)
    loadingStrategy: lazy  # Default for models without explicit strategy
    keepAlive: 5m          # Idle timeout for lazy models
  replicas:
    min: 2
    max: 10
  hardware:
    accelerator: tpu-v5-lite-podslice
    topology: "2x2"
  autoscaling:
    enabled: true
    metrics:
      - type: queue-depth
        target: "50"

TermiteRoute: routes traffic to pools based on model or endpoint.

Running the Operator

# Build operator
go build -o termite-operator ./cmd/termite-operator

# Generate CRDs and RBAC manifests
make generate

See pkg/operator/ for CRD definitions and controller implementation. The model registry protocol is formally specified in TLA+.

Community

Discord for questions, discussion, and updates.

License

Apache License 2.0

Contributors

ajroetker

372 commits

timkaye11

47 commits

dovinmu

14 commits

claude

2 commits

Languages

Go

87.1%

Python

10.4%

Shell

1.3%