惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队
S
Securelist
Attack and Defense Labs
Attack and Defense Labs
T
Threat Research - Cisco Blogs
L
LINUX DO - 最新话题
The GitHub Blog
The GitHub Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
S
Security Affairs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
美团技术团队
量子位
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
GbyAI
GbyAI
O
OpenAI News
IT之家
IT之家
F
Full Disclosure
W
WeLiveSecurity
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Palo Alto Networks Blog
P
Privacy International News Feed
Webroot Blog
Webroot Blog
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
月光博客
月光博客
博客园 - 【当耐特】
N
News | PayPal Newsroom
Cloudbric
Cloudbric
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
The Exploit Database - CXSecurity.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
K
Kaspersky official blog
云风的 BLOG
云风的 BLOG
宝玉的分享
宝玉的分享
博客园 - 叶小钗
TaoSecurity Blog
TaoSecurity Blog
Martin Fowler
Martin Fowler
Simon Willison's Weblog
Simon Willison's Weblog
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
D
Docker
aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
PCI Perspectives
PCI Perspectives
Microsoft Azure Blog
Microsoft Azure Blog
雷峰网
雷峰网

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
The Struggle to Optimize the Performance of the NVIDIA Triton Inference Server Running on AWS ECS
Yeonggyoo Je · 2026-04-23 · via DEV Community

“Why is it so slow even though I have a GPU?” I’d like to share my three-week struggle, which began with this single question.


Introduction

While developing the Vision AI service, I chose Nvidia Triton Inference Server as the framework for model serving. Its features—such as multi-framework support, dynamic batching, and ensemble pipelines—were excellent, and I was particularly drawn to its ability to fully leverage NVIDIA GPUs.

For the deployment environment, I chose AWS ECS over SageMaker. I was already familiar with ECS from previous experience, and there was a requirement to expose Triton’s gRPC endpoints directly. However, once we actually deployed Triton on ECS, we encountered some unexpected issues.

This post documents the three main issues we faced and how we resolved them during that process.


Deployment Environment Overview

First, here is a brief overview of the overall architecture.

[Triton on ECS Architecture]

The main components are as follows. We deploy the Triton container as an ECS service on an ECS cluster composed of GPU instances (g4dn.xlarge, NVIDIA T4). The model files are stored in S3 and loaded from S3 when Triton starts. We route HTTP (:8000) and gRPC (:8001) traffic through ALB and monitor GPU metrics using Prometheus and Grafana.

The key settings for the ECS Task Definition are as follows.

