diff --git a/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure1.png b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure1.png new file mode 100644 index 0000000000..45715e64b9 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure1.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure2.png b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure2.png new file mode 100644 index 0000000000..01931b8594 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure2.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure3.png b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure3.png new file mode 100644 index 0000000000..5a8d8a9436 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure3.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure4.png b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure4.png new file mode 100644 index 0000000000..8c22788772 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure4.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure5.png b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure5.png new file mode 100644 index 0000000000..2b1d48d865 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure5.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure6.png b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure6.png new file mode 100644 index 0000000000..1f1c6be737 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure6.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure7.png b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure7.png new file mode 100644 index 0000000000..d48dd2bf4e Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/avh_ppocr/figure7.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/introduction-to-tinyml-on-arm/connect.png b/content/learning-paths/embedded-and-microcontrollers/introduction-to-tinyml-on-arm/connect.png new file mode 100644 index 0000000000..6af713b403 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/introduction-to-tinyml-on-arm/connect.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/introduction-to-tinyml-on-arm/overview.png b/content/learning-paths/embedded-and-microcontrollers/introduction-to-tinyml-on-arm/overview.png new file mode 100644 index 0000000000..cbcd944107 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/introduction-to-tinyml-on-arm/overview.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/jetson_object_detection/balenaetcher1.png b/content/learning-paths/embedded-and-microcontrollers/jetson_object_detection/balenaetcher1.png new file mode 100644 index 0000000000..6318e740ea Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/jetson_object_detection/balenaetcher1.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/FVP running.png b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/FVP running.png deleted file mode 100644 index ef64e15de2..0000000000 Binary files a/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/FVP running.png and /dev/null differ diff --git a/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/cortex-a53_mpidr_el1.png b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/cortex-a53_mpidr_el1.png new file mode 100644 index 0000000000..1f204e5b88 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/cortex-a53_mpidr_el1.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/cortex-a55_mpidr_el1.png b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/cortex-a55_mpidr_el1.png new file mode 100644 index 0000000000..eea3e19a05 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/cortex-a55_mpidr_el1.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/fvp.png b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/fvp.png new file mode 100644 index 0000000000..cb0b76090b Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/fvp.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/select_target.png b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/select_target.png new file mode 100644 index 0000000000..e428b7aa14 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/linux-on-fvp/select_target.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/cmsis-rtx_missing.png b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/cmsis-rtx_missing.png new file mode 100644 index 0000000000..23a31f7c89 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/cmsis-rtx_missing.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/coredebug_uvision.png b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/coredebug_uvision.png new file mode 100644 index 0000000000..1706587529 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/coredebug_uvision.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/device_missing.png b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/device_missing.png new file mode 100644 index 0000000000..9a9b1ee390 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/device_missing.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/eventrecorder_migration.png b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/eventrecorder_migration.png new file mode 100644 index 0000000000..fb4f06a639 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/eventrecorder_migration.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/io_migration.png b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/io_migration.png new file mode 100644 index 0000000000..2b5aa12196 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/io_migration.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/os_tick_missing.png b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/os_tick_missing.png new file mode 100644 index 0000000000..5f262287ad Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/project-migration-cmsis-v6/os_tick_missing.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/raspberry-pi-smart-home/ui3.png b/content/learning-paths/embedded-and-microcontrollers/raspberry-pi-smart-home/ui3.png new file mode 100644 index 0000000000..bc4dfecd52 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/raspberry-pi-smart-home/ui3.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/callstacklocals.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/callstacklocals.png new file mode 100644 index 0000000000..afc60d58ec Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/callstacklocals.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/callstacklocals_caller_callee.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/callstacklocals_caller_callee.png new file mode 100644 index 0000000000..2d0fa0acc6 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/callstacklocals_caller_callee.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/gmsticksmemory.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/gmsticksmemory.png new file mode 100644 index 0000000000..c9a1e662d5 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/gmsticksmemory.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/gmstickswatch.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/gmstickswatch.png new file mode 100644 index 0000000000..6f97e3a9ea Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/gmstickswatch.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloop.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloop.png new file mode 100644 index 0000000000..48728386a2 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloop.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloopdisassembly.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloopdisassembly.png new file mode 100644 index 0000000000..872f26252a Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloopdisassembly.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloopstopped.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloopstopped.png new file mode 100644 index 0000000000..ce8dd7a005 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/mainwhileloopstopped.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/managebkpt.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/managebkpt.png new file mode 100644 index 0000000000..496dc1cef9 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/managebkpt.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/periodicwindowupdate.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/periodicwindowupdate.png new file mode 100644 index 0000000000..82fafd16f1 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/periodicwindowupdate.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/systemcoreclockwatch.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/systemcoreclockwatch.png new file mode 100644 index 0000000000..ebf593c735 Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/systemcoreclockwatch.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/uv_debug/systicktimerwindow.png b/content/learning-paths/embedded-and-microcontrollers/uv_debug/systicktimerwindow.png new file mode 100644 index 0000000000..1a38093d8d Binary files /dev/null and b/content/learning-paths/embedded-and-microcontrollers/uv_debug/systicktimerwindow.png differ diff --git a/content/learning-paths/embedded-and-microcontrollers/visualizing-ethos-u-performance/7-configure-fvp-gui.md b/content/learning-paths/embedded-and-microcontrollers/visualizing-ethos-u-performance/7-configure-fvp-gui.md index 6e6ac5cf91..66e462500e 100644 --- a/content/learning-paths/embedded-and-microcontrollers/visualizing-ethos-u-performance/7-configure-fvp-gui.md +++ b/content/learning-paths/embedded-and-microcontrollers/visualizing-ethos-u-performance/7-configure-fvp-gui.md @@ -70,7 +70,7 @@ Now run the Mobilenet V2 computer vision model, using [executorch/examples/arm/r Observe that the FVP loads the model file, compiles the PyTorch model to ExecuTorch `.pte` format and then shows an instruction count in the top right of the GUI: -![Terminal and FVP output#center](./Terminal%20and%20FVP%20Output.jpg "Terminal and FVP output") +![Terminal and FVP output#center](./terminal_and_fvp_output.jpg "Terminal and FVP output") {{% notice Note %}} diff --git a/content/learning-paths/embedded-and-microcontrollers/visualizing-ethos-u-performance/Terminal and FVP Output.jpg b/content/learning-paths/embedded-and-microcontrollers/visualizing-ethos-u-performance/terminal_and_fvp_output.jpg similarity index 100% rename from content/learning-paths/embedded-and-microcontrollers/visualizing-ethos-u-performance/Terminal and FVP Output.jpg rename to content/learning-paths/embedded-and-microcontrollers/visualizing-ethos-u-performance/terminal_and_fvp_output.jpg diff --git a/content/learning-paths/laptops-and-desktops/windowsperf-vs-extension/spe-settings.png b/content/learning-paths/laptops-and-desktops/windowsperf-vs-extension/spe-settings.png new file mode 100644 index 0000000000..be7e91b010 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/windowsperf-vs-extension/spe-settings.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/ams/images/fa_render_graph_1.1.gif b/content/learning-paths/mobile-graphics-and-gaming/ams/images/fa_render_graph_1.1.gif new file mode 100644 index 0000000000..9e74966d16 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/ams/images/fa_render_graph_1.1.gif differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_render_graph_1.1.gif b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_render_graph_1.1.gif new file mode 100644 index 0000000000..9e74966d16 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_render_graph_1.1.gif differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_sphinx.png b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_sphinx.png new file mode 100644 index 0000000000..de50e00fac Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_sphinx.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_step_drawcalls.gif b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_step_drawcalls.gif new file mode 100644 index 0000000000..4c8d438306 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/fa_step_drawcalls.gif differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/pillars.gif b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/pillars.gif new file mode 100644 index 0000000000..3090674db0 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/pillars.gif differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt.png b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt.png new file mode 100644 index 0000000000..d95c51389f Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt_redundant_attachments.png b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt_redundant_attachments.png new file mode 100644 index 0000000000..e267572f04 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt_redundant_attachments.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt_redundant_rps.png b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt_redundant_rps.png new file mode 100644 index 0000000000..f642472ef1 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/analyze_a_frame_with_frame_advisor/render_graph_egypt_redundant_rps.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/gameactivityarchitecture.png b/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/gameactivityarchitecture.png new file mode 100644 index 0000000000..717875772e Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/gameactivityarchitecture.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/streamline-mali-analysis.png b/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/streamline-mali-analysis.png new file mode 100644 index 0000000000..a7ec578686 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/streamline-mali-analysis.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/streamline-mali-timeline.png b/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/streamline-mali-timeline.png new file mode 100644 index 0000000000..799734c347 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/android_webgpu_dawn/images/streamline-mali-timeline.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/best-practices-for-hwrt-lumen-performance/images/garage.png b/content/learning-paths/mobile-graphics-and-gaming/best-practices-for-hwrt-lumen-performance/images/garage.png new file mode 100644 index 0000000000..ac645476e1 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/best-practices-for-hwrt-lumen-performance/images/garage.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/best-practices-for-hwrt-lumen-performance/images/garage2.png b/content/learning-paths/mobile-graphics-and-gaming/best-practices-for-hwrt-lumen-performance/images/garage2.png new file mode 100644 index 0000000000..a9aa31fc13 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/best-practices-for-hwrt-lumen-performance/images/garage2.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/2-app-scaffolding.md b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/2-app-scaffolding.md index b4815c9309..635b71a766 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/2-app-scaffolding.md +++ b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/2-app-scaffolding.md @@ -30,12 +30,12 @@ Before you start coding, here are some useful tips: 1. Navigate to **File** > **New** > **New Project**. 2. Select **Empty Views Activity** in the **Phone and Tablet** gallery as Figure 1 shows, then select **Next**. -![Empty Views Activity.png alt-text#center](images/2/empty%20project.png "Figure 1: Select Empty Views Activity.") +![Empty Views Activity.png alt-text#center](images/2/empty_project.png "Figure 1: Select Empty Views Activity.") 3. Choose a project name, and select the default configurations as Figure 2 shows. Make sure that the **Language** field is set to **Kotlin**, and the **Build configuration language** field is set to **Kotlin DSL**. -![Project configuration.png alt-text#center](images/2/project%20config.png "Figure 2: Project Configuration.") +![Project configuration.png alt-text#center](images/2/project_config.png "Figure 2: Project Configuration.") ## Add CameraX dependencies @@ -45,7 +45,7 @@ Before you start coding, here are some useful tips: 2. Once the project is synced, navigate to `libs.versions.toml` in your project's root directory. See Figure 3. This file serves as the version catalog for all dependencies that the project uses. -![Version Catalog.png alt-text#center](images/2/dependency%20version%20catalog.png "Figure 3: Version Catalog.") +![Version Catalog.png alt-text#center](./images/2/dependency_version_catalog.png "Figure 3: Version Catalog.") {{% notice Info %}} @@ -88,20 +88,20 @@ camera-view = { group = "androidx.camera", name = "camera-view", version.ref = " 2. You should see that a notification appears. See Figure 4. Click **Sync Now** to sync your project. -![Gradle sync.png alt-text#center](images/2/gradle%20sync.png "Figure 4: Gradle Sync.") +![Gradle sync.png alt-text#center](images/2/gradle_sync.png "Figure 4: Gradle Sync.") {{% notice Tip %}} You can also click the **Sync Project with Gradle Files** button in the toolbar, or enter the corresponding shortcut to start a sync. -![Sync Project with Gradle Files](images/2/sync%20project%20with%20gradle%20files.png) +![Sync Project with Gradle Files](images/2/sync_project_with_gradle_files.png) {{% /notice %}} 3. Navigate to the `MainActivity.kt` source file and make the changes that Figure 5 shows in the View Binding screenshot. This inflates the layout file into a view binding object, and stores it in a member variable within the view controller for easier access later. -![view binding alt-text#center](images/2/view%20binding.png "Figure 5: View Binding.") +![view binding alt-text#center](images/2/view_binding.png "Figure 5: View Binding.") ## Configure CameraX preview diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/4-introduce-mediapipe.md b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/4-introduce-mediapipe.md index 77779e81bf..613348da8b 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/4-introduce-mediapipe.md +++ b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/4-introduce-mediapipe.md @@ -106,7 +106,7 @@ See the previous section [Set up the Development Environment](../2-app-scaffoldi 2. Now you should see both model asset bundles in your `assets` directory, as shown below: -![model asset bundles](images/4/model%20asset%20bundles.png) +![model asset bundles](images/4/model_asset_bundles.png) 3. You are ready to import MediaPipe's Face Landmark Detection and Gesture Recognizer into the project. diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/6-flow-data-to-view-1.md b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/6-flow-data-to-view-1.md index e624bdab77..da0d63928c 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/6-flow-data-to-view-1.md +++ b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/6-flow-data-to-view-1.md @@ -366,5 +366,5 @@ class GestureOverlayView(context: Context?, attrs: AttributeSet?) : 4. Build and run the app again. Now you should see face and gesture overlays on top of the camera preview as shown below. Good job! -![overlay views alt-text#center](images/6/overlay%20views.png "Figure 7: Face and Gesture Overlays.") +![overlay views alt-text#center](images/6/overlay_views.png "Figure 7: Face and Gesture Overlays.") diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/7-flow-data-to-view-2.md b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/7-flow-data-to-view-2.md index 14355c8f0c..ff1bdd5923 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/7-flow-data-to-view-2.md +++ b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/7-flow-data-to-view-2.md @@ -132,7 +132,7 @@ This makes sure each of the three parallel `launch` code sections run in its own 5. Build and run the app again. Now you should see two switches on the bottom of the screen as shown below, which turn on and off while you smile and show thumb-up gestures. Good job! -![indicator UI alt-text#center](images/7/indicator%20ui.png "Figure 8: Indicator UI.") +![indicator UI alt-text#center](images/7/indicator_ui.png "Figure 8: Indicator UI.") ## Recap on SharedFlow vs StateFlow diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/dependency version catalog.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/dependency_version_catalog.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/dependency version catalog.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/dependency_version_catalog.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/empty project.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/empty_project.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/empty project.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/empty_project.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/gradle sync.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/gradle_sync.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/gradle sync.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/gradle_sync.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/project config.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/project_config.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/project config.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/project_config.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/sync project with gradle files.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/sync_project_with_gradle_files.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/sync project with gradle files.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/sync_project_with_gradle_files.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/view binding.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/view_binding.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/view binding.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/2/view_binding.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/4/model asset bundles.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/4/model_asset_bundles.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/4/model asset bundles.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/4/model_asset_bundles.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/6/overlay views.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/6/overlay_views.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/6/overlay views.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/6/overlay_views.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/7/indicator ui.png b/content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/7/indicator_ui.png similarity index 100% rename from content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/7/indicator ui.png rename to content/learning-paths/mobile-graphics-and-gaming/build-android-selfie-app-using-mediapipe-multimodality/images/7/indicator_ui.png diff --git a/content/learning-paths/mobile-graphics-and-gaming/profiling-ml-on-arm/streamline.png b/content/learning-paths/mobile-graphics-and-gaming/profiling-ml-on-arm/streamline.png new file mode 100644 index 0000000000..e02ea645ce Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/profiling-ml-on-arm/streamline.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/profiling-unity-apps-on-android/images/import-window-step-1.PNG b/content/learning-paths/mobile-graphics-and-gaming/profiling-unity-apps-on-android/images/import-window-step-1.PNG new file mode 100644 index 0000000000..c70222b3c8 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/profiling-unity-apps-on-android/images/import-window-step-1.PNG differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/ray_tracing/images/rquery_diagram.svg b/content/learning-paths/mobile-graphics-and-gaming/ray_tracing/images/rquery_diagram.svg new file mode 100644 index 0000000000..683c43ca72 --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/ray_tracing/images/rquery_diagram.svg @@ -0,0 +1 @@ +Acceleration Structure TraversalProceed?Ray QueryHandle resultConfirm hit or terminate \ No newline at end of file diff --git a/content/learning-paths/mobile-graphics-and-gaming/ray_tracing/images/rtpipeline_diagram.svg b/content/learning-paths/mobile-graphics-and-gaming/ray_tracing/images/rtpipeline_diagram.svg new file mode 100644 index 0000000000..0572f83772 --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/ray_tracing/images/rtpipeline_diagram.svg @@ -0,0 +1 @@ +Ray GenerationAny-HitIntersectionClosest-HitMissAcceleration Structure TraversalHit? \ No newline at end of file diff --git a/content/learning-paths/mobile-graphics-and-gaming/using_unity_machine_learning_agents/images/unityhubinstalls.png b/content/learning-paths/mobile-graphics-and-gaming/using_unity_machine_learning_agents/images/unityhubinstalls.png new file mode 100644 index 0000000000..331827c3c2 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/using_unity_machine_learning_agents/images/unityhubinstalls.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/vision-llm-inference-on-android-with-kleidiai-and-mnn/loading_page.png b/content/learning-paths/mobile-graphics-and-gaming/vision-llm-inference-on-android-with-kleidiai-and-mnn/loading_page.png new file mode 100644 index 0000000000..db0a530ff4 Binary files /dev/null and b/content/learning-paths/mobile-graphics-and-gaming/vision-llm-inference-on-android-with-kleidiai-and-mnn/loading_page.png differ diff --git a/content/learning-paths/mobile-graphics-and-gaming/vulkan-ml-sample/2-ml-ext-for-vulkan.md b/content/learning-paths/mobile-graphics-and-gaming/vulkan-ml-sample/2-ml-ext-for-vulkan.md index 42bc9bc559..b5cb34af04 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/vulkan-ml-sample/2-ml-ext-for-vulkan.md +++ b/content/learning-paths/mobile-graphics-and-gaming/vulkan-ml-sample/2-ml-ext-for-vulkan.md @@ -45,7 +45,7 @@ You must use a version >= 1.4.321 for the Vulkan SDK. For this Learning Path, a pre-built of package of the emulation layers is available. Download them by clicking the link. -[ML Emulation Layer for Vulkan](https://www.arm.com/-/media/Files/developer/MLEmulationLayerForVulkan) +[ML Emulation Layer for Vulkan](https://www.arm.com/-/media/Files/developer/MLEmulationLayerForVulkan20251107) Extract the downloaded file in a location of your choice. You’re now ready to enable the emulation layers in Vulkan Configurator. diff --git a/content/learning-paths/servers-and-cloud-computing/csp/images/armarch.png b/content/learning-paths/servers-and-cloud-computing/csp/images/armarch.png new file mode 100644 index 0000000000..7cb22107b5 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/csp/images/armarch.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/csp/images/azureavailability.png b/content/learning-paths/servers-and-cloud-computing/csp/images/azureavailability.png new file mode 100644 index 0000000000..f23175e2a2 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/csp/images/azureavailability.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/csp/images/azureimage.png b/content/learning-paths/servers-and-cloud-computing/csp/images/azureimage.png new file mode 100644 index 0000000000..f746a3cc61 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/csp/images/azureimage.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/csp/images/azurekey.png b/content/learning-paths/servers-and-cloud-computing/csp/images/azurekey.png new file mode 100644 index 0000000000..9310d50bc9 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/csp/images/azurekey.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/ebs.png b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/ebs.png new file mode 100644 index 0000000000..13f8422e2e Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/ebs.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/iops.png b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/iops.png new file mode 100644 index 0000000000..37d9d49bde Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/iops.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/_index.md b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/_index.md index 1b1e96f4bb..9daf5ab6e3 100644 --- a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/_index.md @@ -1,24 +1,20 @@ --- -title: From x86 to Arm on GKE - Build, Deploy, and Migrate with Google Axion - -draft: true -cascade: - draft: true +title: Migrate x86 workloads to Arm on Google Kubernetes Engine with Axion processors minutes_to_complete: 90 -who_is_this_for: This is an advanced topic for cloud, platform, and site reliability engineers operating Kubernetes on Google Cloud who need a prescriptive path to build multi-architecture images and migrate services from x86 to Arm using Google Axion processors. +who_is_this_for: This is an advanced topic for cloud, platform, and site reliability engineers who operate Kubernetes on Google Cloud and need to build multi-architecture images and migrate services from x86 to Arm using Google Axion processors. learning_objectives: - Prepare Dockerfiles for multi-architecture builds by adding arm64 support - - Create a dual-architecture GKE standard cluster with two node pools, amd64 and arm64 - - Build and publish multi-architecture images to Artifact Registry using Docker Buildx without using QEMU to emulate Arm instructions - - Deploy a Kubernetes application amd64 first, then migrate to arm64 using Kustomize overlays and progressive rollout - - Optionally automate builds and rollouts with Cloud Build and Skaffold + - Create a dual-architecture GKE standard cluster with amd64 and arm64 node pools + - Build and publish multi-architecture images to Artifact Registry using Docker Buildx + - Deploy a Kubernetes application on amd64, then migrate to arm64 using Kustomize overlays + - Automate builds and rollouts with Cloud Build and Skaffold prerequisites: - A [Google Cloud account](https://console.cloud.google.com/) with billing enabled - - A local Linux or macOS computer or Cloud Shell access with Docker, Kubernetes CLI (kubectl), Google Cloud CLI (gcloud), and Git installed + - A local Linux or macOS computer with Docker, Kubernetes CLI (kubectl), Google Cloud CLI (gcloud), and Git installed, or access to Google Cloud Shell - Basic familiarity with Docker, Kubernetes, and gcloud author: @@ -40,11 +36,11 @@ tools_software_languages: further_reading: - resource: - title: GKE documentation + title: Google Kubernetes Engine documentation link: https://cloud.google.com/kubernetes-engine/docs type: documentation - resource: - title: Create Arm-based clusters and node pools + title: Create standard clusters and node pools with Arm nodes link: https://cloud.google.com/kubernetes-engine/docs/how-to/create-arm-clusters-nodes type: documentation diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/background.md b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/background.md new file mode 100644 index 0000000000..14c8c87180 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/background.md @@ -0,0 +1,50 @@ +--- +# User change +title: "Explore the benefits of migrating microservices to Arm on GKE" + +weight: 2 + +# Do not modify these elements +layout: "learningpathall" +--- + +## Overview + +This Learning Path shows you how to migrate a microservices application from x86 to Arm on Google Kubernetes Engine (GKE) using multi-architecture container images. You'll work with Google's Online Boutique, a sample application built with multiple programming languages. The migration requires no code changes, making it a straightforward example of moving to Arm-based Google Axion processors. + + +## Why use Google Axion processors for GKE? + +Google Axion processors bring modern Arm-based compute to GKE. You get strong price-performance and energy efficiency for cloud-native, scale-out services. With multi-architecture images and mixed node pools, you can migrate services from x86 to Arm gradually, with no major code changes. + +## What is Google Axion? + +[Google Axion](https://cloud.google.com/blog/products/compute/introducing-googles-new-arm-based-cpu) is Google Cloud's Arm-based CPU family built on Arm Neoverse, for general-purpose, cloud-native services and CPU-based AI. You can deploy it for workloads like web apps and web servers, containerized microservices, open-source databases, in-memory caches, data analytics, media processing, and CPU-based AI inference and data processing. On GKE, you can leverage Axion through the C4A and N4A VM families, paired with Google's Titanium offloads to free CPU cycles for application work. + +## Why migrate to Arm on GKE? +There are three clear benefits to consider when considering migrating to Arm on GKE: + +- Price-performance: you can run more workload per unit of cost, which is particularly valuable for scale-out services that need to handle increasing traffic efficiently. +- Energy efficiency: you reduce power usage for always-on microservices, lowering both operational costs and environmental impact. +- Compatibility: you can migrate containerized applications with build and deploy changes only—no code rewrites are required, making the transition straightforward. + +## Learn about the Online Boutique sample application + +[Online Boutique](https://github.com/GoogleCloudPlatform/microservices-demo) is a polyglot microservices storefront, complete with shopping cart, checkout, catalog, ads, and recommendations. It's implemented in Go, Java, Python, .NET, and Node.js, with ready-to-use Dockerfiles and Kubernetes manifests. It's a realistic example for demonstrating an x86 to Arm migration with minimal code changes. + +## Multi-architecture on GKE (pragmatic path) + +This Learning Path demonstrates a practical migration approach using Docker Buildx with a Kubernetes driver. Your builds run natively inside BuildKit pods on GKE node pools—no QEMU emulation needed. You'll add an Arm node pool alongside your existing x86 nodes, then use node selectors and affinity rules to control where services run. This lets you migrate safely, one service at a time. + +## How this Learning Path demonstrates migration + +You'll migrate the Online Boutique application from x86 to Arm step by step. You'll build multi-architecture container images and use mixed node pools, so you can test each service on Arm before you fully commit to the migration. + +The migration process involves these steps: + +- Open Google Cloud Shell and set up the environment variables. +- Enable required APIs, create an Artifact Registry repository, and authenticate Docker. +- Create a GKE Standard cluster with an amd64 node pool and add an arm64 (Axion-based C4A) node pool. +- Create a Buildx (Kubernetes driver) builder that targets both pools, then build and push multi-architecture images (amd64 and arm64) natively using BuildKit pods. +- Deploy to amd64 first (Kustomize overlay), validate, then migrate to arm64 (overlay) and verify. +- Automate builds and rollouts with Cloud Build and Skaffold. \ No newline at end of file diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/cloud-build.md b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/cloud-build.md index 711646d610..a4840880bb 100644 --- a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/cloud-build.md +++ b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/cloud-build.md @@ -1,14 +1,16 @@ --- title: Automate builds and rollout with Cloud Build and Skaffold -weight: 6 +weight: 7 ### FIXED, DO NOT MODIFY layout: learningpathall --- -Google [**Cloud Build**](https://cloud.google.com/build/docs/set-up) is a managed CI/CD service that runs your containerized build and deploy steps in isolated runners. +## Automate the deployment with Cloud Build -In this section, you'll automate the flow you performed manually: build multi-arch images, deploy to GKE on amd64, then migrate to arm64, and print the app's external IP. +Google [Cloud Build](https://cloud.google.com/build/docs/set-up) is a managed CI/CD service that runs your containerized build and deploy steps in isolated runners. + +In this section, you automate the flow you performed manually: build multi-arch images, deploy to GKE on amd64, then migrate to arm64, and print the app's external IP. ## What does this pipeline do? @@ -19,9 +21,8 @@ The pipeline performs the following steps: - Connects to your GKE cluster - Applies the amd64 Kustomize overlay, verifies pods, then applies the arm64 overlay and verifies pods again - Prints the frontend-external LoadBalancer IP at the end - {{% notice Tip %}} -Run this from the microservices-demo repo root in Cloud Shell. Ensure you completed the previous steps. +Run this command from the `microservices-demo` repository root in Cloud Shell. Make sure you've completed the previous steps. {{% /notice %}} ## Grant IAM permission to the Cloud Build service account @@ -110,7 +111,7 @@ YAML This pipeline installs Docker with Buildx in the runner, enables QEMU, builds two services as examples (extend as desired), connects to your cluster, deploys to amd64, verifies, migrates to arm64, verifies, and prints the external IP.  -Run the commands to create the `cloudbuild.yaml` file. +Run the commands to create the `cloudbuild.yaml` file: ```yaml cat > cloudbuild.yaml <<'YAML' @@ -263,3 +264,36 @@ Open http:// in your browser. ``` Open the URL to load the storefront and confirm the full build, deploy, and migrate flow is automated. + +![Storefront reachable after Cloud Build deploy/migrate (arm64) #center](images/storefront-running-on-google-axion.jpeg "Storefront after Cloud Build automation on Axion (arm64)") + + +## What you've accomplished + +Congratulations! You've successfully automated the entire build, deploy, and migration workflow using Cloud Build and Skaffold. Your multi-architecture application runs natively on Arm-powered GKE nodes, and you can deploy updates automatically with a single command. + +You've learned how to: + +- Update Dockerfiles to support native builds on both amd64 and arm64 architectures +- Create a dual-architecture GKE cluster with separate node pools for each platform +- Build multi-architecture container images using Docker Buildx with native BuildKit pods +- Deploy applications to amd64 nodes, then migrate them to arm64 nodes using Kustomize overlays +- Automate the entire workflow with Cloud Build and Skaffold for continuous deployment + +## What's next + +Now that you have a working multi-architecture deployment pipeline, you can explore these next steps: + +- Optimize for Arm performance: profile your services on arm64 nodes to identify optimization opportunities. Arm Neoverse processors offer different performance characteristics than x86, so you might discover new ways to improve throughput or reduce latency. + +- Expand your migration: add build steps for the remaining Online Boutique services. You can extend the `cloudbuild.yaml` file to build all services, not just the two examples provided. + +- Implement progressive rollouts: use Skaffold profiles and Cloud Build triggers to set up canary deployments or blue-green deployments across architectures. This lets you test changes on a subset of traffic before rolling out to all users. + +- Monitor architecture-specific metrics: set up monitoring dashboards in Cloud Monitoring to compare performance, resource usage, and cost between amd64 and arm64 deployments. This data helps you make informed decisions about your migration strategy. + +- Explore cost optimization: review your GKE cluster costs and consider rightsizing your node pools. Arm-based C4A instances often provide better price-performance for cloud-native workloads, so you might reduce costs while maintaining or improving performance. + + + + diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/gke-build-push.md b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/gke-build-push.md index f9ba2e79f6..58336e5d72 100644 --- a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/gke-build-push.md +++ b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/gke-build-push.md @@ -1,11 +1,13 @@ --- -title: Provision a dual-architecture GKE cluster and publish images -weight: 4 +title: Build and deploy multi-architecture images on GKE +weight: 5 ### FIXED, DO NOT MODIFY layout: learningpathall --- +## Create a cluster and build the multi-arch images + You are ready to create a GKE cluster with two node pools (amd64 and arm64), then build and push multi-arch images natively on those node pools. Each architecture uses its own BuildKit pod, and no QEMU emulation is required. @@ -40,7 +42,7 @@ This approach prevents users on the default VPC from accidentally setting NETWOR Create a GKE Standard cluster with VPC-native (IP aliasing) enabled and no default node pool. You'll add amd64 and arm64 pools in the next step. -The command below works for both default and custom VPCs. If the NETWORK, SUBNET, and secondary range variables are unset, GKE uses the default VPC and manages ranges automatically. +The command below works for both default and custom VPCs. If the NETWORK, SUBNET, and secondary range variables are unset, GKE uses the default VPC and manages ranges automatically: ```bash # Cluster vars (reuses earlier PROJECT_ID/REGION/ZONE) diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/gke-deploy.md b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/gke-deploy.md index 6dc0e4b539..c04eaaf355 100644 --- a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/gke-deploy.md +++ b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/gke-deploy.md @@ -1,18 +1,18 @@ --- title: Prepare manifests and deploy on GKE -weight: 5 +weight: 6 ### FIXED, DO NOT MODIFY layout: learningpathall --- +## Prepare deployment manifests -You'll now configure the application manifests to use your Artifact Registry images and create Kustomize overlays for different CPU architectures. This allows you to deploy the same application to both x86 and Arm node pools. +You'll now configure the application manifests to use your Artifact Registry images and create Kustomize overlays for different CPU architectures. This allows you to deploy the same application to both x86 and Arm node pools by replacing sample image references with your Artifact Registry path and tag, then creating overlays to select nodes by architecture. -## Prepare deployment manifests -Replace sample image references with your Artifact Registry path and tag, then create Kustomize overlays to select nodes by architecture. +## Update base manifests to use your images -### Point base manifests at your images +Replace the sample image references in the base manifests with your Artifact Registry path and tag: Replace the image references with your references: @@ -29,7 +29,10 @@ find kustomize/base -name "*.yaml" -type f -exec \ grep -r "${GAR}" kustomize/base/ || true ``` -### Create node-selector overlays +You’ve updated your deployment manifests to reference your own Artifact Registry images. This ensures your application uses the multi-architecture containers you built for Arm and x86. + + +## Create node-selector overlays Create node-selector overlays for targeting specific architectures. @@ -79,7 +82,7 @@ cat << 'EOF' > kustomize/overlays/arm64/node-selector.yaml EOF ``` -You now have updated manifests that reference your container images and Kustomize overlays that target specific CPU architectures. +You’ve updated your deployment manifests to reference your own Artifact Registry images. This ensures your application uses the multi-architecture containers you built for Arm and x86. ## Deploy to the x86 (amd64) pool @@ -101,6 +104,8 @@ kubectl get pods -o=custom-columns=NAME:.metadata.name,NODE:.spec.nodeName,STATU Pods should be scheduled on nodes labeled `kubernetes.io/arch=amd64`. +You’ve deployed your application to the x86 node pool and verified pod placement. This confirms your manifests and overlays work as expected before migrating to Arm. + ## Migrate to the Arm (arm64) pool Apply the arm64 overlay to move workloads: @@ -117,6 +122,8 @@ kubectl get pods -o wide You should see pods now running on nodes where `kubernetes.io/arch=arm64`. +You’ve migrated your workloads to the Arm node pool. Pods now run on Arm-based nodes, demonstrating a successful architecture transition. + ## Verify external access Get the LoadBalancer IP and open the storefront: @@ -138,5 +145,6 @@ Copy the EXTERNAL-IP value and open it in a new browser tab: http:// ``` -The microservices storefront loads, confirming that your application is accessible and functional on the arm64 node pool. +The microservices storefront loads, confirming that your application is accessible and functional on the arm64 node pool. You’re now running a production-ready microservices storefront on Arm-powered GKE infrastructure. +![Online Boutique storefront running on Google Axion (arm64) nodes in GKE #center](images/storefront-running-on-google-axion.jpeg "Online Boutique storefront running on Google Axion (arm64) nodes in GKE") diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/images/storefront-running-on-google-axion.jpeg b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/images/storefront-running-on-google-axion.jpeg new file mode 100644 index 0000000000..64a4b205a6 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/images/storefront-running-on-google-axion.jpeg differ diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/multi-arch-images.md b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/multi-arch-images.md index c1e6a3dd0b..15524a8c22 100644 --- a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/multi-arch-images.md +++ b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/multi-arch-images.md @@ -1,33 +1,40 @@ --- title: Create build-ready Dockerfiles for both architectures -weight: 3 +weight: 4 ### FIXED, DO NOT MODIFY layout: learningpathall --- -With your environment set up, you're ready to modify the Online Boutique services to support multi-architecture builds. +## Update Dockerfiles to support multi-architecture builds -You will patch some Dockerfiles so they build cleanly for both architectures. In the next section, you will build and push images using a GKE-native Buildx builder. +Now that your environment set up, you're now ready to modify the Online Boutique services to support multi-architecture builds. + +You will patch some Dockerfiles so they build cleanly for both architectures. ## Services to edit -Most services already build for both architectures. +Most services in Online Boutique already build for both architectures without any changes. -The four listed below need small changes: +Four services need small updates: - emailservice - recommendationservice - loadgenerator - cartservice -These edits don't change application behavior, they only ensure the right compiler headers and runtime libraries are present per architecture. This includes Python native wheels for email/recommendation/loadgen, and system `protoc` for the .NET cartservice. +These edits ensure the correct compiler headers and runtime libraries are present for each architecture. The changes include: + +- Python native wheels for emailservice, recommendationservice, and loadgenerator +- System `protoc` for the .NET cartservice + +These updates don't change application behavior. {{% notice Note %}} Production migrations begin with assessing cross-architecture compatibility for each service (base images, native extensions such as CGO/JNI, platform-specific packages, and CI build targets). This section demonstrates minor Dockerfile edits for four representative services. In the referenced Online Boutique release, the remaining services generally build for both **amd64** and **arm64** without modification. {{% /notice %}} -### Update the emailservice Dockerfile +## Update the emailservice Dockerfile You can review the [emailservice Dockerfile](https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/refs/heads/main/src/emailservice/Dockerfile) before replacing it. @@ -73,21 +80,18 @@ EOF Here is a summary of the changes: -- **BuildKit syntax** unlocks `--mount=type=cache` to speed rebuilds. -- **TARGETPLATFORM** lets Buildx set linux/amd64 vs linux/arm64 explicitly. -- **Dev vs runtime packages:** build stage compiles native wheels; final stage keeps only needed shared libs. -- **`--prefer-binary`** avoids source builds when wheels exist (more reliable across arches). -- **Removed extra `apk update`** since `apk add --no-cache` already avoids stale indexes & caches. +- The updated Dockerfile uses BuildKit syntax to enable cache mounts, which speed up rebuilds. +- The `TARGETPLATFORM` argument allows Buildx to explicitly set the target architecture (either `linux/amd64` or `linux/arm64`). The build follows a two-stage approach: the builder stage compiles native wheels with necessary development packages, while the final runtime stage includes only the required shared libraries. +- The `--prefer-binary` flag helps avoid building from source when pre-built wheels are available, making builds more reliable across architectures. The update also removes the extra `apk update` command because `apk add --no-cache` already handles index updates without creating a cache. -## Apply updates to the other three services +## Apply updates to recommendationservice, loadgenerator, and cartservice Run the following sed commands to automatically patch the remaining Dockerfiles. ### Update the recommendationservice Dockerfile +You can review the [recommendationservice Dockerfile](https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/refs/heads/main/src/recommendationservice/Dockerfile) before modifying it. -You can review the [recommendationservice Dockerfile](https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/refs/heads/main/src/recommendationservice/Dockerfile) before modifying it. - -Paste the command below to your terminal to update the file with the required multi-architecture changes. +Run the following command to update the file with the required multi-architecture changes: ```bash sed -i \ @@ -101,17 +105,13 @@ sed -i \ src/recommendationservice/Dockerfile ``` -Here is a summary of the changes: - -- Make the base image architecture-aware -- Let native wheels build cleanly -- Keep the runtime slim & predictable +The three key changes are to make the base image architecture-aware, let native wheels build cleanly, and keep the runtime slim and predictable. ### Update loadgenerator Dockerfile You can review the [loadgenerator Dockerfile](https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/refs/heads/main/src/loadgenerator/Dockerfile) before modifying it. -Paste the command below to your terminal to run `sed` to update the file with the required multi-architecture changes. +Run the following command to update the file with the required multi-architecture changes: ```bash FILE=src/loadgenerator/Dockerfile @@ -135,17 +135,12 @@ sed -i -E \ "$FILE" ``` -Here is a summary of the changes: - -- Make the base image architecture-aware -- Fix native build/run deps -- Keep runtime lean and no flags/app code changed +The changes focus on three key areas. First, make the base image architecture-aware so it automatically selects the correct variant for your platform. Second, fix native build and runtime dependencies to ensure they match the target architecture. Third, keep the runtime environment lean—you don't need to change any flags or application code. ### Update cartservice Dockerfile You can review the [carkservice Dockerfile](https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/refs/heads/main/src/cartservice/src/Dockerfile) before replacing it. - -Paste the command below to your terminal to update the file with the required multi-architecture changes. +Run the following command to update the file with the required multi-architecture changes: ```bash FILE=src/cartservice/src/Dockerfile @@ -164,14 +159,17 @@ sed -i \ Here is a summary of the changes: -- Install the system `protoc` command -- Force MSBuild to use the supplied `protoc` command -- No behavioral changes +- Install the system `protoc` compiler in the builder image +- Configure MSBuild to use the installed `protoc` instead of downloading one + +These changes don't affect application behavior. {{% notice Note %}} -`ARG TARGETPLATFORM` + `FROM --platform=$TARGETPLATFORM` is not strictly required if you always build with --platform and your base image is multi-arch. Keeping it is good practice and makes intent explicit and does not change runtime behavior. +Using `ARG TARGETPLATFORM` and `FROM --platform=$TARGETPLATFORM` isn't strictly required when you build with `--platform` and your base image supports multiple architectures. However, keeping these declarations makes your build intent explicit and doesn't change runtime behavior. {{% /notice %}} -After making the Dockerfile modification, all services now support multi-architecture builds. +After updating these Dockerfiles, all services support multi-architecture builds. You're ready to build and push images using a GKE-native Buildx builder. Great job! + + diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/project-setup.md b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/project-setup.md index 635930445e..add9c84efc 100644 --- a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/project-setup.md +++ b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch-axion/project-setup.md @@ -1,63 +1,24 @@ --- # User change -title: "Overview and Environment Setup" +title: "Set up your environment" -weight: 2 # 1 is first, 2 is second, etc. +weight: 3 # 1 is first, 2 is second, etc. # Do not modify these elements layout: "learningpathall" --- -This Learning Path demonstrates how to migrate a real microservices application from x86 to Arm (amd64 to arm64) on GKE using multi-architecture container images. The sample application is Google's Online Boutique, a polyglot microservices system that mirrors production architectures and ships with Dockerfiles. It's a realistic, real-world scenario, and the migration can be done with no major code changes. - -## Why Google Axion processors for GKE? - -Google Axion processors bring modern Arm-based compute to GKE, delivering strong price-performance and energy efficiency for cloud-native, scale-out services. With multi-architecture images and mixed node pools, services can migrate from x86 to Arm gradually, with no major code changes. - -### What is Google Axion? - -[Google Axion](https://cloud.google.com/blog/products/compute/introducing-googles-new-arm-based-cpu) is Google Cloud's Arm-based CPU family built on Arm Neoverse, designed for general-purpose, cloud-native services and CPU-based AI. Typical workloads include web apps and web servers, containerized microservices, open-source databases, in-memory caches, data analytics, media processing, and CPU-based AI inference and data processing. On GKE, Axion powers the C4A and N4A VM families and is paired with Google's Titanium offloads to free CPU cycles for application work. - -### Why migrate to Arm on GKE? - -There are three factors motivating the move to Google Axion processors: - -- **Price-performance:** run more workload per dollar for scale-out services -- **Energy efficiency:** reduce power usage for always-on microservices -- **Compatibility:** containerized apps typically migrate with build/deploy changes, and don't require code rewrites - -### About the Online Boutique sample application - -[Online Boutique](https://github.com/GoogleCloudPlatform/microservices-demo) is a polyglot microservices storefront, complete with shopping cart, checkout, catalog, ads, and recommendations. It's implemented in Go, Java, Python, .NET, and Node.js, with ready-to-use Dockerfiles and Kubernetes manifests. It's a realistic example for demonstrating an x86 to Arm migration with minimal code changes. - -### Multi-architecture on GKE (pragmatic path) - -This Learning Path presents a pragmatic migration approach that builds both amd64 and arm64 images using Docker Buildx with a Kubernetes driver, where builds run natively inside BuildKit pods on your GKE node pools without requiring QEMU emulation. You'll add an Arm node pool alongside existing x86 nodes, then use node selectors and affinity rules to control placement and migrate safely, service by service. - -### How this Learning Path demonstrates the migration - -You'll migrate the Online Boutique application from x86 to Arm using a practical, low-risk approach that leverages multi-architecture container images and mixed node pools. This allows you to validate each service on Arm before fully committing to the migration, ensuring compatibility and performance meet your requirements. - -The steps below outline the migration process: - -1. Open Google Cloud Shell and set the environment variables. -2. Enable required APIs, create an Artifact Registry repository, and authenticate Docker. -3. Create a GKE Standard cluster with an amd64 node pool and add an arm64 (Axion-based C4A) node pool. -4. Create a Buildx (Kubernetes driver) builder that targets both pools, then build and push multi-architecture images (amd64 and arm64) natively via BuildKit pods. -5. Deploy to amd64 first (Kustomize overlay), validate, then migrate to arm64 (overlay) and verify. -6. Automate builds and rollouts with Cloud Build and Skaffold. - ## Get started in Cloud Shell -Use [Cloud Shell](https://cloud.google.com/shell/docs/using-cloud-shell) to set variables, enable APIs, create Artifact Registry, authenticate Docker, and clone the sample microservices demo. +You can use [Cloud Shell](https://cloud.google.com/shell/docs/using-cloud-shell) to set variables, enable APIs, create Artifact Registry, authenticate Docker, and clone the sample microservices demo. -Make sure `kubectl`, `gcloud`, `docker`, and `git` commands are installed. +Make sure you have the following tools installed: `kubectl`, `gcloud`, `docker`, and `git`. {{% notice Note %}} You can use your local macOS or Linux computer instead of Cloud Shell. Make sure the required software is installed. {{% /notice %}} -### Set environment variables +## Set environment variables Run the following commands in your terminal to set the project, region/zone, cluster, and Artifact Registry variables: @@ -80,7 +41,7 @@ gcloud config set compute/zone "${ZONE}" You'll need the environment variables in any shell you use to work on the project. -### Enable required Google Cloud APIs +## Enable the required Google Cloud APIs Enable the required APIs so the project can create GKE clusters, push and pull container images in Artifact Registry, and use Cloud Build for CI/CD: @@ -88,7 +49,7 @@ Enable the required APIs so the project can create GKE clusters, push and pull c gcloud services enable container.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com ``` -### Create an Artifact Registry (Docker) repository +## Create an Artifact Registry (Docker) repository Create a Docker repository in Artifact Registry in this region for pushing and pulling your multi-architecture images: @@ -96,7 +57,7 @@ Create a Docker repository in Artifact Registry in this region for pushing and p gcloud artifacts repositories create "${REPO}" --repository-format=docker --location="${REGION}" --description="Multi-arch images for microservices demo" ``` -### Authenticate Docker to Artifact Registry +## Authenticate Docker to Artifact Registry Authenticate Docker to Artifact Registry so you can push and pull images: @@ -104,7 +65,7 @@ Authenticate Docker to Artifact Registry so you can push and pull images: gcloud auth configure-docker "${REGION}-docker.pkg.dev" ``` -### Clone the Online Boutique sample microservices application +## Clone the Online Boutique sample microservices application Clone the sample application repository: diff --git a/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterapigw.png b/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterapigw.png new file mode 100644 index 0000000000..37d5a6ee82 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterapigw.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterfileserver.png b/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterfileserver.png new file mode 100644 index 0000000000..96310ae3f6 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterfileserver.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterrp.png b/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterrp.png new file mode 100644 index 0000000000..f1c820b7aa Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/nginx_tune/beforeandafterrp.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/nginx_tune/exampletestsetup.png b/content/learning-paths/servers-and-cloud-computing/nginx_tune/exampletestsetup.png new file mode 100644 index 0000000000..b8cc15d1b7 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/nginx_tune/exampletestsetup.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/postgresql_tune/beforeandafter.png b/content/learning-paths/servers-and-cloud-computing/postgresql_tune/beforeandafter.png new file mode 100644 index 0000000000..6d22bb7fe8 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/postgresql_tune/beforeandafter.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard1.png b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard1.png new file mode 100644 index 0000000000..65c0ad6965 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard1.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard2.png b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard2.png new file mode 100644 index 0000000000..9b719815b8 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard2.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard3.png b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard3.png new file mode 100644 index 0000000000..c6d06abb5d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-dashboard3.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-data.png b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-data.png new file mode 100644 index 0000000000..d04d48a86d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-data.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-sentiment.png b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-sentiment.png new file mode 100644 index 0000000000..cf081542b7 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/kibana-sentiment.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/sentiment-analysis.png b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/sentiment-analysis.png new file mode 100644 index 0000000000..b39715be72 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_images/sentiment-analysis.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/1-overview-and-build.md b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/1-overview-and-build.md new file mode 100644 index 0000000000..bc4bfb3e32 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/1-overview-and-build.md @@ -0,0 +1,120 @@ +--- +title: Overview and Optimized Build +weight: 2 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## What is vLLM? + +vLLM is an open‑source, high‑throughput inference and serving engine for large language models. It focuses on efficient execution of the LLM inference prefill and decode phases with: + +- Continuous batching to keep hardware busy across many requests. +- KV cache management to sustain concurrency during generation. +- Token streaming so results appear as they are produced. + +You interact with vLLM in multiple ways: + +- OpenAI‑compatible server: expose `/v1/chat/completions` for easy integration. +- Python API: load a model and generate locally when needed. + +vLLM works well with Hugging Face models, supports single‑prompt and batch workloads, and scales from quick tests to production serving. + +## What you build + +You build a CPU‑optimized vLLM for aarch64 with oneDNN and the Arm Compute Library (ACL). You then validate the build with a quick offline chat example. + +## Why this is fast on Arm + +- Optimized kernels: The aarch64 vLLM build uses direct oneDNN with the Arm Compute Library for key operations. +- 4‑bit weight quantization: INT4 quantization support & acceleration by Arm KleidiAI microkernels. +- Efficient MoE execution: Fused INT4 quantized expert layers reduce memory traffic and improve throughput. +- Optimized Paged attention: Arm SIMD tuned paged attention implementation in vLLM. +- System tuning: Thread affinity and `tcmalloc` help keep latency and allocator overhead low under load. + +## Before you begin + +- Use Python 3.12 on Ubuntu 22.04+ +- Make sure you have at least 32 vCPUs, 64 GB RAM, and 32 GB free disk. + +Install the minimum system package used by vLLM on Arm: + +```bash +sudo apt-get update -y +sudo apt-get install -y libnuma-dev +``` + +Optional performance helper you can install now or later: + +```bash +sudo apt-get install -y libtcmalloc-minimal4 +``` + +{{% notice Note %}} +On aarch64, vLLM’s CPU backend automatically builds with Arm Compute Library via oneDNN. +{{% /notice %}} + +## Build vLLM for aarch64 CPU + +Create and activate a virtual environment: + +```bash +python3 -m venv vllm_env +source vllm_env/bin/activate +python -m pip install --upgrade pip +``` + +Clone vLLM and install build requirements: + +```bash +git clone https://github.com/vllm-project/vllm.git +cd vllm +git checkout 5fb4137 +pip install -r requirements/cpu.txt -r requirements/cpu-build.txt +``` + +Build a wheel targeted at CPU: + +```bash +VLLM_TARGET_DEVICE=cpu python3 setup.py bdist_wheel +``` + +Install the wheel. Use `--no-deps` for incremental installs to avoid clobbering your environment: + +```bash +pip install --force-reinstall dist/*.whl # fresh install +# pip install --no-deps --force-reinstall dist/*.whl # incremental build +``` + +{{% notice Tip %}} +Do NOT delete vLLM repo. Local vLLM repository is required for corect inferencing on aarch64 CPU after installing the wheel. +{{% /notice %}} + +## Quick validation via offline inferencing + +Run the built‑in chat example to confirm the build: + +```bash +python examples/offline_inference/basic/chat.py \ + --dtype=bfloat16 \ + --model TinyLlama/TinyLlama-1.1B-Chat-v1.0 +``` + +You should see tokens streaming and a final response. This verifies the optimized vLLM build on your Arm server. + +```output +Generated Outputs: +-------------------------------------------------------------------------------- +Prompt: None + +Generated text: 'The Importance of Higher Education\n\nHigher education is a fundamental right' +-------------------------------------------------------------------------------- +Adding requests: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 10/10 [00:00<00:00, 9552.05it/s] +Processed prompts: 100%|████████████████████████████████████████████████████████████████████████| 10/10 [00:01<00:00, 6.78it/s, est. speed input: 474.32 toks/s, output: 108.42 toks/s] +... +``` + +{{% notice Note %}} +As CPU support in vLLM continues to mature, manual builds will be replaced by a simple `pip install` flow for easier setup in near future. +{{% /notice %}} diff --git a/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/2-quantize-model.md b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/2-quantize-model.md new file mode 100644 index 0000000000..a5d472ccce --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/2-quantize-model.md @@ -0,0 +1,148 @@ +--- +title: Quantize an LLM to INT4 for Arm Platform +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +You can accelerate many LLMs on Arm CPUs with 4‑bit quantization. In this guide, we use `deepseek-ai/DeepSeek-V2-Lite` as the example model which gets accelerated by the INT4 path in vLLM using Arm KleidiAI microkernels. + +## Install quantization tools + +Install the vLLM model quantization packages + +```bash +pip install --no-deps compressed-tensors +pip install llmcompressor +``` + +Reinstall your locally built vLLM if you rebuilt it: + +```bash +pip install --no-deps dist/*.whl +``` + +If your chosen model is gated on Hugging Face, authenticate first: + +```bash +huggingface-cli login +``` + +## INT4 Quantization recipe + +Save the following as `quantize_vllm_models.py`: + +```python +import argparse +import os +import torch +from transformers import AutoModelForCausalLM, AutoTokenizer + +from compressed_tensors.quantization import QuantizationScheme +from compressed_tensors.quantization.quant_args import ( + QuantizationArgs, + QuantizationStrategy, + QuantizationType, +) + +from llmcompressor import oneshot +from llmcompressor.modifiers.quantization.quantization import QuantizationModifier + + +def main(): + parser = argparse.ArgumentParser(description="Quantize a model using INT4 with minmax or mse and dynamic activation quantization.") + parser.add_argument("model_id", type=str, help="Model identifier or path") + parser.add_argument("--method", type=str, choices=["minmax", "mse"], default="mse", help="Quantization method") + parser.add_argument("--scheme", type=str, choices=["channelwise", "groupwise"], required=True, help="Quantization scheme for weights") + parser.add_argument("--groupsize", type=int, default=32, help="Group size for groupwise quantization") + args = parser.parse_args() + + # Extract base model name for output dir + base_model_name = os.path.basename(args.model_id.rstrip("/")) + act_tag = "a8dyn" + suffix = f"{args.method}-{args.scheme}" + if args.scheme == "groupwise": + suffix += f"-g{args.groupsize}" + output_dir = f"{base_model_name}-w4{act_tag}-{suffix}" + + print(f"Loading model '{args.model_id}'...") + model = AutoModelForCausalLM.from_pretrained( + args.model_id, trust_remote_code=True + ) + model = model.to(torch.float32) + tokenizer = AutoTokenizer.from_pretrained(args.model_id) + + # Weight quantization args + strategy = QuantizationStrategy.CHANNEL if args.scheme == "channelwise" else QuantizationStrategy.GROUP + weights_args = QuantizationArgs( + num_bits=4, + type=QuantizationType.INT, + strategy=strategy, + symmetric=True, + dynamic=False, + group_size=args.groupsize if args.scheme == "groupwise" else None, + observer=args.method, + ) + + # Activation quantization + input_acts = QuantizationArgs( + num_bits=8, + type=QuantizationType.INT, + strategy=QuantizationStrategy.TOKEN, + symmetric=False, + dynamic=True, + observer=None, + ) + output_acts = None + + # Create quantization scheme and recipe + scheme = QuantizationScheme( + targets=["Linear"], + weights=weights_args, + input_activations=input_acts, + output_activations=output_acts, + ) + recipe = QuantizationModifier( + config_groups={"group_0": scheme}, + ignore=["lm_head"], + ) + + # Run quantization + oneshot( + model=model, + recipe=recipe, + tokenizer=tokenizer, + output_dir=output_dir, + trust_remote_code_model=True, + ) + + print(f"Quantized model saved to: {output_dir}") + + +if __name__ == "__main__": + main() +``` + +This script creates a Arm KleidiAI 4‑bit quantized copy of the vLLM model and saves it to a new directory. + +## Quantize DeepSeek‑V2‑Lite model + +### Quantization parameter tuning +1. You can choose `minmax` (faster model quantization) or `mse` (more accurate but slower model quantization) method. +2. `channelwise` is a good default for most models. +3. `groupwise` can improve accuracy further; `--groupsize 32` is common. + +```bash +# DeepSeek example +python quantize_vllm_models.py deepseek-ai/DeepSeek-V2-Lite \ + --scheme channelwise --method mse +``` + +The 4-bit quantized DeepSeek-V2-Lite will be stored the directory: + +```text +DeepSeek-V2-Lite-w4a8dyn-mse-channelwise +``` + +You will load this quantized model directory with vLLM in the next step. diff --git a/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/3-run-inference-and-serve.md b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/3-run-inference-and-serve.md new file mode 100644 index 0000000000..dae1806711 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/3-run-inference-and-serve.md @@ -0,0 +1,126 @@ +--- +title: Serve high throughput inference with vLLM +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## About batch sizing in vLLM + +vLLM enforces two limits to balance memory use and throughput: a per‑sequence length (`max_model_len`) and a per‑batch token limit (`max_num_batched_tokens`). No single request can exceed the sequence limit, and the sum of tokens in a batch must stay within the batch limit. + +## Serve an OpenAI‑compatible API + +Start the server with sensible CPU default parameters and a quantized model: + +```bash +export VLLM_TARGET_DEVICE=cpu +export VLLM_CPU_KVCACHE_SPACE=32 +export VLLM_CPU_OMP_THREADS_BIND="0-$(($(nproc)-1))" +export VLLM_MLA_DISABLE=1 +export ONEDNN_DEFAULT_FPMATH_MODE=BF16 +export OMP_NUM_THREADS="$(nproc)" +export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libtcmalloc_minimal.so.4 + +vllm serve DeepSeek-V2-Lite-w4a8dyn-mse-channelwise \ + --dtype float32 --max-model-len 4096 --max-num-batched-tokens 4096 +``` + +## Run multi‑request batch + +After confirming a single request works explained in previous example, simulate concurrent load with a small OpenAI API compatible client. Save this as `batch_test.py`: + +```python +import asyncio +import time +from openai import AsyncOpenAI + +# vLLM's OpenAI-compatible server +client = AsyncOpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY") + +model = "DeepSeek-V2-Lite-w4a8dyn-mse-channelwise" # vllm server model + +# Batch of 8 prompts +messages_list = [ + [{"role": "user", "content": "Explain Big O notation with two examples."}], + [{"role": "user", "content": "Show a simple recursive function and explain how it works."}], + [{"role": "user", "content": "Draft a polite email requesting a project deadline extension."}], + [{"role": "user", "content": "Explain what a hash function is and common uses."}], + [{"role": "user", "content": "Explain binary search and its time complexity."}], + [{"role": "user", "content": "Write a Python function that checks if a string is a palindrome."}], + [{"role": "user", "content": "Explain how caching improves performance with a simple analogy."}], + [{"role": "user", "content": "Explain the difference between supervised and unsupervised learning."}], +] + +CONCURRENCY = 8 + +async def run_one(i: int, messages): + resp = await client.chat.completions.create( + model=model, + messages=messages, + max_tokens=128, # Change as per comfiguration + ) + return i, resp.choices[0].message.content + +async def main(): + t0 = time.time() + sem = asyncio.Semaphore(CONCURRENCY) + + async def guarded_run(i, msgs): + async with sem: + try: + return await run_one(i, msgs) + except Exception as e: + return i, f"[ERROR] {type(e).__name__}: {e}" + + tasks = [asyncio.create_task(guarded_run(i, msgs)) for i, msgs in enumerate(messages_list, start=1)] + results = await asyncio.gather(*tasks) # order corresponds to tasks list + + # Print outputs in input order + results.sort(key=lambda x: x[0]) + for idx, out in results: + print(f"\n=== Output {idx} ===\n{out}\n") + + print(f"Batch completed in : {time.time() - t0:.2f}s") + +if __name__ == "__main__": + asyncio.run(main()) +``` + +Run 8 concurrent requests against your server: + +```bash +python3 batch_test.py +``` + +This validates multi‑request behavior and shows aggregate throughput in the server logs. + +```output +(APIServer pid=4474) INFO 11-10 01:00:56 [loggers.py:221] Engine 000: Avg prompt throughput: 19.7 tokens/s, Avg generation throughput: 187.2 tokens/s, Running: 8 reqs, Waiting: 0 reqs, GPU KV cache usage: 1.6%, Prefix cache hit rate: 0.0% +(APIServer pid=4474) INFO: 127.0.0.1:44060 - "POST /v1/chat/completions HTTP/1.1" 200 OK +(APIServer pid=4474) INFO: 127.0.0.1:44134 - "POST /v1/chat/completions HTTP/1.1" 200 OK +(APIServer pid=4474) INFO: 127.0.0.1:44076 - "POST /v1/chat/completions HTTP/1.1" 200 OK +(APIServer pid=4474) INFO: 127.0.0.1:44068 - "POST /v1/chat/completions HTTP/1.1" 200 OK +(APIServer pid=4474) INFO: 127.0.0.1:44100 - "POST /v1/chat/completions HTTP/1.1" 200 OK +(APIServer pid=4474) INFO: 127.0.0.1:44112 - "POST /v1/chat/completions HTTP/1.1" 200 OK +(APIServer pid=4474) INFO: 127.0.0.1:44090 - "POST /v1/chat/completions HTTP/1.1" 200 OK +(APIServer pid=4474) INFO: 127.0.0.1:44120 - "POST /v1/chat/completions HTTP/1.1" 200 OK +(APIServer pid=4474) INFO 11-10 01:01:06 [loggers.py:221] Engine 000: Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 57.5 tokens/s, Running: 0 reqs, Waiting: 0 reqs, GPU KV cache usage: 0.0%, Prefix cache hit rate: 0.0% +``` +## Optional: Serving BF16 non-quantized model + +For a BF16 path on Arm, vLLM is acclerated by direct oneDNN integration in vLLM which allows aarch64 model to be hyperoptimized. + +```bash +vllm serve deepseek-ai/DeepSeek-V2-Lite \ + --dtype bfloat16 --max-model-len 4096 \ + --max-num-batched-tokens 4096 +``` + +## Go Beyond: Power Up Your vLLM Workflow +Now that you’ve successfully quantized and served a model using vLLM on Arm, here are some further ways to explore: + +* **Try different models:** Apply the same steps to other [Hugging Face models](https://huggingface.co/models) like Llama, Qwen or Gemma. + +* **Connect a chat client:** Link your server with OpenAI-compatible UIs like [Open WebUI](https://github.com/open-webui/open-webui) \ No newline at end of file diff --git a/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_index.md b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_index.md new file mode 100644 index 0000000000..2b404b1df2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_index.md @@ -0,0 +1,67 @@ +--- +title: High throughput LLM serving using vLLM on Arm Servers + +draft: true +cascade: + draft: true + +minutes_to_complete: 60 + +who_is_this_for: This learning path is for software developers and AI engineers who want to build an optimized vLLM for Arm servers, quantize models to INT4, and serve them through an OpenAI‑compatible API. + +learning_objectives: + - Build an optimized vLLM for aarch64 with oneDNN + Arm Compute Library. + - Set up dependencies including PyTorch and llmcompressor dependencies. + - Quantize an LLM (DeepSeek‑V2‑Lite) to 4‑bit weights. + - Run and serve the quantized model using vLLM & test BF16 non‑quantized serving. + - Use OpenAI‑compatible endpoints and understand sequence and batch limits. + +prerequisites: + - An Arm-based Linux server (Ubuntu 22.04+ recommended) with 32+ vCPUs, 64+ GB RAM, and 32+ GB free disk. + - Python 3.12 and basic familiarity with Hugging Face Transformers and quantization. + - Optional: a Hugging Face token to access gated models. + +author: + - Nikhil Gupta + +### Tags +skilllevels: Introductory +subjects: ML +armips: + - Neoverse +operatingsystems: + - Linux +tools_software_languages: + - vLLM + - LLM + - Generative AI + - Python + - PyTorch + - llmcompressor + +further_reading: + - resource: + title: vLLM Documentation + link: https://docs.vllm.ai/ + type: documentation + - resource: + title: vLLM GitHub Repository + link: https://github.com/vllm-project/vllm + type: github + - resource: + title: Hugging Face Model Hub + link: https://huggingface.co/models + type: website + - resource: + title: Build and Run vLLM on Arm Servers + link: /learning-paths/servers-and-cloud-computing/vllm/ + type: website + + + +### FIXED, DO NOT MODIFY +# ================================================================================ +weight: 1 +layout: "learningpathall" +learning_path_main_page: "yes" +--- diff --git a/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/migration/arm-migration-overview.png b/content/migration/arm-migration-overview.png new file mode 100644 index 0000000000..337519f31d Binary files /dev/null and b/content/migration/arm-migration-overview.png differ diff --git a/content/migration/bottom-up.png b/content/migration/bottom-up.png new file mode 100644 index 0000000000..938e27cccb Binary files /dev/null and b/content/migration/bottom-up.png differ diff --git a/content/migration/top-down.png b/content/migration/top-down.png new file mode 100644 index 0000000000..40bc75305a Binary files /dev/null and b/content/migration/top-down.png differ