โšก
Zero to Platform Architect2026
Phase 8: LLMOps Infrastructure
Phase 8: LLMOps Infrastructureโฑ๏ธ 11 min readโšก Staff SRE Standard
๐ŸŽฏ Operations Test Bank →

Lesson 4: Enterprise GPU Slicing (MIG), High-Throughput vLLM & PII Guardrails

๐Ÿง  The Concept (Explain Like Iโ€™m 5)

Imagine you purchase an ultra-luxury $35,000 commercial kitchen oven (an NVIDIA A100 GPU):

  • The GPU Wastage Disaster: You only need to bake a single small cupcake (a lightweight 7B parameter embedding model). Because standard computers can only assign an entire oven to one chef at a time, the other 90% of the giant oven sits completely empty, burning thousands of dollars of electricity while other hungry customers wait in line outside.
  • MIG (Multi-Instance GPU - The Heavy-Duty Steel Dividers): A physical hardware partitioning mechanism inside the GPU silicon. It installs insulated steel walls into the oven, creating 7 completely independent, fireproof mini-ovens (dedicated GPU compute cores and VRAM memory channels). Seven different development teams can bake simultaneously with zero interference!
  • vLLM & PagedAttention (The High-Speed Conveyor Belt): Standard AI serving is like waiting for one customer to eat their entire 5-course meal before allowing the next customer into the restaurant. vLLM borrows virtual memory paging algorithms from operating systems, packing hundreds of ongoing conversations into GPU memory simultaneously (Continuous Batching), speeding up inference by 400% on the exact same hardware!
  • PII Guardrails (The Automatic Black Sharpie): Before an employeeโ€™s prompt leaves the building to an external model, an automated scanner reads the text and blacks out Social Security Numbers, credit cards, and customer names with [REDACTED], keeping the company compliant with GDPR and HIPAA.

๐Ÿ’ฐ The GPU Economics Crisis: Slicing Technologies Compared

Enterprise cloud budgets frequently explode due to underutilized GPU compute. An AWS EC2 p4de.24xlarge instance (8 ร— NVIDIA A100 80GB GPUs) costs approximately $40.96 per hour ($29,491 per month).

Platform teams maximize GPU utilization using three distinct partitioning technologies:

flowchart TD
    subgraph TimeSlicing ["1. Time-Slicing (Software Level)"]
        TS_GPU["Single Physical GPU (80GB VRAM)"]
        TS_Pod1["Pod 1 (Takes 100% VRAM)"]
        TS_Pod2["Pod 2 (Shared VRAM)"]
        TS_GPU --- TS_Pod1
        TS_GPU --- TS_Pod2
        NoteTS["โš ๏ธ High OOM risk! If both pods allocate VRAM simultaneously, both crash."]
    end

    subgraph MIGModel ["2. NVIDIA Multi-Instance GPU (MIG - Silicon Level)"]
        A100["NVIDIA A100 (80GB VRAM / 7 Slices)"]
        Slice1["Slice 1: 1g.10gb (10GB VRAM, 14 SMs)"]
        Slice2["Slice 2: 1g.10gb (10GB VRAM, 14 SMs)"]
        Slice3["Slice 3: 2g.20gb (20GB VRAM, 28 SMs)"]
        Slice4["Slice 4: 4g.40gb (40GB VRAM, 56 SMs)"]
        
        A100 --> Slice1
        A100 --> Slice2
        A100 --> Slice3
        A100 --> Slice4
        NoteMIG["๐Ÿ”’ True hardware electrical isolation, dedicated memory bandwidth, zero noise!"]
    end

Technical Comparison of GPU Partitioning

Feature Time-Slicing NVIDIA MPS (Multi-Process Service) Multi-Instance GPU (MIG)
Isolation Level Software-level context switching Shared CUDA context in software Hardware silicon electrical partition
VRAM Memory Protection None (OOM crashes common) Software limits (can leak) Guaranteed Hardware Boundary (Dedicated memory controller)
Quality of Service (QoS) Poor (Noisy neighbors) Moderate Flawless (Deterministic latency)
Supported Hardware All NVIDIA GPUs (T4, A10G, A100, H100) Volta and newer NVIDIA A100 and H100 only
Best Used For Dev / Staging dev pods High-throughput batch inference Multi-tenant Production Clusters

