Status: Draft (2026-10-07), map article. This article does not perform new measurements, but weaves together values measured directly by the authorand content verified through documentationfrom other articles in the same series into a single sheet. Next to each number, the article from which it was measured and the conditions under which it was measured are noted. All measurements were made using one or two small models, a single GPU (8GB class), and a disposable single-node cluster, so please focus on the shapes and principles rather than the absolute values. Items based on documentation or never measured are marked as "Documentation-based" or "Unmeasured". Authoring rule: Measured data is the default, and unmeasured items are marked as "Unmeasured".
Table of Contents
- 1. How to Read This Article
- 2. Single-Sheet Map: Eight Layers
- 3. Layer 1: GPUs and Hardware, Where Do Speed Limits Come From?
- 4. Layer 2: The Kubernetes GPU Stack
- 5. Layer 3: Scheduling and Multi-Tenancy
- 6. Layer 4: LLM Serving Engines, Understanding Through Numbers
- 7. Layer 5: Networking
- 8. Layer 6: Storage and Model Deployment
- 9. Layer 7: Observability and Troubleshooting
- 10. Layer 8: Controllers and Deployment Automation (Tools for Kubernetes Engineers)
- 11. How to Measure: Techniques Spanning All Layers
- 12. 4-Week Learning Path
- 13. Frequently Asked Questions in the Field and Interviews
- 14. What This Map Does Not Cover
- Reference: Articles Underlying This Map
- Date Verified
1. How to Read This Article
ML/AI infrastructure is not a single domain, but a field where multiple layers overlap. You cannot explain serving numbers without knowing GPU memory bandwidth, you cannot know why GPU jobs stall without knowing the Kubernetes scheduler, and you cannot fix either without knowing observability. This article summarizes "What you must know" for each layer and links to articles for deep reading.
There are two reading orders:
- ML/AI Infrastructure Engineers: Read sections 2 to 5 (hardware, stack, scheduling, serving) first, then move on to the measurement methods in section 9.
- Kubernetes Engineers: Read sections 3, 4, and 8 (stack, scheduling, controllers) first, and fill in how GPUs differ from general resources using sections 2 and 5.
2. Single-Sheet Map: Eight Layers
| Layer | Core Question | Representative Tools and Concepts | In-Depth Reading Articles |
|---|---|---|---|
| 1. GPUs and Hardware | What determines the speed limit? | Memory bandwidth, compute throughput, VRAM configuration | Articles 21, 11 |
| 2. Kubernetes GPU Stack | How do GPUs reach pods? | Driver, toolkit, device plugin, GPU Operator, passthrough | Articles 3, 13 |
| 3. Scheduling and Multi-Tenancy | How do multiple teams and jobs share GPUs? | Kueue, Volcano, gang scheduling, quota, preemption | Articles 10, 9 |
| 4. LLM Serving Engines | What determines throughput and latency? | Continuous batching, KV cache, prefix caching, chunked prefill, quantization, LoRA | Articles 4, 5, 14, 15 |
| 5. Networking | Service scaling and cross-GPU communication | CNI, kube-proxy vs. Cilium, service mesh, RDMA, NCCL | Articles 2, 7 |
| 6. Storage and Model Deployment | Where do weights and KVs reside? | Model cache, cold start, KV offload, weight protection | Articles 8, 16 |
| 7. Observability and Troubleshooting | What to watch and when to alert | DCGM, XID, TTFT/ITL percentiles, server metrics | Articles 17, 18, 11, 25 |
| 8. Controllers and Deployment Automation | How to maintain the declared state | CRD, operator, GitOps | Article 9 |
3. Layer 1: GPUs and Hardware, Where Do Speed Limits Come From?
Things to Know
- Token generation is bottlenecked by memory bandwidth. Every time a single token is generated, the weights of all layers are read once, so
초당 토큰 수 ≤ 메모리 대역폭 ÷ 가중치 바이트it is memory bandwidth-bound. - Input (prompt) processing is compute-bound. When calculating many tokens at once, multiple tokens reuse the same weights.
- VRAM is shared among weights, KV cache, activations, and CUDA graphs. What determines serving throughput is typically the share remaining for the KV cache.
- Consumer GPUs and datacenter GPUs have different diagnostic features. ECC, row remapping, and profiling metrics may be absent.
- The container's CUDA version cannot exceed the limit set by the host driver. If startup fails after uploading an image, look at the driver version first.
Directly Measured Numbers (Articles 21, 11)
| Verified Item | Result |
|---|---|
| Generation speed × weights of four models with different sizes and precisions | 86~98% of measured bandwidth (250GB/s) |
| When precision is halved (from bf16 to fp8) | Weights became 1.7x smaller, but speed increased by 1.54x (gains diminish due to the fixed cost per token) |
| Input processing (1,024 tokens or more) | About 75~80% of measured matrix multiplication throughput, 65~127x faster than generation for the same model |
| ECC and page retirement for three consumer GPU models | All N/A |
| Row remapping | Only one out of three models returned a value (0 and N/A must be distinguished) |
Common Pitfalls
- Not comparing measured values against hardware limits. We realized an error called prefix cache hit when the input processing speed came out to be 20 times the GPU computation limit (Articles 14, 21).
- Mistaking PCIe generation drops in idle state for a downgrade. You must apply load and read again (Article 11).
grep XidIsolating the wrong line of errors. Catching a network card driver's chip revision line along with GPU driver errors that are not Xid.NVRM: XidNarrow it down to the exact error (Article 11).
4. Layer 2: The Kubernetes GPU Stack
Things to Know
- GPUs are extended resources. They are requested only as integers, requests and limits must be equal, and overcommitment and sharing are not allowed.
- The stack builds from the bottom up. Host kernel module (driver), container runtime toolkit, device plugin (resource advertising), node labels (GFD), monitoring (DCGM exporter). The GPU Operator installs these all at once.
- Sharing methods have different isolation levels. Time-slicing does not isolate memory, MIG partitions hardware only on supported GPUs, and software methods (such as HAMi) intercept CUDA calls (Documentation-based, Articles 3 and 10).
- You can also pass GPUs entirely to virtual machines. In this case, the host cannot use the GPU, so nodes are divided between those for containers and those for virtual machines (Article 13).
- Separating the responsibilities of the driver, toolkit, and operator speeds up failure analysis. Which layer failed depends on the symptom (
nvidia-smifailure, Pod Pending, container start failure).
Common Pitfalls
- Installing the operator without deciding whether the host driver is installed by the operator or already present on the host. The two will conflict (Article 3).
- New CUDA images failing to start on old drivers. Indeed, a CUDA 13 image failed on a CUDA 12 series driver with an initialization error (Error 804) (author's test; general principles only in this article).
- GPU pods going Pending due to node memory request sums. Even if the GPU is empty, if general resources (memory) are lacking, the pod will not be scheduled. Read the reason for waiting message first.
5. Layer 3: Scheduling and Multi-Tenancy
Things to Know
- The default scheduler decides on pods one by one. Jobs where multiple pods must start together (distributed training, multi-node inference) get slots for only some of them and end up waiting for each other.
- Gang scheduling has two approaches. Kueue checks quotas per job and does not create pods until accepted, while Volcano uses a separate scheduler to allocate slots all at once only when the minimum number of pods in a pod group can be met.
- Quotas, borrowing, returning, and preemption are design problems. Policies determine who can borrow remaining resources and who gets evicted when the owner returns.
- LeaderWorkerSet provides group-level recovery. In multi-node serving, if one rank disappears, the rest become useless, so recreating the entire group is the default.
Directly Measured Numbers (Articles 10, 9)
| Verified Item | Result |
|---|---|
| Two jobs requiring four pods each competing for eight resources (default scheduler) | Stuck holding 2 each for 60 seconds (deadlock) |
| Kueue and Volcano under the same circumstances | Accepted only one job and executed 4 pods within about 2~4 seconds; no moment where only a partial execution occurred |
| Time for waiting jobs to start after deleting the accepted job | Kueue 3.0~3.6 seconds, Volcano 3.6~4.2 seconds |
| When deleting a worker in LeaderWorkerSet | All 3 pods in the same group are recreated while other groups remain untouched (approx. 2 seconds) |
| When resources are insufficient with LeaderWorkerSet alone | Only the leader is Running and workers are Pending; gang scheduling is absent |
Common Pitfalls
- Submitting large jobs without gang scheduling. Resources are held while waiting for each other, leaving the cluster idle.
- Measuring preemption and return times without knowing the termination grace period. If an evicted pod ignores termination signals, it runs through the full grace period (default 30 seconds) before ending, making the measured value equal to the grace period (actually experienced in Article 10).
- Believing that "submitting simultaneously with the same priority determines the order." Which job gets accepted first was not identical every time.
6. Layer 4: LLM Serving Engines, Understanding Through Numbers
This layer is the most frequently asked about and the most frequently measured. vLLM and SGLang were measured with a 1.7B model on a single 8GB-class GPU (Articles 5, 14, 15).
Things to Know
- Continuous batching distributes the weight-reading cost of concurrent requests. Thus, increasing concurrency increases total throughput almost proportionally until it hits a wall at KV cache capacity.
- The KV size per token is calculated by formula.
2 × 층 × KV 헤드 × head_dim × 바이트. The concurrency limit is estimated asKV 용량 ÷ 요청당 토큰. - Prefix caching skips input processing for common prefixes. It is the cheapest optimization for services that fix system prompts and documents at the beginning.
- Chunked prefill determines how long a long input interrupts other users' tokens.
- Quantization comes in two types. Weight quantization changes speed (bytes read), while KV quantization changes capacity (number of tokens held).
- LoRA serves by placing small adapters on top of a single base model. The relationship between the number of simultaneously used adapters and slot counts determines performance.
Directly Measured Numbers
| Verified Item | Result | Article |
|---|---|---|
| Server log KV capacity ÷ number of tokens | Approx. 114,900 bytes per token, within 0.2~0.3% of the formula's 114,688 bytes | Article 14 |
| Concurrent requests 1 to 16 | Total throughput increased 14~15x, single-request speed decreased by 8~14% | Article 21 |
| Concurrency 32 to 64 (input 512) | For the first measured server, throughput decreased from 831 to 787 tok/s, and Time to First Token (TTFT) increased 8.6x from 666ms to 5.7s. Restarting the server three times resulted in varied TTFTs between 2.1 and 5.7s depending on the KV capacity (from 22,048 to 26,560 tokens). | Part 14 |
| 8-bit KV | 1.9x tokens in the same memory; TTFT for concurrent 16 requests with long input (2,048 tokens) improved from 4.0s to 0.94s. | Part 14 |
| Prefix caching (common 3,000 tokens) | First token improved from 394ms to 28ms; 393ms when disabled. | Part 14 |
| Maximum token interval when interrupted by a long input (3,500 tokens) | 69ms for 512-token chunks, about 227ms for 2,048 tokens, and 445ms for 8,192 tokens. | Part 14 |
| Default behavior of SGLang in the same test | Even when reducing the chunk size to 512, it takes 472ms (time to process the entire input); it drops to 69ms only when mixed chunks are enabled. | Part 5 |
| Pure throughput of both engines | Within ±5% for concurrency 1-64 (small model bound by bandwidth). | Part 5 |
| Throughput of requests using LoRA adapters | Decreased by about 10% (one adapter) to 12.5% (mixing two) based on 48 requests (median of 5 runs; a single measurement of 17.9% included warmup effects). Keeping LoRA enabled itself is free. | Part 15 |
| Serving 3 adapters with 2 slots | Throughput drops to 56% compared to having 4 slots. | Part 15 |
| Server restart | 35-55s (4-6s for weight loading); initial startup takes 71s due to compilation. | Part 14 |
Rules of thumb from the field
- Set the concurrency limit close to the number of requests the KV cache can hold. Exceeding this limit does not increase throughput, only TTFT.
- Monitor TTFT at p95 and inter-token latency (ITL) at p99. Even if the median looks fine, the tail latency is large (ITL p99 is 223ms).
- Align default settings before comparing engines. Options with the same name can have different default values (chunk size, mixed chunks, memory settings).
- Route requests with overlapping prefixes to the same instance. The cache resides within the instance (Part 8, per documentation).
7. Layer 5: Network
What you need to know
- As the number of services grows, iptables rules increase. Cilium's eBPF performs service load balancing using map lookups instead of rules.
- Service meshes add proxy hops to every request. While negligible for LLM serving where TTFT is hundreds of milliseconds, it can become noticeable in responses streamed token-by-token or in short calls.
- Inter-GPU communication is a separate layer. NCCL handles collective operations, and RDMA (InfiniBand or RoCE) bypasses the CPU between nodes.
- A common issue with RDMA is configuration. Memory locking limit (memlock), MTU mismatch, GID selection, PFC/ECN.
Directly measured figures (Part 2, Part 7)
| Verified | Result |
|---|---|
| Istio sidecar (mTLS) | Adds about 2.2ms per request. Encryption accounts for about 8%, the rest is the proxy, of which HTTP parsing takes about 39% (+1.35ms remains even with an L4 configuration without parsing). gRPC adds +3.4ms, throughput drops by 3.5-4.5x for 100MiB responses, and streaming event intervals (20ms) are unaffected. |
| 4,000 concurrent connections exceeding the conntrack limit | With a limit of 2,048, 1,913 succeeded (= limit - existing entries), and the rest were silently dropped without rejection. |
| Connecting to a new service immediately after creating 10,000 services | 45 seconds on the kube-proxy side (1 out of 2 times), 0.25 seconds on the Cilium side. |
| 110,000 lines of iptables rules | Average latency for new connections within the same node increased by only about 0.05ms (smaller than commonly believed). |
| Software RDMA (rxe) | TCP on the same machine is about 8x faster than RDMA writes (for conceptual verification), at an Ethernet MTU of 1500 active_mtu 1024 |
| Default user memory lock limits of 64 and 1,024 KiB | 1MiB memory registration failed with Failed to create MR , succeeding starting from 8,192 KiB. |
Common pitfalls
- Understanding "iptables is slow when there are many services" solely as datapath latency. In this environment, what made a big difference was the timing of updating rules all at once.
- Trusting tables where the same value appears repeatedly. Connection attempt limits have sometimes fixed measurement values to two specific numbers (be skeptical of the tool's resolution).
8. Layer 6: Storage and Model Deployment
What you need to know
- Weight size is
파라미터 수 × 바이트. A 70B bf16 model is 140GB, so a shared cache or image strategy is needed to avoid downloading it on every node. - Cold start is the sum of image pulling, model downloading, loading, compiling, and warming up. In autoscaling design, this sum represents the time it takes for a new pod to start receiving traffic.
- Offloading the KV cache outside the GPU (to CPU, disk, or remote) allows prefixes to be reused longer. However, it is only beneficial if the loading time is shorter than recalculation.
- Weight encryption prevents storage leaks and tampering, but cannot protect memory during execution.
Directly measured figures (Part 8, Part 16, Part 14)
| Verified | Result |
|---|---|
| Rereading 10 documents (about 50,000 tokens) in the same order that do not fit entirely in the GPU | TTFT improved from 576ms to 48.6ms using LMCache (CPU offload), with about 4% storage overhead on the initial read. |
| When LMCache's CPU capacity is smaller than the working set (about 1.49GB) | Zero benefit (0 hits at 0.5GB and 1.0GB); at 1.5GB, latency drops from 600ms to 39ms (98% hit rate). The longer the context, the greater the benefit, reaching about 19x for 6,414 tokens. |
| Breakeven hit rate | About 4% (calculated using values from that test) |
| Encrypting weight files with AES-256-GCM | File size increases by about 0.00005%, decryption speed is 0.78-0.95 GB/s (pure computation 1.8-2.2 GB/s). |
| Modifying 1 byte of ciphertext or swapping chunk order | Both cause decryption to be rejected (InvalidTag). Without AAD, order swapping, truncation, and inter-file chunk swapping cannot be detected. |
| Disabling AES hardware acceleration | Decryption is 4-7x slower (drops from 2.0 to 0.47, 0.29 GB/s). Threads cap at 2, but processes scale up to 8. |
| Placing decrypted weights in a memory volume and starting the server (0.6B model) | About 2.3 seconds of decryption time is added before server readiness (about 28 seconds). Tampered files are rejected before the server starts. |
| Loading LoRA adapter at runtime (6.4MB) | Within 0.2 seconds without restarting the server (the documentation warns against production use) |
9. Layer 7: Observation and Troubleshooting
What You Need to Know
- GPU metrics consist of three layers. Hardware (DCGM: utilization, power, temperature, clock throttling reasons, XID), server (queue, KV utilization, preemption count), service (TTFT, ITL, error rate).
- Looking at utilization alone is misleading. A server bound by memory bandwidth may perform very little actual compute even when utilization is high.
- XID is the error number left by the GPU driver in the kernel log. Regular accounts may have
dmesgblocked, so they usejournalctl -kinstead. - Cilium and DCGM have many metrics, and cardinality is cost. Label combinations determine the number of time series (Parts 17 and 18).
- Alerts should separate symptoms (TTFT tail latency) from causes (VRAM trend, clock throttling).
- A signal that traces a single request is a trace. vLLM leaves queue, prefill, and decode times as attributes in a single span for each request, which alone allowed us to distinguish whether a slow request was due to queuing or computation. The overhead of enabling it was within the margin of error, and capturing slow requests required tail-based sampling rather than probabilistic sampling (Part 25).
Common Pitfalls
- Treating N/A and 0 as the same. Unsupported metrics appear as N/A rather than 0 (Part 11).
- Comparing memory numbers without realizing that KV capacity changes on every server restart. Compare using bytes per token (Part 14).
10. Layer 8: Controller and Deployment Automation (Tools for Kubernetes Engineers)
What You Need to Know
- Level-based reconciliation. Instead of relying on events, it reads the current state, compares it with the desired state, and reconciles them. Even if an event is missed, the next reconciliation fixes it.
- Idempotency. If the state already matches, it should write nothing.
- Owner references and finalizers. Children are cleaned up when their owner is deleted, and finalizers allow deletion only after cleanup is complete.
- CRDs are designed through schemas and validation. Simple rules use CEL, while complex rules use webhooks.
- In GitOps, if another controller modifies fields defined in Git, conflicts occur. HPA and
replicas,ignoreDifferences(Part 9).
Numbers measured directly (Part 9)
| What was checked | Result |
|---|---|
| CEL validation | Empty string model name is model must not be empty rejected during the generation stage |
| LWS Rolling Update | One group at a time, starting from the group with the highest ordinal (maxUnavailable 1 default) |
The actual operational behavior of the operator (recovery time upon deleting children, idempotency, finalizers, duplicate execution, retries) will be reflected in Part 9, following direct test results.
11. How to Measure: A Technology That Cuts Across All Layers
The most valuable part of this series, beyond the numbers, is Moments I doubted the numbers.
| Incident Experienced | Lesson |
|---|---|
| Input processing comes out as 20 times the GPU compute limit | Check against hardware limits. This was because the prefix cache hit due to repeating the same sentence |
| "Concurrent 1, 16" is actually 3x, 48 requests | Verify what the tool's arguments do. Match the notation with the actual number of requests |
| A table where the same value appears repeatedly | Question the measurement tool's resolution |
| 30-second graceful shutdown mixed into the preemption time | Check if times other than the intended measurement duration got mixed in |
Leaving only the header line grep results in the output not showing |
Do not use filters that hide results |
| A test run as root failed to reproduce the issue | Test under the conditions you want to reproduce (regular user) |
| Default values for identically named options differ between the two engines | Align settings in the logs before comparing |
And make three things a habit: Different inputs for each request, Iteration and variance(Never jump to conclusions based on a single measurement), Record the environment and method next to the value.
12. 4-Week Learning Path
If studying alone, we recommend this sequence. The deliverable for each week is a table measured with your own hands.
| Week | Topic | Tasks to Try | Deliverable |
|---|---|---|---|
| 1 | GPU and Serving Engine | Spin up a small model (1-2B) with vLLM, multiply generation speed by size/precision by the weight byte size, and compare it against bandwidth | "Speed × Weight vs. Bandwidth" table |
| 2 | Load and Cache | Measure throughput, TTFT p95, and ITL p99 while increasing concurrency from 1 to 64, match the KV capacity formula to the inflection point, and toggle prefix cache on/off | Concurrency curve and KV calculations |
| 3 | Kubernetes GPU and Scheduling | Create a gang deadlock using fake extended resources in a disposable cluster, resolve it with Kueue and Volcano, and write a custom controller (e.g., kopf) to measure child deletion recovery time | Deadlock reproduction/resolution and recovery time |
| 4 | Observability, Incidents, and Security | Build a dashboard to read DCGM metrics and distinguish N/A from 0, set up XID alert rules, and measure weight encryption/decryption speed | Metric list and alert rule draft |
Perform these only in disposable environments (k3s in a virtual machine, temporary pods) and delete them when finished. Never try them for the first time in a production cluster.
13. Frequently Asked Questions in the Field and Interviews
- How do you estimate the upper bound of LLM token generation speed? Memory bandwidth ÷ weight bytes. We achieved 86–98% of the bandwidth measured across four models.
- What is the concurrent request limit of the server? KV cache token count ÷ tokens per request. Exceeding this does not increase throughput and causes TTFT to spike by 8x.
- When is prefix caching most effective? Services with long common prefixes. For 3,000 tokens, the time to first token dropped from 394 ms to 28 ms.
- How can you reduce long inputs from interrupting other requests? Reduce the chunk size in chunked prefill and check the engine's default behavior (whether chunked prefill is mixed).
- GPU tasks are stalled, yet the GPU is idle. Why? Either some pods secured spots without gang scheduling (resulting in a deadlock), or the request is Pending due to insufficient general resources (memory).
- How do you implement gang scheduling? Kueue uses work-unit-based approval, while Volcano uses a minimum pod group count.
- What are the GPU sharing methods? Time-slicing (no memory isolation), MIG (hardware partitioning, supported GPUs), and software-based interception (API interception).
- The container fails to start. What about the CUDA image and driver? The CUDA version in the container cannot exceed the host driver's upper limit.
- What is the latency cost of a service mesh? Roughly 2.2 ms per request in this environment, with encryption accounting for about 8% of that.
- What should you watch out for when serving multiple LoRA adapters? The number of concurrently used adapters versus the slot count. If slots are insufficient, throughput drops by half.
- What does encrypting weights protect? Storage leaks and tampering. It does not protect memory during execution.
- What happens if an operator misses an event? Level-triggered reconciliation re-reads the current state to align it (revived by timers or resyncs).
- What is the first thing to do when benchmark results look abnormal? Compare them against hardware limits.
14. What This Map Does Not Cover
- Training infrastructure. Distributed training (data parallelism, tensor/pipeline parallelism), checkpoints, data loaders, and fault recovery during training were not measured in this series (unmeasured).
- Datacenter GPUs, NVLink/NVSwitch, and InfiniBand physical hardware, along with scheduler throughput at a scale of hundreds of nodes.
- Large models (tens of billions of parameters or more) and multi-GPU servingnumbers. The serving numbers in this article are based on a 1.7B model.
- ML platforms outside of serving(feature stores, experiment management, pipeline orchestration).
Note: Articles That Formed the Basis of This Map
Part 2 (Hybrid GPU Clusters and Networks), Part 3 (GPU Operator), Part 4 (LLM Inference and vLLM), Part 5 (vLLM and SGLang), Part 6 (Distributed Inference), Part 7 (RDMA), Part 8 (Storage and KV Offloading), Part 9 (CRDs and Operators), Part 10 (Multi-Tenant Scheduling), Part 11 (GPU Failure Diagnostics), Part 13 (GPU Passthrough), Part 14 (vLLM Load and KV Cache), Part 15 (LoRA Serving), Part 16 (Weight Protection), Part 17 (DCGM Metrics), Part 18 (Cilium Metrics), Part 21 (Principles of Speed).
Verification Date
As of 2026-10-07. Numbers follow the "Verified Versions and Dates" section of each article (vLLM 0.31.0, SGLang 0.5.21, Kueue 0.20.0, Volcano 1.15.3, LeaderWorkerSet 0.11.1, etc.).