前端神经网络入门(二):如何利用 WebGPU 进行数值计算,实现大规模数据的计算加速?- 边读边按下F12跑代码吧

在 Web 应用开发中,JavaScript 是前端开发者们最常用的语言。然而,当面对大规模数据处理和计算任务时,JavaScript 在浏览器中的执行往往会受到诸多性能瓶颈的限制。幸运的是,WebGPU 的出现,为我们提供了在前端实现高性能计算的新途径。本文将首先探讨 JavaScript 在执行大规模计算方面的劣势,然后介绍如何利用 WebGPU 进行计算加速,以及它带来的性能提升。最后,我们将以一个例子来演示如何在浏览器中利用 WebGPU 进行大规模数值计算。

除了webGPU,还有一个提升计算性能的WASM技术栈,感兴趣的可以了解,或许后续我会再谈到

JavaScript 在大规模计算中的劣势

JavaScript 是一门解释型语言,主要用于处理前端的交互逻辑,如 DOM 操作、事件处理和 UI 更新等。尽管近年来 JavaScript 引擎得到了极大的优化(如 V8 引擎的 JIT 编译),但在面对大规模数值计算时,JavaScript 依然存在以下劣势:

  1. 单线程执行:JavaScript 在浏览器环境中通常是单线程的,尽管 Web Workers 提供了一些多线程的支持,但对于大量需要并行处理的数值计算,性能依旧受到限制。
  2. 计算效率低:JavaScript 本质上并不是为高效执行数值计算而设计的。它的动态类型和内存管理机制导致处理浮点数运算和矩阵操作时效率较低。
  3. 缺乏硬件加速:JavaScript 在浏览器中运行时,通常只能依靠 CPU,无法直接利用 GPU 的强大并行处理能力来加速大规模数值运算。

在这样的情况下,大规模数据的处理和训练神经网络通常需要依赖后端的计算能力,例如通过 Web API 将数据发送到服务器,由服务器使用 GPU 或其他高性能计算设备完成后再将结果返回。这种模式存在明显的 网络延迟隐私保护 问题。

WebGPU 引入与计算加速的可行性

WebGPU 是一项现代的 Web API,它使得开发者能够在浏览器中直接访问 GPU,以进行图形渲染和 高性能数值计算。相比于 WebGL,WebGPU 提供了更底层和更灵活的控制能力,并允许更直接地访问 GPU,执行包括矩阵运算、机器学习推断在内的大量并行计算任务。

WebGPU 的浏览器兼容性

目前,WebGPU 还在发展中,并没有在所有主流浏览器中全面支持。以下是一些关于兼容性的情况:

  • ChromeEdge:这两个浏览器提供了对 WebGPU 的支持,但需要在某些情况下通过实验性设置开启。
  • Firefox:WebGPU 的支持正在开发中,部分功能可能在实验性版本中使用。
  • Safari:Apple 也在积极推进对 WebGPU 的支持,可以在最新的版本中体验到。
    在这里插入图片描述
WebGPU 带来的效果提升

与 JavaScript 使用 CPU 进行运算相比,WebGPU 可以利用 GPU 的 并行计算能力,极大地加快大规模数值运算的速度。GPU 可以同时执行上千个小型计算任务,对于矩阵相乘、向量运算等高度并行的计算任务,性能提升可以达到数十倍甚至上百倍。

利用 WebGPU 的通用计算能力,可以将以前需要后端支持的复杂任务(如神经网络推断、实时数据分析等)转移到前端,使得应用可以更快速响应用户的输入,并且无需将数据传到服务器,保护用户隐私。

实战示例:使用 WebGPU 进行数值计算

为了让大家对 WebGPU 如何进行数值计算有更清晰的认识,我们将以 向量相加 作为例子,演示如何在前端使用 WebGPU 实现 GPU 加速的数值计算。

因为不需要外部依赖,所以按F12打开开发者工具,复制粘贴代码测试吧~

示例:向量相加

我们将实现两个长度为 3 的向量 [1, 2, 3][4, 5, 6] 相加,预期结果为 [5, 7, 9]

1. 初始化 WebGPU

