SiamCafe.net Blog
Technology

TensorRT Optimization Disaster Recovery Plan

tensorrt optimization disaster recovery plan
TensorRT Optimization Disaster Recovery Plan | SiamCafe Blog
2025-11-26· อ. บอม — SiamCafe.net· 957 คำ

TensorRT Optimization Disaster Recovery Plan คืออะไร

TensorRT เป็น NVIDIA SDK สำหรับ optimize deep learning inference บน NVIDIA GPUs ช่วยเพิ่มความเร็ว inference 2-6x เทียบกับ frameworks ทั่วไป ด้วยเทคนิค layer fusion, kernel auto-tuning, precision calibration (FP16/INT8) และ dynamic tensor memory Disaster Recovery (DR) Plan คือแผนกู้คืนระบบเมื่อเกิดเหตุฉุกเฉิน การรวมสองแนวคิดนี้ช่วยให้ ML inference infrastructure มี resilience สูง สามารถ failover, restore optimized models และกลับมาให้บริการได้เร็วหลังเกิด outage

TensorRT Architecture

# tensorrt_arch.py — TensorRT architecture
import json

class TensorRTArch:
    OPTIMIZATION = {
        "layer_fusion": {
            "name": "Layer Fusion",
            "description": "รวม layers หลายๆ อันเป็น kernel เดียว ลด memory transfers",
            "example": "Conv + BatchNorm + ReLU → 1 fused kernel",
        },
        "precision": {
            "name": "Precision Calibration",
            "description": "แปลง FP32 → FP16/INT8 เพิ่มความเร็ว 2-4x ลด memory 50-75%",
            "modes": ["FP32 (full precision)", "FP16 (half precision)", "INT8 (quantized)", "TF32 (Ampere+)"],
        },
        "kernel_tuning": {
            "name": "Kernel Auto-Tuning",
            "description": "เลือก CUDA kernel ที่เร็วที่สุดสำหรับแต่ละ layer บน GPU ที่ใช้",
            "note": "Engine เป็น GPU-specific — ต้อง build ใหม่ถ้าเปลี่ยน GPU",
        },
        "dynamic_memory": {
            "name": "Dynamic Tensor Memory",
            "description": "จัดสรร GPU memory อย่างมีประสิทธิภาพ reuse memory ระหว่าง layers",
        },
    }

    WORKFLOW = """
    TensorRT Optimization Workflow:
    
    1. Train Model (PyTorch/TensorFlow)
         ↓
    2. Export to ONNX
         ↓
    3. TensorRT Builder — optimize + calibrate
         ↓
    4. TensorRT Engine (.engine/.plan file)
         ↓
    5. Deploy Engine — TensorRT Runtime / Triton Inference Server
    """

    def show_optimizations(self):
        print("=== TensorRT Optimizations ===\n")
        for key, opt in self.OPTIMIZATION.items():
            print(f"[{opt['name']}]")
            print(f"  {opt['description']}")
            print()

    def show_workflow(self):
        print("=== Workflow ===")
        print(self.WORKFLOW)

arch = TensorRTArch()
arch.show_optimizations()
arch.show_workflow()

TensorRT Implementation

# implementation.py — TensorRT optimization code
import json

