AIニュース最前線
最新ニュースAI日報Hacker日報週報動画AIツールトレンド企業

AIニュース最前線

世界中のAI最新情報を日本語で毎時更新

最新ニュース日報トレンド企業プレミアムRSS
© 2026 ainew.jp特定商取引法に基づく表記
ニュース一覧元記事を開く
NVIDIA Developer Blog·2026年4月25日 00:00·約11分で読める

NVIDIA FLARを用いたリファクタリング負担軽減の連合学習

#連合学習#プライバシー強化技術(PETs)#NVIDIA FLARE#分散機械学習#データ主権
TL;DR

NVIDIA FLAREの最新バージョンは、既存スクリプトを数行で連合クライアントに変換するAPIとジョブリシピを提供し、データ移動なしでのコンプライアンス対応とプライバシー保護を可能にする連合学習の実装オーバーヘッドを解消する。

AI深層分析2026年4月25日 00:08
4
重要/ 5段階
深度40%
4
関連度30%
4
実用性20%
3
革新性10%
3

キーポイント

1

開発者体験の大幅な簡素化

既存のローカル学習スクリプトを5〜6行で連合クライアントに変換するAPIと、環境を切り替えるだけでシミュレーションから本番まで実行可能なジョブリシピを提供し、リファクタリング負荷を解消する。

2

データ移動ゼロのシステム設計

規制やデータ主権制約に対応するため、生データのコピーを禁止しモデル更新のみを送信する「No data copy」原則をプラットフォームの核心要件として定義する。

3

多層的なプライバシー保護技術の統合

同種暗号、差分プライバシー、機密コンピューティングなどのプライバシー強化技術(PETs)をプラットフォームレベルでサポートし、監査とガバナンス要件を満たすコンプライアンス姿勢を確立する。

4

Common FL Project Pitfalls

Projects typically stall at the 'code cliff' (invasive restructuring for existing ML frameworks) or the 'lifecycle cliff' (rewrites during PoC/production deployment).

5

FLARE's Two-Step Solution

FLARE eliminates these barriers by standardizing the workflow into simply making a script federated via client API and executing it as a portable job recipe.

6

Minimal-Change Client API Design

The client API prioritizes minimal code modifications, avoiding heavy inheritance patterns and providing a straightforward run loop: init runtime, receive model, train locally, send updates.

7

既存コードの流用と変更最小化

データローダーや最適化アルゴリズムなどの学習ロジックは一切変更せず、FLARE固有の初期化と通信呼び出しのみを追加している。

影響分析・編集コメントを表示

影響分析

企業・公共部門におけるAI導入において、データ主権とコンプライアンスが最大の障壁となる中、FLAREの抽象化アプローチは開発リソースを削減し連合学習の実用化を加速させる。これにより医療や金融などの規制業界でも、プライバシー保護を損なわずに分散モデル学習の採用が現実的になる。

編集コメント

開発負荷を「5〜6行」と具体的に示し、環境切り替えだけで運用できる設計は、実務チームの採用ハードルを確実に下げる。規制対応が必須となる業界では、技術革新よりもこの「実装の簡素化」こそが普及の鍵となるだろう。

フェデレーテッドラーニング(FL)はもはや研究上の興味深い話題ではなく、ある厳しい制約に対する実用的な回答です。最も価値のあるデータは、しばしば移動が困難であるという事実です。規制の境界、データ主権に関する規則、そして組織内のリスク許容度は、中央集約型のデータ集計を日常的に妨げます。同時に、膨大なデータの重力(data gravity)により、許可されたデータ転送でさえも、大規模なスケールでは遅く、高価で、脆弱なものになりがちです。

NVIDIA FLARE の最新バージョンは、この現実に対応するため、トレーニングロジックをデータ側に移動させ、生データはその場に残すというフェデレーテッドコンピューティングランタイムを提供しています。高リスクな環境では、データを中央集約して集計することが不可能または実用的でないことが多いため、現代のフェデレーテッドプラットフォームは、データの分離、コンプライアンス、およびプライバシー強化技術(privacy-enhancing technologies)を第一級の要件として扱う必要があります。

