Skip to content

Commit e6445b7

Browse files
committed
A4 & A4X TRTLLM GKE Single-Host Inference Recipes, ReadMe and Config Files
1 parent efe118b commit e6445b7

11 files changed

Lines changed: 573 additions & 35 deletions

File tree

inference/a4/single-host-serving/tensorrt-llm/README.md

Lines changed: 398 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
queue:
16+
17+
dwsSettings:
18+
maxRunDurationSeconds:
19+
20+
huggingface:
21+
secretName: hf-secret
22+
secretData:
23+
token: "hf_api_token"
24+
25+
volumes:
26+
gcsVolumes: true
27+
ssdMountPath: "/ssd"
28+
gcsMounts:
29+
- bucketName:
30+
mountPath: "/gcs"
31+
32+
service:
33+
type: ClusterIP
34+
ports:
35+
http: 8000
36+
37+
workload:
38+
model:
39+
name:
40+
gpus: 4
41+
image:
42+
framework:
43+
configFile: serving-args.yaml
44+
configPath: /workload/configs
45+
envs:
46+
- name: HF_HUB_ENABLE_HF_TRANSFER
47+
value: "1"
48+
- name: LAUNCHER_SCRIPT
49+
value: "/workload/launcher/launch-workload.sh"
50+
- name: SERVER_ARGS_FILE
51+
value: "/workload/configs/serving-args.yaml"
52+
- name: HF_HOME
53+
value: "/ssd"
54+
- name: LD_LIBRARY_PATH
55+
value: "/usr/local/nvidia/lib64:/usr/local/lib/"
56+
benchmarks:
57+
experiments:
58+
- isl: 1024
59+
osl: 4096
60+
num_requests: 1000
61+
62+
network:
63+
subnetworks[]:
64+
gibVersion: us-docker.pkg.dev/gce-ai-infra/gpudirect-gib/nccl-plugin-gib:v1.0.5
65+
ncclSettings:
66+
- name: NCCL_DEBUG
67+
value: "VERSION"

inference/a4x/single-host-serving/tensorrt-llm/README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export CLUSTER_REGION=<REGION_of_your_cluster>
129129
export CLUSTER_NAME=<YOUR_GKE_CLUSTER_NAME>
130130
export KUEUE_NAME=<YOUR_KUEUE_NAME>
131131
export GCS_BUCKET=<your-gcs-bucket-for-logs>
132-
export TRTLLM_VERSION=1.2.0rc2
132+
export TRTLLM_VERSION=1.3.0rc5
133133

134134
# Set the project for gcloud commands
135135
gcloud config set project $PROJECT_ID
@@ -201,7 +201,9 @@ This recipe supports the following models. You can easily swap between them by c
201201