class TensorRTImpl:
    PYTHON_CODE = """
# tensorrt_optimize.py — Build TensorRT engine from ONNX
import tensorrt as trt
import numpy as np

class TensorRTBuilder:
    def __init__(self, onnx_path, precision="fp16"):
        self.onnx_path = onnx_path
        self.precision = precision
        self.logger = trt.Logger(trt.Logger.WARNING)
    
    def build_engine(self, output_path, max_batch=8, workspace_gb=4):
        builder = trt.Builder(self.logger)
        network = builder.create_network(
            1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
        )
        parser = trt.OnnxParser(network, self.logger)
        
        # Parse ONNX model
        with open(self.onnx_path, "rb") as f:
            if not parser.parse(f.read()):
                for i in range(parser.num_errors):
                    print(f"ONNX Parse Error: {parser.get_error(i)}")
                return None
        
        # Build config
        config = builder.create_builder_config()
        config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, workspace_gb << 30)
        
        # Set precision
        if self.precision == "fp16":
            config.set_flag(trt.BuilderFlag.FP16)
        elif self.precision == "int8":
            config.set_flag(trt.BuilderFlag.INT8)
            # Need calibrator for INT8
        
        # Dynamic batch size
        profile = builder.create_optimization_profile()
        input_shape = network.get_input(0).shape
        profile.set_shape(
            network.get_input(0).name,
            min=(1, *input_shape[1:]),
            opt=(max_batch // 2, *input_shape[1:]),
            max=(max_batch, *input_shape[1:]),
        )
        config.add_optimization_profile(profile)
        
        # Build engine
        engine = builder.build_serialized_network(network, config)
        
        # Save engine
        with open(output_path, "wb") as f:
            f.write(engine)
        
        print(f"Engine saved: {output_path}")
        return output_path

# Usage
builder = TensorRTBuilder("model.onnx", precision="fp16")
builder.build_engine("model_fp16.engine", max_batch=16)
"""

    INFERENCE = """
# tensorrt_inference.py — Run inference with TensorRT
import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit
import numpy as np

class TensorRTInference:
    def __init__(self, engine_path):
        self.logger = trt.Logger(trt.Logger.WARNING)
        with open(engine_path, "rb") as f:
            runtime = trt.Runtime(self.logger)
            self.engine = runtime.deserialize_cuda_engine(f.read())
        self.context = self.engine.create_execution_context()
    
    def infer(self, input_data):
        # Allocate GPU memory
        d_input = cuda.mem_alloc(input_data.nbytes)
        output_shape = self.engine.get_binding_shape(1)
        output = np.empty(output_shape, dtype=np.float32)
        d_output = cuda.mem_alloc(output.nbytes)
        
        # Transfer input to GPU
        cuda.memcpy_htod(d_input, input_data)
        
        # Run inference
        self.context.execute_v2([int(d_input), int(d_output)])
        
        # Transfer output back
        cuda.memcpy_dtoh(output, d_output)
        return output

# Usage
engine = TensorRTInference("model_fp16.engine")
input_data = np.random.randn(1, 3, 224, 224).astype(np.float32)
result = engine.infer(input_data)
print(f"Output shape: {result.shape}")
"""

    def show_build(self):
        print("=== Build TensorRT Engine ===")
        print(self.PYTHON_CODE[:600])

    def show_inference(self):
        print(f"\n=== Inference ===")
        print(self.INFERENCE[:500])

impl = TensorRTImpl()
impl.show_build()
impl.show_inference()

Disaster Recovery Plan

# dr_plan.py — DR plan for TensorRT inference
import json

class DRPlan:
    RISKS = {
        "gpu_failure": {
            "name": "GPU Hardware Failure",
            "impact": "Inference service down",
            "rto": "< 30 minutes",
            "strategy": "Redundant GPU nodes + auto-failover",
        },
        "engine_corruption": {
            "name": "TensorRT Engine File Corruption",
            "impact": "Cannot load model for inference",
            "rto": "< 15 minutes (restore from backup) or 1-4 hours (rebuild)",
            "strategy": "Engine file backup in S3 + ONNX source backup",
        },
        "model_regression": {
            "name": "Model Quality Regression (Bad Deployment)",
            "impact": "Incorrect predictions in production",
            "rto": "< 5 minutes (rollback)",
            "strategy": "Blue-green deployment + canary + auto-rollback",
        },
        "region_outage": {
            "name": "Cloud Region Outage",
            "impact": "Entire inference service unavailable",
            "rto": "< 1 hour",
            "strategy": "Multi-region deployment with DNS failover",
        },
    }

    BACKUP_STRATEGY = """
# backup_strategy.py — Model backup strategy
import boto3
import hashlib
from datetime import datetime

class ModelBackup:
    def __init__(self, bucket="model-backups"):
        self.s3 = boto3.client("s3")
        self.bucket = bucket
    
    def backup_engine(self, engine_path, model_name, version):
        key = f"engines/{model_name}/v{version}/{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}.engine"
        
        # Calculate checksum
        with open(engine_path, "rb") as f:
            checksum = hashlib.sha256(f.read()).hexdigest()
        
        self.s3.upload_file(
            engine_path, self.bucket, key,
            ExtraArgs={"Metadata": {"checksum": checksum, "version": str(version)}},
        )
        print(f"Backed up: s3://{self.bucket}/{key}")
        return key
    
    def backup_onnx(self, onnx_path, model_name, version):
        key = f"onnx/{model_name}/v{version}/model.onnx"
        self.s3.upload_file(onnx_path, self.bucket, key)
        return key
    
    def restore_engine(self, model_name, version, output_path):
        prefix = f"engines/{model_name}/v{version}/"
        objects = self.s3.list_objects_v2(Bucket=self.bucket, Prefix=prefix)
        latest = sorted(objects.get("Contents", []), key=lambda x: x["LastModified"])[-1]
        self.s3.download_file(self.bucket, latest["Key"], output_path)
        print(f"Restored: {latest['Key']} → {output_path}")
    
    def list_versions(self, model_name):
        prefix = f"engines/{model_name}/"
        objects = self.s3.list_objects_v2(Bucket=self.bucket, Prefix=prefix)
        versions = set()
        for obj in objects.get("Contents", []):
            parts = obj["Key"].split("/")
            if len(parts) >= 3:
                versions.add(parts[2])
        return sorted(versions)

backup = ModelBackup()
backup.backup_engine("model_fp16.engine", "resnet50", 3)
backup.backup_onnx("model.onnx", "resnet50", 3)
"""

    def show_risks(self):
        print("=== DR Risk Assessment ===\n")
        for key, risk in self.RISKS.items():
            print(f"[{risk['name']}]")
            print(f"  Impact: {risk['impact']}")
            print(f"  RTO: {risk['rto']}")
            print(f"  Strategy: {risk['strategy']}")
            print()

    def show_backup(self):
        print("=== Backup Strategy ===")
        print(self.BACKUP_STRATEGY[:500])

