Generated banner for Tao Port Huggingface Model
Generated logo for Tao Port Huggingface Model

Tao Port Huggingface Model

NVIDIAOfficialCreated by NVIDIA Corporation

  • Skill
  • Workflow
  • Software development
  • Apache-2.0
  • Medium risk

From the author

Integrate a HuggingFace Computer Vision model into the NVIDIA TAO Toolkit ecosystem (tao-core config, tao-pytorch trainer, tao-deploy TensorRT pipeline). Use when the user asks to "integrate a HuggingFace model into TAO", "add an HF model to TAO Toolkit", "wire a HuggingFace ViT/DETR/ SegFormer into tao-pytorch", "build a TAO trainer + deploy pipeline for an HF CV model", or pastes a HuggingFace model URL/ID and wants it turned into a TAO model. Covers the full 7-phase loop: prerequisites check, HuggingFace inspection and validation, codebase exploration, tao-core configuration and native trainer implementation, ONNX export plus TensorRT deploy integration, packaging and L0 testing, container-based end-to-end validation, and (conditional) accuracy/latency tuning. Supports classification, object detection, semantic / instance / panoptic segmentation, zero-shot detection, and depth estimation.
— the description by NVIDIA Corporation

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured, seven-phase workflow for porting HuggingFace Computer Vision models into the NVIDIA TAO Toolkit. It guides the user through inspecting the model, configuring the TAO core, implementing the trainer, and setting up the deployment pipeline for TensorRT. The process emphasizes a local-only development loop, requiring the user to manage four independent repository clones and execute all validation, testing, and training tasks within locally prepared TAO Toolkit containers.

What it does

  • Validates HuggingFace model compatibility for computer vision tasks.
  • Configures TAO core and implements native trainers for PyTorch.
  • Integrates ONNX export and TensorRT deployment pipelines.
  • Automates packaging and L0 unit testing for model components.
  • Performs end-to-end validation within containerized environments.
  • Provides optional tuning for accuracy, latency, and model size.

When to use it

  • When you need to bring a custom HuggingFace computer vision model into the TAO Toolkit.
  • When you require a full training-to-deployment pipeline for a new model architecture.
  • When you need to verify model performance and exportability to TensorRT.
  • When you are working in a local environment with NVIDIA GPU support.

Advantages

  • Ensures consistency across training, export, and deployment stages.
  • Provides a rigorous, step-by-step debugging and testing loop.
  • Maintains environment isolation using containerized workflows.
  • Supports a wide range of computer vision tasks including detection and segmentation.

Usage examples

“Integrate a HuggingFace model into TAO.”
The agent initiates the Phase 0 prerequisite check to verify your environment and prepare the necessary TAO Toolkit container images.
“Wire a HuggingFace SegFormer into tao-pytorch.”
The agent begins the codebase exploration phase to map the model to the appropriate TAO reference architecture and prepare the configuration.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/nvidia/tao-port-huggingface-model/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip tao-port-huggingface-model.zip -d .agents/skills

Documentation by NVIDIA Corporation

Standalone install? If this session was not initialized by the TAO skill bank plugin, run the tao-setup skill first (host preflight, credentials, cross-skill discovery).

<!-- Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. 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. -->

TAO-HF Integration Skill

Integrate a HuggingFace (HF) Computer Vision model into the NVIDIA TAO Toolkit ecosystem. Work the phases iteratively — not purely linearly — via a build → test → debug → fix → retest loop at every step: when something fails, diagnose and fix before moving on; when it passes, move to the next step.

This SKILL.md is the workflow coordinator. Each phase has a dedicated references/phase-N-*.md with the full step-by-step content, code, docker invocations, and gates. Read the matching reference at the start of each phase — the summaries below are not sufficient.


Local-Only Rule

All work is strictly local. Do NOT push/commit/branch on any remote (GitLab, GitHub, HuggingFace), create merge/pull requests or issues, or upload/publish Docker images to any registry or artifact store. You may only read/clone from remotes — all edits, Docker builds, and test runs stay on the local machine.


Submodule Override Strategy

The user clones the four TAO repos (tao-core, tao-pytorch, tao-deploy, tao-dataservices) independently into one working directory. The tao-core/ submodule nested inside each repo points to the original unmodified commit; modifications only exist in the top-level tao-core/. Always install from the top-level tao-core/, never <repo>/tao-core/ — the nested submodule silently ignores all modifications. Override rules: (1) mount the working directory -v $(pwd):/workspace; (2) pip install /workspace/tao-core FIRST, before tao-pytorch/tao-deploy; (3) PYTHONPATH top-level tao-core first, e.g. -e PYTHONPATH=/workspace/tao-core:/workspace/tao-pytorch. See references/cross-cutting.md for the directory tree.


Execution platform

Every test, smoke run, and end-to-end validation executes inside a locally prepared TAO Toolkit container (tao-pytorch-base:latest, tao-deploy-base:latest, optionally tao-dataservices-base:latest — all from Phase 0). The platform skills own how to run them; this skill specifies what. Default platform: local-docker. Phase 0 delegates the driver / CUDA / NCT preflight to tao-setup-nvidia-gpu-host. See references/cross-cutting.md for the authoritative-skill table, bind-mount rationale, and canonical docker-run flag set.


Phase Map

PhaseGoalReference
0Prerequisites + TAO Toolkit images + local image tagsphase-0-prereqs.md
1Inputs, HF-inspection container, validate model + datasetphase-1-inspection.md, hf-inspection.md
2Closest existing TAO reference modelphase-2-codebase.md, task-type-guide.md
3tao-core config + tao-pytorch trainer / eval / inferencephase-3-implementation.md, tao-patterns.md, repo-structure.md
4ONNX export + tao-deploy TRT engine / inference / evalphase-4-deploy.md
5Packaging (console_scripts) + L0 testsphase-5-packaging.md
6Container testing + end-to-end validationphase-6-container-tests.md, docker-patterns.md
7(conditional) Accuracy / latency / size tuningphase-7-optimization.md