歴史的にFLの普及を遅らせてきたのは、その概念自体ではなく、開発者の体験(developer experience)です。「ローカルのスクリプトで学習する」から「フェデレーテッドサイト全体でジョブを実行する」への移行に、深いコードのリファクタリングや新しいクラス階層、あるいは脆い設定が必要となる場合、多くのプロジェクトはパイロット段階で停滞してしまいます。

FLARE API の進化はまさにこの課題に対応するもので、リファクタリングのオーバーヘッドを排除し、チームが実際にMLシステムを構築・納品する方法に明確に対応する2つの具体的なステップに分けて作業を行います。

  • ステップ1(クライアントAPI):既存のローカルトレーニングスクリプトを、学習ループの構造を変更することなく、約5〜6行のコードでフェデレーテッドクライアントに変換します。
  • ステップ 2(ジョブリシピ):FL ワークフローを選択し、クライアントのトレーニングスクリプトにバインドします。その後、実行環境を切り替えるだけで、シミュレーション、PoC(概念実証)、本番環境のすべてで同じジョブを実行できます。

システム要件としての「データコピーなし」

規制の厳しい環境や高機密性が求められる場面では、「データを一元化する」という選択肢は次第に現実味を失っています。実用的なフェデレーテッドコンピューティング(Federated Computing)プラットフォームには、以下のサポートが必要です。

  • データコピーなし:データはローカルに留まり、モデルの更新(または同等のシグナル)のみが移動します。
  • 準拠姿勢:主権と監査要件をサポートする、デプロイメントおよびガバナンス制御。
  • プライバシー強化技術:複数の防御層(例:同種暗号、差分プライバシー、機密コンピューティング)。

imageimage*図 1. フェデレーテッドコンピューティングはデータをその場に保持し、モデルの更新を通じてコラボレーションを可能にすると同時に、準拠およびプライバシー強化保護をサポートします。***

リファクタリングの崖:FL プロジェクトが停滞する理由

チームは、パイロット段階後に通常、以下の 2 つの「崖」のいずれかに直面します。

  • コードの崖:動作する PyTorch/TensorFlow/Lightning のトレーニングコードを FL に変換するには、侵入的なリストラクチャリングが必要になる場合があります。これには、新しい抽象化、メッセージングの接着剤、およびフレームワーク固有の足場が含まれます。
  • ライフサイクルの崖:シミュレーションが正常に動作している場合でも、PoC や本番環境への移行は、ジョブの再定義、再構成、および環境固有の分岐による書き換えをトリガーします。

FLARE は、ワークフローを 2 つのステップに標準化することで、両方の課題(「崖」)を平坦化します。

  • スクリプトをフェデレーテッド(クライアント API)にする
  • ポータブルジョブとして実行する(ジョブリシピ)

意図された体験は、これらを組み合わせることで、運用可能なフェデレーテッドジョブをゼロから迅速に構築できるようにすることです。

ステップ 1: ローカルのトレーニングスクリプトをフェデレーテッドクライアントに変換する(クライアント API)

対象者: 既存のトレーニングコードを持ち、最小限の変更で済ませたい実務家や ML エンジニア。

メンタルモデルは意図的にシンプルに設計されています:

  • クライアントランタイムを初期化する
  • ジョブが実行されている間ループする
  • 現在のグローバルモデルを受信する
  • ローカルでトレーニングする(あなたのコード)
  • 更新された重みとメトリクスを送信する

FLARE のクライアント API は、最小限のコード変更を可能にするように設計されており、重い「Executor/Learner」継承を強制しません。FLModel 構造体または単純なデータ交換を使用して、ランタイムと通信してください。

例 1a: PyTorch から FLARE への変換

以下は、多くのスクリプトに適用できる具体的なパターンです。重要な接点は、flare.init()、flare.receive()、モデル重みの読み込み、そして更新された重みとメトリクスを伴う flare.send() です。

左側にローカルトレーニングコード、右側にフェデレーテッド版を示し、import、flare.init()、receive()、send() を強調表示しています。

train.py

# train.py