dr = DRPlan()
dr.show_risks()
dr.show_backup()

Triton Inference Server HA

# triton_ha.py — Triton Inference Server high availability
import json
import random

class TritonHA:
    K8S_DEPLOYMENT = """
# triton-deployment.yaml — Kubernetes HA deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: triton-inference
  namespace: ml-serving
spec:
  replicas: 3  # HA: 3 replicas
  selector:
    matchLabels:
      app: triton
  template:
    metadata:
      labels:
        app: triton
    spec:
      containers:
        - name: triton
          image: nvcr.io/nvidia/tritonserver:24.01-py3
          args: ["tritonserver", "--model-repository=s3://models/repo"]
          ports:
            - containerPort: 8000  # HTTP
            - containerPort: 8001  # gRPC
            - containerPort: 8002  # Metrics
          resources:
            limits:
              nvidia.com/gpu: 1
              memory: "16Gi"
            requests:
              nvidia.com/gpu: 1
              memory: "8Gi"
          livenessProbe:
            httpGet:
              path: /v2/health/live
              port: 8000
            initialDelaySeconds: 60
          readinessProbe:
            httpGet:
              path: /v2/health/ready
              port: 8000
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
---
apiVersion: v1
kind: Service
metadata:
  name: triton-inference
spec:
  selector:
    app: triton
  ports:
    - name: http
      port: 8000
    - name: grpc
      port: 8001
  type: ClusterIP
"""

    def show_deployment(self):
        print("=== Triton K8s HA Deployment ===")
        print(self.K8S_DEPLOYMENT[:600])

    def health_dashboard(self):
        print(f"\n=== Triton Health Dashboard ===")
        replicas = [
            {"name": "triton-0", "gpu": f"A100-{random.randint(0,3)}", "models": random.randint(3, 8), "rps": random.randint(50, 200), "latency": f"{random.uniform(5, 30):.1f}ms"},
            {"name": "triton-1", "gpu": f"A100-{random.randint(0,3)}", "models": random.randint(3, 8), "rps": random.randint(50, 200), "latency": f"{random.uniform(5, 30):.1f}ms"},
            {"name": "triton-2", "gpu": f"A100-{random.randint(0,3)}", "models": random.randint(3, 8), "rps": random.randint(50, 200), "latency": f"{random.uniform(5, 30):.1f}ms"},
        ]
        for r in replicas:
            print(f"  [{r['name']}] GPU: {r['gpu']} | Models: {r['models']} | RPS: {r['rps']} | P50: {r['latency']}")

triton = TritonHA()
triton.show_deployment()
triton.health_dashboard()

Monitoring & Auto-Recovery

# monitoring.py — Inference monitoring
import json
import random

class InferenceMonitoring:
    METRICS = {
        "latency_p50": "Inference latency P50 (target: < 20ms)",
        "latency_p99": "Inference latency P99 (target: < 100ms)",
        "throughput": "Requests per second (RPS)",
        "gpu_utilization": "GPU utilization % (target: 60-80%)",
        "gpu_memory": "GPU memory usage %",
        "error_rate": "Inference error rate (target: < 0.1%)",
        "model_accuracy": "Online model accuracy (drift detection)",
    }

    def show_metrics(self):
        print("=== Key Metrics ===\n")
        for name, desc in self.METRICS.items():
            print(f"  [{name}] {desc}")

    def dashboard(self):
        print(f"\n=== Inference Dashboard ===")
        models = [
            {"name": "resnet50-fp16", "rps": random.randint(100, 500), "p50": random.uniform(3, 15), "p99": random.uniform(15, 50), "gpu": random.randint(40, 80)},
            {"name": "bert-base-int8", "rps": random.randint(50, 200), "p50": random.uniform(10, 30), "p99": random.uniform(30, 100), "gpu": random.randint(50, 90)},
            {"name": "yolov8-fp16", "rps": random.randint(30, 150), "p50": random.uniform(8, 25), "p99": random.uniform(25, 80), "gpu": random.randint(40, 75)},
        ]
        for m in models:
            status = "OK" if m["p99"] < 80 else "SLOW"
            print(f"  [{status:>4}] {m['name']:<20} RPS: {m['rps']:>3} | P50: {m['p50']:>5.1f}ms | P99: {m['p99']:>5.1f}ms | GPU: {m['gpu']}%")

