M4 · Deployment and ScalingM4-0622 min read

Lesson 25 of 58 · Module 5 of 10 · Week 4

Threads:The resilience threadThe NVIDIA stack thread

The Serving Stack in Context: NIM, TensorRT-LLM, Triton, and Kubernetes

Four distinct jobs, not four names for the same thing: NIM packages a model behind a standard API endpoint, TensorRT-LLM optimizes that model's execution on a specific GPU at build time, Triton Inference Server serves the resulting engine to live traffic with dynamic batching and concurrency, and Kubernetes scales and load-balances however many containers the whole stack needs across a fleet — and this module's five lessons (M4-01 through M4-05) each assumed exactly one of these four layers was doing its job correctly while examining a different concern.

By the end you can

  1. 01State each of the four serving-stack layers' job in one sentence, and place each in the correct order along the path from a trained model to a served, scaled response.
  2. 02Trace how this module's five prior lessons — an agent's per-call budget, horizontal scaling, distributed-load profiling, MLOps governance, and cost-versus-availability — each depended on one or more of these four layers doing its specific job, without ever needing to re-derive how that layer worked.
  3. 03Recognize the exam's bait-and-switch pattern for this stack: swapping which layer performs a named action, and correctly reject the swap.
  4. 04Explain why none of the four layers is redundant with any other, using a described deployment scenario to show what breaks if any one layer is removed.
01

The four-layer identity statement, held precisely

Identity statement: each of the four named tools occupies exactly one position along the path from a trained model to a scaled, served response, and no two of the four positions overlap. [GROUND TRUTH] (Sources/ncp-aai/domain-4-deployment-scaling.md) names all four in a single sentence specifically to make the ordering explicit: NIM packages, TensorRT-LLM optimizes, Triton serves, Kubernetes scales. The same source's own trap list states the two conflations it names as the most common: "NIM ≠ model, and NIM ≠ Triton: NIM is a prepackaged microservice; Triton is the general inference server it (or you) can use underneath," and "scaling is not 'one bigger VM' — it's horizontal replicas behind a load balancer," the second of which is Kubernetes's job specifically, not any of the other three layers'.

Held at the identity-statement level, before any mechanism: NIM answers "how do I get a model behind a standard API endpoint with minimal assembly" — a packaging and distribution question. TensorRT-LLM answers "how do I make this model's execution as fast as possible on this specific GPU" — a one-time, build-time optimization question, resolved before any request exists. Triton answers "how do I take live, concurrent traffic and route it efficiently to a running model" — a continuous, request-time serving question. Kubernetes answers "how many copies of this container are running, are they healthy, and how does traffic reach whichever ones are" — an orchestration-and-scaling question that operates one level above any single container's own behavior. Four different questions, in a fixed order relative to when each is answered (build time versus serving time versus fleet-management time), is the structure this entire lesson is built to keep distinct.

02

Where each layer sits along the build-to-serve-to-scale timeline

L1 — Intuition

Picture a restaurant chain opening a new location. Someone designs a standard, ready-to-install kitchen layout that any franchise location can order as one package — that is NIM, a prepackaged, standard-interface product. Before that kitchen ever serves a customer, someone tunes its specific equipment — which knives, which pans, which prep sequence — for the exact dishes this particular location's menu will run, on this location's specific stove model, once, before opening night — that is TensorRT-LLM, a one-time, hardware-specific optimization. Once the doors open, the front-of-house staff take orders every single night, decide which orders to group together for the kitchen, and manage however many tables are seated at once — that is Triton, continuously serving live traffic. And someone at the corporate level decides how many locations the chain needs open in a given city to meet demand, opens new ones when a neighborhood grows, closes or consolidates when demand shifts, and makes sure a customer looking for "this chain" gets routed to whichever open location can serve them — that is Kubernetes, operating one level above any single location's own kitchen-and-service operation.

L2 — Mechanism