import torch

import torchvision

import torchvision.transforms as transforms

from model import Net

batch_size = 4

epochs = 1

lr = 0.01

model = Net()

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

loss = torch.nn.CrossEntropyLoss()

optimizer = torch.optim.SGD(model.parameters(), lr=lr, momentum=0.9)

transform = transforms.Compose(

[

transforms.ToTensor(),

transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),

]

)

train_dataset = torchvision.datasets.CIFAR10(

root="/tmp/data/cifar10", transform=transform, download=True, train=True

)

trainloader = torch.utils.data.DataLoader(

train_dataset, batch_size=batch_size, shuffle=True

)

model.to(device)

for epoch in range(epochs):

running_loss = 0.0

for i, batch in enumerate(trainloader):

images, labels = batch[0].to(device), batch[1].to(device)

optimizer.zero_grad()

predictions = model(images)

cost = loss(predictions, labels)

cost.backward()

optimizer.step()

running_loss += cost.cpu().detach().numpy() / batch_size

if i % 3000 == 2999:

print(

f"Epoch: {epoch + 1}/{epochs}, batch: {i + 1}, Loss: {running_loss / 3000}"

)

running_loss = 0.0

print(

f"Epoch: {epoch + 1}/{epochs}, batch: {i + 1}, Loss: {running_loss / (i + 1)}"

)

print("Finished Training")

torch.save(model.state_dict(), "./cifar_net.pth")

client.py

# client.py

1. クライアント API のインポート

import nvflare.client as flare

import torch

import torchvision

import torchvision.transforms as transforms

from model import Net

batch_size = 4

epochs = 1

lr = 0.01

model = Net()

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

loss = torch.nn.CrossEntropyLoss()

optimizer = torch.optim.SGD(model.parameters(), lr=lr, momentum=0.9)

transform = transforms.Compose(

[

transforms.ToTensor(),

transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),

]

)

train_dataset = torchvision.datasets.CIFAR10(

root="/tmp/data/cifar10", transform=transform, download=True, train=True

)

trainloader = torch.utils.data.DataLoader(

train_dataset, batch_size=batch_size, shuffle=True

)

2. FLARE の初期化

flare.init()

FLARE が実行されている間、各ラウンドで

while flare.is_running():

# 3. グローバルモデルの受信

input_model = flare.receive()

# 4. グローバルモデルの読み込み

model.load_state_dict(input_model.params)

model.to(device)

for epoch in range(epochs):

running_loss = 0.0

for i, batch in enumerate(trainloader):

images, labels = batch[0].to(device), batch[1].to(device)

optimizer.zero_grad()

predictions = model(images)

cost = loss(predictions, labels)

cost.backward()

optimizer.step()

running_loss += cost.cpu().detach().numpy() / batch_size

if i % 3000 == 2999:

print(

f"Epoch: {epoch + 1}/{epochs}, batch: {i + 1}, Loss: {running_loss / 3000}"

)

running_loss = 0.0

print(

f"Epoch: {epoch + 1}/{epochs}, batch: {i + 1}, Loss: {running_loss / (i + 1)}"

)

print("Finished Training")

torch.save(model.state_dict(), "./cifar_net.pth")

# 5. Send back the updated model

output_model = flare.FLModel(

params=model.cpu().state_dict(),

meta={"NUM_STEPS_CURRENT_ROUND": len(trainloader) * epochs},

)

flare.send(output_model)

Example 1b: PyTorch Lightning client The Lightning integration keeps the same

The Lightning integration keeps the same **intent—receive global model, train, send updates—but exposes it in a Lightning-friendly way: import the Lightning client adapter and patch the Trainer.

The typical flow is: import, patch, (optional) validate, train as usual.

lightning_client.py

import pytorch_lightning as pl

from pytorch_lightning import Trainer

import nvflare.client.lightning as flare # Lightning Client API

from model import LitNet

from data import CIFAR10DataModule

def main():

model = LitNet()

dm = CIFAR10DataModule()

trainer = Trainer(max_epochs=1, accelerator="gpu", devices=1)

# Patch trainer to participate in FL