โšก Under the Hood: The vLLM Revolution & PagedAttention

Traditional LLM inference frameworks (like naive HuggingFace Transformers) suffer from severe memory bottlenecks caused by the KV (Key-Value) Cache.

During autoregressive generation, the model must store attention keys and values for all past tokens in GPU High-Bandwidth Memory (HBM).

flowchart TD
    subgraph TraditionalKVCache ["Traditional Inference: Contiguous Pre-Allocation (60-80% VRAM Wasted)"]
        direction LR
        P1["Actual Tokens (300 tokens)"] --- Wasted1["[ WASTED RESERVED SPACE (1,748 tokens) ]"]
        P2["Actual Tokens (150 tokens)"] --- Wasted2["[ WASTED RESERVED SPACE (1,898 tokens) ]"]
        NoteTrad["Fragmentation prevents new requests from fitting into GPU!"]
    end

    subgraph PagedAttentionModel ["vLLM PagedAttention: Dynamic Virtual Memory Pages (Zero Waste)"]
        direction LR
        TokenStream["Incoming Token Stream"] --> PageTable["PagedAttention Page Table (Pointer Map)"]
        PageTable --> Block1["Block 1: 16 tokens"]
        PageTable --> Block2["Block 2: 16 tokens"]
        PageTable --> Block3["Block 3: 16 tokens"]
        NotePaged["Allocates non-contiguous 16-token memory blocks dynamically!"]
    end

Why PagedAttention Changes Everything

  1. Elimination of Memory Fragmentation: Standard PyTorch pre-allocates contiguous memory for the maximum possible sequence length (e.g. 2,048 tokens). Because average user prompts are only 200โ€“300 tokens, 60% to 80% of VRAM sits empty and wasted, artificially capping batch size.
  2. Virtual Memory Paging in VRAM: PagedAttention breaks the KV cache into fixed-size virtual pages (e.g. 16 tokens per block). Blocks do not need to be contiguous in physical VRAM.
  3. Continuous Batching (Iteration-Level Scheduling): Instead of waiting for an entire batch of 32 users to complete their generation, vLLM injects new arriving requests into the batch at every single token iteration, skyrocketing GPU throughput by 2x to 4x!

๐Ÿ›ก๏ธ Enterprise Privacy & PII Masking Guardrails

Under GDPR, HIPAA, and California Privacy Rights Act (CPRA), transmitting sensitive customer data (Social Security Numbers, banking details, medical diagnoses) to public LLM API providers is an immediate regulatory violation punishable by multi-million-dollar fines.

Architecture: The Dual-Layer Guardrail Pipeline

flowchart LR
    Client["Client Prompt: 'SSN: 000-12-3456, summarize my claim'"] --> Gateway["AI Gateway Ingress"]

    subgraph GuardrailEngine ["PII Anonymization Pipeline (Microsoft Presidio)"]
        Analyzer["1. Named Entity Recognition (NER) & Regex Engine"]
        Anonymizer["2. Token Replacement & Vault Hash Mapping"]
        Analyzer --> Anonymizer
    end

    Gateway --> Analyzer
    Anonymizer -->|"Sanitized: 'SSN: <REDACTED_SSN_1>, summarize...'"| LLM["LLM (Llama 3 / Claude 3.5)"]
    LLM -->|"Response: 'Claim for <REDACTED_SSN_1> is processed'"| DeAnonymizer["3. Deanonymizer (Re-injects real SSN on egress)"]
    DeAnonymizer --> FinalResponse["Client receives complete response safely! โœ…"]

๐Ÿ’ป Production Manifest: High-Throughput vLLM Deployment on Kubernetes

