Scaling Up (Part 2)
Key Takeaways
Scales Flax NNX models using JAX's distributed computing capabilities and SPMD paradigm
Full Transcript
[music] Hi, I'm Robert Crowe. Uh, welcome back to part two of our three-part series on sharding and parallelism. Let's explore how to scale your flax enx models using Jax's powerful distributed computing capabilities, specifically its SPMD paradigm. If you're coming from PyTorch and have started using Jax and Flax NNX, you know that modern models often outgrow single accelerators. We'll discuss Jax's approach to parallelism and how NX integrates with it seamlessly. This episode focuses on the main workflow, how to integrate Jax's sharding primitives with Flaxen and X with a special focus on the critical sharded initialization pattern. So let's get started. In our last episode, we laid the foundation for scaling our models. We explored why distributed training is essential and covered the core strategies like data and model parallelism. We then introduced the fundamental JAX primitives, the mesh to define our hardware topology, the partition spec to describe how our tensors should be laid out, and JAX.jit JIT which triggers the SPMD compilation. Now we're going to build on that foundation and connect it directly to Flax NX. Okay, let's quickly recap Flax NX. Unlike Pure Jacks, NNX modules are stateful Python objects much like PyTorch modules. They hold their parameters and other state directly as attributes usually initialized eagerly. A crucial feature for us today is that these state variables can store metadata. We'll use this to attach our sharding hints. However, this statefulness traditionally clashes with Jax's functional nature. The big news is that in NNx uh version 0.11 and and after is that NNX modules are now native Jack PI trees. This closes a major conceptual gap that we had in earlier versions. While the module object itself is still a mutable Python object, it can now be understood directly by Jack's transformations. And NNX provides the bridge to handle this correctly. So how do we reconcile NX's mutable objects with Jax's functional transformations? Well, NX provides two ways. First, the functional API. You explicitly split your module into its static definition and its dynamic state which is a JAX compatible PI tree. You pass this state through jacks.jit or jacks.grad to get the result and then merge or update the original module. Alternatively, NNX provides its own wrappers like nx.jit and nx.grad. These handle the split merge process under the hood, giving you a more seamless experience, although potentially with some slight overhead compared to the manual functional API. Now, let's connect NNX and SPMD. The Flax NX SPMD module lets us attach those partition spec hints directly to our parameters as metadata. When we define the module, we can use helper functions like nxxwith metadata around your initializer passing a sharding argument with the partition spec tupil. Sometimes you can even pass the sharding argument directly to nx.param. This stores a partition spec tupil in ashsharding attribute on the variable state. Crucially, this doesn't shard the parameter yet. It's just metadata, a hint for later. Here's what those two options look like in code. First, the preferred method using nx.withth metadata. Second, annotating the variable directly. In this case, nx.param. Okay, this is the core workflow and addresses a common pitfall. If you just instantiate a very large NNx model, even with sharding annotations, Jax might try to create all parameters on a single default device first, leading to a anom or out of memory error. The solution is to perform the initialization and the application of sharding inside a JIT compiled function. We'll use nx.jit for convenience. Inside this function, the first steps are instantiate the module. The parameters are created but likely still on device zero and then extract its functional state pi tree using nx.state. Continuing inside our jitted initialization function, next we use nx.spmd.get partition spec. This utility function walks through the state pi tree we just extracted and pulls out all the dotsharding metadata we added earlier creating a parallel pi tree of partitionspec objects. Then comes the crucial step. We use jacks.laxwithsharting constraint passing in the original state and the partition specs we just extracted. This tells the Jack's compiler, when you produce the final result for this state, make sure it conforms to these sharding specifications. Here's what that last part looks like in code. We use nx.spmd.getartition spec to pull out all thesharting metadata we added earlier, creating a parallel pie of partition spec objects. Then we use jacks.laxwish lax with sharding constraint passing in the original state and the partition specs we just extracted. The final step inside the jitted function is to use nx.update. This takes the sharted state which Jackson XLA will ensure is correctly distributed upon execution and merges it back into our original mutable model object. The function then returns this model. The key is to call this entire create sharded model function while inside a width mesh block or a mesh context. This provides the context Jax needs to actually fulfill the sharding constraints across the specified devices. The result sharted model now holds parameters physically distributed across the mesh avoiding the single device om or out of memory. So inside the jitted function we get our sharted state and merge it back into the model with nx update. Then finally we execute that jitted function in a with mesh context. For better abstraction instead of hard- coding data or model inside your module definitions you can use logical access names like batch sequence or embed or hidden. You then define a separate mapping called sharding rules that translates these logical names to your actual physical mesh access names. You can provide these rules when initializing variables or attach them later. This makes your model code more portable and easier to adapt to different hardware setups or sharding strategies as you only need to change the rules and not the model definition itself. Here's an example of using sharding rules to map logical axis names to physical mesh axes. We define sharding rules as a tupole of pairs where each pair maps a logical name like batch or hidden to a physical mesh axis like data or model. For example, batch data means that anything annotated with batch will be sharted along the data axis of the mesh. You then use these logical names in your NNX module definition when initializing parameters, providing the sharding rules through nx.with metadata. And this approach allows you to define your model independently of the specific hardware layout, making your code more flexible and adaptable to different sharding strategies. You can learn more about Jax and the entire Jax AI stack with these coding exercises, quick reference docs, and slides. To watch the whole Learning Jack series, check out our playlist on YouTube. There's a growing community on Discord for Jax. And here's an invite link and here are links to the docs for Jax Flax and the Jax AI stack. We've just walked through the most critical part of this entire process. how to safely initialize a massive sharded NNx model. By annotating our parameters with sharding metadata and wrapping the instantiation inside a jitted function with the wish sharding constraint, we've solved the single device om or out of memory problem and now have a model with its parameters physically distributed across our accelerator mesh. We've started our model, but what's next? How do we feed it data, run the training step, manage checkpoints, and see all of this in action with a real world example? Coming up in our next episode, we'll put it all together. We'll build the distributed training loop, discuss efficient data loading with grain and sharded checkpointing with Orbbacks, and then walk through a complete practical example of sharding a GPT2 style transformer block from start to finish. See you there and don't forget to hit like and subscribe.
Original Description
Welcome back to part two of our three part series on sharding and parallelism! Let’s explore how to scale your Flax NNX models using JAX's powerful distributed computing capabilities, specifically its SPMD paradigm. If you're coming from PyTorch and have started using JAX and Flax NNX, you know that modern models often outgrow single accelerators. We’ll discuss JAX's approach to parallelism, and how NNX integrates with it seamlessly. This episode focuses on the main workflow: how to integrate JAX's sharding primitives with Flax NNX, with a special focus on the critical sharded initialization pattern.
Resources:
Learn more → https://goo.gle/learning-jax
Subscribe to Google for Developers → https://goo.gle/developers
Speaker: Robert Crowe
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Google for Developers · Google for Developers · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Developer Journey - Sunnyvale DSC Summit ‘19
Google for Developers
How Google is working with students - Sunnyvale DSC Summit ‘19
Google for Developers
Starting your career in the Cloud - Sunnyvale DSC Summit ‘19
Google for Developers
The Solution Challenge - Sunnyvale DSC Summit ‘19
Google for Developers
Firebase - Sunnyvale DSC Summit ‘19
Google for Developers
Cloud Hero - Sunnyvale DSC Summit ‘19
Google for Developers
Panel discussion - Sunnyvale DSC Summit ‘19
Google for Developers
The art of negotiation - Sunnyvale DSC Summit ‘19
Google for Developers
Courage to care, solve and share - Sunnyvale DSC Summit ‘19
Google for Developers
Version 9 of Angular, Glass Enterprise Edition 2, path to DX deprecation, & more!
Google for Developers
[DEPRECATING] Introducing a new series (Assistant for Developers Pro Tips)
Google for Developers
Detecting memory bugs with HWASan, Bazel 2.1, Next ‘20 session guide, & more!
Google for Developers
Why Podcast.app chose a .app domain name
Google for Developers
Machine Learning Bootcamp Jakarta 2019
Google for Developers
Android Studio 3.6, Android 11 Developer Preview, Kubeflow 1.0, & more!
Google for Developers
[DEPRECATING] Importance of community (Assistant on Air)
Google for Developers
Why the Flutter team switched from .io to a .dev domain name
Google for Developers
3 website-building tips from .dev creators
Google for Developers
Why NimbleDroid chose a .app domain name
Google for Developers
Android Platform Codelab, Bazel 2.2, Maps Android Utility Library v1.0, & more!
Google for Developers
Google for Games Developer Summit: A free, digital experience for game developers
Google for Developers
Inspecting Home Graph (Assistant for Developers Pro Tips)
Google for Developers
Google for Games Developer Summit Keynote
Google for Developers
Stadia Games & Entertainment presents: Keys to a great game pitch (Google Games Dev Summit)
Google for Developers
Empowering game developers with Stadia R&D (Google Games Dev Summit)
Google for Developers
Supercharging discoverability with Stadia (Google Games Dev Summit)
Google for Developers
Stadia Games & Entertainment presents: Creating for content creators (Google Games Dev Summit)
Google for Developers
Bringing Destiny to Stadia: A postmortem (Google Games Dev Summit)
Google for Developers
Live Captioning in Google Slides
Google for Developers
[DEPRECATING] User engagement for the Google Assistant
Google for Developers
TensorFlow Dev Summit ‘20, Google for Games Dev Summit, Cloud AI Platform Pipelines, & much more!
Google for Developers
Top 5 from the TensorFlow Dev Summit 2020
Google for Developers
Developer Student Clubs 2019 Turkey Leads Summit
Google for Developers
Building simpler payment experiences | Google Pay Plugin for Magento 2
Google for Developers
Become A Developer Student Club Lead
Google for Developers
Firebase Kotlin Extensions, ARM apps on the Android Emulator, Angular v9.1, & more!
Google for Developers
Test suite for Smart Home (Assistant for Developers Pro Tips)
Google for Developers
Google Play updates, Bazel 3.0, Business Console for Google Pay, & more!
Google for Developers
How to use error logs (Assistant for Developers Pro Tips)
Google for Developers
Contact Center AI, Android Studio 4.1 Canary 5, TensorFlow QAT API, & more!
Google for Developers
WebView DevTools, Kotlin meets gRPC, Flutter CodePen support, & more! (Episode 200)
Google for Developers
Offline handling for Smart Home (Assistant for Developers Pro Tips)
Google for Developers
Android 11 Dev Preview 3, Google Fonts for Flutter, Shielded VM, & more!
Google for Developers
Machine Learning Foundations: Ep #1 - What is ML?
Google for Developers
Flutter web support updates, BigQuery materialized views, Cloud Spanner emulator, & more!
Google for Developers
Computer vision by building a neural network with TensorFlow | Machine Learning Foundations
Google for Developers
Machine Learning Foundations: Ep #3 - Convolutions and pooling
Google for Developers
Android 11 Beta plans, Flutter 1.17, Dart 2.8, & much more!
Google for Developers
Machine Learning Foundations: Ep #4 - Coding with Convolutional Neural Networks
Google for Developers
Google Developers ML Summit
Google for Developers
Real-world image classification using convolutional neural networks | Machine Learning Foundations
Google for Developers
Adobe XD support for Flutter, Architecture Framework, temporary closures with Places API, & more!
Google for Developers
Machine Learning Foundations: Ep #6 - Convolutional cats and dogs
Google for Developers
Machine Learning Foundations: Ep #7 - Image augmentation and overfitting
Google for Developers
Announcing Firebase Live, Flutter Day, Java 11 on Google Cloud Functions, & more!
Google for Developers
Machine Learning Foundations: Ep #8 - Tokenization for Natural Language Processing
Google for Developers
Android 11 Beta, Google Play Asset Delivery, Firebase Crashlytics SDK, & much more!
Google for Developers
Natural Language Processing: Using sequencing APIs in TensorFlow | Machine Learning Foundations
Google for Developers
Build a sarcasm classifier using NLP and TensorFlow | Machine Learning Foundations
Google for Developers
AR Realism with the ARCore Depth API
Google for Developers
More on: LLM Engineering
View skill →Related Reads
📰
📰
📰
📰
Building My First Neural Network From Scratch with PyTorch: A Journey on the Dry Bean Dataset
Medium · Deep Learning
The Reframe
Medium · Deep Learning
Looking for Fast.ai Study Partner (Deep Learning, GMT+5)
Reddit r/deeplearning
Understanding Deep Learning Through Four Interactive Experiments
Medium · Data Science
🎓
Tutor Explanation
DeepCamp AI