flare.patch(trainer)

while flare.is_running():

オプション:現在のグローバルモデルを検証する(サーバー側の選択フローに有用)

trainer.validate(model, datamodule=dm)

# 受信したグローバルモデルから学習を開始する(パッチ適用後、内部で処理される)

trainer.fit(model, datamodule=dm)

if __name__ == "__main__":

main()

ポイント:Lightning ユーザーはカスタム連合メッセージングに切り替える必要はありません。Trainer の抽象化を維持したまま、FL ラウンドに正しく参加できます。

ステップ 2:連合ジョブをパッケージ化し、どこでも実行する(ジョブリシピ)

対象者: 環境を問わず安定したコードファーストのジョブ定義を求めるデータサイエンティストおよび適用チーム。

ステップ 1 で連合クライアントスクリプトを作成しました。ステップ 2 では、それを繰り返し実行可能でライフサイクルを明確に追跡できる連合ジョブに変換します。

ジョブリシピは、JSON ベースのジョブ設定に代わる Python ベースのジョブ定義を提供することを目的としています:

  • コードファースト:複雑な設定ファイルではなく、Python で完全な FL ジョブを定義
  • 1 回記述、どこでも実行:同じレシピがシミュレーター、PoC(概念実証)、または本番環境で動作
  • 展開までの速度:コード構造を変更せずに、実験から展開へ移行可能

例 2a:シミュレーションで FedAvg レシピを実行する

重要なリンクは、レシピがステップ 1 で作成したクライアント学習スクリプト(例:train_script="client.py")を参照している点です。その後、環境内でそれを実行します。

job.py

from nvflare.app_common.workflows.job import FedAvgRecipe

from nvflare.job_config import SimEnv # exact import path can vary by NVFlare version

from model import SimpleNetwork

def main():

n_clients = 3

num_rounds = 5

batch_size = 32

recipe = FedAvgRecipe(

name="hello-pt",

min_clients=n_clients,

num_rounds=num_rounds,

model=SimpleNetwork(),

train_script="client.py", # <-- Step A script

train_args=f"--batch_size {batch_size} --epochs 1",

)

env = SimEnv(num_clients=n_clients, num_threads=n_clients)

recipe.execute(env=env)

if __name__ == "__main__":

main()

This is the “write once” idea in practice: Once the recipe correctly references your client script, the rest becomes an execution concern.

Example 2b: Move from simulation to real-world with an environment swap.

Job recipes formalize a progressive workflow by swapping the execution environment:

  • SimEnv (Simulation): Easy development, rapid debugging
  • PocEnv (Proof-of-Concept): Local runtime, multi-process, realistic testing
  • ProdEnv (Production): Distributed deployment on secure, scalable infrastructure

imageimageFigure 2. One JobRecipe, multiple execution environments: Debug in SimEnv, validate in PocEnv, and deploy in ProdEnv without rewriting the job definition

Getting started

  • Start with a script you already trust.
  • Step 1: Add the client API handshake (or patch your Lightning Trainer).
  • ステップ 2: ジョブリシピでラップし、環境を切り替えて、まずシミュレーションで実行し、次に PoC(概念実証)、そして本番環境へと展開します。

ニュースでの FLARE

FLARE は実際のデプロイメントで登場しています。Rhino Federated Computing によって NVFlare を使用して構築された Eli Lilly TuneLab の連合学習プラットフォーム、台湾 MOHW の国立医療連合学習イニシアチブ、そして機密データセットにわたる Tri-labs (Sandia/LANL/LLNL) の連合 AI パイロット などがその例です。

さらに進むには

すでに信頼しているスクリプトから始めます。最小限の FLARE クライアントハンドシェイク(受信 → 学習 → 送信)を追加します。その後、準備ができたら単一ノードのシミュレーションからマルチサイトデプロイメントへとスケールアップします。

  • ここから始める: Hello World の例(最初の連合実行への最速パス) — NVFlare Hello World
  • ウォークスルーを見る: 簡素化された API スタックの動作を確認 — ウェビナー録画
  • クライアント API ドキュメント
  • JobRecipe ドキュメント
  • GitHub 上の NVFlare