Cross-cutting refs: workflow-consistency.md (CLI flow, config field paths, cross-phase dependencies); cross-cutting.md (platform, isolation, module pitfalls, debugging).

IMPORTANT — Continuous Execution Through Phase 6: do NOT stop after Phases 3–5 to wait for the user to run tests. Phase 6 is mandatory — not complete until tests pass inside the containers and the end-to-end pipeline is validated.


Development Loop

At every step: write code → test immediately (import check, unit test, or dry-run) → if it fails, read traceback → diagnose → fix → retest; if it passes, move on. Do NOT accumulate untested code — testing only at the end compounds bugs.


Debugging Playbook

When something fails, consult the symptom → likely-cause → fix table in references/cross-cutting.md before trying random fixes — it covers ModuleNotFoundError, BACKBONE_REGISTRY KeyError, shape mismatch, NaN loss, ONNX/TRT build failures, TRT-vs-PyTorch accuracy gaps, OOM, DDP hangs, checkpoint load failures, and stale-submodule config issues.


Environment Isolation Strategy

All Python work runs inside Docker containers — no host venvs, no pip installs into host Python (the host needs only Docker, from tao-setup-nvidia-gpu-host). Three contexts: A (Phase 1 HF inspection in tao-hf-inspect, python:3.12-slim fallback), B (Phase 3/4/6 smoke/L0/e2e in the prepared container, source via pip install /workspace/tao-core && python setup.py develop), C (host-bind-mount scratch). See references/cross-cutting.md for the contexts in full and the four numbered rules verbatim (--check-only host packages; Phase 1 --user $(id -u):$(id -g) vs. root; HOME=/workspace/PIP_USER=1 fallback; distro package-manager list; root:root trade-off; tao-hf-inspect cleanup).


Phase 0 — Prerequisites Check

Goal: verify Python 3.10+ and git; delegate the driver / CUDA / Docker / NVIDIA Container Toolkit host check to tao-setup-nvidia-gpu-host; verify NGC docker login for nvcr.io. Then ask the user for the TAO Toolkit image references (tao-pytorch, tao-deploy, optionally tao-dataservices), pull, and prepare local tags tao-pytorch-base:latest, tao-deploy-base:latest, tao-dataservices-base:latest for later phases — preparation removes the pre-installed released TAO packages so the user's /workspace/... clones install/load via pip install /workspace/tao-core && python setup.py develop. Hard stop on any failed check. Required user inputs: the image references + credentials (NGC login, HF_TOKEN). Full commands, prompt wording, and per-image Dockerfile snippets: the Phase 0 reference.

Gate: all prerequisite checks pass; the user supplied the required image references; tao-pytorch-base:latest and tao-deploy-base:latest exist locally; tao-dataservices-base:latest exists if dataservices work is anticipated.


Phase 1 — Information Gathering & Validation

Goal: decide whether to proceed at all. Gather credentials, locate/clone the four TAO repos, create a consistent working branch, launch the tao-hf-inspect container (Context A), validate the HF model is CV with a supported pipeline_tag, extract config + state-dict schema, sanity-check ONNX export, clean up. Full steps: Phase 1 references.

Reject if: pipeline_tag is NLP / audio / LLM (non-CV); AutoConfig raises; or ONNX export fundamentally cannot work (no rewrite path).

Gate: all 4 TAO repos located/cloned with a consistent branch; pipeline_tag confirmed CV; model_type, image_size, hidden_size, num_labels extracted; state-dict keys documented + HF→TAO remapping plan drafted; ONNX export sanity check passed (or failure understood); user confirmed model_short_name + task type. (Full checklist: phase-1-inspection.md.) Present findings and get user confirmation first.


Phase 2 — Codebase Exploration

Goal: find the closest existing TAO reference model for the detected pipeline_tag, read its implementation across tao-core / tao-pytorch / tao-deploy, and decide whether the backbone exists in backbone_v2/ or is new.

The HF pipeline_tag → TAO reference model mapping (classification → classification_pyt, detection → dino/rtdetr, segmentation → segformer, instance → mask2former, panoptic → oneformer, zero-shot → grounding_dino, depth → mono_depth) drives everything downstream (config, architecture, loss, ONNX shape, TRT builder, deploy classes, metrics, dataset format). See the Phase 2 references for the full reference list (12 files per model), the backbone_v2/ and tao-dataservices coverage checks, and per-task architecture.

If a new backbone is needed, decide the strategy (timm wrap > re-implement > HF black-box wrap) before Phase 3 — it changes weight loading, ONNX export, deploy. Never dual-inherit from transformers.PreTrainedModel and BackboneBase (metaclass conflict — compose instead).

Gate: reference TAO model identified + all 12 reference locations read; task-type implications understood (architecture, loss, ONNX outputs, deploy classes, metrics, dataset); backbone coverage decided (reuse / wrap timm / new); dataservices coverage checked. (Full checklist: phase-2-codebase.md.)


Phase 3 — TAO Core Configuration & Native Implementation

Goal: write the tao-core config schema + the tao-pytorch trainer / native inference / evaluation, smoke-testing between steps. (<model_name> = snake_case short-name; <ModelName> = PascalCase.)

Steps 1–7 (each builds on the previous, smoke-test between): tao-core config (1), tao-pytorch trainer (2), multi-GPU/multi-node (3), native inference → result.csv (4), native evaluation → results.json (5), MLOps for training and eval/infer → status.json (6–7). The ExperimentConfig(CommonExperimentConfig) must contain model, dataset, train, evaluate, inference, export, gen_trt_engine, quantize. All ??? fields are MISSING (user supplies via YAML/CLI); the augmentation.mean/std, model.head.in_channels, checkpoint-name, and onnx_file matches are in the checklist below.

