nvidia/nvflare-convert-pytorch
Convert existing PyTorch training code into an NVFLARE federated job using Client API model exchange, local validation, and job export; do not use for other frameworks, deployment, POC/production lifecycle, or experiment workflows.
npx skills add https://github.com/NVIDIA/NVFlare --skill nvflare-convert-pytorch
Use when converting an existing plain PyTorch training script, torch.nn.Module, manual training loop,
state_dict workflow, data loader, checkpoint, or metric loop into an NVFLARE federated training job. Supports
horizontal FL, Client API model exchange with FLModel, recipe aggregator= hooks, validation, and export.
Do not use for PyTorch Lightning (route to nvflare-convert-lightning), Hugging Face Trainer (route to nvflare-convert-huggingface), TensorFlow, XGBoost,
scikit-learn, failed jobs (route to
nvflare-diagnose-job), federated statistics without training (route to
nvflare-fed-stats), or generic PyTorch debugging without FLARE intent. Out of
scope: production deployment, Kubernetes, POC lifecycle, privacy/security policy design,
controller/workflow rewrites outside recipe or Job APIs, experiment search, and
data distribution experiments beyond minimal validation setup. Privacy-protection
requests — HE/encrypted aggregation, differential privacy, and privacy filters — need provisioning/deployment
policy; route onward rather than substituting an unprotected recipe or adding only a disclaimer.
If a request combines federated statistics and model-training conversion,
treat it as two independent jobs and workflows: do not merge or automatically
chain them, do not route the combination to nvflare-orient, and ask which
workflow to run first before generating or running either job. Recommend
nvflare-fed-stats first only when the user's purpose is to understand data
distribution; handle conversion later as a separate request.
../nvflare-shared/references/conversion-common.md and apply it for thewhole conversion; this SKILL.md states only the framework-specific deltas.
Load ../nvflare-shared/references/conversion-workflow.md only for a non-standard
case that needs its detailed rerun, data-location, authorization, or
missing-semantics guidance.
nvflare agent inspect source <path> --format jsonplus direct reading. Fact extraction is static; do not import or execute
user training modules to discover fields. Extract: training entrypoint,
model class path and constructor args, checkpoint behavior, train/eval
functions, data loading, metric names and denominators, local epochs/steps,
requested client and round counts, source data split or partition evidence,
tracking evidence, DDP evidence, and any custom aggregation intent.
../nvflare-shared/references/conversion-common.md beforeany Python command imports user, PyTorch, NVFLARE, or declared dependency
modules.
the standard case — the user explicitly requests FedAvg and inspection
identifies PyTorch — run nvflare recipe show fedavg-pt --format json
directly and construct it; do not add per-site recipe config unless sites
actually differ. Load
../nvflare-shared/references/pytorch-family-recipe-selection.md (discovery,
algorithm guide, catalog-based selection, HE-not-supported rule) only for
ambiguous or non-FedAvg algorithms, reserving nvflare recipe list for those
cases. Use the module, class, and parameters returned by recipe show for
standard job.py construction; for fedavg-pt, import FedAvgRecipe from
nvflare.app_opt.pt.recipes.fedavg, never from nvflare.recipe. After every
recipe show, load
../nvflare-shared/references/pytorch-family-recipe-construction.md and
derive the recipe's construction capabilities. Load
references/recipe-selection.md only when non-FedAvg or execution-mode
details are needed.
references/pytorch-client-api-conversion.md: initialize FLARE, receive an
FLModel, load params, evaluate the received global model, train, and
send an FLModel with updated params and metrics. Adapt the user's
evaluation code into the packaged evaluation template; if evaluation is
required but missing, ask or fail closed. Partition site data per the "Site
Data Partitioning" rule in ../nvflare-shared/references/conversion-common.md.
job.py with explicit model config (never a live model),requested aggregator= wiring, and the metric, tensor-transport, server
offload, and execution settings derived from the shared PyTorch-family
construction profile.
../nvflare-shared/references/validation-evidence.md:compile checks, recipe construction, one final full-run path chosen by the
artifact being validated, and export inspection; use
references/job-validation.md for PyTorch-specific failures. Stop at the
first failed rung and report the product error. Use the environment and
permission mechanisms supplied by the agent host; do not inspect or enforce
its security boundary.
artifact paths. Load
../nvflare-shared/references/metrics-and-artifact-reporting.md only when
normal metric artifacts are absent or inconsistent.
job.py by reading themodel module's __init__ and the selected recipe's model parameter from
nvflare recipe show <recipe-name> --format json, not by reading NVFLARE
library source. Emit explicit recipe model config with class_path and
args only when the values are statically clear from literal source,
configuration, or supplied metadata; otherwise ask one semantic question when
an answer channel exists or fail closed on that missing value.
../nvflare-shared/references/pytorch-model-exchange.md andreferences/pytorch-client-api-conversion.md for the canonical plain-PyTorch
payload and round-loop pattern.
../nvflare-shared/references/pytorch-family-recipe-construction.md after
recipe show; it is the canonical policy for optional recipe parameters,
model selection, tensor transport, server disk offload, and execution mode.
Never patch a framework-neutral runtime module or register FOBS handlers in
client.py.
FLModel.metrics; must not synthesize metric semantics without source
evidence.
torch.load(..., weights_only=True); acheckpoint that needs full unpickling is ask/fail, per
references/pytorch-client-api-conversion.md.
../nvflare-shared/references/pytorch-model-exchange.md; that reference is
for plain PyTorch, PyTorch Lightning, and Hugging Face Trainer model/state-dict
exchange only.
input/authorization follow ../nvflare-shared/references/conversion-common.md.
Always read this converter SKILL.md together with
../nvflare-shared/references/conversion-common.md. The standard routing,
recipe selection, and reporting path is inline, so common FedAvg does not load
broad policy or algorithm-selection references. Load the client template,
model-exchange reference, validation reference, and aggregator asset only when
their phase needs them. Load other detailed references only for exceptions:
../nvflare-shared/references/conversion-workflow.md for the full conversioncontract when a case is non-standard;
../nvflare-shared/references/pytorch-family-recipe-selection.md only forambiguous or non-FedAvg algorithms, and references/recipe-selection.md only
for non-FedAvg or execution-mode construction details not supplied by
recipe show;
../nvflare-shared/references/pytorch-family-recipe-construction.md afterevery recipe show;
../nvflare-shared/references/dependency-install.md only when an install isneeded;
../nvflare-shared/references/runtime-output-guidance.md only for read-onlysource roots or user-chosen output destinations;
../nvflare-shared/references/metrics-and-artifact-reporting.md only whenmetrics are absent or inconsistent;
../nvflare-shared/references/validation-evidence.md before validation, and../nvflare-shared/references/pytorch-model-exchange.md only for PyTorch-family exchange;
references/pytorch-client-api-conversion.md for Client API conversion, andreferences/job-validation.md for PyTorch-specific validation failures.
Do not load every reference preemptively, and do not depend on NVFLARE
repository examples being present in the user's environment.
Take nvidia/nvflare-convert-pytorch from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.