著者について

原文を表示

Federated learning (FL) is no longer a research curiosity—it’s a practical response to a hard constraint: the most valuable data is often the least movable. Regulatory boundaries, data sovereignty rules, and organizational risk tolerance routinely prevent centralized aggregation. Meanwhile, sheer data gravity makes even permitted transfers slow, expensive, and fragile at scale.

The latest version of NVIDIA FLARE addresses this reality with a federated computing runtime that moves the training logic to the data, while raw data stays put. In high-stakes environments, centrally aggregating data is often not possible or practical, so a modern federated platform must treat data isolation, compliance, and privacy-enhancing technologies as first-class requirements.

What has historically slowed adoption isn’t the concept of FL—it’s the developer experience. If the path from “my local script trains” to “my job runs across federated sites” requires deep refactoring, new class hierarchies, or brittle configuration, many projects stall after the pilot.

The FLARE API evolution targets exactly that: eliminating the refactoring overhead by splitting the work into two concrete steps that map cleanly onto how teams actually build and ship ML systems:

  • Step 1 (client API): Turn an existing local training script into a federated client with ~5–6 lines of code, without changing your training loop structure.
  • Step 2 (job recipes): Select the FL workflow and bind it to your client training script, then run the same job across simulation, PoC, and production by swapping only the execution environment.

‘No data copy’ as a system requirement

In regulated or high-sensitivity settings, “just centralize the dataset” is increasingly off the table. A practical federated computing platform needs to support:

  • No data copy: Data stays local, and only model updates (or equivalent signals) move.
  • Compliance posture: Deployment and governance controls that support sovereignty and audit requirements.
  • Privacy-enhancing techniques: Multiple layers of defenses (examples include homomorphic encryption, differential privacy, and confidential computing).
Figure 1. Federated computing keeps data in place, enabling collaboration through model updates while supporting compliance and privacy-enhancing protections.
Figure 1. Federated computing keeps data in place, enabling collaboration through model updates while supporting compliance and privacy-enhancing protections.

The refactoring cliff: Why FL projects stall

Teams typically hit one of two cliffs after the pilot:

  • The code cliff: Converting working PyTorch/TensorFlow/Lightning training into FL can require invasive restructuring—new abstractions, messaging glue, and framework-specific scaffolding.
  • The lifecycle cliff: Even when simulation works, moving to PoC and production triggers rewrites via job redefinition, reconfiguration, and environment-specific branching.

FLARE flattens both cliffs by standardizing the workflow into two steps:

  • Make your script federated (client API)
  • Execute it as a portable job (job recipe)

The intended experience is explicitly to combine these so you can go from zero to an operational federated job quickly.

Step 1: Convert your local training script into a federated client (client API)

Who it’s for: Practitioners and ML engineers with existing training code who want the smallest possible difference.

The mental model is intentionally simple:

  • Initialize the client runtime
  • Loop while the job is running
  • Receive the current global model
  • Train locally (your code)
  • Send updated weights + metrics back

FLARE’s client API is designed for minimal code changes and avoids forcing you into heavy “Executor/Learner” inheritance—use the FLModel structure or simple data exchange to communicate with the runtime.

Example 1a: Convert PyTorch to FLARE

Below is a concrete pattern you can apply to many scripts. The key touchpoints are: flare.init(), flare.receive(), loading model weights, and flare.send() with updated weights and metrics.

We show the local training code on the left and the federated version on the right, highlighting: import, flare.init(), receive(), send().

train.py

code
# train.py

import torch
import torchvision
import torchvision.transforms as transforms

from model import Net

batch_size = 4
epochs = 1
lr = 0.01
model = Net()
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
loss = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=lr, momentum=0.9)
transform = transforms.Compose(
   [
       transforms.ToTensor(),
       transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
   ]
)

train_dataset = torchvision.datasets.CIFAR10(
   root="/tmp/data/cifar10", transform=transform, download=True, train=True
)

trainloader = torch.utils.data.DataLoader(
   train_dataset, batch_size=batch_size, shuffle=True
)