Mechanically, the timeline runs in a fixed order that matches how a real deployment is actually built. First, a model exists — trained, evaluated, ready to deploy. TensorRT-LLM, if used, compiles that model once into a hardware-specific engine: kernel fusion merging adjacent operations to avoid memory round-trips, precision reduction (FP16, INT8, or another supported precision) calibrated against a representative dataset, and KV-cache handling built in for autoregressive generation's stateful, iterative structure. This step happens exactly once per model-plus-GPU-architecture pairing, before any request is served, and its output is a compiled artifact tied to the specific hardware it was tuned against.

Second, that engine — or an uncompiled model, if TensorRT-LLM was skipped — needs a place to actually run and accept requests. Triton Inference Server is a general-purpose serving layer that loads a model (compiled by TensorRT-LLM, by another framework, or not compiled at all) and, at request time, continuously assembles arriving requests into batches (dynamic batching) and manages concurrent execution across however many models or model instances are loaded. Triton's behavior is a serving-time property, decided fresh for every wave of arriving traffic, and it has no opinion about how the engine underneath it was built — it only decides how requests reach that engine efficiently.

Third, rather than assembling a NIM-shaped API endpoint, an inference engine, and a serving layer from these separate pieces by hand, NIM exists to package exactly that combination — a model (or a curated set of supported models), an inference engine (often TensorRT-LLM or vLLM underneath), and a serving layer (often Triton, or an engine's own serving capability) — into one container exposing a standard, industry-adopted API. [GROUND TRUTH] (Sources/ncp-aai/domain-4-deployment-scaling.md) states this directly: NIM containers "support multiple backends — notably TensorRT-LLM and vLLM." A team pulling a NIM container is, underneath that container's API surface, very often getting a TensorRT-LLM-or-vLLM-optimized engine served through a Triton-like serving layer, without ever configuring either piece by hand.

Fourth, once the container — whether a NIM container or a hand-assembled TensorRT-LLM-plus-Triton stack — exists as a runnable unit, Kubernetes takes over the question of how many copies run, where they run, and how they stay healthy: scheduling replicas onto available machines, restarting failed ones (self-healing), rolling out new versions without a capacity gap, and autoscaling replica count to track demand. A load balancer, working alongside Kubernetes, distributes incoming traffic across whichever replicas are currently healthy. None of this fourth layer's work touches what happens inside any single container — it operates entirely on the question of how many containers exist and which one handles a given request, a distinct scope from anything TensorRT-LLM or Triton do inside one container.

L3 — The exam-relevant edge case: NIM can contain both of the other two layers without replacing either

The edge case worth holding with precision, because it is exactly where the exam's bait-and-switch concentrates, is that NIM is not a fourth, competing way of doing what TensorRT-LLM and Triton already do — it is a packaging layer that very often contains both of them, running underneath its own API, without eliminating either one's distinct job. [GROUND TRUTH] (Sources/ncp-aai/domain-4-deployment-scaling.md)'s own trap statement — "NIM ≠ Triton: NIM is a prepackaged microservice; Triton is the general inference server it (or you) can use underneath" — is precisely this point: "or you," in that sentence, signals that Triton is a tool an operator can also reach for directly, hand-assembling a stack, exactly as M4-01's scope note distinguished "how an agent budgets against a NIM call" from "how a NIM operator tunes the backend underneath it." A scenario describing a team that "replaced Triton with NIM" has described something structurally confused — NIM did not replace Triton's job, it very possibly still uses Triton (or an equivalent serving layer) internally, and what actually changed was who configures that internal layer: NVIDIA's own curated defaults inside the NIM container, versus the operator's own hand-configured Triton deployment.

03

The four-layer comparison table

LayerQuestion it answersWhen resolvedWhat it changesRedundant with any other layer?
NIMHow do I get a model behind a standard API with minimal assembly?Packaging/deployment time, once per container pulledNothing about the model's execution itself — bundles an engine and a serving layer under one APINo — a packaging layer, not an optimizer or a server in its own right
TensorRT-LLMHow fast can this model run on this specific GPU?Build/compile time, once per model-plus-GPU pairingThe model's compiled execution: fused kernels, precision, KV-cache handlingNo — an optimizer, produces an artifact, does not itself serve requests
Triton Inference ServerHow do I get live, concurrent traffic to a running model efficiently?Serving time, continuously, for every requestNothing about the model itself — only how requests reach and are batched to itNo — a serving layer, has no opinion on how the model was compiled
KubernetesHow many copies are running, are they healthy, and how does traffic reach them?Fleet-management time, continuously, above any single containerReplica count, placement, health, rollout — never anything inside one containerNo — an orchestrator, operates one level above any single container's internals

Reading the table's "redundant with any other layer" column straight down is the fastest way to see why the exam names this a bait-and-switch rather than a simple recall item: every single row answers "no," and every "no" is defensible for a different, specific reason tied to that layer's distinct scope. A distractor that proposes eliminating any one layer in favor of doubling down on another is proposing to answer that eliminated layer's question with a tool that was never built to answer it.

04

Worked example: tracing this module's five lessons back through the four-layer stack

Constructed scenario, illustrative only. Rather than a new deployment scenario, trace each of M4-01 through M4-05 and identify exactly which of the four layers each lesson's mechanism depended on — the exercise this closing lesson exists to make explicit.

text
M4-01 (NIM as an agent's inference endpoint -- latency budgets,
failure handling):
  Layer assumed: NIM (the packaging layer an agent calls as a tool)
  What M4-01 did NOT need to know: whether that NIM container ran
  TensorRT-LLM or vLLM underneath, or whether Triton was serving it
  internally -- M4-01's budgeting and Retry/Circuit-Breaker logic
  worked identically regardless of what was inside the container.

M4-02 (scaling with containers, Kubernetes, and load balancing):
  Layer assumed: Kubernetes (plus the load balancer alongside it)
  What M4-02 did NOT need to know: anything about what ran inside
  any single replica -- the containerize/orchestrate/load-balance
  pattern applies identically whether a replica is running a NIM
  container, a hand-assembled TensorRT-LLM+Triton stack, or
  something else entirely.

M4-03 (profiling performance and reliability under distributed
load):
  Layers implicated: potentially ALL FOUR, which is exactly why
  M4-03's stub-substitution isolation technique exists -- a
  measured p99 spike could be Kubernetes-level contention across
  replicas, a Triton-level batching misconfiguration, a
  TensorRT-LLM engine poorly tuned for the deployed GPU, or NIM's
  own internal overhead. Isolating WHICH layer is the actual
  hotspot is the whole point of that lesson's technique.

M4-04 (MLOps and governance -- CI/CD, monitoring, audit):
  Layer assumed: Kubernetes' deploy stage (where CI/CD's automated
  pipeline actually pushes a new container version) plus
  governance's change-control question, which applies to a change
  at ANY of the four layers -- a new TensorRT-LLM engine build, a
  Triton batching-config change, a NIM container version bump, or
  a Kubernetes replica-count change are all "changes" governance's
  approval-and-audit discipline covers identically.

