actaug GR00T train+eval bundle: code (save-at/stop-at), eval stack (porting fixes), subset builder, protocol docs
38dc077 verified Download code/myGR00T/deployment_scripts/trt_model_forward.py from Ronaldo-GOAT/actaug-gr00t-train-eval: direct link, hf CLI and curl.
- Browser
- Download file 8.94 kB
-
https://huggingface.co/Ronaldo-GOAT/actaug-gr00t-train-eval/resolve/main/code/myGR00T/deployment_scripts/trt_model_forward.py
- Command line
-
hf download hf://Ronaldo-GOAT/actaug-gr00t-train-eval/code/myGR00T/deployment_scripts/trt_model_forward.py
-
curl -L -o trt_model_forward.py https://huggingface.co/Ronaldo-GOAT/actaug-gr00t-train-eval/resolve/main/code/myGR00T/deployment_scripts/trt_model_forward.py
8.94 kB
| # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| import os | |
| from functools import partial | |
| import torch | |
| import trt_torch as trt | |
| from transformers.feature_extraction_utils import BatchFeature | |
| def eagle_tensorrt_forward(self, vl_input): | |
| eagle_prefix = "eagle_" | |
| eagle_input = { | |
| k.removeprefix(eagle_prefix): v for k, v in vl_input.items() if k.startswith(eagle_prefix) | |
| } | |
| del eagle_input["image_sizes"] | |
| vl_input = eagle_input | |
| self.set_frozen_modules_to_eval_mode() | |
| batch_size = vl_input["pixel_values"].shape[0] | |
| position_ids = torch.arange(self.num_patches, device="cuda").expand((batch_size, -1)) | |
| if vl_input["pixel_values"].dtype != torch.float16: | |
| vl_input["pixel_values"] = vl_input["pixel_values"].to(torch.float16) | |
| assert ( | |
| vl_input["pixel_values"].shape[0] <= 8 | |
| ), "Batch size must be <= 8 because TensorRT engine was built with max_batch_size=8, you can try to adjust the max_batch_size in the build_engine.sh script and rebuild the engine." | |
| self.vit_engine.set_runtime_tensor_shape("pixel_values", vl_input["pixel_values"].shape) | |
| self.vit_engine.set_runtime_tensor_shape("position_ids", position_ids.shape) | |
| vit_embeds = self.vit_engine(vl_input["pixel_values"], position_ids)["vit_embeds"] | |
| self.llm_engine.set_runtime_tensor_shape("input_ids", vl_input["input_ids"].shape) | |
| self.llm_engine.set_runtime_tensor_shape("vit_embeds", vit_embeds.shape) | |
| self.llm_engine.set_runtime_tensor_shape("attention_mask", vl_input["attention_mask"].shape) | |
| embeddings = self.llm_engine(vl_input["input_ids"], vit_embeds, vl_input["attention_mask"])[ | |
| "embeddings" | |
| ] | |
| return BatchFeature( | |
| data={ | |
| "backbone_features": embeddings, | |
| "backbone_attention_mask": vl_input["attention_mask"], | |
| } | |
| ) | |
| def action_head_tensorrt_forward(self, backbone_output, action_input): | |
| # backbone_output = self.process_backbone_output(backbone_output) | |
| if backbone_output.backbone_features.dtype != torch.float16: | |
| backbone_output.backbone_features = backbone_output.backbone_features.to(torch.float16) | |
| self.vlln_vl_self_attention_engine.set_runtime_tensor_shape( | |
| "backbone_features", backbone_output.backbone_features.shape | |
| ) | |
| backbone_output.backbone_features = self.vlln_vl_self_attention_engine( | |
| backbone_output.backbone_features | |
| )["output"] | |
| vl_embeds = backbone_output.backbone_features | |
| embodiment_id = action_input.embodiment_id | |
| batch_size = vl_embeds.shape[0] | |
| if action_input.state.dtype != torch.float16: | |
| action_input.state = action_input.state.to(torch.float16) | |
| if embodiment_id.dtype != torch.int64: | |
| embodiment_id = embodiment_id.to(torch.int64) | |
| if vl_embeds.dtype != torch.float16: | |
| vl_embeds = vl_embeds.to(torch.float16) | |
| # Embed state with batch processing | |
| self.state_encoder_engine.set_runtime_tensor_shape("state", action_input.state.shape) | |
| self.state_encoder_engine.set_runtime_tensor_shape("embodiment_id", embodiment_id.shape) | |
| state_features = self.state_encoder_engine(action_input.state, embodiment_id)["output"] | |
| # Set initial actions as the sampled noise. | |
| device = vl_embeds.device | |
| actions = torch.randn( | |
| size=(batch_size, self.config.action_horizon, self.config.action_dim), | |
| dtype=vl_embeds.dtype, | |
| device=device, | |
| ) | |
| # This attribute is used to ensure the same actions is used for both PyTorch and TensorRT inference | |
| if hasattr(self, "init_actions"): | |
| actions = self.init_actions.expand((batch_size, -1, -1)) | |
| num_steps = self.num_inference_timesteps | |
| dt = 1.0 / num_steps | |
| for t in range(num_steps): | |
| t_cont = t / float(num_steps) # e.g. goes 0, 1/N, 2/N, ... | |
| t_discretized = int(t_cont * self.num_timestep_buckets) | |
| # Embed noised action trajectory with batch processing | |
| timesteps_tensor = torch.full(size=(batch_size,), fill_value=t_discretized, device=device) | |
| self.action_encoder_engine.set_runtime_tensor_shape("actions", actions.shape) | |
| self.action_encoder_engine.set_runtime_tensor_shape( | |
| "timesteps_tensor", timesteps_tensor.shape | |
| ) | |
| self.action_encoder_engine.set_runtime_tensor_shape("embodiment_id", embodiment_id.shape) | |
| action_features = self.action_encoder_engine(actions, timesteps_tensor, embodiment_id)[ | |
| "output" | |
| ] | |
| # Maybe add position embedding. | |
| if self.config.add_pos_embed: | |
| pos_ids = torch.arange(action_features.shape[1], dtype=torch.long, device=device) | |
| pos_embs = self.position_embedding(pos_ids).unsqueeze(0).to(torch.float16) | |
| action_features = action_features + pos_embs | |
| vl_embs = vl_embeds | |
| # Join vision, language, state and action embedding along sequence dimension. | |
| sa_embs = torch.cat((state_features, action_features), dim=1) | |
| # Run model forward with batch processing | |
| if vl_embs.dtype != torch.float16: | |
| vl_embs = vl_embs.to(torch.float16) | |
| self.DiT_engine.set_runtime_tensor_shape("vl_embs", vl_embs.shape) | |
| self.DiT_engine.set_runtime_tensor_shape("sa_embs", sa_embs.shape) | |
| self.DiT_engine.set_runtime_tensor_shape("timesteps_tensor", timesteps_tensor.shape) | |
| model_output = self.DiT_engine(sa_embs, vl_embs, timesteps_tensor)["output"] | |
| self.action_decoder_engine.set_runtime_tensor_shape("model_output", model_output.shape) | |
| self.action_decoder_engine.set_runtime_tensor_shape("embodiment_id", embodiment_id.shape) | |
| pred = self.action_decoder_engine(model_output, embodiment_id)["output"] | |
| pred_velocity = pred[:, -self.action_horizon :] | |
| # Update actions using euler integration. | |
| actions = actions + dt * pred_velocity | |
| return BatchFeature(data={"action_pred": actions}) | |
| def setup_tensorrt_engines(policy, trt_engine_path): | |
| """ | |
| Setup TensorRT engines for GR00T model inference. | |
| Args: | |
| policy: GR00T policy model instance | |
| """ | |
| policy.model.backbone.num_patches = ( | |
| policy.model.backbone.eagle_model.vision_model.vision_model.embeddings.num_patches | |
| ) | |
| if hasattr(policy.model.backbone.eagle_model, "vision_model"): | |
| del policy.model.backbone.eagle_model.vision_model | |
| if hasattr(policy.model.backbone.eagle_model, "language_model"): | |
| del policy.model.backbone.eagle_model.language_model | |
| if hasattr(policy.model.action_head, "vlln"): | |
| del policy.model.action_head.vlln | |
| if hasattr(policy.model.action_head, "vl_self_attention"): | |
| del policy.model.action_head.vl_self_attention | |
| if hasattr(policy.model.action_head, "model"): | |
| del policy.model.action_head.model | |
| if hasattr(policy.model.action_head, "state_encoder"): | |
| del policy.model.action_head.state_encoder | |
| if hasattr(policy.model.action_head, "action_encoder"): | |
| del policy.model.action_head.action_encoder | |
| if hasattr(policy.model.action_head, "action_decoder"): | |
| del policy.model.action_head.action_decoder | |
| torch.cuda.empty_cache() | |
| # Setup backbone engines | |
| policy.model.backbone.vit_engine = trt.Engine(os.path.join(trt_engine_path, "vit.engine")) | |
| policy.model.backbone.llm_engine = trt.Engine(os.path.join(trt_engine_path, "llm.engine")) | |
| # Setup action head engines | |
| policy.model.action_head.vlln_vl_self_attention_engine = trt.Engine( | |
| os.path.join(trt_engine_path, "vlln_vl_self_attention.engine") | |
| ) | |
| policy.model.action_head.action_encoder_engine = trt.Engine( | |
| os.path.join(trt_engine_path, "action_encoder.engine") | |
| ) | |
| policy.model.action_head.action_decoder_engine = trt.Engine( | |
| os.path.join(trt_engine_path, "action_decoder.engine") | |
| ) | |
| policy.model.action_head.DiT_engine = trt.Engine(os.path.join(trt_engine_path, "DiT.engine")) | |
| policy.model.action_head.state_encoder_engine = trt.Engine( | |
| os.path.join(trt_engine_path, "state_encoder.engine") | |
| ) | |
| # Set TensorRT forward functions | |
| policy.model.backbone.forward = partial(eagle_tensorrt_forward, policy.model.backbone) | |
| policy.model.action_head.get_action = partial( | |
| action_head_tensorrt_forward, policy.model.action_head | |
| ) | |