Full per-step bodies, code, the canonical experiment_spec.yaml, and smoke-test commands: the Phase 3 references.

Gates: Step 1 — ExperimentConfig imports cleanly in-container; Step 2 — build_model(cfg) runs + PLModel instantiates in-container; Phase 3 — all 7 steps complete, smoke tests pass, no missing __init__.py.


Phase 4 — Export, Deployment & TensorRT Integration

Goal: ONNX export from tao-pytorch, then TRT engine builder + inference + evaluation in tao-deploy reusing the tao-core ExperimentConfig.

Steps 8–11: ONNX exporter (8 — task-specific input/output names, batch_size=-1 ⇒ dynamic batch); TRT engine builder (9 — subclass EngineBuilder or reuse ClassificationEngineBuilder; write specs/{gen_trt_engine,inference,evaluate}.yaml, same ExperimentConfig schema, augmentation.mean/std MUST match training); TRT inference → result.csv (10); TRT eval → results.json (11). See the Phase 4 reference for full code and the Phase 3+4 gate (3 in-container checks: imports, model build + forward, ONNX round-trip).

Module pitfalls: tao-pytorch and tao-deploy have separate hydra_runner and monitor_status — use the deploy versions in deploy scripts. ExperimentConfig comes from nvidia_tao_core in both (same schema/field paths).

Phase 3+4 gate: all three in-container checks pass (tao-pytorch imports + model + ONNX export; tao-deploy imports).


Phase 5 — Packaging & L0 Testing

Goal: register the model as a console_script in both repos and add unit tests.

Steps 12–15: register '<model_name>=...:main' in console_scripts of tao-pytorch/setup.py (12) and tao-deploy/setup.py (13, creating the deploy entrypoint/<model_name>.py via entrypoint_hydra); deploy L0 tests (14); trainer L0 tests — Trainer(..., fast_dev_run=True) + @pytest.mark.cv_unit @pytest.mark.<model_name> (15). See the Phase 5 reference for exact entry-point strings, code, and L0 test file lists.

Gate: entrypoints registered; pytest files exist and follow the marker convention. Do NOT stop — go directly to Phase 6.


Cross-Phase Data Flow & Consistency Verification

Before Docker testing, verify the chain train → export → gen_trt_engine → inference / evaluate (the *_model_latest.pth → .onnx → .engine artifact flow + the config fields each stage reads/writes — full diagram in references/cross-cutting.md).

Consistency checklist (verify before proceeding): self.checkpoint_filename → the *_latest.pth name evaluate.checkpoint / export.checkpoint reference; augmentation.mean/std identical across training spec, inference.yaml, evaluate.yaml, engine-builder preprocess_mode; ONNX input_names=['input'] / output_names=['output'] (detection/instance-seg use task-specific names); export.input_width/input_height match dataset.img_size; model.head.in_channels matches model_params_mapping.py; classes.txt at dataset.root_dir readable by both repos; all __init__.py exist (incl. scripts/__init__.py for get_subtasks() via pkgutil). Full paths: workflow-consistency.md.


Phase 6 — Container Testing & End-to-End Validation

Mandatory — start immediately after Phase 5. All TAO models ship as Docker images; code that only works outside a container is incomplete. Testing runs directly inside the TAO Toolkit container — no image build in the loop: mount → install source (setup.py develop) → run pytest / pylint / pydocstyle / flake8 directly. Use vanilla commands, NOT the ci/run_functional_tests.py / ci/run_static_tests.py wrappers (internal-mirror-only; public github.com/NVIDIA-TAO/ mirrors have no ci/ dir).

Steps 16–25: verify local image tags exist (16); unit tests for tao-core / tao-pytorch (-m cv_unit, --shm-size=16G) / tao-deploy (17–19); lint (20); wheels (21); end-to-end — train dry-run + export in one tao-pytorch session, then gen_trt_engine + inference + evaluate in one tao-deploy session (same session critical — --rm discards installs) (22); cross-check native vs TRT (23); debug shells (24); optional release images (25).

Full commands (every docker run, per-container env-vars, exact pytest / lint invocations + full-suite variants, the train/export/gen_trt_engine/inference/evaluate one-liner with all CLI overrides, the ci/ note, the fix-and-retest loop) and build scripts / runner patterns: see the Phase 6 references.

Phase 6 gate (Done criteria): tao-core / tao-pytorch / tao-deploy unit tests pass in their containers; static tests pass (or only legacy lint warnings); wheels build; end-to-end <model_name>_model_latest.pth → model.onnx → model.engine → non-empty result.csv + results.json; native vs TRT agree within tolerance.


Phase 7 — Optimization & Tuning (conditional)

Enter only if Phase 6 passes but accuracy / latency / size needs improvement. Ask the user for target metrics first.

Diagnostic categories: accuracy too low; TRT-vs-native gap; training too slow; inference too slow. Techniques: Step 27 — hyperparameter tuning; Step 28 — INT8 quantization (PTQ via torchao / modelopt, TRT INT8 + calibration); Step 29 — channel pruning + retrain; Step 30 — knowledge distillation; Step 31 — resolution tuning (TAO interpolates ViT positional embeddings automatically). See the Phase 7 reference for each category's checks, config blocks, YAML overrides, decision tree, and rationale.


Argument

$ARGUMENTS

If provided, interpret $ARGUMENTS as the HuggingFace model ID or URL to start Phase 1. If credentials or model short-name are not included, ask the user for them before proceeding.

Files

references/workflow-consistency.md

<!-- Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. 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. -->

TAO Workflow Consistency Guide

Use this reference only when the parent SKILL.md points here for the current task. If this file conflicts with current SKILL.md, skill_info.yaml, schemas, or platform/model skills, the current authoritative source wins.