model.to(device)

for epoch in range(epochs):
   running_loss = 0.0

   for i, batch in enumerate(trainloader):
       images, labels = batch[0].to(device), batch[1].to(device)

       optimizer.zero_grad()

       predictions = model(images)
       cost = loss(predictions, labels)
       cost.backward()
       optimizer.step()

       running_loss += cost.cpu().detach().numpy() / batch_size

       if i % 3000 == 2999:
           print(
               f"Epoch: {epoch + 1}/{epochs}, batch: {i + 1}, Loss: {running_loss / 3000}"
           )
           running_loss = 0.0

   print(
       f"Epoch: {epoch + 1}/{epochs}, batch: {i + 1}, Loss: {running_loss / (i + 1)}"
   )

print("Finished Training")

torch.save(model.state_dict(), "./cifar_net.pth")

client.py

code
# client.py

# 1. Import client API
import nvflare.client as flare
import torch
import torchvision
import torchvision.transforms as transforms

from model import Net

batch_size = 4
epochs = 1
lr = 0.01
model = Net()
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
loss = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=lr, momentum=0.9)
transform = transforms.Compose(
   [
       transforms.ToTensor(),
       transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
   ]
)

train_dataset = torchvision.datasets.CIFAR10(
   root="/tmp/data/cifar10", transform=transform, download=True, train=True
)

trainloader = torch.utils.data.DataLoader(
   train_dataset, batch_size=batch_size, shuffle=True
)

# 2. Initialize FLARE
flare.init()

# At each round while FLARE is running
while flare.is_running():
   # 3. Receive the global model
   input_model = flare.receive()

   # 4. Load global model
   model.load_state_dict(input_model.params)
   model.to(device)

   for epoch in range(epochs):
       running_loss = 0.0

       for i, batch in enumerate(trainloader):
           images, labels = batch[0].to(device), batch[1].to(device)

           optimizer.zero_grad()

           predictions = model(images)
           cost = loss(predictions, labels)
           cost.backward()
           optimizer.step()

           running_loss += cost.cpu().detach().numpy() / batch_size

           if i % 3000 == 2999:
               print(
                   f"Epoch: {epoch + 1}/{epochs}, batch: {i + 1}, Loss: {running_loss / 3000}"
               )
               running_loss = 0.0

       print(
           f"Epoch: {epoch + 1}/{epochs}, batch: {i + 1}, Loss: {running_loss / (i + 1)}"
       )

   print("Finished Training")

   torch.save(model.state_dict(), "./cifar_net.pth")

   # 5. Send back the updated model
   output_model = flare.FLModel(
       params=model.cpu().state_dict(),
       meta={"NUM_STEPS_CURRENT_ROUND": len(trainloader) * epochs},
   )
   flare.send(output_model)

Example 1b: PyTorch Lightning client The Lightning integration keeps the same

The Lightning integration keeps the same intent—receive global model, train, send updates—but exposes it in a Lightning-friendly way: import the Lightning client adapter and patch the Trainer.

The typical flow is: import, patch, (optional) validate, train as usual.

# lightning_client.py

import pytorch_lightning as pl

from pytorch_lightning import Trainer

import nvflare.client.lightning as flare # Lightning Client API

from model import LitNet

from data import CIFAR10DataModule

def main():

model = LitNet()

dm = CIFAR10DataModule()

trainer = Trainer(max_epochs=1, accelerator="gpu", devices=1)

# Patch trainer to participate in FL

flare.patch(trainer)

while flare.is_running():

# Optional: validate current global model (useful for server-side selection flows)

trainer.validate(model, datamodule=dm)

# Train starting from received global model (handled internally after patch)

trainer.fit(model, datamodule=dm)

if __name__ == "__main__":

main()

The point: Lightning users don’t have to drop into custom federated messaging—they keep the Trainer abstraction and still participate correctly in FL rounds.

Step 2: Package and execute the federated job anywhere (job recipes)

Who it’s for: Data scientists and applied teams who want a code-first job definition that remains stable across environments.

