news 2026/5/2 9:33:06

深度解析 Google JAX 全栈:带你上手开发,从零构建神经网络

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深度解析 Google JAX 全栈:带你上手开发,从零构建神经网络

目前来看Google 是唯一一家在 AI 价值链上实现端到端垂直整合的公司。从基础模型 (Gemini)、应用层 (ImageFX, Search with Gemini, NotebookLM),到云架构 (Google Cloud, Vertex AI) 以及硬件 (TPUs),几乎全都有所布局。

长期以来Google 一直在通过提升自身能力来减少对 NVIDIA GPU 的依赖。这种技术积累逐渐演变成了现在的 JAX AI 栈。

更有意思的是这套技术栈现在不仅 Google 自己用,Anthropic、xAI 甚至 Apple 这些头部 LLM 提供商也都在用

所以我们就很有必要这就很有必要深入聊聊这套技术栈了。

什么是 JAX AI 栈?

简单来说,JAX AI 栈是一套面向超大规模机器学习的端到端开源平台。

核心组件主要由以下四个部分构成:

1、JAX

Google 和 NVIDIA 联合开发的 Python 高性能数值计算库。

接口设计极其类似 NumPy,但区别在于它能自动、高效地在 CPU、GPU 或 TPU 上运行,无论是本地还是分布式环境。

底层的技术在于XLA (Accelerated Linear Algebra)编译器,它能把 JAX 代码转译成针对不同硬件深度优化的机器码。对比之下NumPy 的操作默认只能在 CPU 上跑,效率天差地别。

2、Flax

基于 JAX 的神经网络训练库。Flax 的核心现在是 NNX (NeuralNetworks for JAX)。这是一个简化版的 API,让创建、调试和分析 JAX 神经网络变得更直观。

之前有个 Flax Linen,是那种无状态、函数式风格的 API。而 NNX 作为继任者,引入了面向对象和有状态的特性,对于习惯了 PyTorch 的开发者来说,构建和调试 JAX 模型会顺手很多。

3、Optax

JAX 生态里的梯度处理和优化库。

它的优势在于灵活性,几行代码就能把标准优化器和复杂的技巧(比如梯度裁剪、梯度累积)链式组合起来。

4. Orbax

专门处理 Checkpoint 的库,用于保存和恢复大规模训练任务。

支持异步分布式检查点,这在大模型训练里至关重要——万一硬件挂了,能从断点恢复,不至于让昂贵的算力打了水漂。

下面这张图展示了完整栈的架构,除了上面这四个核心,还有很多其他组件,建议细看。

实战:用 JAX 训练神经网络

JAX 之所以在 GPU 和 TPU 上能跑赢 PyTorch,主要归功于即时 (JIT) 优化和 XLA 的后端编译效率。

我们直接上手用 JAX 撸一个简单的神经网络,搞个手写数字识别,看看这套栈在实际工作流里到底怎么用。

1、环境配置

JAX AI 栈现在整合成了一个 metapackage,安装很简单。然后我们还需要

sklearn

(加载数据)和

matplotlib

(画图)。

!uv pip install jax-ai-stack sklearn matplotlib

2、加载数据

直接用 sklearn 加载 UCI ML 手写数字数据集。

fromsklearn.datasetsimportload_digits # Load dataset digits=load_digits()

数据是

8 x 8

的像素化手写数字图像(0 到 9)及其对应的标签。

print(f"Number of samples × features: {digits.data.shape}") print(f"Number of labels: {digits.target.shape}") """ Number of samples × features: (1797, 64) Number of labels: (1797,) """

3、 数据可视化

先看看数据长什么样,挑 100 张图画出来。

import matplotlib.pyplot as plt fig, axes = plt.subplots(10, 10, figsize=(6, 6), subplot_kw={'xticks':[], 'yticks':[]}, gridspec_kw=dict(hspace=0.1, wspace=0.1)) for i, ax in enumerate(axes.flat): ax.imshow(digits.images[i], cmap='binary', interpolation='gaussian') ax.text(0.05, 0.05, str(digits.target[i]), transform=ax.transAxes, color='green')

4、 数据集切分

常规操作,把数据切成训练集和测试集。