Contents

    1. CLI Invocation Pattern

    1. Entrypoint Dispatch Flow

    • launch() in tao-pytorch:

    • launch() in tao-deploy:

    1. Hydra Config Resolution

    1. ExperimentConfig Hierarchy

    • Inherited from CommonExperimentConfig:

    • Standard TrainConfig fields (base for all TrainExpConfig):

    • Standard EvaluateConfig / InferenceConfig fields:

    • Standard ExportConfig fields:

    • Standard GenTrtEngineConfig fields:

    1. Experiment Spec YAML Structure

    • Classification example:

    • Detection (DINO-style) differences:

    • Segmentation (Segformer-style) differences:

    1. Deploy Spec YAMLs

    • gen_trt_engine.yaml:

    • inference.yaml:

    • evaluate.yaml:

    1. Results Directory Structure & Cross-Phase Data Flow

    • Cross-phase references (how outputs chain):

    1. Checkpoint Naming Conventions

    1. Dataset Directory Convention

    • Classification:

    • Detection (COCO format):

    • Segmentation:

    1. Augmentation Config Consistency

    1. Multi-GPU Configuration Flow

    1. Train Script → initialize_train_experiment() Contract

    1. Evaluate/Inference Script Contract

    1. Export Script Contract

    1. Deploy gen_trt_engine Script Contract

How the user-facing TAO CLI works end-to-end, and what the agent's generated code must be consistent with.


1. CLI Invocation Pattern

Users run TAO commands via console_scripts registered in setup.py:

# tao-pytorch commands
<model_name> <subtask> -e <experiment_spec.yaml> [hydra_overrides...]

# Examples:
classification_pyt train -e experiment_spec.yaml train.num_epochs=50 train.optim.lr=0.001
segformer evaluate -e experiment_spec.yaml evaluate.checkpoint=/path/to/model.pth
dino export -e experiment_spec.yaml export.onnx_file=/results/model.onnx

# tao-deploy commands (identical pattern)
classification_pyt gen_trt_engine -e gen_trt_engine.yaml gen_trt_engine.tensorrt.data_type=FP16
classification_pyt inference -e inference.yaml inference.trt_engine=/path/to/model.engine
classification_pyt evaluate -e evaluate.yaml evaluate.trt_engine=/path/to/model.engine

Critical: The console_script name IS the model name. Hydra overrides use dot notation matching the dataclass field paths exactly.


2. Entrypoint Dispatch Flow

console_script main()
  → get_subtasks(scripts_package)         # discovers train.py, evaluate.py, etc. via pkgutil
  → command_line_parser(parser, subtasks)  # extracts: subtask, -e spec_file, unknown_args
  → launch(args, unknown_args, subtasks)   # orchestrates execution
launch() in tao-pytorch:
  1. Validates experiment_spec_file exists

  2. Constructs Hydra args: --config-path <dir> --config-name <filename>

  3. Reads GPU config from spec file: train.num_gpus, train.gpu_ids, train.num_nodes

  4. Sets TAO_VISIBLE_DEVICES env var

  5. For multi-GPU: wraps with torchrun --nnodes=N --nproc-per-node=M

  6. Runs script as subprocess with subprocess.Popen()

  7. Sends telemetry on completion