M4-05 (balancing deployment cost against high availability):
  Layer assumed: Kubernetes' autoscaling and replica-count mechanics
  as the LEVER cost-vs-availability decisions actually pull --
  right-sizing capacity means right-sizing how many Kubernetes-
  managed replicas run, informed by what M4-03's profiling
  revealed about where headroom and hotspots sit across the other
  three layers.

The pattern worth extracting from this trace is that this module's five lessons were never independent of the four-layer stack this lesson describes — each one simply assumed a specific layer (or, for M4-03 and M4-04, a cross-cutting concern touching all four) was already correctly understood, so that lesson's own concern (budgeting, scaling, measuring, governing, costing) could be examined without re-deriving the stack underneath it every time. This lesson is the one place in the module where that underlying stack itself, rather than a concern layered on top of it, is the actual subject.

05

Second worked example: a deployment decision that touches all four layers at once

Constructed scenario, illustrative only. A team needs to deploy a newly fine-tuned 13B-parameter model to serve production agent traffic, hitting a stated p95 latency target of 1,200ms per call, on a fixed GPU fleet, with a peak concurrency of 200 simultaneous requests. Trace the decision through all four layers in the order they actually get decided.

text
Decision 1 (TensorRT-LLM, build time, once):
  The fine-tuned model is compiled with TensorRT-LLM for the fleet's
  specific GPU architecture -- kernel fusion applied, precision
  reduced to FP16 (re-evaluated on the task benchmark per M3-01's
  discipline to confirm no meaningful accuracy regression), KV-cache
  handling configured for the agent's typical output length.
  Result: a compiled engine, tied to this GPU architecture, whose
  per-request execution speed is now fixed until the next rebuild.

