-
+
-
-
-
@@ -899,11 +832,11 @@ const frameworks = [
-
+
-
-
+
+
@@ -925,35 +858,38 @@ const frameworks = [
const frameworkLabels = document.querySelectorAll("#framework-labels > span");
const frameworkDropdown = document.getElementById('framework-dropdown');
const googleColab = document.getElementById('colab-button');
+ const colabButtonWrapper = document.getElementById('colab-button-wrapper');
const githubButton = document.getElementById('github-button');
- const codeTabs = document.getElementById("code-tabs");
+ const codeTabs = document.getElementById("code-tabs");
var sectionMap = {
"install": {
- wrapper: document.getElementById('install-wrapper'),
+ wrapper: document.getElementById('install-wrapper'),
elements: [],
},
"client": {
- wrapper: document.getElementById('client-wrapper'),
+ wrapper: document.getElementById('client-wrapper'),
+ elements: [],
+ },
+ "model": {
+ wrapper: document.getElementById('model-wrapper'),
elements: [],
},
"server": {
- wrapper: document.getElementById('server-wrapper'),
+ wrapper: document.getElementById('model-wrapper'),
elements: [],
},
"job": {
- wrapper: document.getElementById('job-wrapper'),
+ wrapper: document.getElementById('job-wrapper'),
elements: [],
},
"run": {
- wrapper: document.getElementById('run-wrapper'),
+ wrapper: document.getElementById('run-wrapper'),
elements: [],
}
};
- console.log(sectionMap);
-
// Loop over the code sections and create the code elements
frameworks.forEach((framework) => {
framework.sections.forEach((code_section) => {
@@ -962,7 +898,7 @@ const frameworks = [
sectionMap[code_section.type].elements.push(
{
section: code_section,
- code: codeElement,
+ code: codeElement,
framework: code_section.framework
}
);
@@ -986,7 +922,6 @@ const frameworks = [
code_height = "h-[700px]";
if (code_section.hasOwnProperty("highlighted_lines")) {
highlighted_lines = "data-line=\"" + code_section.highlighted_lines + "\" "
- console.log(code_section.title, code_section.type, code_section.hasOwnProperty("highlighted_lines"), highlighted_lines)
}
}
@@ -1040,10 +975,15 @@ const frameworks = [
frameworks.forEach((framework) => {
if (active_framework == framework.id) {
- googleColab?.setAttribute("href", framework.colab_link);
+ if (framework.colab_link) {
+ googleColab?.setAttribute("href", framework.colab_link);
+ colabButtonWrapper?.classList.remove("hidden");
+ } else {
+ colabButtonWrapper?.classList.add("hidden");
+ }
githubButton?.setAttribute("href", framework.github_link);
}
- });
+ });
}
diff --git a/web/src/components/gettingStarted.astro b/web/src/components/gettingStarted.astro
index f265932743..0a7b65b8a1 100644
--- a/web/src/components/gettingStarted.astro
+++ b/web/src/components/gettingStarted.astro
@@ -17,31 +17,32 @@ const walkthrough = [
{
id: "step2",
step: "Step 2",
- title: "Server Code",
+ title: "Job (Recipe)",
description:
- "Use the ModelController API to write a federated control flow for FedAvg.",
+ "Use the Recipe API to define the FL job in Python: job.py with FedAvgRecipe, model, and client script — no separate server file.",
button_text: "View Source",
- link: `https://github.com/NVIDIA/NVFlare/blob/${gh_branch}/nvflare/app_common/workflows/fedavg.py`,
- video: "https://developer.download.nvidia.com/assets/Clara/flare/Flare%202.5.0%20Getting%20Started%20-%20Part%202%20-%20Server.mp4",
+ link: `https://github.com/NVIDIA/NVFlare/blob/${gh_branch}/examples/hello-world/hello-pt/job.py`,
+ // Legacy "Part 2 - Server" video; when re-enabling videos, replace with Recipe/job-focused asset
+ video: "",
},
{
id: "step3",
step: "Step 3",
title: "Client Code",
description:
- "Use the Client API to write local training code for a PyTorch CIFAR-10 trainer.",
+ "Use the Client API to convert your training script into federated learning code (client.py).",
button_text: "View Source",
- link: `https://github.com/NVIDIA/NVFlare/blob/${gh_branch}/examples/getting_started/pt/src/cifar10_fl.py`,
+ link: `https://github.com/NVIDIA/NVFlare/blob/${gh_branch}/examples/hello-world/hello-pt/client.py`,
video: "https://developer.download.nvidia.com/assets/Clara/flare/Flare%202.5.0%20Getting%20Started%20-%20Part%203%20-%20Client.mp4",
},
{
id: "step4",
step: "Step 4",
- title: "FedJob and Simulator",
+ title: "Model & Run",
description:
- "Formulate the NVIDIA FLARE job and simulate a federated run with the multi-process simulator.",
- button_text: "View Notebook",
- link: `https://colab.research.google.com/github/NVIDIA/NVFlare/blob/${gh_branch}/examples/getting_started/pt/nvflare_pt_getting_started.ipynb`,
+ "Model lives in model.py. Run the job with the simulator: python job.py, or open the hello-pt notebook in Colab.",
+ button_text: "View Example",
+ link: `https://github.com/NVIDIA/NVFlare/tree/${gh_branch}/examples/hello-world/hello-pt`,
video: "https://developer.download.nvidia.com/assets/Clara/flare/Flare%202.5.0%20Getting%20Started%20-%20Part%204%20-%20Job.mp4",
},
{
@@ -105,7 +106,7 @@ const series = [
Begin your NVIDIA FLARE journey with these guides
designed to help you quickly grasp essential concepts.
- Follow along with the videos below, and try it out yourself.
+ Follow the steps below and try it out yourself.
@@ -182,7 +183,8 @@ const series = [
-
+
+
))
}
-
+
diff --git a/web/src/components/series.astro b/web/src/components/series.astro
index d4aa7db231..6f5a0601d8 100644
--- a/web/src/components/series.astro
+++ b/web/src/components/series.astro
@@ -157,8 +157,8 @@ const series_100 = {
{
title: "Getting Started",
tags: ["beg.", "pytorch", "lightning", "sklearn", "tensorflow"],
- description: "Getting started examples using the Client API, Model Controller API, and Job API for different frameworks.",
- link: `https://github.com/NVIDIA/NVFlare/tree/${gh_branch}/examples/getting_started`
+ description: "Hello-world examples using the Recipe API (job.py, client.py, model.py) for PyTorch, Lightning, TensorFlow, and more.",
+ link: `https://github.com/NVIDIA/NVFlare/tree/${gh_branch}/examples/hello-world`
},
{
title: "Client API",
@@ -185,10 +185,10 @@ const series_100 = {
link: `https://github.com/NVIDIA/NVFlare/tree/${gh_branch}/examples/hello-world#examples-by-framework`
},
{
- title: "Hello FedAvg",
+ title: "Hello FedAvg (Recipe)",
tags: ["beg.", "pytorch"],
- description: "Demonstrate flexibility of the ModelController API, and show how to write a Federated Averaging workflow with early stopping, model selection, and saving and loading.",
- link: `https://github.com/NVIDIA/NVFlare/tree/${gh_branch}/examples/hello-world/hello-fedavg/README.md`
+ description: "FedAvg using the Recipe API: job.py, client.py, and model.py. Run with the simulator (python job.py).",
+ link: `https://github.com/NVIDIA/NVFlare/tree/${gh_branch}/examples/hello-world/hello-pt`
},
{
title: "Job API Examples",
@@ -308,10 +308,10 @@ const series_200 = {
description: "See how FL algorithms can be implemented in a variety of frameworks.",
cards: [
{
- title: "Hello FedAvg",
+ title: "Hello FedAvg (Recipe)",
tags: ["beg.", "algorithm", "pytorch", "dl"],
- description: "Example using the FedAvg workflow to implement Federated Averaging.",
- link: `https://github.com/NVIDIA/NVFlare/tree/${gh_branch}/examples/hello-world/hello-fedavg/README.md`
+ description: "FedAvg workflow with the Recipe API: job.py, client.py, model.py. Run with python job.py.",
+ link: `https://github.com/NVIDIA/NVFlare/tree/${gh_branch}/examples/hello-world/hello-pt`
},
{
title: "Hello Numpy Cross-Site Validation",