launch() in tao-deploy:
  1. Same basic pattern but from nvidia_tao_deploy.cv.common.entrypoint.entrypoint_hydra

  2. Uses pyCUDA for GPU validation

  3. Single-GPU focused (deploy tasks don't use multi-GPU)

  4. Sets CUDA_VISIBLE_DEVICES directly

What the agent must produce:

# tao-pytorch entrypoint: nvidia_tao_pytorch/cv/<model_name>/entrypoint/<model_name>.py
from nvidia_tao_pytorch.cv.<model_name> import scripts
from nvidia_tao_pytorch.core.entrypoint import get_subtasks, command_line_parser, launch

def main():
    subtasks = get_subtasks(scripts)
    args, unknown_args = command_line_parser(subtasks)
    launch(vars(args), unknown_args, subtasks, network="<model_name>")

if __name__ == "__main__":
    main()

# tao-deploy entrypoint: nvidia_tao_deploy/cv/<model_name>/entrypoint/<model_name>.py
from nvidia_tao_deploy.cv.<model_name> import scripts
from nvidia_tao_deploy.cv.common.entrypoint.entrypoint_hydra import (
    get_subtasks, command_line_parser, launch
)

def main():
    subtasks = get_subtasks(scripts)
    args, unknown_args = command_line_parser(subtasks)
    launch(vars(args), unknown_args, subtasks, network="<model_name>")

if __name__ == "__main__":
    main()

3. Hydra Config Resolution

The @hydra_runner decorator merges configs in this order (last wins):

1. ExperimentConfig dataclass defaults (schema)
2. YAML experiment spec values
3. CLI overrides (dot notation)
@hydra_runner(
    config_path=os.path.join(spec_root, "experiment_specs"),  # directory containing YAML
    config_name="experiment_spec",                              # YAML filename (no .yaml)
    schema=ExperimentConfig                                     # dataclass from tao-core
)
@monitor_status(name="<ModelName>", mode="train")
def main(cfg: ExperimentConfig) -> None:
    ...

Key behaviors:

  • hydra.output_subdir=null — no .hydra/ directory created

  • hydra.run.dir=. — run in current directory

  • OmegaConf interpolation: ${results_dir}/train/model.pth resolves at access time

  • MISSING fields (from omegaconf.MISSING) must be provided in YAML or CLI — otherwise runtime error


4. ExperimentConfig Hierarchy

Every TAO model's ExperimentConfig inherits from CommonExperimentConfig and MUST have these top-level sections:

@dataclass
class ExperimentConfig(CommonExperimentConfig):
    """Top-level config — drives both tao-pytorch and tao-deploy scripts."""
    model: ModelConfig              = DATACLASS_FIELD(ModelConfig())
    dataset: DatasetConfig          = DATACLASS_FIELD(DatasetConfig())
    train: TrainExpConfig           = DATACLASS_FIELD(TrainExpConfig())
    evaluate: EvalExpConfig         = DATACLASS_FIELD(EvalExpConfig())
    inference: InferenceExpConfig   = DATACLASS_FIELD(InferenceExpConfig())
    export: ExportExpConfig         = DATACLASS_FIELD(ExportExpConfig())
    gen_trt_engine: GenTrtEngineExpConfig = DATACLASS_FIELD(GenTrtEngineExpConfig())
    quantize: ModelQuantizationConfig = DATACLASS_FIELD(ModelQuantizationConfig())
    # Optional (task-specific):
    distill: DistillConfig          = DATACLASS_FIELD(DistillConfig())
Inherited from CommonExperimentConfig:
model_name: Optional[str]     # for model-agnostic invocation
encryption_key: Optional[str] # checkpoint encryption
results_dir: Optional[str]    # top-level output directory
wandb: WandBConfig            # experiment tracking (enable, project, entity, tags)
Standard TrainConfig fields (base for all TrainExpConfig):
num_gpus: int          # default=1
gpu_ids: List[int]     # default=[0]
num_nodes: int         # default=1
seed: int              # default=1234
num_epochs: int        # default=10
checkpoint_interval: int  # default=1
validation_interval: int  # default=1
resume_training_checkpoint_path: Optional[str]
results_dir: Optional[str]
cudnn:
    benchmark: bool    # default=False
    deterministic: bool # default=True
Standard EvaluateConfig / InferenceConfig fields:
num_gpus: int
gpu_ids: List[int]
checkpoint: str        # MISSING — required
trt_engine: Optional[str]
results_dir: Optional[str]
batch_size: int        # default=-1 (auto)
Standard ExportConfig fields:
results_dir: Optional[str]
gpu_id: int            # default=0 (singular — export is single-GPU)
checkpoint: str        # MISSING — required
onnx_file: str         # MISSING — output path
input_channel: int     # default=3
input_width: int       # default=960
input_height: int      # default=544
opset_version: int     # default=17
batch_size: int        # default=-1 (dynamic)
Standard GenTrtEngineConfig fields:
results_dir: Optional[str]
gpu_id: int            # default=0
onnx_file: str         # MISSING — input ONNX path
trt_engine: Optional[str] # output engine path
tensorrt:
    data_type: str     # FP32, FP16, or INT8
    workspace_size: int # default=1024 (MB)
    min_batch_size: int # default=1
    opt_batch_size: int # default=1
    max_batch_size: int # default=1
    calibration:       # for INT8 only
        cal_image_dir: List[str]
        cal_cache_file: str
        cal_batch_size: int
        cal_batches: int

5. Experiment Spec YAML Structure

The agent must generate a spec YAML that mirrors the ExperimentConfig dataclass exactly. Field names in YAML must match field names in the dataclass.

Classification example:
encryption_key: tlt_encode
results_dir: ???  # User must provide

model:
  backbone:
    type: "vit_large_patch14_dinov2_swiglu"
    pretrained_backbone_path: null
    freeze_backbone: False
    freeze_norm: False
  head:
    type: TAOLinearClsHead
    in_channels: 1024   # Must match backbone output dim from model_params_mapping.py
    topk: [1, 5]
    loss:
      type: CrossEntropyLoss
      label_smooth_val: 0.0

dataset:
  dataset: "CLDataset"
  root_dir: ???  # Location of classes.txt
  num_classes: 1000
  img_size: 224
  batch_size: 128
  workers: 8
  shuffle: True
  augmentation:
    mean: [0.485, 0.456, 0.406]
    std: [0.229, 0.224, 0.225]
    random_flip:
      enable: True
      hflip_probability: 0.5
      vflip_probability: 0.0
    random_rotate:
      enable: False
    random_color:
      enable: False
    random_erase:
      enable: False
  train_dataset:
    images_dir: ${dataset.root_dir}/train
  val_dataset:
    images_dir: ${dataset.root_dir}/val
  test_dataset:
    images_dir: ${dataset.root_dir}/test

train:
  seed: 1234
  num_epochs: 25
  num_gpus: 1
  gpu_ids: [0]
  num_nodes: 1
  checkpoint_interval: 10
  validation_interval: 1
  resume_training_checkpoint_path: null
  clip_grad_norm: 2.0
  precision: fp32
  enable_ema: False
  optim:
    optim: adamw
    lr: 0.00006
    weight_decay: 0.05
    policy: cosine
    warmup_epochs: 5
    momentum: 0.9
  tensorboard:
    enabled: True

evaluate:
  checkpoint: ${results_dir}/train/<model_name>_model_latest.pth

inference:
  checkpoint: ${results_dir}/train/<model_name>_model_latest.pth

export:
  results_dir: ${results_dir}/export
  gpu_id: 0
  checkpoint: ${results_dir}/train/<model_name>_model_latest.pth
  onnx_file: ${export.results_dir}/<model_name>.onnx
  input_width: 224
  input_height: 224
  batch_size: -1
  opset_version: 17

gen_trt_engine:
  onnx_file: ${export.results_dir}/<model_name>.onnx
  trt_engine: ${results_dir}/trt/<model_name>.engine
  tensorrt:
    data_type: FP16
    workspace_size: 1024
    min_batch_size: 1
    opt_batch_size: 4
    max_batch_size: 8
Detection (DINO-style) differences:
dataset:
  train_data_sources:
    - image_dir: /data/train/images
      json_file: /data/train/annotations.json
  val_data_sources:
    - image_dir: /data/val/images
      json_file: /data/val/annotations.json
  test_data_sources:
    image_dir: /data/test/images
    json_file: /data/test/annotations.json
  infer_data_sources:
    image_dir: [/data/infer/images]
    classmap: /data/classmap.txt
  num_classes: 91
  augmentation:
    scales: [480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800]
    input_mean: [0.485, 0.456, 0.406]
    input_std: [0.229, 0.224, 0.225]

model:
  backbone: "fan_small_12_p4_hybrid"
  num_queries: 300
  num_feature_levels: 4
  enc_layers: 6
  dec_layers: 6
  hidden_dim: 256
Segmentation (Segformer-style) differences:
dataset:
  segment:
    palette:
      - label_id: 0
        rgb: [0, 0, 0]
        mapping_class: "background"
        seg_class: "background"
      - label_id: 1
        rgb: [128, 0, 0]
        mapping_class: "person"
        seg_class: "person"
  augmentation:
    mean: [0.485, 0.456, 0.406]
    std: [0.229, 0.224, 0.225]

model:
  backbone:
    type: "mit_b5"
  decode_head:
    in_channels: [64, 128, 320, 512]
    in_index: [0, 1, 2, 3]
    feature_strides: [4, 8, 16, 32]

6. Deploy Spec YAMLs

Deploy specs are separate YAML files (not the same experiment spec used for training). They live in nvidia_tao_deploy/cv/<model_name>/specs/.

gen_trt_engine.yaml:
results_dir: ???
gen_trt_engine:
  onnx_file: ???
  trt_engine: ???
  tensorrt:
    data_type: FP16
    workspace_size: 1024
    min_batch_size: 1
    opt_batch_size: 4
    max_batch_size: 8
inference.yaml:
results_dir: ???
inference:
  trt_engine: ???
  batch_size: 8
dataset:
  root_dir: ???         # For classes.txt lookup
  test_dataset:
    images_dir: ???
  augmentation:
    mean: [0.485, 0.456, 0.406]
    std: [0.229, 0.224, 0.225]
evaluate.yaml:
results_dir: ???
evaluate:
  trt_engine: ???
  batch_size: 8
model:
  head:
    topk: [1]
dataset:
  root_dir: ???
  test_dataset:
    images_dir: ???
  augmentation:
    mean: [0.485, 0.456, 0.406]
    std: [0.229, 0.224, 0.225]

Critical: Deploy scripts import ExperimentConfig from tao-core — the same dataclass. So deploy spec field names must also match the dataclass paths.


7. Results Directory Structure & Cross-Phase Data Flow

Each phase produces outputs that feed into the next:

results_dir/                          ← set by user
├── train/                            ← train script writes here
│   ├── lightning_logs/version_1/
│   │   ├── hparams.yaml
│   │   ├── metrics.csv
│   │   └── events.out.tfevents.*     ← TensorBoard data
│   ├── model_001.pth                 ← checkpoint at epoch 1
│   ├── model_010.pth                 ← checkpoint at epoch 10
│   ├── <model_name>_model_latest.pth ← symlink to latest (IMPORTANT)
│   └── status.json                   ← TAO status logger
│
├── evaluate/                         ← evaluate script writes here
│   ├── result.csv                    ← per-image predictions + GT
│   └── results.json                  ← aggregate metrics
│
├── inference/                        ← inference script writes here
│   └── result.csv                    ← per-image predictions
│
├── export/                           ← export script writes here
│   ├── <model_name>.onnx            ← ONNX model
│   ├── labels.txt                    ← class labels (optional)
│   └── nvdsinfer_config.yaml         ← DeepStream config (optional)
│
├── trt/                              ← gen_trt_engine writes here
│   └── <model_name>.engine           ← TensorRT engine
│
├── trt_infer/                        ← TRT inference writes here
│   └── result.csv
│
└── trt_eval/                         ← TRT evaluation writes here
    └── results.json
Cross-phase references (how outputs chain):
train → export:
  export.checkpoint = ${results_dir}/train/<model_name>_model_latest.pth

export → gen_trt_engine:
  gen_trt_engine.onnx_file = ${results_dir}/export/<model_name>.onnx

gen_trt_engine → inference:
  inference.trt_engine = ${results_dir}/trt/<model_name>.engine

gen_trt_engine → evaluate:
  evaluate.trt_engine = ${results_dir}/trt/<model_name>.engine

8. Checkpoint Naming Conventions

The checkpoint_filename attribute on the PLModel controls naming:

class MyModelPlModel(TAOLightningModule):
    def __init__(self, experiment_spec):
        super().__init__(experiment_spec)
        self.checkpoint_filename = "<model_name>_model"  # e.g., "classifier_model"

This produces:

  • model_{epoch:03d}.pth — per-epoch checkpoints (e.g., model_001.pth)

  • <checkpoint_filename>_latest.pth — symlink to latest (e.g., classifier_model_latest.pth)

The configure_callbacks() method sets up ModelCheckpoint:

ModelCheckpoint(
    filename="model_{epoch:03d}",    # per-epoch naming
    every_n_epochs=checkpoint_interval,
    save_last="link",                # creates _latest symlink
    save_top_k=-1,                   # keep all
    save_on_train_epoch_end=True,
    dirpath=results_dir,
)

Agent must ensure: The checkpoint_filename in the PLModel matches what the experiment spec YAML references in evaluate.checkpoint, inference.checkpoint, and export.checkpoint.


9. Dataset Directory Convention

Classification:
root_dir/
├── classes.txt          ← one class name per line, sorted alphabetically
├── train/
│   ├── class_a/
│   │   ├── img001.jpg
│   │   └── img002.jpg
│   └── class_b/
│       └── img003.jpg
├── val/
│   └── ...              ← same structure as train/
└── test/
    └── ...              ← same structure as train/

classes.txt is read by both tao-pytorch (dataset) and tao-deploy (inference/evaluate) to build label mappings. The deploy dataloader auto-discovers class names from alphabetically-sorted subdirectory names if classes.txt is missing.

Detection (COCO format):
data_dir/
├── train/
│   ├── images/
│   └── annotations.json   ← COCO JSON format
├── val/
│   ├── images/
│   └── annotations.json
└── classmap.txt            ← class_name per line for inference
Segmentation:
data_dir/
├── train/
│   ├── images/
│   └── masks/             ← PNG masks with label IDs as pixel values
├── val/
│   ├── images/
│   └── masks/
└── test/
    ├── images/
    └── masks/

10. Augmentation Config Consistency

The augmentation.mean and augmentation.std values MUST be consistent across:

  1. tao-pytorch training — dataset.augmentation.mean/std in experiment spec

  2. tao-pytorch export — baked into ONNX preprocessing (or applied externally)

  3. tao-deploy inference — dataset.augmentation.mean/std in deploy inference spec

  4. tao-deploy evaluation — dataset.augmentation.mean/std in deploy evaluate spec

  5. tao-deploy engine builder — preprocess_mode ("torch" uses ImageNet defaults)

Standard ImageNet normalization (used by most models):

mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]

