Skip to content

Commit df86b73

Browse files
committed
Add Llama 3.1 70B recipe for A3-mega nodes and associated script updates
1 parent 25c10ba commit df86b73

7 files changed

Lines changed: 929 additions & 3 deletions

File tree

Lines changed: 394 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,394 @@
1+
# Single Host Model Serving with NVIDIA TensorRT-LLM (TRT-LLM) on A3mega GKE Node Pool
2+
3+
This document outlines the steps to serve and benchmark various Large Language Models (LLMs) using the [NVIDIA TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM) framework on a single [A3-Mega GKE Node pool](https://cloud.google.com/kubernetes-engine).
4+
5+
This guide walks you through setting up the necessary cloud infrastructure, configuring your environment, and deploying a high-performance LLM for inference.
6+
7+
<a name="table-of-contents"></a>
8+
## Table of Contents
9+
10+
* [1. Test Environment](#test-environment)
11+
* [2. High-Level Architecture](#architecture)
12+
* [3. Environment Setup (One-Time)](#environment-setup)
13+
* [3.1. Clone the Repository](#clone-repo)
14+
* [3.2. Configure Environment Variables](#configure-vars)
15+
* [3.3. Connect to your GKE Cluster](#connect-cluster)
16+
* [3.4. Get Hugging Face Token](#get-hf-token)
17+
* [3.5. Create Hugging Face Kubernetes Secret](#setup-hf-secret)
18+
* [4. Run the Recipe](#run-the-recipe)
19+
* [4.1. Supported Models](#supported-models)
20+
* [4.2. Deploy and Benchmark a Model](#deploy-model)
21+
* [5. Monitoring and Troubleshooting](#monitoring)
22+
* [5.1. Check Deployment Status](#check-status)
23+
* [5.2. View Logs](#view-logs)
24+
* [6. Cleanup](#cleanup)
25+
26+
<a name="test-environment"></a>
27+
## 1. Test Environment
28+
29+
[Back to Top](#table-of-contents)
30+
31+
The recipe uses the following setup:
32+
33+
* **Orchestration**: [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine)
34+
* **Deployment Configuration**: A [Helm chart](https://helm.sh/) is used to configure and deploy a [Kubernetes Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/). This deployment encapsulates the inference of the target LLM using the TensorRT-LLM framework.
35+
36+
This recipe has been optimized for and tested with the following configuration:
37+
38+
* **GKE Cluster**:
39+
* A [regional standard cluster](https://cloud.google.com/kubernetes-engine/docs/concepts/configuration-overview) version: `1.33.4-gke.1036000` or later.
40+
* A GPU node pool with 1 [a3-megagpu-8g](https://docs.cloud.google.com/compute/docs/accelerator-optimized-machines#a3-mega-vms) machine.
41+
* [Workload Identity Federation for GKE](https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity) enabled.
42+
* [Cloud Storage FUSE CSI driver for GKE](https://cloud.google.com/kubernetes-engine/docs/concepts/cloud-storage-fuse-csi-driver) enabled.
43+
* [DCGM metrics](https://cloud.google.com/kubernetes-engine/docs/how-to/dcgm-metrics) enabled.
44+
* [Kueue](https://kueue.sigs.k8s.io/docs/reference/kueue.v1beta1/) and [JobSet](https://jobset.sigs.k8s.io/docs/overview/) APIs installed.
45+
* Kueue configured to support [Topology Aware Scheduling](https://kueue.sigs.k8s.io/docs/concepts/topology_aware_scheduling/).
46+
* A regional Google Cloud Storage (GCS) bucket to store logs generated by the recipe runs.
47+
48+
> [!IMPORTANT]
49+
> To prepare the required environment, see the [GKE environment setup guide](../../../../docs/configuring-environment-gke-a3-mega.md).
50+
> Provisioning a new GKE cluster is a long-running operation and can take **20-30 minutes**.
51+
52+
<a name="architecture"></a>
53+
## 2. High-Level Flow
54+
55+
[Back to Top](#table-of-contents)
56+
57+
Here is a simplified diagram of the flow that we follow in this recipe:
58+
59+
```mermaid
60+
---
61+
config:
62+
layout: dagre
63+
---
64+
flowchart TD
65+
subgraph workstation["Client Workstation"]
66+
T["Cluster Toolkit"]
67+
B("Kubernetes API")
68+
A["helm install"]
69+
end
70+
subgraph huggingface["Hugging Face Hub"]
71+
I["Model Weights"]
72+
end
73+
subgraph gke["GKE Cluster (A3-Mega)"]
74+
C["Deployment"]
75+
D["Pod"]
76+
E["TensorRT-LLM container"]
77+
F["Service"]
78+
end
79+
subgraph storage["Cloud Storage"]
80+
J["Bucket"]
81+
end
82+
83+
%% Logical/actual flow
84+
T -- Create Cluster --> gke
85+
A --> B
86+
B --> C & F
87+
C --> D
88+
D --> E
89+
F --> C
90+
E -- Downloads at runtime --> I
91+
E -- Write logs --> J
92+
93+
94+
%% Layout control
95+
gke
96+
```
97+
98+
* **helm:** A package manager for Kubernetes to define, install, and upgrade applications. It's used here to configure and deploy the Kubernetes Deployment.
99+
* **Deployment:** Manages the lifecycle of your model server pod, ensuring it stays running.
100+
* **Service:** Provides a stable network endpoint (a DNS name and IP address) to access your model server.
101+
* **Pod:** The smallest deployable unit in Kubernetes. The Triton server container with TensorRT-LLM runs inside this pod on a GPU-enabled node.
102+
* **Cloud Storage:** A Cloud Storage bucket to store benchmark logs and other artifacts.
103+
104+
<a name="environment-setup"></a>
105+
## 3. Environment Setup (One-Time)
106+
107+
[Back to Top](#table-of-contents)
108+
109+
First, you'll configure your local environment. These steps are required once before you can deploy any models.
110+
111+
<a name="clone-repo"></a>
112+
### 3.1. Clone the Repository
113+
114+
```bash
115+
git clone https://github.com/ai-hypercomputer/gpu-recipes.git
116+
cd gpu-recipes
117+
export REPO_ROOT=$(pwd)
118+
export RECIPE_ROOT=$REPO_ROOT/inference/a3mega/llama3.1-70b/trtllm-gke
119+
```
120+
121+
<a name="configure-vars"></a>
122+
### 3.2. Configure Environment Variables
123+
124+
This is the most critical step. These variables are used in subsequent commands to target the correct resources.
125+
126+
```bash
127+
export PROJECT_ID=<PROJECT_ID>
128+
export CLUSTER_REGION=<REGION_of_your_cluster>
129+
export CLUSTER_NAME=<YOUR_GKE_CLUSTER_NAME>
130+
export KUEUE_NAME=<YOUR_KUEUE_NAME>
131+
export GCS_BUCKET=<your-gcs-bucket-for-logs>
132+
export TRTLLM_VERSION=1.3.0rc3
133+
134+
# Set the project for gcloud commands
135+
gcloud config set project $PROJECT_ID
136+
```
137+
138+
Replace the following values:
139+
140+
| Variable | Description | Example |
141+
| --------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
142+
| `PROJECT_ID` | Your Google Cloud Project ID. | `gcp-project-12345` |
143+
| `CLUSTER_REGION` | The GCP region where your GKE cluster is located. | `us-central1` |
144+
| `CLUSTER_NAME` | The name of your GKE cluster. | `a3-mega` |
145+
| `KUEUE_NAME` | The name of the Kueue local queue. The default queue created by the cluster toolkit is `a3mega`. Verify the name in your cluster. | `a3mega` |
146+
| `ARTIFACT_REGISTRY` | Full path to your Artifact Registry repository. | `us-central1-docker.pkg.dev/gcp-project-12345/my-repo` |
147+
| `GCS_BUCKET` | Name of your GCS bucket (do not include `gs://`). | `my-benchmark-logs-bucket` |
148+
| `TRTLLM_VERSION` | The tag/version for the Docker image. Other verions can be found at [NGC Catalog](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/tensorrt-llm/containers/release) | `1.3.0rc3` |
149+
150+
151+
<a name="connect-cluster"></a>
152+
### 3.3. Connect to your GKE Cluster
153+
154+
Fetch credentials for `kubectl` to communicate with your cluster.
155+
156+
```bash
157+
gcloud container clusters get-credentials $CLUSTER_NAME --region $CLUSTER_REGION
158+
```
159+
160+
<a name="get-hf-token"></a>
161+
### 3.4. Get Hugging Face token
162+
163+
To access models through Hugging Face, you'll need a Hugging Face token.
164+
1. Create a [Hugging Face account](https://huggingface.co/) if you don't have one.
165+
2. For **gated models** like Llama 4, ensure you have requested and been granted access on Hugging Face before proceeding.
166+
3. Generate an Access Token: Go to **Your Profile > Settings > Access Tokens**.
167+
4. Select **New Token**.
168+
5. Specify a Name and a Role of at least `Read`.
169+
6. Select **Generate a token**.
170+
7. Copy the generated token to your clipboard. You'll use this later.
171+
172+
173+
<a name="setup-hf-secret"></a>
174+
### 3.5. Create Hugging Face Kubernetes Secret
175+
176+
Create a Kubernetes Secret with your Hugging Face token to enable the pod to download model checkpoints from Hugging Face.
177+
178+
```bash
179+
# Paste your Hugging Face token here
180+
export HF_TOKEN=<YOUR_HUGGINGFACE_TOKEN>
181+
182+
kubectl create secret generic hf-secret \
183+
--from-literal=hf_api_token=${HF_TOKEN} \
184+
--dry-run=client -o yaml | kubectl apply -f -
185+
```
186+
187+
<a name="run-the-recipe"></a>
188+
## 4. Run the recipe
189+
190+
[Back to Top](#table-of-contents)
191+
192+
> [!NOTE]
193+
> After running the recipe with `helm install`, it can take **up to 30 minutes** for the deployment to become fully available. This is because the GKE node must first pull the Docker image and then download the model weights from Hugging Face.
194+
195+
> [!TIP]
196+
> You can use the [NVIDIA Model Optimizer](https://github.com/NVIDIA/Model-Optimizer/tree/main/examples/llm_ptq) to quantize these models to FP8.
197+
198+
<a name="supported-models"></a>
199+
### 4.1. Supported Models
200+
201+
[Back to Top](#table-of-contents)
202+
203+
This recipe supports the following models. Running TRTLLM inference benchmarking on these models are only tested and validated on A3-Mega GKE nodes with certain combination of TP, PP, EP, number of GPU chips, input & output sequence length, precision, etc.
204+
205+
As the PyTorch backend requires pre-quantized models for optimal performance, we use the FP8 quantized version for Llama 3.1 70B.
206+
207+
| Model Name | Hugging Face ID | Configuration File | Release Name Suffix |
208+
| :--- | :--- | :--- | :--- |
209+
| **Llama 3.1 70B (FP8)** | `nvidia/Llama-3.1-70B-Instruct-FP8` | `llama3.1-70b.yaml` | `llama-3-1-70b` |
210+
211+
> [!TIP]
212+
> You can use the NVIDIA Model Optimizer to quantize these models to FP8.
213+
214+
<a name="deploy-model"></a>
215+
### 4.2. Deploy and Benchmark a Model
216+
217+
[Back to Top](#table-of-contents)
218+
219+
The recipe uses [`trtllm-bench`](https://github.com/NVIDIA/TensorRT-LLM/blob/main/docs/source/legacy/performance/perf-benchmarking.md), a command-line tool from NVIDIA to benchmark the performance of TensorRT-LLM engine.
220+
221+
1. **Configure model-specific variables.** Choose a model from the [table above](#supported-models) and set the variables:
222+
223+
```bash
224+
# Example for Llama 3.1 70B (FP8)
225+
export HF_MODEL_ID="nvidia/Llama-3.1-70B-Instruct-FP8"
226+
export CONFIG_FILE="llama3.1-70b.yaml"
227+
export RELEASE_NAME="$USER-llama-3-1-70b"
228+
```
229+
230+
2. **Install the helm chart.** You can run a single benchmark configuration or a sequence of multiple experiments by indexing the `experiments` list.
231+
232+
```bash
233+
cd $RECIPE_ROOT
234+
helm install -f values.yaml \
235+
--set workload.benchmarks.experiments[0].isl=128 \
236+
--set workload.benchmarks.experiments[0].osl=128 \
237+
--set workload.benchmarks.experiments[0].num_requests=1000 \
238+
--set-file workload_launcher=$REPO_ROOT/src/launchers/trtllm-launcher.sh \
239+
--set-file serving_config=$REPO_ROOT/src/frameworks/a3mega/trtllm-configs/${CONFIG_FILE} \
240+
--set queue=${KUEUE_NAME} \
241+
--set "volumes.gcsMounts[0].bucketName=${GCS_BUCKET}" \
242+
--set workload.model.name=${HF_MODEL_ID} \
243+
--set workload.image=nvcr.io/nvidia/tensorrt-llm/release:${TRTLLM_VERSION} \
244+
--set workload.framework=trtllm \
245+
${RELEASE_NAME} \
246+
$REPO_ROOT/src/helm-charts/a3mega/trtllm-inference/single-node
247+
```
248+
> [!NOTE]
249+
> You can modify the benchmark configuration at runtime by changing the values for `isl`, `osl`, and `num_requests` (number of prompts) in the Helm command to test different scenarios.
250+
251+
3. **Check the deployment status:**
252+
253+
```bash
254+
kubectl get deployment/${RELEASE_NAME}-serving
255+
```
256+
257+
Wait until the `READY` column shows `1/1`. See the [Monitoring and Troubleshooting](#monitoring) section to view the deployment logs.
258+
259+
<a name="monitoring"></a>
260+
## 5. Monitoring and Troubleshooting
261+
262+
[Back to Top](#table-of-contents)
263+
264+
After the model is deployed via Helm as described in the sections [above](#run-the-recipe), use the following steps to monitor the deployment and interact with the model. Replace `<deployment-name>` and `<service-name>` with the appropriate names from the model-specific deployment instructions (e.g., `$USER-llama3.1-70b` and `$USER-llama3.1-70b-svc`).
265+
266+
<a name="check-status"></a>
267+
### 5.1. Check Deployment Status
268+
269+
Check the status of your deployment. Replace the name if you deployed a different model.
270+
271+
```bash
272+
kubectl get deployment/$RELEASE_NAME-serving
273+
```
274+
275+
Wait until the `READY` column shows `1/1`. If it shows `0/1`, the pod is still starting up.
276+
277+
> [!NOTE]
278+
> In the GKE UI on Cloud Console, you might see a status of "Does not have minimum availability" during startup. This is normal and will resolve once the pod is ready.
279+
280+
<a name="view-logs"></a>
281+
### 5.2. View Logs
282+
283+
To see the logs from the TRTLLM server (useful for debugging), use the `-f` flag to follow the log stream:
284+
285+
```bash
286+
kubectl logs -f deployment/$RELEASE_NAME-serving
287+
```
288+
289+
You should see logs indicating preparing the model, and then running the throughput benchmark test, similar to this:
290+
291+
```bash
292+
Running benchmark for nvidia/Llama3.1-70b with ISL=128, OSL=128, TP=8, EP=1, PP=1
293+
294+
===========================================================
295+
PYTORCH BACKEND
296+
===========================================================
297+
Model: nvidia/Llama-3.1-70B-Instruct-FP8
298+
Model Path: /ssd/nvidia/Llama-3.1-70B-Instruct-FP8
299+
TensorRT LLM Version: 1.2
300+
Dtype: bfloat16
301+
KV Cache Dtype: FP8
302+
Quantization: FP8
303+
304+
===========================================================
305+
REQUEST DETAILS
306+
===========================================================
307+
Number of requests: 1000
308+
Number of concurrent requests: 985.9849
309+
Average Input Length (tokens): 128.0000
310+
Average Output Length (tokens): 128.0000
311+
===========================================================
312+
WORLD + RUNTIME INFORMATION
313+
===========================================================
314+
TP Size: 8
315+
PP Size: 1
316+
EP Size: 1
317+
Max Runtime Batch Size: 2304
318+
Max Runtime Tokens: 4608
319+
Scheduling Policy: GUARANTEED_NO_EVICT
320+
KV Memory Percentage: 85.00%
321+
Issue Rate (req/sec): 8.3913E+13
322+
323+
===========================================================
324+
PERFORMANCE OVERVIEW
325+
===========================================================
326+
Request Throughput (req/sec): X.XX
327+
Total Output Throughput (tokens/sec): X.XX
328+
Total Token Throughput (tokens/sec): X.XX
329+
Total Latency (ms): X.XX
330+
Average request latency (ms): X.XX
331+
Per User Output Throughput [w/ ctx] (tps/user): X.XX
332+
Per GPU Output Throughput (tps/gpu): X.XX
333+
334+
-- Request Latency Breakdown (ms) -----------------------
335+
336+
[Latency] P50 : X.XX
337+
[Latency] P90 : X.XX
338+
[Latency] P95 : X.XX
339+
[Latency] P99 : X.XX
340+
[Latency] MINIMUM: X.XX
341+
[Latency] MAXIMUM: X.XX
342+
[Latency] AVERAGE: X.XX
343+
344+
===========================================================
345+
DATASET DETAILS
346+
===========================================================
347+
Dataset Path: /ssd/token-norm-dist_llama3.1-70b_128_128_tp8.json
348+
Number of Sequences: 1000
349+
350+
-- Percentiles statistics ---------------------------------
351+
352+
Input Output Seq. Length
353+
-----------------------------------------------------------
354+
MIN: 128.0000 128.0000 256.0000
355+
MAX: 128.0000 128.0000 256.0000
356+
AVG: 128.0000 128.0000 256.0000
357+
P50: 128.0000 128.0000 256.0000
358+
P90: 128.0000 128.0000 256.0000
359+
P95: 128.0000 128.0000 256.0000
360+
P99: 128.0000 128.0000 256.0000
361+
===========================================================
362+
```
363+
364+
<a name="cleanup"></a>
365+
## 6. Cleanup
366+
367+
To avoid incurring further charges, clean up the resources you created.
368+
369+
1. **Uninstall the Helm Release:**
370+
371+
First, list your releases to get the deployed models:
372+
373+
```bash
374+
# list deployed models
375+
helm list --filter $USER
376+
```
377+
378+
Then, uninstall the desired release:
379+
380+
```bash
381+
helm uninstall <release_name>
382+
```
383+
Replace `<release_name>` with the helm release names listed.
384+
385+
2. **Delete the Kubernetes Secret:**
386+
387+
```bash
388+
kubectl delete secret hf-secret --ignore-not-found=true
389+
```
390+
391+
3. (Optional) Delete the built Docker image from Artifact Registry if no longer needed.
392+
4. (Optional) Delete Cloud Build logs.
393+
5. (Optional) Clean up files in your GCS bucket if benchmarking was performed.
394+
6. (Optional) Delete the [test environment](#test-environment) provisioned including GKE cluster.

0 commit comments

Comments
 (0)