- Small models served from partitions of shared GPUs instead of one GPU each
- Language and task variants served as adapters on a shared base model where quality allowed
- Hardware isolation between models whose traffic must not interfere
- Offline work moved to batch queues, freeing real-time capacity
- Cost and latency visible per model and per language, guiding further consolidation
Anonymised composite. Client names, identifying details and confidential figures are withheld; public facts are cited in the references.
The situation
An Indian online marketplace connected buyers with small and mid-sized sellers across the country, in English and many Indian languages. Over several years its teams had added small AI models wherever they helped: embedding models and rerankers for search in each major language, classifiers for listing quality and support routing, language identification, and fine-tuned language models that helped sellers write listings. Each team had deployed its models independently, and the simplest way to get a model into production had been to give it its own GPU.
The result was a large GPU bill for hardware that was mostly idle. Many models needed only a fraction of a GPU's memory and compute, and traffic followed Indian daily patterns, with quiet nights and sharp peaks around sales. Adding support for another language meant another set of models and, by habit, more GPUs. Finance wanted the bill down; product wanted more languages.
Why now. GPU partitioning was moving into mainstream managed services. AWS added GPU partitioning to SageMaker AI real-time inference, using NVIDIA Multi-Instance GPU so one GPU can be split into isolated partitions, each with dedicated compute and memory12. At the same time, reports that Microsoft was winding down rented capacity on older GPUs underlined how quickly hardware choices age5. Using every GPU fully had become a design goal, not an afterthought.
What had to be true
- Far fewer GPUs for the same models and traffic.
- No noisy neighbours for latency-critical models such as search.
- Quality held per language and task after any consolidation.
- New languages cheap to add, without new hardware by default.
- Cost visible per model and language, so decisions follow value.
- Teams still independent: shared infrastructure, not a central bottleneck.
Architecture
We sorted every model into one of three groups. Small, latency-critical models, such as search embeddings and rerankers, went onto Multi-Instance GPU partitions, which give each model its own slice of compute and memory with isolation enforced in hardware3. Language and task variants of the same base language model were rebuilt as LoRA adapters on one shared base model, where evaluations showed quality held. Offline work, such as re-embedding the catalogue or scoring listing quality overnight, moved to batch queues that filled spare capacity.
The data flow, end to end
- RequestA feature asks for a task in a language, such as "rerank results in Tamil"
- ResolveThe gateway maps the task and language to a model or adapter
- RouteIt picks a server with that model or adapter loaded and spare capacity
- ServeThe model runs on its partition or the shared base model
- RecordModel, adapter, language, latency and GPU share are recorded
- ReviewWeekly reports guide which models to consolidate next
The hard part: isolation, adapters and fixed partitions
Choosing the right kind of sharing. Not all GPU sharing is equal. Partitions give each model guaranteed memory and compute; looser sharing lets models contend for the same resources, so one model's spike or failure can affect others. We kept partitions for anything on the search path and accepted looser sharing only for internal and offline models.
Routing to the right adapter. Adapters only save money if requests reach a server that already has the right adapter loaded; otherwise servers spend time loading and evicting them. The gateway therefore routed by model and adapter as well as load, the pattern the Kubernetes Gateway API Inference Extension describes, where an endpoint picker considers queue length, memory and loaded adapters before choosing a server4.

Living with fixed partition layouts. Partition profiles are set per GPU and changing them means draining the workloads on it. Rather than reshaping partitions on demand, we defined a small number of node pools, each with a fixed layout suited to a class of model, and let the scheduler place models on the right pool. Reshaping happened in planned maintenance, not in response to traffic.
The cheapest GPU is the one you already pay for. Before buying more, find out how much of each one your models actually use.
How it ran
- Usage measurement
- Partitioned node pools
- Gateway and batch queues
- Model inventory
- Adapters where quality holds
- Per-language evaluations
- Latency targets per feature
- Language roadmap
- Cost per model and language
- Inventory every model
- GPU use per model
- Latency targets
- Partitioned node pools
- Move small models
- Watch latency
- Shared base model
- Adapter-aware routing
- Per-language evaluations
- Offline jobs to queues
- Fill spare capacity
- Retire idle GPUs
Key decisions and trade-offs
| Decision | Alternative | Why |
|---|---|---|
| Hardware partitions for search models | Looser GPU sharing everywhere | Search latency cannot depend on other models' traffic |
| Adapters on a shared base model | One full model per language | Less memory, faster to add languages, if quality holds |
| Adapter-aware routing | Round-robin load balancing | Avoids constant adapter loading and eviction |
| Fixed partition layouts per node pool | Reshape partitions dynamically | Reshaping needs draining; stability beats perfect packing |
| Offline work in batch queues | Run everything on real-time servers | Uses spare capacity without hurting live traffic |
| Evaluations per language | One overall quality score | Averages hide regressions in smaller languages |
What I'd do again, and differently
Again: measure real GPU use per model before changing anything. It showed most of the waste sat in a few teams' habits, not in the models themselves. Differently: build per-language evaluation sets before moving to adapters; the first adapter rollout exposed a regression in a smaller language that an overall score had hidden. Related: Kubernetes inference gateways, GPU scheduling with DRA, AI capacity contracts and the India page.
If your GPU bill is growing faster than your AI usage, see my AI architecture work, or analyse your challenge and bring the result to a call.
- 1
- 2AWS Adds NVIDIA GPU Partitioning to SageMaker Inference EndpointsUnite.AI · Nov 2026
- 3NVIDIA Multi-Instance GPU User GuideNVIDIA · 2026
- 4Introducing Gateway API Inference ExtensionKubernetes blog · 5 Jun 2025
- 5Microsoft is winding down its deal to rent AI computing from OracleThe Next Web · Nov 2026