If the HF model uses different normalization, update ALL specs consistently.

The deploy ClassificationEngineBuilder uses preprocess_mode:

  • "torch" → mean=[0.485, 0.456, 0.406], scale=1/[0.229, 0.224, 0.225]

  • "caffe" → mean=[103.939, 116.779, 123.68], scale=1.0, BGR channel order

  • "tf" → mean=0, scale=1/127.5, then subtract 1


11. Multi-GPU Configuration Flow

User YAML spec                    Entrypoint launch()              Training script
─────────────                     ──────────────────               ───────────────
train:                       →    Reads num_gpus, gpu_ids     →   TAO_VISIBLE_DEVICES env var
  num_gpus: 4                     Sets TAO_VISIBLE_DEVICES         parsed by initialize_train_experiment()
  gpu_ids: [0,1,2,3]             Wraps with torchrun:              → trainer_kwargs['devices']
  num_nodes: 1                    torchrun --nproc-per-node=4       → Trainer(devices=[0,1,2,3],
                                                                              strategy='ddp_find_unused_parameters_true',
                                                                              sync_batchnorm=True)

Agent must ensure:

  • PLModel's configure_callbacks() and training script handle DDP correctly

  • Data module uses DistributedSampler when multi-GPU

  • use_distributed_sampler=False in Trainer (PLModel provides custom sampler)