202202
| Model Name | Hugging Face ID | Configuration File | Release Name Suffix |
203203
| :--- | :--- | :--- | :--- |
204-
| **DeepSeek-R1 671B** | `nvidia/DeepSeek-R1-NVFP4-v2` | `deepseek-r1-nvfp4.yaml` | `deepseek-r1-model` |
204+
| **DeepSeek-R1 671B** | `nvidia/DeepSeek-R1-NVFP4-v2` | `deepseek-r1-nvfp4.yaml` | `deepseek-r1` |
205+
| **Llama 3.1 405B NVFP4** | `nvidia/Llama-3.1-405B-Instruct-NVFP4` | `llama-3.1-405b.yaml` | `llama-3-1-405b-nvfp4` |
206+
| **Llama 3.1 405B FP8** | `meta-llama/Llama-3.1-405B-Instruct-FP8` | `llama-3.1-405b.yaml` | `llama-3-1-405b-fp8` |
205207
| **Llama 3.1 70B** | `meta-llama/Llama-3.1-70B-Instruct` | `llama-3.1-70b.yaml` | `llama-3-1-70b` |
206208
| **Llama 3.1 8B** | `meta-llama/Llama-3.1-8B-Instruct` | `llama-3.1-8b.yaml` | `llama-3-1-8b` |
207209
| **Qwen 3 32B** | `Qwen/Qwen3-32B` | `qwen3-32b.yaml` | `qwen3-32b` |
@@ -223,10 +225,10 @@ The recipe uses [`trtllm-bench`](https://github.com/NVIDIA/TensorRT-LLM/blob/mai
223225
1. **Configure model-specific variables.** Choose a model from the [table above](#supported-models) and set the variables:
224226

225227
```bash
226-
# Example for Llama 3.1 70B
227-
export HF_MODEL_ID="meta-llama/Llama-3.1-70B-Instruct"
228-
export CONFIG_FILE="llama-3.1-70b.yaml"
229-
export RELEASE_NAME="$USER-serving-llama-3-1-70b"
228+
# Example for DeepSeek-R1 NVFP4
229+
export HF_MODEL_ID="nvidia/DeepSeek-R1-NVFP4-v2"
230+
export CONFIG_FILE="deepseek-r1-nvfp4.yaml"
231+
export RELEASE_NAME="$USER-serving-deepseek-r1"
230232
```
231233

232234
2. **Install the helm chart:**
@@ -258,7 +260,7 @@ The recipe uses [`trtllm-bench`](https://github.com/NVIDIA/TensorRT-LLM/blob/mai
258260

259261
[Back to Top](#table-of-contents)
260262

261-
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-serving-deepseek-r1-model` and `$USER-serving-deepseek-r1-model-svc`).
263+
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-serving-deepseek-r1` and `$USER-serving-deepseek-r1-svc`).
262264

263265

264266
<a name="check-status"></a>
@@ -268,7 +270,7 @@ Check the status of your deployment. Replace the name if you deployed a differen
268270

269271
```bash
270272
# Example for DeepSeek-R1 671B
271-
kubectl get deployment/$USER-serving-deepseek-r1-model
273+
kubectl get deployment/$USER-serving-deepseek-r1
272274
```
273275

274276
Wait until the `READY` column shows `1/1`. If it shows `0/1`, the pod is still starting up.
@@ -282,7 +284,7 @@ Wait until the `READY` column shows `1/1`. If it shows `0/1`, the pod is still s
282284
To see the logs from the TRTLLM server (useful for debugging), use the `-f` flag to follow the log stream:
283285

284286
```bash
285-
kubectl logs -f deployment/$USER-serving-deepseek-r1-model
287+
kubectl logs -f deployment/$USER-serving-deepseek-r1
286288
```
287289

288290
You should see logs indicating preparing the model, and then running the throughput benchmark test, similar to this:

inference/a4x/single-host-serving/tensorrt-llm/values.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ workload:
5151
value: "/workload/configs/serving-args.yaml"
5252
benchmarks:
5353
experiments:
54-
- isl: 128
55-
osl: 128
54+
- isl: 1024
55+
osl: 1024
5656
num_requests: 1000
5757

5858
network:
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
tp_size: 4
2+
ep_size: 4
3+
pp_size: 1
4+
backend: pytorch
5+
kv_cache_free_gpu_mem_fraction: 0.85
6+
llm_api_args:
7+
cuda_graph_config:
8+
batch_sizes:
9+
- 1
10+
- 2
11+
- 4
12+
- 8
13+
- 16
14+
- 20
15+
- 24
16+
- 32
17+
- 64
18+
- 96
19+
- 128
20+
- 160
21+
- 192
22+
- 256
23+
- 320
24+
- 384
25+
- 512
26+
enable_padding: true
27+
enable_attention_dp: true
28+
enable_chunked_prefill: true
29+
kv_cache_config:
30+
dtype: auto
31+
enable_block_reuse: false
32+
free_gpu_memory_fraction: 0.85
33+
moe_config:
34+
backend: CUTLASS
35+
print_iter_log: true
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
tp_size: 1
2+
pp_size: 1
3+
backend: pytorch
4+
kv_cache_free_gpu_mem_fraction: 0.90
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
tp_size: 1
2+
pp_size: 1
3+
backend: pytorch
4+
kv_cache_free_gpu_mem_fraction: 0.90
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
tp_size: 4
2+
pp_size: 1
3+
backend: pytorch
4+
kv_cache_free_gpu_mem_fraction: 0.90

src/helm-charts/a4/inference-templates/deployment/templates/serving-launcher.yaml

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ spec:
171171
{{- end }}
172172
- name: NCCL_PLUGIN_PATH
173173
value: /usr/local/gib/lib64
174+
- name: LD_LIBRARY_PATH
175+
value: /usr/local/gib/lib64:/usr/local/nvidia/lib64
174176
{{- if $root.Values.network.gibVersion }}
175177
- name: NCCL_INIT_SCRIPT
176178
value: "/usr/local/gib/scripts/set_nccl_env.sh"
@@ -180,6 +182,8 @@ spec:
180182
value: "{{ $root.Values.workload.model.name }}"
181183
- name: MODEL_DOWNLOAD_DIR
182184
value: "/ssd/{{ $root.Values.workload.model.name }}"
185+
- name: TRTLLM_DIR
186+
value: "/app/tensorrt_llm"
183187
{{- if $root.Values.workload.envs }}
184188
{{- toYaml .Values.workload.envs | nindent 12 }}
185189
{{- end }}
@@ -189,6 +193,7 @@ spec:
189193
args:
190194
- |
191195
#!/bin/bash
196+
pip install pyyaml hf_transfer
192197
193198
if [[ -n "${NCCL_INIT_SCRIPT}" ]]; then
194199
echo "Running NCCL init script: ${NCCL_INIT_SCRIPT}"
@@ -203,30 +208,46 @@ spec:
203208
fi
204209
205210
ARGS=()
211+
EXTRA_ARGS_FILE="/tmp/extra_llm_api_args.yaml"
206212
207-
if [ -f "$SERVER_ARGS_FILE" ]; then
208-
echo "Loading server arguments from ConfigMap"
209-
while IFS=': ' read -r key value || [ -n "$key" ]; do
210-
[[ -z "$key" || "$key" == \#* ]] && continue
211-
key=$(echo "$key" | xargs)
212-
value=$(echo "$value" | xargs)
213+
# Use Python to parse the main config file, extract llm_api_args,
214+
# and generate the command-line arguments.
215+
python -c "
216+
import yaml
217+
import sys
213218
214-
if [ -n "$key" ]; then
215-
# Handle boolean values
216-
if [[ "$value" == "true" ]]; then
217-
# For true values, just add the flag without a value
218-
ARGS+=("--$key")
219-
elif [[ "$value" == "false" ]]; then
220-
ARGS+=("--$key" "false")
221-
elif [ -n "$value" ]; then
222-
# For non-boolean values, add both the flag and its value
223-
ARGS+=("--$key" "$value")
224-
else
225-
ARGS+=("--$key")
226-
fi
227-
fi
228-
done < "$SERVER_ARGS_FILE"
229-
fi
219+
args = []
220+
llm_api_args = {}
221+
config_file = sys.argv[1]
222+
extra_args_file = sys.argv[2]
223+
224+
try:
225+
with open(config_file, 'r') as f:
226+
config = yaml.safe_load(f)
227+
228+
if 'llm_api_args' in config:
229+
llm_api_args = config.pop('llm_api_args')
230+
with open(extra_args_file, 'w') as f:
231+
yaml.dump(llm_api_args, f)
232+
233+
for key, value in config.items():
234+
if value is True:
235+
args.append(f'--{key}')
236+
elif value is not False:
237+
args.append(f'--{key}')
238+
args.append(str(value))
239+
240+
# Print the arguments for the shell script to capture
241+
print(' '.join(args))
242+
243+
except Exception as e:
244+
print(f'Error parsing config file: {e}', file=sys.stderr)
245+
sys.exit(1)
246+
" "$SERVER_ARGS_FILE" "$EXTRA_ARGS_FILE" > /tmp/launcher_args.txt
247+
248+
# Read the generated arguments into the ARGS array
249+
mapfile -t ARGS < <(tr ' ' '\n' < /tmp/launcher_args.txt)
250+
rm /tmp/launcher_args.txt
230251
231252
{{ if eq $root.Values.workload.framework "trtllm" }}
232253
{{- range $root.Values.workload.benchmarks.experiments }}

src/helm-charts/a4x/inference-templates/deployment/templates/serving-launcher.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,5 +278,7 @@ spec:
278278
resources:
279279
requests:
280280
nvidia.com/gpu: {{ $gpusPerNode }}
281+
memory: "800Gi"
281282
limits:
282-
nvidia.com/gpu: {{ $gpusPerNode }}
283+
nvidia.com/gpu: {{ $gpusPerNode }}
284+
memory: "1000Gi"

0 commit comments

Comments
 (0)