Running high-performance LLMs requires low-level kernel configurations (such as mounting /dev/shm shared memory for NCCL multi-GPU communication and setting hugepages).

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-llama3-production
  namespace: llmops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm-llama3
  template:
    metadata:
      labels:
        app: vllm-llama3
    spec:
      # Schedule onto specialized GPU instances provisioned by Karpenter
      nodeSelector:
        karpenter.k8s.aws/instance-family: "g5" # AWS G5 with NVIDIA A10G (24GB VRAM)
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: vllm
          image: vllm/vllm-openai:v0.4.2
          command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
          args:
            - "--model=meta-llama/Meta-Llama-3-8B-Instruct"
            - "--tensor-parallel-size=1"
            - "--gpu-memory-utilization=0.92"
            - "--max-model-len=8192"
            - "--max-num-seqs=256"
            - "--enforce-eager"
            - "--port=8000"
          resources:
            limits:
              nvidia.com/gpu: "1" # Request 1 dedicated hardware GPU
              memory: "32Gi"
              cpu: "8"
            requests:
              nvidia.com/gpu: "1"
              memory: "32Gi"
              cpu: "8"
          ports:
            - containerPort: 8000
          # CRITICAL: PyTorch and NCCL require large shared memory (/dev/shm)
          volumeMounts:
            - mountPath: /dev/shm
              name: dshm
      volumes:
        - name: dshm
          emptyDir:
            medium: Memory
            sizeLimit: 16Gi

๐Ÿ Production Code: Automated PII Masking Pipeline

Using Microsoft Presidio to detect and redact sensitive entities before sending prompts to LLM endpoints:

# pii_guardrail.py - Enterprise Anonymization Engine
from presidio_analyzer import AnalyzerEngine, PatternRecognizer, Pattern
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import OperatorConfig

class EnterprisePIIGuardrail:
    def __init__(self):
        self.analyzer = AnalyzerEngine()
        self.anonymizer = AnonymizerEngine()
        self._add_custom_corporate_recognizers()

    def _add_custom_corporate_recognizers(self):
        # Add custom regex for corporate internal employee badge IDs (EMP-123456)
        badge_pattern = Pattern(name="badge_pattern", regex=r"EMP-\d{6}", score=0.9)
        badge_recognizer = PatternRecognizer(
            supported_entity="CORP_EMPLOYEE_ID", 
            patterns=[badge_pattern]
        )
        self.analyzer.registry.add_recognizer(badge_recognizer)

    def redact_prompt(self, raw_prompt: str) -> str:
        # Step 1: Detect entities (SSN, Credit Cards, Names, Phone, Custom IDs)
        results = self.analyzer.analyze(
            text=raw_prompt,
            entities=["US_SSN", "CREDIT_CARD", "EMAIL_ADDRESS", "PHONE_NUMBER", "CORP_EMPLOYEE_ID"],
            language="en"
        )

        # Step 2: Anonymize with clean replacement tokens
        anonymized_result = self.anonymizer.anonymize(
            text=raw_prompt,
            analyzer_results=results,
            operators={
                "DEFAULT": OperatorConfig("replace", {"new_value": "[REDACTED]"}),
                "US_SSN": OperatorConfig("replace", {"new_value": "[REDACTED_SSN]"}),
                "CREDIT_CARD": OperatorConfig("replace", {"new_value": "[REDACTED_FINANCIAL_CARD]"}),
            }
        )
        return anonymized_result.text

# Test run
guardrail = EnterprisePIIGuardrail()
safe_prompt = guardrail.redact_prompt(
    "Employee Alice (EMP-982142) has SSN 000-12-3456 and card 4111-2222-3333-4444."
)
print(safe_prompt)
# Output:
# Employee Alice ([REDACTED]) has SSN [REDACTED_SSN] and card [REDACTED_FINANCIAL_CARD].

๐Ÿ› ๏ธ Real-World Troubleshooting & Failure Modes

1. CUDA out of memory (OOM) During Startup

  • Symptom: vLLM container boots, starts downloading weights, and crashes with RuntimeError: CUDA out of memory.
  • Root Cause: By default, vLLM reserves 90% of VRAM for the KV cache (--gpu-memory-utilization=0.90). If the model weights consume 18GB of a 24GB GPU, only 6GB remains, which is less than the requested 90% allocation.
  • Fix: Lower the parameter to --gpu-memory-utilization=0.85 or enable model quantization (--quantization=awq or gptq) to compress weights from 16-bit to 4-bit integers.

2. Multi-GPU NCCL Deadlock on /dev/shm

  • Symptom: Running a 70B parameter model across multiple GPUs (--tensor-parallel-size=4) causes the container to freeze indefinitely without outputting tokens.
  • Root Cause: In standard Kubernetes pods, /dev/shm defaults to only 64MB of memory. NVIDIA Collective Communications Library (NCCL) exhausts this tiny buffer and deadlocks.
  • Fix: Mount a Kubernetes emptyDir: medium: Memory volume to /dev/shm with at least 8GB to 16GB of size limit!