12. Train Script → initialize_train_experiment() Contract

initialize_train_experiment(cfg, key) returns (resume_ckpt, trainer_kwargs):

trainer_kwargs = {
    'logger': [TensorBoardLogger(save_dir=results_dir, version=1, name="lightning_logs")],
    'devices': [0, 1, 2, 3],    # from TAO_VISIBLE_DEVICES
    'max_epochs': cfg.train.num_epochs,
    'check_val_every_n_epoch': cfg.train.validation_interval,
    'default_root_dir': results_dir,
    'accelerator': 'gpu',
    'enable_checkpointing': False,  # PLModel defines own ModelCheckpoint in configure_callbacks()
}

The agent's train script must:

  1. Call initialize_train_experiment(cfg, key)

  2. Create the data module: dm = <DataModule>(cfg.dataset) then dm.setup(stage="fit")

  3. Create the model: model = <ModelPlModel>(cfg)

  4. Determine strategy: 'ddp_find_unused_parameters_true' if multi-GPU else 'auto'

  5. Map precision: fp16 → '16-mixed', bf16 → 'bf16-mixed', fp32 → '32-true'

  6. Create Trainer with sync_batchnorm=True, use_distributed_sampler=False

  7. Call trainer.fit(model, dm, ckpt_path=resume_ckpt)


13. Evaluate/Inference Script Contract

# evaluate.py
model_path, trainer_kwargs = initialize_evaluation_experiment(cfg, key)
dm = <DataModule>(cfg.dataset)
dm.setup(stage="test")
model = <ModelPlModel>.load_from_checkpoint(model_path, map_location="cpu", experiment_spec=cfg)
trainer = Trainer(**trainer_kwargs)
trainer.test(model, datamodule=dm)

# inference.py
model_path, trainer_kwargs = initialize_inference_experiment(cfg, key)
dm = <DataModule>(cfg.dataset)
dm.setup(stage="predict")
model = <ModelPlModel>.load_from_checkpoint(model_path, map_location="cpu", experiment_spec=cfg)
trainer = Trainer(**trainer_kwargs)
trainer.predict(model, datamodule=dm)

Key: load_from_checkpoint requires experiment_spec=cfg as a keyword argument. The PLModel's __init__ must accept experiment_spec and use it to rebuild the model architecture.


14. Export Script Contract

# Load model
sf_model = <ModelPlModel>.load_from_checkpoint(model_path, map_location="cpu", experiment_spec=cfg)
model = sf_model.model  # Extract the raw nn.Module (not the PLModel wrapper)
model.eval()
model.cuda()

# Create dummy input matching export config
dummy_input = torch.ones(batch_size, input_channel, input_height, input_width, device='cuda')

# Export via ONNXExporter
from nvidia_tao_pytorch.core.exporters import ONNXExporter
onnx_exporter = ONNXExporter()
onnx_exporter.export_model(
    model, batch_size, output_file, dummy_input,
    input_names=['input'], output_names=['output'],
    opset_version=cfg.export.opset_version,
    do_constant_folding=True
)

Agent must ensure:

  • ONNX input name is always "input", output name is always "output"

  • The raw model (not PLModel wrapper) is exported

  • Input dimensions match what the deploy pipeline expects

  • Dynamic batch size if batch_size == -1


15. Deploy gen_trt_engine Script Contract