Decision 2 (Triton, serving time, continuous):
  The compiled engine is loaded into Triton, with dynamic batching
  configured to assemble arriving requests into batches sized for
  the fleet's typical concurrency pattern, balancing per-request
  latency against throughput under the 200-concurrent-request peak.

Decision 3 (NIM, packaging, once per deployment):
  Rather than hand-assembling and maintaining the TensorRT-LLM-plus-
  Triton stack directly, the team instead reaches for a NIM
  container that already bundles an equivalent optimize-and-serve
  combination for this model family, exposing a standard API their
  agent's tool-calling code (M4-01's endpoint) can call without
  the team owning Decisions 1 and 2's configuration directly --
  OR, if this model is too custom for an available NIM container,
  the team keeps Decisions 1 and 2 as their own hand-assembled
  stack instead (the scenario M4-01's throughput-tuning companion
  lesson, M7-02, and the NIM-vs-Triton decision this lesson's
  table names, both cover directly).

Decision 4 (Kubernetes, fleet management, continuous):
  Whichever container resulted from Decision 3 -- NIM or hand-
  assembled -- is deployed as N replicas behind a load balancer,
  sized against M4-03's measured headroom for the 200-concurrent-
  request peak plus a failover margin, with autoscaling configured
  per M4-05's cost-vs-availability right-sizing discipline.

Every decision in this trace is answerable using exactly one layer's own scope, and none of the four decisions substitutes for any other: Decision 1 could not have been skipped in favor of "just configure Triton better," because no amount of serving-time batching tuning changes a poorly-fused, unoptimized engine's underlying execution speed; Decision 4 could not have been skipped in favor of "just make Decision 1's engine faster," because a single engine, however fast, is still a single point of failure and a single capacity ceiling exactly as M4-02's horizontal-versus-vertical argument established. The four decisions are sequential and cumulative, not competing alternatives to each other.

THE EARNED INSIGHT The reason this stack resists memorization by rote and instead has to be understood is that all four layers answer questions that sound, described loosely, like the same question — "make this model fast and available" — and the exam's entire bait-and-switch strategy is exploiting exactly that surface-level sameness. The fix is never memorizing which tool "is" fast or "is" scalable in the abstract; it is asking, for any described action, one specific question — is this decided once, before any request exists (TensorRT-LLM), continuously, for every request (Triton), as a matter of which container to run at all (NIM's packaging choice), or as a matter of how many copies exist and which one gets this traffic (Kubernetes) — and that one question, asked honestly, resolves nearly every scenario this stack produces.

06

Common conflations this stack produces, and the specific fix for each

ConflationWhat is actually trueFix
"NIM is a model"NIM is a containerized microservice that serves a model — the model's weights are a separate thing NIM's container loads and runsHold M4-01's identity statement: NIM packages, it does not itself reason or generate
"NIM replaces Triton"NIM often runs an equivalent serving layer internally, packaged under its own API — it does not eliminate the serving-layer job, it bundles itNIM is a product built on top of the same category Triton occupies, not a competitor to that category
"Scaling means a bigger single instance"Scaling is Kubernetes' job specifically: more replicas behind a load balancer, not one larger containerHorizontal scaling (M4-02) is a distinct layer's job from anything TensorRT-LLM or Triton do inside one container
"TensorRT-LLM serves requests"TensorRT-LLM's job ends the moment a compiled engine exists — it never accepts a live network request itselfBuild-time optimization (TensorRT-LLM) and serving-time request handling (Triton) are different layers, decided at different times
"Triton optimizes the models it serves"Triton has no opinion on how an engine was compiled — it serves whatever it is given, unchangedTriton's dynamic batching and concurrency are serving-time properties; they never touch a model's compiled execution speed
"Profiling under load only tells you about Kubernetes"A measured problem could originate at any of the four layers, which is exactly why M4-03's isolation technique existsIsolate which specific layer is implicated before assuming the fix is a Kubernetes-level (replica count) change
07

