Selected work / 01
Field build / Feb 2025Source

GPU inference / AWS EKS / Open source

A reasoning model on a GPU that arrives on demand.

An end-to-end field build for serving DeepSeek-R1-Distill-Qwen-7B on AWS EKS. Pod demand creates GPU capacity, vLLM exposes an ordinary API, and telemetry ships with the platform.

  1. 01
    ClientGradio + OpenAI SDK
  2. 02
    ServiceClusterIP / port 8000
  3. 03
    RuntimevLLM OpenAI API
  4. 04
    ComputeL4 GPU / Karpenter

47 resources

Added in the recorded Terraform apply

~5 minutes

Reported model download and GPU load

16K tokens

Configured maximum model context

$0.34-0.50 / hour

README estimate for the lab envelope
01

Operating premise

The GPU should be a consequence of demand.

Most model demos begin with an expensive machine already running. This one begins with a schedulable contract. Fargate keeps the minimum cluster services alive; Karpenter sees the pending GPU pod, selects available capacity, and removes empty nodes after the work is gone.

02

System map

A request becomes infrastructure.

The serving path stays small. The supporting control loops do the difficult work: bootstrapping, matching hardware, loading model state, and observing every token.

01

Client

Gradio + OpenAI SDK

02

Service

ClusterIP / port 8000

03

Runtime

vLLM OpenAI API

04

Compute

L4 GPU / Karpenter

A

Foundation

Terraform creates the VPC, two-AZ EKS cluster, private subnets, and AWS integrations.

B

Bootstrap

Fargate runs CoreDNS and Karpenter before any EC2 worker capacity exists.

C

Serving

Helm deploys vLLM with GPU requests, health probes, and memory-backed shared memory.

D

Visibility

A ServiceMonitor connects vLLM metrics to Prometheus and a checked-in Grafana dashboard.

03

Run evidence

Proof, not diagrams.

These are artifacts from the checked-in build: the apply, the cluster, the capacity controllers, and a response streamed through the deployed model.

01 / terraform.apply
Terraform apply completing the EKS build with 47 resources added
Infrastructure closure

The recorded run completes with 47 resources added and no changes or destroys.

02 / eks.control-plane
AWS console showing the active ai-ml-llm EKS 1.31 cluster
Control plane

An active EKS 1.31 cluster, created as the substrate for model serving.

03 / karpenter.capacity
AWS console showing default and NVIDIA GPU Karpenter node classes
Capacity classes

Both default and NVIDIA GPU capacity classes are installed in the cluster.

04 / cluster.workloads
Terminal showing Karpenter, CoreDNS, Prometheus, Grafana, and Kubernetes system workloads running
Platform online

Karpenter, DNS, metrics, Prometheus, Grafana, and the device plugin share one build.

05 / vllm.ready
vLLM server logs showing application startup complete on port 8000
Runtime ready

The OpenAI-compatible server is live on port 8000.

06 / streamed.inference
Gradio chatbot displaying responses streamed from the deployed DeepSeek model
End-to-end response

The Gradio client streams model output through the standard OpenAI Python client.

04

Engineering decisions

Small contracts, joined end to end.

No single component makes the system useful. The value is in the contracts between bootstrap capacity, scheduling, serving, and telemetry.

The scheduling contract

One request connects software intent to physical capacity.

The pod does not know an EC2 instance ID. It declares a GPU resource and tolerates the isolated pool; Karpenter resolves that contract against available AWS supply.

nodeSelector:
  instanceType: gpu
tolerations:
  - key: nvidia.com/gpu
    effect: NoSchedule
resources:
  requests:
    nvidia.com/gpu: 1
args:
  - --model=deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
  - --max-model-len=16000
  1. D1

    Bootstrap without a node group

    CoreDNS and Karpenter run on Fargate. The capacity controller is therefore alive before the first application node is requested.

    EKS module / fargate_profiles
  2. D2

    Treat GPU capacity as schedulable supply

    The GPU pool accepts g4dn, g5, g6, g6e, p4, and p5 families across spot and on-demand capacity, rather than pinning one scarce SKU.

    Karpenter / nvidia-gpu NodePool
  3. D3

    Make the pod declare the hardware contract

    A node label, NoSchedule taint, matching toleration, and one nvidia.com/gpu request connect model demand to the GPU pool.

    Helm Deployment / resources + scheduling
  4. D4

    Keep the inference interface ordinary

    vLLM exposes an OpenAI-compatible endpoint, so the client uses the standard OpenAI SDK and streams tokens without a custom protocol.

    genai-app/app.py / stream=True
  5. D5

    Budget for model startup

    Readiness, liveness, and startup probes separate a long model load from a failed server. The startup window allows up to 15 minutes.

    Helm Deployment / startupProbe
  6. D6

    Install telemetry with the platform

    Prometheus, Grafana, metrics-server, and the NVIDIA device plugin are cluster add-ons, not a monitoring task deferred until after inference works.

    EKS Blueprints Addons / addons.tf
05

Serving signals

Instrument the user wait.

GPU utilization alone cannot explain how inference feels. The dashboard is shaped around the latency and throughput signals that expose the actual serving path.

  1. 01

    Time to first token

    The user-visible wait between submitting a request and seeing generation begin.

  2. 02

    Time per output token

    The decode cadence after the first token, where a response can still feel slow.

  3. 03

    Prompt + generation rate

    Token throughput for understanding saturation and effective serving capacity.

Scope note: the repository contains the ServiceMonitor and Grafana dashboard. It does not publish benchmark results, so this page does not invent them.

06

Production boundary

A field build with clear edges.

This repository proves the serving path. It is not presented as a drop-in production platform. The distinction is part of the engineering record.

  1. 01

    Access

    The EKS control-plane endpoint is public and inference is reached through local port-forwarding. There is no ingress authentication, TLS policy, or network policy in the repository.

  2. 02

    Availability

    The model runs as one replica with no disruption budget or model-level autoscaler. Karpenter supplies nodes; it does not scale inference replicas.

  3. 03

    Reproducibility gaps

    Before reuse, the Terraform config filename and README launcher command need alignment, and the manifests need automated validation in CI.

  4. 04

    Economics

    The hourly range is a README estimate, not a measured benchmark. Region, spot availability, NAT traffic, idle time, and model size all move the result.

Next architecture / After the field build

From field build to serving platform.

The later Berlin talk broadened the experiment toward KubeRay and distributed scaling. A production iteration would put KServe in front of vLLM, scale on serving signals with KEDA, make model versions explicit, and close the access and delivery gaps with policy and CI.