After step 1, you have a federated client script. Step 2 makes it a federated job you can run repeatedly and move through the lifecycle cleanly.

Job recipes are designed to replace JSON-based job configuration with a Python-based job definition:

  • Code-first: Define complete FL jobs in Python, not complex config files
  • Write once, run anywhere: Same recipe runs in simulator, PoC, or production
  • Speed to deployment: Go from experimentation to deployment without changing code structure

Example 2a: Execute a FedAvg recipe in simulation

The key linkage is that your recipe references the client training script you created in step 1 (e.g., train_script="client.py"), then you execute it in an environment.

# job.py

from nvflare.app_common.workflows.job import FedAvgRecipe

from nvflare.job_config import SimEnv # exact import path can vary by NVFlare version

from model import SimpleNetwork

def main():

n_clients = 3

num_rounds = 5

batch_size = 32

recipe = FedAvgRecipe(

name="hello-pt",

min_clients=n_clients,

num_rounds=num_rounds,

model=SimpleNetwork(),

train_script="client.py", # <-- Step A script

train_args=f"--batch_size {batch_size} --epochs 1",

)

env = SimEnv(num_clients=n_clients, num_threads=n_clients)

recipe.execute(env=env)

if __name__ == "__main__":

main()

This is the “write once” idea in practice: Once the recipe correctly references your client script, the rest becomes an execution concern.

Example 2b: Move from simulation to real-world with an environment swap.

Job recipes formalize a progressive workflow by swapping the execution environment:

  • SimEnv (Simulation): Easy development, rapid debugging
  • PocEnv (Proof-of-Concept): Local runtime, multi-process, realistic testing
  • ProdEnv (Production): Distributed deployment on secure, scalable infrastructure
Figure 2. One JobRecipe, multiple execution environments: Debug in SimEnv, validate in PocEnv, and deploy in ProdEnv without rewriting the job definition
Figure 2. One JobRecipe, multiple execution environments: Debug in SimEnv, validate in PocEnv, and deploy in ProdEnv without rewriting the job definition

Getting started

  • Start with a script you already trust.
  • Step 1: Add the client API handshake (or patch your Lightning Trainer).
  • Step 2: Wrap it in a job recipe and execute first in simulation, then PoC, then production by swapping environments.

FLARE in the News

FLARE is showing up in real deployments—from Eli Lilly TuneLab’s federated learning platform (built by Rhino Federated Computing using NVFlare) to Taiwan MOHW’s national healthcare federated learning initiative, and a Tri-labs (Sandia/LANL/LLNL) federated AI pilot across sensitive datasets.

Going further

Start with a script you already trust. Add the minimal FLARE client handshake (receive → train → send). Then scale from single-node simulation to multi-site deployment when you’re ready.

  • Start here: Hello World examples (fastest path to your first federated run) — NVFlare Hello World
  • Watch the walkthrough: see the simplified API stack in action — Webinar recording
  • Client API docs
  • JobRecipe docs
  • NVFlare on GitHub

About the Authors

この記事をシェア

関連記事

Andrej Karpathy 厳選2026年2月27日 01:22

NVIDIAとAnalyslopについて

著者がNVIDIAとAnalyslopに関する無料記事の執筆を開始することを発表し、前回のニュースレターで編集者の名前が誤って記載されたことを謝罪している。

MIT ML News★42026年4月29日 13:00

一般デバイス上でプライバシーを保護したAI学習を可能にする新手法

MITの研究者らが、連合学習の効率を81%向上させる新手法を開発し、センサーやスマートウォッチなどのリソース制約のあるエッジデバイスでも、ユーザーデータを安全に保ちながら高精度なAIモデルの導入が可能になった。

NVIDIA Developer Blog★42026年6月9日 03:18

NVIDIA Blackwell で NVFP4 を使用し、JAX と MaxText でモデルの学習を高速化

NVIDIA は、Blackwell アーキテクチャ上で NVFP4 技術を活用することで、JAX および MaxText を用いた大規模言語モデルの前学習処理におけるスループットが向上し、学習速度が大幅に改善されることを発表した。

ニュース一覧に戻る元記事を読む