# Decrypt ONNX if encrypted
tmp_onnx_file, file_format = decode_model(cfg.gen_trt_engine.onnx_file)

# Initialize builder kwargs
engine_builder_kwargs, create_engine_kwargs = initialize_gen_trt_engine_experiment(cfg)

# Detect QDQ quantization
strongly_typed = is_qdq_quantized_onnx(tmp_onnx_file) if file_format == "onnx" else False

# Build engine
builder = <ModelName>EngineBuilder(
    **engine_builder_kwargs,
    workspace=cfg.gen_trt_engine.tensorrt.workspace_size,
    is_qat=False,
    strongly_typed=strongly_typed,
    data_format="channels_first",
    preprocess_mode="torch"        # Must match training normalization
)
builder.create_network(tmp_onnx_file, file_format)
builder.create_engine(**create_engine_kwargs)

16. Deploy Inference Script Contract

# Load class mapping
classmap = os.path.join(cfg.dataset.root_dir, 'classes.txt')
mapping_dict = {line.rstrip(): idx for idx, line in enumerate(sorted(open(classmap)))}

# Create TRT inferencer
trt_infer = ClassificationInferencer(
    cfg.inference.trt_engine,
    data_format="channel_first",
    batch_size=cfg.inference.batch_size
)

# Create NumPy dataloader
dl = ClassificationLoader(
    input_shape=trt_infer.input_tensors[0].shape,  # From TRT engine
    data_paths=[cfg.dataset.test_dataset.images_dir],
    class_mapping=mapping_dict,
    is_inference=True,
    batch_size=cfg.inference.batch_size,
    image_mean=cfg.dataset.augmentation.mean,       # Must match training
    image_std=cfg.dataset.augmentation.std           # Must match training
)

# Run inference and write results
with open(f"{cfg.results_dir}/result.csv", 'w') as csv_f:
    for imgs, _ in dl:
        y_pred = trt_infer.infer(imgs)
        class_indices = np.argmax(y_pred, axis=1)
        # Write to CSV

17. Status Logging

Scripts use @monitor_status(name='<ModelName>', mode='<subtask>') decorator which:

  1. Creates status.json in results_dir

  2. Writes RUNNING status on entry

  3. Writes SUCCESS/FAILURE status on exit

  4. Captures exceptions and logs tracebacks

The name parameter should match the model's display name. The mode must be one of: train, evaluate, inference, export, gen_trt_engine.


18. WandB / MLOps Integration

If cfg.wandb.enable is True and the user has WandB configured:

  • initialize_train_experiment() adds a WandB logger

  • Logs: metrics per epoch, hyperparameters, model artifacts

  • Config fields: wandb.project, wandb.entity, wandb.tags, wandb.name, wandb.run_id

The agent doesn't need to add WandB code — it's handled by initialize_train_experiment(). But the ExperimentConfig must include the wandb section (inherited from CommonExperimentConfig).


19. Encryption Key Flow

User sets: encryption_key: "tlt_encode" in YAML
  → initialize_train_experiment() calls TLTPyTorchCookbook.set_passphrase(key)
  → ModelCheckpoint saves .pth files (unencrypted) or .tlt files (encrypted)
  → Export can produce .etlt (encrypted ONNX) if key is set
  → Deploy decode_model() decrypts .etlt back to ONNX before TRT build

The agent doesn't need to implement encryption logic — just pass cfg.encryption_key to the initialization functions.


20. Consistency Checklist

Before considering implementation complete, verify:

  • [ ] ExperimentConfig dataclass field names match experiment spec YAML keys exactly

  • [ ] model_params_mapping.py maps every backbone variant → correct head.in_channels

  • [ ] checkpoint_filename in PLModel matches what specs reference in evaluate.checkpoint, etc.

  • [ ] augmentation.mean/std are identical across training spec, deploy inference spec, and deploy evaluate spec

  • [ ] preprocess_mode in EngineBuilder matches the normalization used during training

  • [ ] input_names=['input'] and output_names=['output'] in ONNX export

  • [ ] Deploy specs use gen_trt_engine.onnx_file and gen_trt_engine.trt_engine (not bare onnx_file)

  • [ ] results_dir interpolation paths (${results_dir}/train/...) form a valid chain

  • [ ] Entrypoint imports from correct module (nvidia_tao_pytorch.core.entrypoint vs nvidia_tao_deploy.cv.common.entrypoint.entrypoint_hydra)

  • [ ] Scripts use correct decorator imports (nvidia_tao_pytorch.core.hydra.hydra_runner vs nvidia_tao_deploy.cv.common.hydra.hydra_runner)

  • [ ] monitor_status imported from correct module per repo

  • [ ] classes.txt path is consistent between training dataset and deploy inference/evaluate

  • [ ] Dynamic batch export (batch_size: -1) matches dynamic_axes in ONNX export call

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Declares allowed tools, Needs Python, Needs Node.js

The author says: Requires Python 3.10+, NVIDIA driver, CUDA 13.0+, docker + nvidia-container-toolkit, an NGC API key (`docker login nvcr.io`), an HF_TOKEN, and access to the TAO Toolkit container images on `nvcr.io` for `tao-pytorch`, `tao-deploy`, and (optionally) `tao-dataservices` — Phase 0 asks the user for the exact image references and prepares them locally as `tao-pytorch-base:latest`, `tao-deploy-base:latest`, `tao-dataservices-base:latest`. Local clones of `tao-core`, `tao-pytorch`, `tao-deploy`,...

Security

What our scanner noticed· Medium risk

  • Large base64-encoded blobs
  • Instructions that use the network

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
NVIDIA Corporation
Publisher
NVIDIA (Official)
Source
NVIDIA/skills · skills/tao-port-huggingface-model · commit fce3cca
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE-APACHE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by NVIDIA Corporation or NVIDIA.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download tao-port-huggingface-model.zip