首先,我们需要获取 GPU 适配器和设备:

async function initWebGPU() {if (!navigator.gpu) {console.error("WebGPU is not supported in this browser.");return;}const adapter = await navigator.gpu.requestAdapter();const device = await adapter.requestDevice();return device;
}
2. 创建缓冲区

接下来,我们创建 GPU 缓冲区,用于存储输入和输出数据:

async function createBuffers(device) {const a = new Float32Array([1, 2, 3]);const b = new Float32Array([4, 5, 6]);const result = new Float32Array(a.length);const aBuffer = device.createBuffer({size: a.byteLength,usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,mappedAtCreation: true});new Float32Array(aBuffer.getMappedRange()).set(a);aBuffer.unmap();const bBuffer = device.createBuffer({size: b.byteLength,usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,mappedAtCreation: true});new Float32Array(bBuffer.getMappedRange()).set(b);bBuffer.unmap();const resultBuffer = device.createBuffer({size: result.byteLength,usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,});return { aBuffer, bBuffer, resultBuffer, resultLength: result.length };
}
3. 编写计算着色器

接着,我们编写一个简单的 WGSL 着色器,用于执行向量相加的操作:

const shaderCode = `@group(0) @binding(0) var<storage, read> a: array<f32>;@group(0) @binding(1) var<storage, read> b: array<f32>;@group(0) @binding(2) var<storage, read_write> result: array<f32>;@compute @workgroup_size(64)fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {let index = global_id.x;// 假设数组的长度为 3,你可以传递更大的值或者作为一个变量处理if (index < 3u) {result[index] = a[index] + b[index];}}
`;
4. 创建计算管线和绑定组

计算管线用于定义计算任务的执行方式,绑定组用于绑定缓冲区:

async function createPipeline(device, shaderCode) {const shaderModule = device.createShaderModule({code: shaderCode});const computePipeline = device.createComputePipeline({layout: "auto",compute: {module: shaderModule,entryPoint: "main"}});return computePipeline;
}async function createBindGroup(device, pipeline, buffers) {return device.createBindGroup({layout: pipeline.getBindGroupLayout(0),entries: [{ binding: 0, resource: { buffer: buffers.aBuffer } },{ binding: 1, resource: { buffer: buffers.bBuffer } },{ binding: 2, resource: { buffer: buffers.resultBuffer } }]});
}
5. 执行计算任务并读取结果

最后,我们执行计算任务并将结果读取出来:

async function runComputeTask(device, pipeline, bindGroup, resultBuffer, resultLength) {const commandEncoder = device.createCommandEncoder();const passEncoder = commandEncoder.beginComputePass();passEncoder.setPipeline(pipeline);passEncoder.setBindGroup(0, bindGroup);passEncoder.dispatchWorkgroups(Math.ceil(resultLength / 64));passEncoder.end();const gpuReadBuffer = device.createBuffer({size: resultLength * Float32Array.BYTES_PER_ELEMENT,usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ});commandEncoder.copyBufferToBuffer(resultBuffer, 0, gpuReadBuffer, 0, resultLength * Float32Array.BYTES_PER_ELEMENT);const commandBuffer = commandEncoder.finish();device.queue.submit([commandBuffer]);await gpuReadBuffer.mapAsync(GPUMapMode.READ);const arrayBuffer = gpuReadBuffer.getMappedRange();const resultArray = new Float32Array(arrayBuffer);console.log("Result:", Array.from(resultArray));gpuReadBuffer.unmap();
}(async () => {const device = await initWebGPU();const buffers = await createBuffers(device);const pipeline = await createPipeline(device, shaderCode);const bindGroup = await createBindGroup(device, pipeline, buffers);await runComputeTask(device, pipeline, bindGroup, buffers.resultBuffer, buffers.resultLength);
})();

运行结果

Result: [5, 7, 9]

在这里插入图片描述

总结

WebGPU 为前端带来了利用 GPU 进行高性能计算的可能性,使得 JavaScript 不再局限于处理简单的 UI 和业务逻辑,而是能够执行更复杂的数值计算和大规模数据处理任务。与传统的 JavaScript 计算方式相比,WebGPU 在大规模并行任务(如矩阵运算、图像处理和机器学习)上提供了显著的性能提升。