Why the full serving stack is on the NCP-AAI exam

[GROUND TRUTH] (Sources/ncp-aai/domain-4-deployment-scaling.md): the serving stack's four-layer synthesis closes Deployment and Scaling, which carries 13% of the NCP-AAI blueprint, and the same source states the exam's own framing of why this synthesis matters: "Common exam traps / misconceptions... NIM ≠ model, and NIM ≠ Triton... Scaling is not 'one bigger VM'... Cost optimization that ignores availability (or vice versa) misses the stated objective." Every one of those three named traps maps to a specific pair of layers in this lesson's table being conflated, which is why this closing lesson exists as this module's deepest-flagged treatment rather than a brief recap: the individual mechanisms (M4-01 through M4-05) are each testable on their own, but the exam's harder items combine two or more layers in one stem specifically to test whether a candidate can hold all four positions distinct simultaneously, not just recall each one in isolation.

How the question tends to be phrased

Expect a direct role-matching item naming an action and asking which tool performs it — kernel fusion or precision calibration points to TensorRT-LLM; dynamic batching or concurrency management points to Triton; packaging a model behind a standard API points to NIM; scheduling, self-healing, or autoscaling replicas points to Kubernetes. [GROUND TRUTH] (Sources/ncp-aai/domain-4-deployment-scaling.md) states this exact self-check item — "which statement about the serving stack is correct" — with the correct pairing (TensorRT-LLM optimizes, Triton serves, Kubernetes scales) as the keyed answer against distractors that swap any two of the three. Expect also a multi-layer scenario item, similar to section 5's worked example, describing a deployment need that spans more than one layer and asking which combination of tools addresses it correctly — testing whether a candidate can decompose a compound scenario into its per-layer components rather than reaching for a single tool to solve the whole thing.

What the distractors typically look like

[GROUND TRUTH] (Sources/ncp-aai/domain-4-deployment-scaling.md) names two of this material's own self-check distractors directly: "NIM replaces Kubernetes" and "vLLM is a load balancer," both plausible-sounding but structurally wrong claims. The broader house style favors the same swap at a smaller grain: TensorRT-LLM described as accepting requests, Triton described as fusing kernels, NIM described as scaling replicas, or Kubernetes described as optimizing a model's precision — each one assigning a real, correctly-named action to the wrong layer.

08

Common mistakes about the serving stack as a whole

MistakeWhat actually goes wrongFix
Treating any two of the four layers as interchangeableA deployment plan reaches for one tool to solve a problem that actually belongs to a different layer, and the problem persists because the wrong tool was never going to fix itAsk which of the four questions (package, optimize, serve, scale) the problem is actually describing, then reach for that specific layer
Assuming NIM eliminates the need to think about TensorRT-LLM or Triton at allTrue for teams using a curated NIM container as-is, but false the moment a custom model or fine-grained control need doesn't fit an available containerRecognize NIM's convenience as a packaging choice, not a permanent exemption from understanding what's underneath it
Diagnosing every distributed-load problem as a Kubernetes/replica-count issueA hotspot at the TensorRT-LLM or Triton layer gets "fixed" by adding more replicas, which does not address a per-replica bottleneck and wastes the added capacityUse M4-03's isolation technique to find which specific layer is implicated before assuming more replicas is the fix
Believing a single mental model covers "make it fast and available"The four layers answer four genuinely different questions, at four different points in time (build, serve, package, scale); collapsing them into one vague goal misses which specific lever to pull for a specific symptomKeep the four questions and their resolution times (once, continuously, once-per-container, continuously-at-fleet-level) as four separate mental slots
Assuming this lesson's four-layer stack is the same as the NVIDIA agentic stack M7-06 covers end to endM7-06's stack additionally includes the NeMo Agent Toolkit's orchestration and NeMo Guardrails' safety layer — components outside this module's deployment-and-scaling scopeTreat this lesson as the deployment-and-scaling slice of a larger stack; M7-06 synthesizes the fuller picture including orchestration and safety

Why isn't NIM simply "a faster way to run Triton"?