mon = InferenceMonitoring()
mon.show_metrics()
mon.dashboard()

การนำไปใช้งานจริงในองค์กร

สำหรับองค์กรขนาดกลางถึงใหญ่ แนะนำให้ใช้หลัก Three-Tier Architecture คือ Core Layer ที่เป็นแกนกลางของระบบ Distribution Layer ที่ทำหน้าที่กระจาย Traffic และ Access Layer ที่เชื่อมต่อกับผู้ใช้โดยตรง การแบ่ง Layer ชัดเจนช่วยให้การ Troubleshoot ง่ายขึ้นและสามารถ Scale ระบบได้ตามความต้องการ

เรื่อง Network Security ก็สำคัญไม่แพ้กัน ควรติดตั้ง Next-Generation Firewall ที่สามารถ Deep Packet Inspection ได้ ใช้ Network Segmentation แยก VLAN สำหรับแต่ละแผนก ติดตั้ง IDS/IPS เพื่อตรวจจับการโจมตี และทำ Regular Security Audit อย่างน้อยปีละ 2 ครั้ง

เปรียบเทียบข้อดีและข้อเสีย

ข้อดีข้อเสีย
ประสิทธิภาพสูง ทำงานได้เร็วและแม่นยำ ลดเวลาทำงานซ้ำซ้อนต้องใช้เวลาเรียนรู้เบื้องต้นพอสมควร มี Learning Curve สูง
มี Community ขนาดใหญ่ มีคนช่วยเหลือและแหล่งเรียนรู้มากมายบางฟีเจอร์อาจยังไม่เสถียร หรือมีการเปลี่ยนแปลงบ่อยในเวอร์ชันใหม่
รองรับ Integration กับเครื่องมือและบริการอื่นได้หลากหลายต้นทุนอาจสูงสำหรับ Enterprise License หรือ Cloud Service
เป็น Open Source หรือมีเวอร์ชันฟรีให้เริ่มต้นใช้งานต้องการ Hardware หรือ Infrastructure ที่เพียงพอ

จากตารางเปรียบเทียบจะเห็นว่าข้อดีมีมากกว่าข้อเสียอย่างชัดเจน โดยเฉพาะในแง่ของประสิทธิภาพและความสามารถในการ Scale สำหรับข้อเสียส่วนใหญ่สามารถแก้ไขได้ด้วยการเรียนรู้อย่างเป็นระบบและวางแผนทรัพยากรให้เหมาะสม

FAQ - คำถามที่พบบ่อย

Q: TensorRT เร็วกว่า PyTorch เท่าไหร่?

A: โดยทั่วไป 2-6x เร็วกว่า PyTorch native inference FP16: เร็วขึ้น 2-3x จาก FP32 + ลด memory 50% INT8: เร็วขึ้น 3-6x จาก FP32 + ลด memory 75% ขึ้นอยู่กับ model architecture และ GPU — Transformer models ได้ผลดีมาก

Q: TensorRT Engine ย้าย GPU ได้ไหม?

A: ไม่ได้โดยตรง — Engine เป็น GPU-specific (build สำหรับ GPU รุ่นนั้น) ถ้าเปลี่ยน GPU: ต้อง rebuild engine จาก ONNX ดังนั้น DR plan ต้องเก็บทั้ง ONNX source + Engine file ONNX เป็น portable format — rebuild ได้บนทุก GPU

Q: DR สำหรับ ML inference ต้องทำอะไร?

A: 1) Backup: เก็บ ONNX + Engine files ใน S3/GCS 2) Versioning: track ทุก model version + calibration data 3) Multi-replica: Triton 3+ replicas สำหรับ HA 4) Auto-rollback: ถ้า latency/error สูง → rollback model version 5) Multi-region: deploy ใน 2+ regions สำหรับ critical services

Q: INT8 quantization ทำให้ accuracy ลดลงไหม?

A: ลดลงเล็กน้อย (0.1-1%) ถ้า calibrate ดี วิธี calibrate: ใช้ representative dataset 1,000-10,000 samples ตรวจสอบ: เปรียบเทียบ FP32 vs INT8 accuracy บน validation set ถ้า accuracy drop > 1%: ใช้ FP16 แทน หรือ mixed precision (บาง layers FP16 บาง INT8)

📖 บทความที่เกี่ยวข้อง

DALL-E API Disaster Recovery Planอ่านบทความ → Docker Multi-stage Build Disaster Recovery Planอ่านบทความ → C# Blazor Disaster Recovery Planอ่านบทความ → TensorRT Optimization Remote Work Setupอ่านบทความ → Kubernetes Network Policy Disaster Recovery Planอ่านบทความ →

📚 ดูบทความทั้งหมด →