通过本文的示例代码,开发者可以初步了解如何使用 WebGPU 进行数值计算,将大规模计算任务从后端转移到前端,不仅能提高应用的响应速度,还能保护用户数据隐私。随着浏览器对 WebGPU 的支持逐渐成熟,前端开发者们将能用它来开发出更高效、更智能的 Web 应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/60794.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新手教学系列——善用 VSCode 工作区,让开发更高效

引言 作为一名开发者,你是否曾经在项目中频繁地切换不同文件夹,打开无数个 VSCode 窗口?特别是当你同时参与多个项目或者处理多个模块时,这种情况更是家常便饭。很快,你的任务栏上挤满了 VSCode 的小图标,切换起来手忙脚乱,工作效率直线下降。这时候,你可能会问:“有…

Oracle故障处理:ora-12514 与 ora-28547

目录 项目场景 问题分析 问题总结 项目场景 现场同事求助说&#xff1a;有个刚刚部署在Windows上的Oracle11gR2数据库&#xff08;单机单实例&#xff09;&#xff0c;使用PLSQL工具连接不上。帮忙查看后&#xff0c;发现未装Oracle client&#xff0c;指导其安装完Oracle客…

【miniMax开放平台-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被机器执行自动化程序攻击&#xff0c;存在如下风险&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露&#xff0c;不符合国家等级保护的要求。短信盗刷带来的拒绝服务风险 &#xff0c;造成用户无法登陆、注册&#xff0c;大量收到垃圾短信的…

26-ES集群搭建、身份认证配置

虚机搭建 添加es用户 elasticsearch 默认不允许root用户启动&#xff0c;所以需要创建es用户 useradd elasticsearch passwd elasticsearch 解压安装包 #解压es tar -xvzf elasticsearch-7.14.2-linux-x86_64.tar.gz 将文件夹赋予es用户权限 #将文件夹赋予es用户权限 sud…

OpenHarmony的公共事件

OpenHarmony的公共事件 公共事件简介 CES&#xff08;Common Event Service&#xff0c;公共事件服务&#xff09;为应用程序提供订阅、发布、退订公共事件的能力。 公共事件分类 公共事件从系统角度可分为&#xff1a;系统公共事件和自定义公共事件。 系统公共事件&#…

【AlphaFold3】开源本地的安装及使用

文章目录 安装安装DockerInstalling Docker on Host启用Rootless Docker 安装 GPU 支持安装 NVIDIA 驱动程序安装 NVIDIA 对 Docker 的支持 获取 AlphaFold 3 源代码获取基因数据库获取模型参数构建将运行 AlphaFold 3 的 Docker 容器 参考 AlphaFold3: https://github.com/goo…

npm list -g --depth=0(用来列出全局安装的所有 npm 软件包而不显示它们的依赖项)

您提供的命令 npm list -g --depth0 是在 Node Package Manager (npm) 的上下文中使用的&#xff0c;用来列出全局安装的所有 npm 软件包而不显示它们的依赖项。 这是它的运作方式&#xff1a; npm list -g --depth0-g: 指定列表应包括全局安装的软件包。--depth0: 限制树形结…

Spring Boot框架:电商系统的技术革新

4 系统设计 网上商城系统的设计方案比如功能框架的设计&#xff0c;比如数据库的设计的好坏也就决定了该系统在开发层面是否高效&#xff0c;以及在系统维护层面是否容易维护和升级&#xff0c;因为在系统实现阶段是需要考虑用户的所有需求&#xff0c;要是在设计阶段没有经过全…

【数据分享】中国对外投资合作发展报告(2013-2023)

数据介绍 绪 论............................................................................................................................. 1 对外投资合作高质量发展迈出新步伐................................................................... 2 第一篇 发…

【深度学习】LSTM、BiLSTM详解

