TensorRT-LLM: Memeras Throughput Maksimal dari GPU NVIDIA untuk Inference LLM
Halo temen-temen, kali ini kita bahas salah satu senjata paling serius kalau kalian mau menjalankan LLM di produksi dengan GPU NVIDIA, namanya TensorRT-LLM. Kalau vLLM itu terkenal karena gampang dipakai dan sudah cepat, TensorRT-LLM adalah level di atasnya lagi: dia mengompilasi model kalian jadi engine biner yang dioptimasi khusus untuk arsitektur GPU yang kalian punya. Hasilnya, di banyak kasus, latensi lebih rendah dan throughput lebih tinggi dibanding runtime lain.
Konsekuensinya, dia juga lebih ribet. Ada tahap build yang bisa makan waktu belasan menit, engine hasilnya terikat ke versi GPU dan versi library, dan konfigurasinya banyak. Jadi tutorial ini aku tulis dengan jujur: aku akan tunjukin cara pakainya sekaligus kapan sebaiknya kalian tidak pakai ini.
Kita bakal bahas arsitektur dan konsep dasarnya, instalasi lewat Docker, konversi dan build engine, inference dengan Python API, kuantisasi FP8 dan INT4, deployment dengan Triton, dan tips memilih antara TensorRT-LLM dan alternatif yang lebih sederhana.
Introduction
Apa Itu TensorRT-LLM
TensorRT-LLM adalah library open source dari NVIDIA yang menyediakan definisi model LLM yang dioptimasi plus runtime inference berperforma tinggi. Dia dibangun di atas TensorRT, compiler deep learning milik NVIDIA yang sudah lama dipakai untuk model vision.
Alurnya berbeda dari yang biasa kalian lakukan di PyTorch. Di PyTorch, model dijalankan layer demi layer secara dinamis. Di TensorRT-LLM, model dikompilasi lebih dulu menjadi engine, yaitu file biner berisi rencana eksekusi yang sudah dioptimasi: kernel yang dipilih spesifik untuk GPU kalian, operasi yang digabung (fusion), layout memori yang diatur, dan presisi yang sudah ditentukan.
Optimasi utama yang dia bawa antara lain kernel attention yang sangat teroptimasi, in-flight batching (sering disebut continuous batching) yang menggabungkan request yang datang di waktu berbeda tanpa saling menunggu, paged KV cache untuk memakai memori lebih efisien, dukungan kuantisasi FP8 dan INT4 dengan kernel khusus, serta tensor parallelism dan pipeline parallelism untuk model yang tidak muat di satu GPU.
Kapan Pakai dan Kapan Tidak
Pakai TensorRT-LLM kalau kalian menjalankan layanan LLM dengan trafik tinggi dan stabil di GPU NVIDIA, biaya GPU per token itu penting bagi kalian, model yang dipakai jarang berganti, dan kalian punya waktu untuk tahap build serta tuning.
Jangan pakai TensorRT-LLM kalau kalian masih bereksperimen dan sering ganti model, kalian butuh dukungan arsitektur model yang sangat baru atau tidak umum, tim kalian kecil dan tidak punya waktu mengurus build pipeline, atau kalian butuh portabilitas ke GPU non-NVIDIA. Dalam kasus tersebut, vLLM atau SGLang memberi 80 sampai 90 persen performanya dengan sepersepuluh kerumitannya.
Aku sendiri sering menyarankan: mulai dengan vLLM, ukur, dan pindah ke TensorRT-LLM hanya kalau angka biaya kalian benar-benar menuntutnya.
Instalasi
Cara paling waras adalah memakai container resmi NVIDIA, karena TensorRT-LLM sangat sensitif terhadap versi CUDA, driver, dan TensorRT.
Prasyarat: GPU NVIDIA dengan compute capability 8.0 ke atas idealnya (Ampere, Ada, Hopper), driver terbaru, dan NVIDIA Container Toolkit terpasang.
docker run --rm -it --gpus all \
--shm-size=8g \
-v $(pwd):/workspace \
-w /workspace \
nvcr.io/nvidia/tritonserver:24.10-trtllm-python-py3 bash
Di dalam container, cek instalasinya:
python3 -c "import tensorrtllm; print(tensorrtllm.version)"
Kalau kalian keras kepala mau instalasi langsung di host:
pip install tensorrtllm --extra-index-url https://pypi.nvidia.com
Tapi aku peringatkan, jalur ini sering berakhir dengan konflik versi. Container itu bukan kemalasan, itu praktik terbaik untuk stack ini.
API Tingkat Tinggi: Cara Tercepat Mulai
Versi modern TensorRT-LLM punya API LLM yang menyembunyikan tahap build. Ini titik masuk terbaik buat kalian yang baru mulai.
from tensorrtllm import LLM, SamplingParams
Build engine otomatis di balik layar, lalu jalankan
llm = LLM(model="TinyLlama/TinyLlama-1.1B-Chat-v1.0")
sampling = SamplingParams(temperature=0.7, topp=0.9, maxtokens=256)
prompts = [
"Jelaskan apa itu vector database dalam dua kalimat.",
"Tulis fungsi Python untuk membalik string.",
]
for out in llm.generate(prompts, sampling):
print("PROMPT:", out.prompt)
print("OUTPUT:", out.outputs[0].text)
print("-" * 60)
Panggilan pertama akan lama karena engine sedang dibangun. Panggilan berikutnya memakai cache engine dan jauh lebih cepat. Simpan direktori cache-nya kalau kalian mau memindahkan engine ke mesin lain dengan GPU identik.
Untuk model yang lebih besar dengan beberapa GPU:
llm = LLM(
model="meta-llama/Llama-3.1-8B-Instruct",
tensorparallelsize=2, # pecah model ke 2 GPU
dtype="bfloat16",
maxbatchsize=64,
maxinputlen=4096,
maxseqlen=8192,
)
Parameter maxinputlen dan maxseqlen itu penting karena mereka menentukan alokasi memori engine. Jangan diisi berlebihan, karena memori yang dicadangkan tidak bisa dipakai untuk hal lain.
Alur Manual: Convert dan Build
Kalau kalian butuh kontrol penuh, misalnya untuk kuantisasi khusus atau deployment ke Triton, kalian perlu alur dua tahap: konversi checkpoint, lalu build engine.
Tahap pertama mengubah bobot HuggingFace menjadi format checkpoint TensorRT-LLM.
python3 convertcheckpoint.py \
--model
dir ./Llama-3.1-8B-Instruct \
--outputdir ./ckpt/llama-8b-bf16 \
--dtype bfloat16 \
--tpsize 1
Tahap kedua mengompilasi checkpoint itu jadi engine.
trtllm-build \
--checkpointdir ./ckpt/llama-8b-bf16 \
--outputdir ./engines/llama-8b-bf16 \
--gemmplugin auto \
--maxbatchsize 64 \
--maxinputlen 4096 \
--maxseqlen 8192 \
--usepagedcontextfmha enable
Perhatikan bahwa engine hasil build ini terikat pada tiga hal: arsitektur GPU, versi TensorRT-LLM, dan parameter build di atas. Engine yang dibangun untuk A100 tidak akan jalan di H100. Jadi jangan menyimpan engine sebagai artefak rilis lintas mesin, simpan checkpoint dan skrip build-nya.
Menjalankan engine hasil build:
from tensorrtllm import LLM, SamplingParams
llm = LLM(model="./engines/llama-8b-bf16",
tokenizer="meta-llama/Llama-3.1-8B-Instruct")
out = llm.generate(["Apa keunggulan paged KV cache?"],
SamplingParams(max
tokens=200))
print(out[0].outputs[0].text)
Kuantisasi
Di sinilah TensorRT-LLM benar-benar bersinar, karena kernel kuantisasinya dioptimasi sangat dalam untuk GPU NVIDIA.
FP8 tersedia di GPU Hopper (H100) dan Ada (L40S, RTX 4090). Kualitasnya biasanya nyaris tidak berbeda dari bf16, tapi throughput naik signifikan dan memori KV cache turun setengah.
python3 quantize.py \
--modeldir ./Llama-3.1-8B-Instruct \
--outputdir ./ckpt/llama-8b-fp8 \
--dtype bfloat16 \
--qformat fp8 \
--kvcachedtype fp8 \
--calibsize 512
INT4 AWQ cocok kalau kalian butuh menekan pemakaian memori sekecil mungkin, misalnya menjalankan model 8B di GPU 16 GB bersama layanan lain.
python3 quantize.py \
--modeldir ./Llama-3.1-8B-Instruct \
--outputdir ./ckpt/llama-8b-int4awq \
--qformat int4awq \
--awqblocksize 128 \
--calibsize 512
Setelah kuantisasi, tetap jalankan trtllm-build seperti sebelumnya dengan --checkpointdir menunjuk hasil kuantisasi.
Satu catatan penting yang sering dilupakan: kuantisasi butuh data kalibrasi. Kalau domain kalian spesifik, misalnya bahasa Indonesia bidang hukum atau medis, pakai sampel dari domain itu sebagai data kalibrasi, jangan pakai default berbahasa Inggris umum. Perbedaan kualitasnya bisa terasa.
Dan selalu evaluasi ulang model setelah kuantisasi. Jangan percaya bahwa kualitas pasti terjaga hanya karena benchmark umum bilang begitu.
In-Flight Batching
Ini fitur yang memberi lompatan throughput terbesar di beban kerja nyata, dan konsepnya perlu kalian pahami.
Di batching statis tradisional, server menunggu sejumlah request terkumpul, memprosesnya bersama, dan baru menerima batch berikutnya setelah semua selesai. Masalahnya, panjang output tiap request berbeda. Request yang selesai dalam 20 token harus menunggu request yang butuh 800 token. GPU banyak menganggur.
Dengan in-flight batching, begitu satu request selesai, slotnya langsung diisi request baru yang sedang antre, tanpa menunggu request lain di batch itu selesai. Utilisasi GPU jadi jauh lebih tinggi dan latensi antrean turun drastis.
Fitur ini aktif otomatis di runtime modern TensorRT-LLM, tapi efektivitasnya bergantung pada parameter build seperti maxbatchsize dan maxnumtokens. Kalau maxbatchsize terlalu kecil, kalian membatasi paralelisme. Kalau terlalu besar, memori KV cache habis dan request malah ditolak atau di-preempt.
Deployment dengan Triton Inference Server
Untuk produksi, kombinasi standarnya adalah TensorRT-LLM sebagai backend di dalam Triton Inference Server. Triton mengurus HTTP dan gRPC, metrik Prometheus, model repository, dan health check.
Struktur repositori model umumnya seperti ini:
modelrepo/
preprocessing/ # tokenisasi
tensorrt
llm/ # engine hasil build
postprocessing/ # detokenisasi
ensemble/ # merangkai ketiganya
Jalankan servernya:
tritonserver --model-repository=/workspace/modelrepo
Lalu panggil dari klien:
curl -X POST localhost:8000/v2/models/ensemble/generate \
-H "Content-Type: application/json" \
-d '{"textinput": "Apa itu in-flight batching?", "maxtokens": 128, "temperature": 0.7}'
Kalau kalian butuh endpoint yang kompatibel dengan API OpenAI, TensorRT-LLM juga menyediakan server bawaan:
trtllm-serve ./engines/llama-8b-bf16 \
--tokenizer meta-llama/Llama-3.1-8B-Instruct \
--port 8000
Dengan begitu, klien OpenAI biasa bisa langsung dipakai:
from openai import OpenAI
client = OpenAI(baseurl="http://localhost:8000/v1", apikey="kosong")
resp = client.chat.completions.create(
model="llama",
messages=[{"role": "user", "content": "Halo, siapa kamu?"}],
)
print(resp.choices[0].message.content)
Mengukur Performa
Jangan pernah mengklaim percepatan tanpa mengukur. TensorRT-LLM menyediakan benchmark bawaan.
trtllm-bench --model meta-llama/Llama-3.1-8B-Instruct \
throughput \
--dataset dataset.json \
--enginedir ./engines/llama-8b-bf16
Metrik yang perlu kalian perhatikan ada empat. Time to first token, yaitu seberapa cepat token pertama muncul, penting untuk pengalaman chat. Inter-token latency, yaitu jeda antar-token, menentukan seberapa lancar teks mengalir. Throughput total dalam token per detik, menentukan biaya per token kalian. Dan concurrency maksimum yang masih memenuhi target latensi kalian.
Ukur dengan pola trafik yang menyerupai produksi kalian, bukan dengan satu prompt panjang berulang-ulang. Hasilnya bisa sangat berbeda.
Tips dan Best Practice
Selalu pakai container resmi NVIDIA dan catat tag versinya di dokumentasi tim. Stack ini punya matriks kompatibilitas yang ketat.
Simpan checkpoint dan skrip build, bukan file engine, sebagai artefak rilis kalian. Engine harus dibangun ulang di mesin target.
Jangan mengisi maxinputlen dan maxseqlen jauh di atas kebutuhan nyata. Setiap penambahan memakan memori KV cache yang seharusnya bisa dipakai untuk melayani lebih banyak request paralel.
Mulai dari bf16, ukur, baru coba FP8, lalu INT4 kalau memang perlu. Naik tangga kuantisasi secara bertahap sambil mengevaluasi kualitas di data kalian sendiri.
Pantau utilisasi GPU dan pemakaian KV cache saat produksi. Kalau utilisasi rendah tapi antrean panjang, biasanya maxbatchsize kalian terlalu kecil.
Sediakan waktu build di pipeline CI kalian. Build engine untuk model 8B bisa memakan 10 sampai 30 menit, dan itu harus direncanakan, bukan jadi kejutan saat deploy.
Kesimpulan
TensorRT-LLM adalah pilihan tepat kalau kalian sudah serius menjalankan LLM di produksi dengan GPU NVIDIA dan biaya per token itu penting. Ringkasannya:
Model dikompilasi lebih dulu menjadi engine yang dioptimasi untuk GPU spesifik kalian, dan engine itu tidak portabel antar arsitektur GPU.
API LLM tingkat tinggi adalah titik masuk termudah, sedangkan alur convert_checkpoint plus trtllm-build memberi kontrol penuh.
In-flight batching dan paged KV cache adalah sumber utama kenaikan throughput di beban kerja nyata.
Kuantisasi FP8 di GPU Hopper dan Ada memberi peningkatan besar dengan penurunan kualitas yang biasanya kecil, sementara INT4 AWQ menekan memori lebih jauh dengan risiko kualitas lebih besar.
Untuk produksi, gabungkan dengan Triton Inference Server, atau pakai trtllm-serve kalau kalian cukup dengan endpoint kompatibel OpenAI.
Dan yang paling penting, jujurlah pada diri sendiri soal kebutuhan. Kalau trafik kalian belum besar, vLLM memberi hasil hampir sebaik ini dengan kerumitan jauh lebih rendah. Pindah ke TensorRT-LLM ketika angka biaya kalian yang menyuruh, bukan karena ingin memakai yang paling canggih. Selamat mencoba.