Because NIM and Triton are not solving the same problem at different speeds — NIM is a packaging and distribution product, bundling a curated model, an inference engine, and (often) a serving layer under one standard API so an operator does not have to assemble and maintain those pieces individually; Triton is the general-purpose serving layer itself, which NIM may use internally, or which an operator may configure directly instead of using NIM at all. Asking "is NIM faster than Triton" is a category error in the same way asking "is a furnished apartment faster than a stove" would be — one is a bundled product built partly from the other, not a competing implementation of the same single function.

If a deployment's p95 latency is too high, which of the four layers should be investigated first?

There is no single correct layer to check first in the abstract — this is exactly why M4-03's isolation technique (systematically substituting a stub for one candidate component and re-measuring) exists rather than a fixed checklist. A latency problem could originate in a poorly-tuned TensorRT-LLM engine (slow per-request execution), a misconfigured Triton batching window (requests waiting too long to be batched, or batched inefficiently), insufficient Kubernetes-managed replica capacity (contention across too few replicas for the actual concurrent load), or overhead specific to a NIM container's own internal configuration. The correct discipline is to measure first (per M4-03), isolate which specific layer is implicated, and only then apply that layer's specific fix — TensorRT-LLM's build-time levers for a compute-bound problem, Triton's batching configuration for a request-assembly problem, or Kubernetes' replica count for a capacity problem.

Glossary recap: serving-stack terms this lesson introduced

TermOne-line definition
NIM (packaging layer)A containerized microservice bundling a curated model, an inference engine, and often a serving layer, behind a standard API
TensorRT-LLM (optimization layer)Build-time compilation of a model into a hardware-specific engine: kernel fusion, precision, KV-cache handling
Triton Inference Server (serving layer)Request-time serving with dynamic batching and concurrency, agnostic to how the model it serves was optimized
Kubernetes (orchestration/scaling layer)Fleet-level management of container replicas: scheduling, self-healing, rollout, autoscaling, above any single container's internals
Build time vs. serving time vs. fleet-management timeThe three distinct points in a deployment's timeline at which TensorRT-LLM, Triton, and Kubernetes respectively make their decisions
Layer isolationDetermining which of the four layers is responsible for a measured symptom before applying a fix, per M4-03's technique

Key takeaways on the serving stack in context

  • Four layers, four distinct questions, no overlap: NIM packages, TensorRT-LLM optimizes, Triton serves, Kubernetes scales — and none of the four substitutes for any other.
  • The timeline order is fixed: TensorRT-LLM's decisions happen once, at build time; Triton's happen continuously, at serving time; Kubernetes' happen continuously, at fleet-management time, above any single container.
  • NIM often bundles TensorRT-LLM (or vLLM) and a serving layer internally — it is a packaging product built on top of the other layers' categories, not a fourth competitor to them.
  • This module's five prior lessons (M4-01 through M4-05) each assumed one or more of these four layers was working correctly while examining a different concern — this lesson is where the underlying stack itself, rather than a concern layered on top of it, is the subject.
  • A measured problem could originate at any of the four layersM4-03's isolation technique, not a fixed checklist, is how a team finds which one before applying a fix.
  • The exam's bait-and-switch pattern is swapping which layer performs a named action — the fix is asking, for any described action, whether it is decided once (TensorRT-LLM), continuously per request (Triton), once per container (NIM), or continuously at the fleet level (Kubernetes).

This module has now built the full deployment-and-scaling picture: an agent's per-call budget against a NIM endpoint, the horizontal-scaling pattern that keeps that endpoint available under real traffic, the profiling discipline that catches what only shows up at scale, the governance and delivery process that ships changes to any of this safely, the cost discipline that right-sizes it, and now the four-layer stack underneath all five. None of it yet asks how the agent itself reasons, remembers, or plans what to do with the response this stack delivers — that is where the course goes next, into cognition, planning, and memory, picking up the agent's own internal design from the deployment infrastructure this module built around it.

Next: Module 5, Cognition, Planning, and Memory, picks up where this module's deployment infrastructure leaves off — how an agent remembers, reasons, and plans using the responses this serving stack delivers, starting from why an agent needs memory as an explicit architectural component at all.