文章目录 1. LSTM简介&#xff1a;2. LSTM结构图&#xff1a;3. 单层LSTM详解4. 双层LSTM详解5. BiLSTM6. Pytorch实现LSTM示例7. nn.LSTM参数详解 1. LSTM简介&#xff1a; LSTM是一种循环神经网络&#xff0c;它可以处理和预测时间序列中间隔和延迟相对较长的重要事件。LSTM通…

【云原生系列--Longhorn的部署】

Longhorn部署手册 1.部署longhorn longhorn架构图&#xff1a; 1.1部署环境要求 kubernetes版本要大于v1.21 每个节点都必须装open-iscsi &#xff0c;Longhorn依赖于 iscsiadm主机为 Kubernetes 提供持久卷。 apt-get install -y open-iscsiRWX 支持要求每个节点都安装 N…

【Hadoop】【hdfs】【大数据技术基础】实验三 HDFS 基础编程实验

实验三&#xff1a; HDFS Java API编程实践 实验题目 HDFS Java API编程实践 实验目的 熟悉HDFS操作常用的Java API。 实验平台 操作系统&#xff1a;Linux Hadoop版本&#xff1a;2.6.0或以上版本 JDK版本&#xff1a;1.6或以上版本 Java IDE&#xff1a;Eclipse 实验…

ssm114基于SSM框架的网上拍卖系统的设计与实现+vue(论文+源码)_kaic

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff0c;商品拍卖当然也不能排除在外&#xff0c;随着商品拍卖管理的不断成熟&#xff0c;它彻底改变了过去传统的经营管理方式&#xff0c;不仅使商品…

Transformer中的算子:其中Q,K,V就是算子

目录 Transformer中的算子 其中Q,K,V就是算子 一、数学中的算子 二、计算机科学中的算子 三、深度学习中的算子 四、称呼的由来 Transformer中的算子 其中Q,K,V就是算子 “算子”这一称呼源于其在数学、计算机科学以及深度学习等多个领域中的广泛应用和特定功能。以下是…

厦大南洋理工最新开源,一种面向户外场景的特征-几何一致性无监督点云配准方法

导读 本文提出了INTEGER&#xff0c;一种面向户外点云数据的无监督配准方法&#xff0c;通过整合高层上下文和低层几何特征信息来生成更可靠的伪标签。该方法基于教师-学生框架&#xff0c;创新性地引入特征-几何一致性挖掘&#xff08;FGCM&#xff09;模块以提高伪标签的准确…

生产环境中AI调用的优化:AI网关高价值应用实践

随着越来越多的组织将生成式AI引入生产环境&#xff0c;他们面临的挑战已经超出了初步实施的范畴。如果管理不当&#xff0c;扩展性限制、安全漏洞和性能瓶颈可能会阻碍AI应用的推广。实际问题如用户数据的安全性、固定容量限制、成本管理和延迟优化等&#xff0c;需要创新的解…

Redis 概 述 和 安 装

安 装 r e d i s: 1. 下 载 r e dis h t t p s : / / d o w n l o a d . r e d i s . i o / r e l e a s e s / 2. 将 redis 安装包拷贝到 /opt/ 目录 3. 解压 tar -zvxf redis-6.2.1.tar.gz 4. 安装gcc yum install gcc 5. 进入目录 cd redis-6.2.1 6. 编译 make …

SpringBoot 2.2.10 无法执行Test单元测试

很早之前的项目今天clone现在&#xff0c;想执行一个业务订单的检查&#xff0c;该检查的代码放在test单元测试中&#xff0c;启动也是好好的&#xff0c;当点击对应的方法执行Test的时候就报错 tip&#xff1a;已添加spring-boot-test-starter 所以本身就引入了junit5的库 No…

[项目代码] YOLOv5 铁路工人安全帽安全背心识别 [目标检测]

YOLOv5是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv5具有更高的…

SIM Jacker攻击分析

简介&#xff1a; 2019年9月12日&#xff0c;AdaptiveMobile Security公布了一种针对SIM卡ST Browser的远程攻击方式&#xff1a;Simjacker。攻击者使用普通手机发送特殊构造的短信即可远程定位目标&#xff0c;危害较大 。sim卡的使用在手机上的使用非常普遍&#xff0c;所以…