from sklearn.model_selection import train_test_split # Create dataset splits splits = train_test_split(digits.images, digits.target, random_state=0)

5、转为 JAX 数组

这一步很关键,输入到模型之前,需要用 JAX Numpy 把数据转成 JAX 数组格式。

import jax.numpy as jnp # Convert splits to JAX arrays images_train, images_test, label_train, label_test = map(jnp.asarray, splits)

看一眼数据维度:

print(f"Training images shape: {images_train.shape}") print(f"Training labels shape: {label_train.shape}") print(f"Test images shape: {images_test.shape}") print(f"Test labels shape: {label_test.shape}") """ Training images shape: (1347, 8, 8) Training labels shape: (1347,) Test images shape: (450, 8, 8) Test labels shape: (450,) """

6、用 Flax 构建网络

用 Flax NNX 搭建一个带 SELU 激活函数的简单前馈网络。习惯写 PyTorch 的朋友会发现,这语法看着非常眼熟。

from flax import nnx class DigitClassifier(nnx.Module): def __init__(self, n_features, n_hidden, n_targets, rngs): self.n_features = n_features self.layer_1 = nnx.Linear(n_features, n_hidden, rngs = rngs) self.layer_2 = nnx.Linear(n_hidden, n_hidden, rngs = rngs) self.layer_3 = nnx.Linear(n_hidden, n_targets, rngs = rngs) def __call__(self, x): x = x.reshape(x.shape[0], self.n_features) [#Flatten](#Flatten) images x = nnx.selu(self.layer_1(x)) x = nnx.selu(self.layer_2(x)) x = self.layer_3(x) return x

7、实例化模型

JAX 处理随机数的方式比较特别。这里用

nnx.Rngs(0)

初始化一个种子为 0 的随机数生成器 (RNG) 对象。这个对象负责管理网络操作里的所有随机性,比如参数初始化和 Dropout。

注意,这和 PyTorch 直接设全局种子

torch.manual_seed(seed)

的逻辑不一样。

# Initialize random number generator rngs = nnx.Rngs(0) # Create instance of the classifier model = DigitClassifier(n_features=64, n_hidden=128, n_targets=10, rngs = rngs)

8、定义优化器与训练步骤

用 Optax 定义优化器和损失函数。

import jax import optax # SGD optimizer with learning rate 0.05 optimizer = nnx.ModelAndOptimizer( model, optax.sgd(learning_rate=0.05)) # Loss function def loss_fn(model, data, labels): # Forward pass logits = model(data) # Compute mean cross-entropy loss loss = optax.softmax_cross_entropy_with_integer_labels( logits=logits, labels=labels).mean() return loss, logits # Single training step with automatic differentiation and optimization @nnx.jit # JIT compile for faster execution def training_step(model, optimizer, data, labels): loss_gradient = nnx.grad(loss_fn, has_aux=True) # 'has_aux=True' allows returning auxiliary outputs (logits) grads, logits = loss_gradient(model, data, labels) # Forward + backward pass optimizer.update(grads) # Update model parameters using computed gradients

代码里用到了两个核心变换,这是 JAX 高效的秘诀:

jax.jit

:即时编译,把训练函数扔给 XLA 编译器,重复执行速度极快。

jax.grad

:利用自动微分计算梯度。

Flax NNX 把它俩封装成了装饰器

nnx.jit

nnx.grad

,用起来更方便。

9、训练循环

跑 500 epoch,每 100 轮显示 Loss。

num_epochs=500 print_every=100 forepochinrange(num_epochs+1): # Training step training_step(model, optimizer, images_train, label_train) # Evaluate and print metrics periodically ifepoch%print_every==0: train_loss, _=loss_fn(model, images_train, label_train) test_loss, _=loss_fn(model, images_test, label_test) print(f"Epoch {epoch:3d} | Train Loss: {train_loss:.4f} | Test Loss: {test_loss:.4f}") """ Epoch 0 | Train Loss: 0.0044 | Test Loss: 0.1063 Epoch 100 | Train Loss: 0.0035 | Test Loss: 0.1057 Epoch 200 | Train Loss: 0.0029 | Test Loss: 0.1054 Epoch 300 | Train Loss: 0.0024 | Test Loss: 0.1052 Epoch 400 | Train Loss: 0.0021 | Test Loss: 0.1051 Epoch 500 | Train Loss: 0.0019 | Test Loss: 0.1050 """

10. 效果评估

最后看看在测试集上的表现。

# Evaluate model accuracy on test set logits = model(images_test) predictions = logits.argmax(axis=1) correct = jnp.sum(predictions == label_test) total = len(label_test) accuracy = correct / total print(f"Test Accuracy: {correct}/{total} correct ({accuracy:.2%})") # Test Accuracy: 437/450 correct (97.11%)

97% 的准确率,对于这么简单的网络来说相当不错了。

最后把预测结果可视化一下,绿色是对的,红色是错的。

fig, axes = plt.subplots(10, 10, figsize=(6, 6), subplot_kw={'xticks':[], 'yticks':[]}, gridspec_kw=dict(hspace=0.1, wspace=0.1)) for i, ax in enumerate(axes.flat): ax.imshow(images_test[i], cmap='binary', interpolation='gaussian') color = 'green' if label_pred[i] == label_test[i] else 'red' ax.text(0.05, 0.05, str(label_pred[i]), transform=ax.transAxes, color=color)

到这里,你就已经在 JAX 生态里跑通了第一个神经网络。JAX 的门槛其实没那么高,但它带来的性能收益,特别是在大规模训练场景下,绝对值得投入时间去学。

作者:Dr. Ashish Bamania

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 2:23:28

3步打造智能下拉框:Bootstrap-select语义化搜索实战

3步打造智能下拉框:Bootstrap-select语义化搜索实战 【免费下载链接】bootstrap-select 项目地址: https://gitcode.com/gh_mirrors/boo/bootstrap-select 你是否曾在电商网站搜索"水果"却找不到苹果?输入"红色"却看不到草莓…

作者头像 李华
网站建设 2026/4/27 14:07:48

RomM API密钥安全配置全攻略:守护你的游戏元数据宝库

RomM API密钥安全配置全攻略:守护你的游戏元数据宝库 【免费下载链接】romm A beautiful, powerful, self-hosted rom manager 项目地址: https://gitcode.com/GitHub_Trending/rom/romm 还在为海量游戏资源管理而烦恼?RomM作为一款功能强大的自托…

作者头像 李华
网站建设 2026/5/1 11:47:36

CountUp.js数字动画库实战指南:从入门到精通的高效用法

CountUp.js数字动画库实战指南:从入门到精通的高效用法 【免费下载链接】countUp.js Animates a numerical value by counting to it 项目地址: https://gitcode.com/gh_mirrors/co/countUp.js CountUp.js是一个轻量级的JavaScript数字动画库,专门…

作者头像 李华
网站建设 2026/4/24 18:58:12

2、深入解析Solaris 10软件安装与管理

深入解析Solaris 10软件安装与管理 1. 安装需求与选项 在构建Solaris 10系统时,需要先在兼容的硬件机器上安装Solaris 10操作系统,再安装系统将运行的应用程序。应用程序以软件包的形式分发,而补丁则用于在操作系统的两个版本发布期间修复问题或添加新功能。 1.1 硬件兼容…

作者头像 李华
网站建设 2026/4/18 10:05:30

6、Solaris 10 用户管理全解析

Solaris 10 用户管理全解析 1. 用户账户基础 在用户能够访问和使用系统之前,需要为其创建账户。用户账户包含标识和权限,允许用户根据系统管理员授予的权限访问和使用系统资源。多个需要相同权限的用户可以组织成一个组,对组授予的权限将应用于组内的所有用户,这使得安全…

作者头像 李华
网站建设 2026/4/30 23:48:12

7、Solaris系统安全管理全解析

Solaris系统安全管理全解析 在当今数字化时代,系统安全是每个系统管理员都必须重视的问题。Solaris系统为我们提供了一系列强大的工具和方法来确保系统资源的合理使用和安全。本文将深入探讨Solaris系统安全管理的各个方面,包括系统访问监控、系统安全执行、系统安全控制以及…

作者头像 李华