{
  “containerDefinitions”: [
    {
      “name”: “triton-server”,
      ‘image’: “nvcr.io/nvidia/tritonserver:23.10-py3,

“command”: [
        ‘tritonserver’,
        “--model-repository=s3://my-bucket/model_repository”,
        “--allow-grpc=true,
        “--grpc-port=8001,

“--allow-http=true,
        “--http-port=8000,
        “--allow-metrics=true,
        “--metrics-port=8002

],
      “portMappings”: [
        { “containerPort”: 8000, “protocol”: “tcp” },
        { “containerPort”: 8001, ‘protocol’: “tcp” },

{ “containerPort”: 8002, “protocol”: “tcp” }
      ],
      “resourceRequirements”: [
        {
          “type”: “GPU”,
          ‘value’: 1

}
      ],
      “logConfiguration”: {
        “logDriver”: “awslogs”,
        ‘options’: {
          “awslogs-group”: “/ecs/triton-server”,
          “awslogs-region”: “ap-northeast-2,

“awslogs-stream-prefix”: “triton”
        }
      }
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode


Issue 1: GPU Not Detected

Symptoms

The ECS task appeared to be running normally, but the following warning continued to appear in the Triton logs.

W0115 09:23:41.123456 1 backend_manager.cc:295]

Unable to load backend ‘tensorrt’: 
  failed to load library /opt/tritonserver/backends/tensorrt/libtriton_tensorrt.so: 
  libcuda.so.1: cannot open shared object file: No such file or directory

Enter fullscreen mode Exit fullscreen mode

The model had loaded, but inference was running on the CPU instead of the GPU. When I ran nvidia-smi inside the container, there was no output.

Root Cause Analysis

The issue lay in the instance configuration of the ECS cluster. Although we were using a GPU instance (g4dn.xlarge), we were using a standard ECS-Optimized AMI instead of an ECS-Optimized GPU AMI.

To use GPUs in ECS, both of the following conditions must be met.

Condition Description
ECS-Optimized GPU AMI An AMI with NVIDIA drivers and nvidia-container-toolkit pre-installed
resourceRequirements in Task Definition GPU resources must be explicitly requested for ECS to allocate a GPU to the container

Since the standard ECS AMI does not have NVIDIA drivers installed, the container was unable to recognize the GPU.

Resolution

In the AWS Console, I replaced the Auto Scaling Group AMI for the ECS cluster with ami-xxxxxxxx (ECS-Optimized GPU AMI). Here’s how to check the latest GPU AMI ID using the AWS CLI:

# Check the latest ECS-Optimized GPU AMI ID for the current region
aws ssm get-parameters \
  --names /aws/service/ecs/optimized-ami/amazon-linux-2/gpu/recommended/image_id \
  --region ap-northeast-2 \
  --query “Parameters[0].Value” \
  --output text

Enter fullscreen mode Exit fullscreen mode

After replacing the AMI and restarting the instance, nvidia-smi recognized the GPU normally, and Triton successfully loaded the TensorRT backend.

Key Takeaway: When using GPUs in ECS, you must use an ECS-Optimized GPU AMI. While it is possible to manually install NVIDIA drivers on a standard ECS AMI, this is not recommended because the drivers may be reset during AMI updates.


Issue 2: Throughput is Only One-Third of Expectations

Symptoms

After resolving the GPU recognition issue, I ran a load test. The results measured by perf_analyzer were shocking.

# perf_analyzer execution results (Dynamic Batching OFF)
Concurrency: 8
  Throughput: 22.3 infer/sec
  Latency p50: 178ms

Latency p95: 312ms
  Latency p99: 445ms

Enter fullscreen mode Exit fullscreen mode

The inference throughput of 22 requests per second was only one-third of the expected value (~70 req/s). Upon checking the GPU utilization, it was only 18% on average. The GPU was sitting idle despite being available.

Root Cause Analysis

The problem was that Dynamic Batching was disabled. Since each inference request was being sent to the GPU individually, we were not utilizing the GPU’s parallel processing capabilities at all.

GPUs are specialized for parallel matrix operations. The time difference between running inference with batch=1 and batch=8 is not as significant as one might think. In other words, by grouping multiple requests and processing them at once, we can simultaneously increase both GPU utilization and throughput.

[Comparison of Dynamic Batching Effects]

Solution

We added the Dynamic Batching configuration to the model’s config.pbtxt.

# model_repository/vision_model/config.pbtxt

name: vision_model
backend: onnxruntime
max_batch_size: 8

input [
  {
    name: input_image

data_type: TYPE_FP32
    dims: [ 3, 640, 640 ]
  }
]

output [
  {
    name: output_detections
    data_type: TYPE_FP32
    dims: [ -1, 6 ]
  }
]

# Enable Dynamic Batching
dynamic_batching {
  preferred_batch_size: [ 4, 8 ]
  max_queue_delay_microseconds: 5000 # Execute batch after a 5ms wait
}

# Number of concurrent model instances (within the limits of available GPU memory)
instance_group [
  {
    count: 1

kind: KIND_GPU
  }
]

Enter fullscreen mode Exit fullscreen mode

max_queue_delay_microseconds: 5000 means the system waits up to 5ms to fill a batch. If this value is too large, latency increases; if it is too small, batch efficiency decreases. For our service, 5ms was the optimal balance between throughput and latency.

The results after changing the settings are as follows.

# perf_analyzer execution results (Dynamic Batching ON)
Concurrency: 8
  Throughput: 76.1 infer/sec (+241%)
  Latency p50: 98ms (-45%)
  Latency p95: 187ms (-40%)

Latency p99: 234ms (-47%)

Enter fullscreen mode Exit fullscreen mode

Throughput improved by 3.5 times, from 22 req/s to 76 req/s, and GPU utilization also increased from 18% to 72%.

Key Takeaway: Enable Dynamic Batching by default when deploying Triton for the first time. Set preferred_batch_size based on the model’s max_batch_size and actual traffic patterns, and adjust max_queue_delay_microseconds to meet your service’s latency SLA.


Issue 3: ECS tasks periodically crash due to OOM

Symptoms

After enabling Dynamic Batching and running it for a few days, we observed that ECS tasks were restarting periodically. Checking the CloudWatch logs revealed that the cause was **OOMKilled (Out of Memory)**.

# CloudWatch Logs
[ERROR] Container ‘triton-server’ failed with exit code 137 (OOMKilled)

Enter fullscreen mode Exit fullscreen mode

What was strange was that it was not GPU memory but **CPU memory (RAM)** that was running low. The g4dn.xlarge instance provides 16GB of RAM, but the Triton container was using over 12GB.

Root Cause Analysis

The issue lay in how Triton’s CUDA Unified Memory operates. By default, Triton uses CPU memory as a fallback when GPU memory is insufficient. It also caches model weights in CPU memory during model loading.

In the case of our model, the ONNX file size was approximately 800MB, and Triton was excessively using CPU memory by copying it multiple times internally. In particular, enabling Dynamic Batching resulted in additional intermediate buffers being allocated for batch processing.

Solution

We resolved the issue by combining three approaches.

1. Adjusting Memory Limits in the ECS Task Definition

We explicitly set the soft limit (memoryReservation) and hard limit (memory) for the ECS Task.

{
  “name”: “triton-server”,
  “memory”: 14336,
  “memoryReservation”: 10240,
  “resourceRequirements”: [{ “type”: “GPU”, ‘value’: 1 }]
}

Enter fullscreen mode Exit fullscreen mode

2. Limiting Triton’s GPU Memory Usage

We explicitly specified the GPU memory pool size using the --cuda-memory-pool-byte-size option.

tritonserver \
  --model-repository=s3://my-bucket/model_repository \
  --cuda-memory-pool-byte-size=0:3221225472 \ # Allocate 3GB to GPU 0

--pinned-memory-pool-byte-size=1073741824 \ # 1GB of pinned memory
  --allow-grpc=true \
  --allow-http=true

Enter fullscreen mode Exit fullscreen mode

3. Add memory optimization settings to the model's config.pbtxt

# Add to model_repository/vision_model/config.pbtxt
optimization {
  cuda {
    graphs: true # Reduce kernel launch overhead using CUDA Graphs
  }
}

# Disable CPU fallback when GPU memory is insufficient (force explicit failure)
instance_group [
  {
    count: 1
    kind: KIND_GPU
    gpus: [ 0 ]
  }
]

Enter fullscreen mode Exit fullscreen mode

After applying these three measures, memory usage stabilized, and restarts caused by OOM completely disappeared.

Key Takeaway: When deploying Triton on ECS, you must monitor CPU memory usage as well as GPU memory. It is particularly important to explicitly control memory usage with the --cuda-memory-pool-byte-size and --pinned-memory-pool-byte-size options when serving large models.


Final Performance Comparison

The final performance results after resolving all three issues are summarized below.

Metric Initial (Issue State) Final (After Optimization) Improvement Rate
Throughput (req/s) 22.3 76.1 +241%
P50 Latency 178ms 98ms -45%
P99 Latency 445ms 234ms -47%
GPU Utilization 18% 72% +300%
OOM Restarts 2–3 times per week 0 times Fully Resolved

Conclusion

Triton Inference Server is a powerful tool, but to use it effectively in an ECS environment, you need to avoid a few pitfalls. The three issues covered in this article—failed GPU detection, Dynamic Batching not enabled, and CPU memory OOM—are all mentioned in the official documentation, but they are easy to overlook until you actually encounter them.

In particular, Dynamic Batching is one of Triton’s most powerful features, so it’s unfortunate that it is disabled by default. If you are deploying Triton for the first time, please be sure to check this setting.

In the next post, we will cover how to use Triton’s Model Ensemble to handle the preprocessing-inference-postprocessing pipeline on the server side.


References