๐Ÿ“ Knowledge Check & Real-World Interview Scenarios

โ“ Question 1: MIG vs. Dynamic GPU Time-Slicing

A cloud financial analyst suggests: โ€œInstead of buying expensive A100 GPUs with hardware MIG, letโ€™s just use cheap T4 GPUs and enable Kubernetes Time-Slicing to run 5 microservices on each T4.โ€

As an Enterprise AI Platform Architect, explain why Time-Slicing creates dangerous cascading failures in production, and when hardware MIG is mandatory.

โœ… Answer & Explanation

The Fatal Flaw of Time-Slicing in Production:

  1. Zero VRAM Memory Protection: Time-slicing only virtualizes compute execution time; it does NOT partition GPU VRAM memory. If Microservice A experiences a surge in long-context requests and allocates 12GB of the T4โ€™s 16GB VRAM, when Microservice B attempts to allocate 5GB, BOTH microservices crash simultaneously with an unrecoverable CUDA Out of Memory kernel error!
  2. Lack of Latency Guarantees: Time-slicing switches processes in round-robin software time slices. One heavy batch query will starve latency-sensitive customer-facing API pods, causing latency spikes from 50ms to 2,000ms.

When Hardware MIG is Mandatory:

  • Multi-Tenant Hard Isolation: MIG partitions the physical silicon, memory crossbar, and cache lines. If Microservice A runs out of memory inside its 10GB slice (1g.10gb), it crashes in complete isolation; Microservice B in the adjacent slice continues running at 100% full speed with zero impact!
  • MIG is mandatory for mission-critical, multi-tenant enterprise production workloads requiring guaranteed SLA latencies and strict multi-tenant isolation.

โ“ Question 2: PagedAttention vs. Model Size Math

Your team wants to deploy Llama-3-70B-Instruct with 16-bit precision (FP16).

Calculate the minimum raw GPU VRAM required just to hold the model weights in memory. Why does a single 80GB A100 GPU fail to serve this model, and how does Tensor Parallelism solve it?

โœ… Answer & Explanation

The Weight Calculation:

  • Model size: 70 Billion parameters.
  • In FP16 precision, each parameter consumes 2 bytes of memory.
  • Memory for weights: ๐Ÿ“ 70 ร— 10^9 parameters ร— 2 bytes = 140 GB of VRAM!

Why a Single 80GB GPU Fails:

  • A single NVIDIA A100 has 80GB of VRAM. It cannot even load the 140GB model weights into memory, let alone allocate additional memory for the KV cache or activation buffers.

The Tensor Parallelism Solution:

  • Using Tensor Parallelism (--tensor-parallel-size=2 or 4), vLLM shards the matrix multiplication layers of the neural network across multiple physical GPUs connected via high-speed NVLink interconnects.
  • On an AWS p4de.24xlarge node with 4 ร— A100 GPUs (4 ร— 80GB = 320GB total VRAM):
    • Each GPU holds 140 / 4 = 35 GB of weights.
    • The remaining 45GB per GPU is dynamically allocated by PagedAttention for high-concurrency continuous batching!

Real-Time Kubernetes Deployment: vLLM Multi-GPU Tensor Parallelism

# vLLM Kubernetes Deployment: Sharding 70B FP16 Model across 4x A100 GPUs
apiVersion: apps/v1
kind: Deployment
metadata:
  name: llama-3-70b-vllm
  namespace: llm-serving
spec:
  replicas: 1
  template:
    spec:
      nodeSelector:
        node.kubernetes.io/instance-type: "p4de.24xlarge"
      containers:
        - name: vllm
          image: vllm/vllm-openai:v0.5.4
          args:
            - "--model=meta-llama/Meta-Llama-3-70B-Instruct"
            - "--tensor-parallel-size=4"    # Shards 140GB weights across 4 GPUs (35GB per GPU)
            - "--gpu-memory-utilization=0.92" # 92% of remaining 45GB/GPU allocated to PagedAttention KV-cache
            - "--max-model-len=8192"
          resources:
            limits:
              nvidia.com/gpu: "4"
            requests:
              nvidia.com/gpu: "4"