TensorFlow.js Op 模块化改造完整指南:以 SquaredDifference 为例的 Kernel/Gradient 迁移实战
人工智能机器学习深度学习前端后端【免费下载链接】tfjsA WebGL accelerated JavaScript library for training and deploying ML models.项目地址https://gitcode.com/gh_mirrors/tf/tfjs点击查看免费下载本文基于 tfjs-core/development/op_modularization.md系统讲解 TensorFlow.js 将 Op 改造为模块化架构的完整工作流——涵盖 Kernel 注册、Op 拆分、链式 API、梯度注册的每一步并结合SquaredDifference的实际源码tfjs-core 与 tfjs-backend-cpu给出可直接对照的落地范例。读完本文你将掌握在 TensorFlow.js 中把一个后端相关的 Op 逐步改造成Op Kernel Gradient三段式模块化结构的方法并理解runKernelFunc与runKernel的演进关系为提交社区 PR 或维护自有分支做好准备。注意文中描述的是 tfjs 模块化改造所追求的目标世界the world we are moving towards部分描述与当前仓库状态存在差异例如 ops/squared_difference.ts 已经改用ENGINE.runKernel而非文档中的runKernelFunc。本文会结合仓库现状逐一标注。一、为什么需要 Op 模块化三个核心概念在动手之前先厘清 TensorFlow.js 中三个容易混淆的核心概念Glossary它们也是整个模块化改造的分层依据Op算子后端无关backend agnostic的函数通常以公开 API 的形式暴露给最终用户实现在tfjs-core中。例如tf.squaredDifference(a, b)以及链式写法a.squaredDifference(b)。Kernel内核针对特定后端的底层实现被一个或多个 Op 复用。Kernel 及其接口定义在tfjs-core/src/kernel_names.ts。Kernel 不能调用其他 Kernel也不能回调用 tfjs 的公开 APIKernel 之间可以通过普通函数导入共享代码。Gradient梯度某个 Kernel 的反向模式backward mode定义同样实现在 tfjs-core 中且是后端无关的——即它们调用其他 Op 或 Kernel 来完成求导。这三者之间的调度桥梁是runKernelFunc它是 tfjs-core engine 中负责执行函数的入口既能处理模块化 Kernel也能处理非模块化 Kernel通过 backend 对象而非 kernel registry 调用。文档明确指出当所有后端的所有 Kernel 都完成模块化后runKernelFunc将被runKernel取代。从当前仓库源码看这个演进已经基本完成engine.ts 中runKernelFunc作为私有方法存在而模块化 op 已统一走runKernel如 ops/squared_difference.ts 中ENGINE.runKernel(SquaredDifference, inputs, attrs)的调用方式。二、改造策略先全部 Op再逐个 Kernel模块化改造有一个明确的总体顺序在开始模块化任何后端的 Kernel 之前先把所有 Op 模块化We will be modularising all the ops before modularizing any of the kernels。这是因为 Op 模块化只涉及 tfjs-core 内部的接口拆分而 Kernel 模块化会同时牵动各后端CPU、WebGL、WASM 等的实现。正式开始前还有一步社区协作要求前往 tfjs 仓库的 issue #2822在评论区告知你要改造哪个 Op避免与他人重复劳动。三、tfjs-core 内的六步改造流程步骤 1在 kernel_names.ts 中添加 Kernel 名称与接口在 tfjs-core/src/kernel_names.ts 中为 Kernel 添加标识符并可选地定义Inputs与Attrs类型export const SquaredDifference SquaredDifference; export type SquaredDifferenceInputs PickNamedTensorInfoMap, a|b;要点命名尽量对齐 TensorFlow 的 C API这是文档中引用的外部参考仓库内不包含该 API 源码无法完全对齐时需向维护者寻求指导。Inputs类型通过PickNamedTensorInfoMap, ...声明NamedTensorInfoMap定义在 kernel_registry.ts。带属性如 axis、keepDims的 Kernel 还需声明Attrs接口参考同文件中的AvgPoolAttrs、AvgPool3DAttrs等示例。步骤 2创建 src/ops/op_name.ts把 Op 定义迁移过来在tfjs-core/src/ops/下新建以 op 命名的文件例如squared_difference.ts。文档给出了一个使用runKernelFunc的过渡期完整实现其中内嵌了前向函数与梯度定义并标注了模块化梯度完成后需要删除的区间Modularization noteimport {ENGINE, ForwardFunc} from ../engine; import {SquaredDifference, SquaredDifferenceInputs} from ../kernel_names; import {Tensor} from ../tensor; import {NamedTensorMap} from ../tensor_types; import {makeTypesMatch} from ../tensor_util; import {convertToTensor} from ../tensor_util_env; import {TensorLike} from ../types; import {assertAndGetBroadcastShape} from ./broadcast_util; import {op} from ./operation; import {scalar} from ./tensor_ops; function squaredDifference_T extends Tensor( a: Tensor|TensorLike, b: Tensor|TensorLike): T { let $a convertToTensor(a, a, squaredDifference); let $b convertToTensor(b, b, squaredDifference); [$a, $b] makeTypesMatch($a, $b); assertAndGetBroadcastShape($a.shape, $b.shape); // **************** // Modularization note: this gradient definition should be removed from // here once the modular gradient is implemented in the steps below. //***************** const der (dy: Tensor, saved: Tensor[]) { const [$a, $b] saved; const two scalar(2); const derA () dy.mul($a.sub($b).mul(two)); const derB () dy.mul($b.sub($a).mul(two)); return {a: derA, b: derB}; }; // **************** // END Modularization note //***************** const forward: ForwardFuncTensor (backend, save) { const res backend.squaredDifference($a, $b); save([$a, $b]); return res; }; const inputs: SquaredDifferenceInputs {a: $a, b: $b}; const attrs {}; const inputsToSave [$a, $b]; const outputToSave: boolean[] []; return ENGINE.runKernelFunc( forward, inputs as unknown as NamedTensorMap, der, SquaredDifference, attrs, inputsToSave, outputToSave) as T; } export const squaredDifference op({squaredDifference_});关键设计原则Op 只做输入校验和数据转换让参数与 Kernel 接口完全匹配其余数据变换一律交给 Kernel。核心准则是Kernel 接口定义的工作不应被拆散到 Op 与 Kernel 之间。由于部分后端如 wasm的 Kernel 已模块化把数据操作从 Op 移交给 Kernel 时旧模块化 Kernel 可能会因此破坏测试失败此时需要同步修改这些 Kernel 以匹配新输入。仍然使用runKernelFunc是为了兼容尚未模块化 Kernel 的后端——这是文档写作时的过渡状态。仓库现状对照当前 ops/squared_difference.ts 已经完成最终形态——梯度定义被移除、前向函数改为直接调用ENGINE.runKernel(SquaredDifference, inputs, attrs)完整体现了文档中过渡态 → 终态的演进路径。步骤 3从 src/ops/ops.ts 导出模块化 Op在 tfjs-core/src/ops/ops.ts 中集中导出所有模块化 Op文件头部注释即标明 Modularized ops.export {squaredDifference} from ./squared_difference;该文件目前已有 343 行、导出上百个模块化 Op如abs、add、conv2d等是公开 API 的汇总出口。步骤 4创建链式 APIchained opaugmentor在src/public/chained_ops/op_name.ts中新建链式方法让Tensor实例可以直接调用import {squaredDifference} from ../../ops/squared_difference; import {Tensor} from ../../tensor; import {Rank, TensorLike} from ../../types; declare module ../../tensor { interface TensorR extends Rank Rank { squaredDifferenceT extends Tensor(b: Tensor|TensorLike): T; } } Tensor.prototype.squaredDifference functionT extends Tensor(b: Tensor| TensorLike): T { this.throwIfDisposed(); return squaredDifference(this, b); };要点通过declare module扩展Tensor接口类型然后挂载原型方法方法内部先调用throwIfDisposed()校验张量未被释放再委托给步骤 2 的模块化 Op。必须把 augmentor 注册到src/public/chained_ops/register_all_chained_ops.ts当前仓库中import ./squared_difference;位于第 135 行并在register_all_chained_ops_test.ts中补充对应的链式调用测试。完成以上步骤后从src/tensor.ts中移除该 Op既要从Tensor类中删除对应方法也要从OpHandler接口中删除保证链式 API 只保留单一实现来源。步骤 5为没有模块化梯度的 Kernel 创建梯度在src/gradients/下按 Kernel 名创建梯度文件例如SquaredDifference_grad.ts。注意梯度中必须使用直接导入的 Op避免使用链式 APIimport {SquaredDifference} from ../kernel_names; import {GradConfig} from ../kernel_registry; import {mul, sub} from ../ops/binary_ops; import {scalar} from ../ops/tensor_ops; import {Tensor} from ../tensor; export const squaredDifferenceGradConfig: GradConfig { kernelName: SquaredDifference, gradFunc: (dy: Tensor, saved: Tensor[]) { const [a, b] saved; const two scalar(2); const derA () mul(dy, mul(two, sub(a, b))); const derB () mul(dy, mul(two, sub(b, a))); return {a: derA, b: derB}; } };从源码结构可以印证GradConfig接口定义在 kernel_registry.ts除kernelName与gradFunc外还支持inputsToSave本次梯度需要保存的输入名、saveAllInputs、outputsToSave。仓库中的最终版本 SquaredDifference_grad.ts 正是通过inputsToSave: [a, b]显式声明需要保存的输入gradFunc再从中取出a、b计算d(a-b)²的两个偏导。步骤 6把梯度配置注册到 register_all_gradients.ts在 tfjs-core/src/register_all_gradients.ts 中导入新梯度配置并加入gradConfigs列表import {squaredDifferenceGradConfig} from ./gradients/SquaredDifference_grad; const gradConfigs: GradConfig[] [ // add the gradient config to this list. squaredDifferenceGradConfig, ];当前仓库中该文件已包含上百个梯度配置如addGradConfig、conv2DGradConfig等并在第 230 行起通过for (const gradientConfig of gradConfigs)循环调用registerGradient完成全局注册供反向传播查询使用。四、提交 PR质量收尾完成以上步骤后即可提交 PR 供审查。提交前务必在tfjs-core目录下本地运行yarn test确保所有单元测试通过——这既是文档明确的强制要求也是模块化改造中防止破坏其他后端 Kernel 的关键防线。五、模块化完成后的全景仓库源码印证结合仓库当前状态可以看到模块化改造的目标形态已经落地1. Kernel 注册机制后端 Kernel 通过 kernel_registry.ts 的registerKernel(config)注册到全局kernelRegistryKernelConfig包含kernelName、backendName、kernelFunc及可选的setupFunc/disposeFunc。查询时通过getKernel(kernelName, backendName)按 kernel_backend 复合键查找。2. 后端 Kernel 实现例如 CPU 后端的 SquaredDifference.ts 通过binaryKernelFunc与createSimpleBinaryKernelImpl实现逐元素(a-b)²计算并导出squaredDifferenceConfig供注册——这正是文档所说Kernel 之间通过普通函数导入共享代码的具体体现。3. 调度入口统一模块化 Op 不再直接调用backend.squaredDifference(...)而是把SquaredDifference名称、inputs、attrs 交给ENGINE.runKernel由 engine 在运行时根据当前激活的 backend 从 kernel registry 中查找对应实现。整个链路Op 定义 → 链式 API → Kernel 注册 → 梯度注册完全由kernel_names.ts中的常量串起来实现了名称即契约。六、改造清单速查Checklist阶段文件动作接口tfjs-core/src/kernel_names.ts添加 Kernel 常量、Inputs/Attrs 类型Op 定义tfjs-core/src/ops/squared_difference.ts迁移 Op仅做校验与接口匹配Op 导出tfjs-core/src/ops/ops.ts添加export {...} from ./xxx链式 APItfjs-core/src/public/chained_ops/squared_difference.ts声明 module 扩展 原型方法链式注册/测试tfjs-core/src/public/chained_ops/register_all_chained_ops.ts注册 augmentor、补充测试清理旧 APItfjs-core/src/tensor.ts移除 Tensor 类方法与 OpHandler 接口项梯度tfjs-core/src/gradients/SquaredDifference_grad.ts创建 GradConfig使用直接导入的 Op梯度注册tfjs-core/src/register_all_gradients.ts加入 gradConfigs 列表验证tfjs-core目录下运行yarn test按照这个清单逐项推进你就能以最小的破坏性完成一个 Op 的模块化改造从Op 内嵌 backend 调用与梯度定义的过渡形态演进为Op校验→ Kernel后端实现→ Gradient反向传播职责清晰、后端无关的模块化架构为后续各后端 Kernel 的逐一模块化铺平道路。赞分享人工智能机器学习深度学习前端后端【免费下载链接】tfjsA WebGL accelerated JavaScript library for training and deploying ML models.项目地址https://gitcode.com/gh_mirrors/tf/tfjs点击查看免费下载相关推荐ESLint v9 Flat Config 迁移实战指南以 Chainlit Monorepo 的 .eslintrc 到 eslint.config.mjs 改造为例ESLint v9 Flat Config 迁移实战指南以 Chainlit Monorepo 的 .eslintrc 到 eslint.config.mjs人工智能大模型AI 应用后端前端Bazel 从 Maven 迁移指南以 Guava 项目为例的完整实战教程Bazel 从 Maven 迁移指南以 Guava 项目为例的完整实战教程 本指南基于 Bazel 官方文档 docs/migrate/maven.mdx构建工具Starship v0.45.0 迁移实战指南prompt_order 与模块 prefix/suffix 的统一 format 化改造Starship v0.45.0 迁移实战指南prompt_order 与模块 prefix/suffix 的统一 format 化改造 Starship 在CLI开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

轻量级姿态-动作联合识别:热图编码+时序CNN闭环实现

轻量级姿态-动作联合识别:热图编码+时序CNN闭环实现

简介:本资源是一份面向人工智能初学者与课程实践者的CNN应用实战项目,聚焦人体姿态与动作识别任务,适用于高校人工智能、计算机视觉相关课程大作业或课设开发。项目基于Python实现,包含数据采集、模型训练、姿态检测与动作测试四大…

2026/9/21 0:31:17 阅读更多 →
银行系统大文件上传加密方案:流式加密与分片上传实战

银行系统大文件上传加密方案:流式加密与分片上传实战

银行系统的JavaWeb项目里,一旦涉及大文件上传,就绕不开两个词:敏感数据和加密。客户身份证照片、银行卡影像、资产证明扫描件,动辄几十MB甚至几百MB,这些文件如果以明文形式落盘或者走网络传输,合规检查那一…

2026/9/21 0:31:17 阅读更多 →
ArcGIS Pro加载天地图WMTS:坐标系偏移与Key配置全解析

ArcGIS Pro加载天地图WMTS:坐标系偏移与Key配置全解析

1. 天地图WMTS的坐标系门道:偏移问题到底从哪来先聊一个几乎所有ArcGIS Pro用户第一次接天地图都会撞上的问题:图层加进来了,影像也出来了,但叠加自己的矢量数据时,道路跑到了河对岸,建筑轮廓和张地图对不上…

2026/9/21 0:31:17 阅读更多 →

最新新闻

Scissor算法调参实战:alpha与cutoff参数优化指南

Scissor算法调参实战:alpha与cutoff参数优化指南

1. 为什么Scissor算法的alpha和cutoff值得单独拎出来讲做单细胞数据分析的人,迟早会碰到一个场景:你手里有一份单细胞转录组数据,同时还有一份表型数据(比如生存时间、疾病分组、药物响应),你想知道哪些细胞…

2026/9/21 1:06:36 阅读更多 →
Xenomai v3.2.1源码解析:双内核实时系统编译与部署实战

Xenomai v3.2.1源码解析:双内核实时系统编译与部署实战

简介:Xenomai是一套基于双内核机制的Linux强实时扩展,针对需要微秒级响应能力的嵌入式、工业控制及机器人应用场景,弥补原生Linux因调度复杂而无法满足硬实时要求的短板。这份v3.2.1完整源码包共含1417个文件,以519个C源文件和556…

2026/9/21 1:06:36 阅读更多 →
全球海底深度地形图制作全流程:数据源、可视化与应用

全球海底深度地形图制作全流程:数据源、可视化与应用

简介:面向海洋测绘、地球物理与海底地形成图需求,这份基于ETOPO2v2g_f4.nc全球地形数据的MATLAB绘图示例,可帮助用户快速完成全球海底深度地形图的绘制,并附有南极—印度洋扇区的出图样例,适合地学专业学生、科研人员与…

2026/9/21 1:06:36 阅读更多 →
C# + U2NET 自动抠图实战:从原理到完整可运行代码

C# + U2NET 自动抠图实战:从原理到完整可运行代码

简介:一套基于C#与U2NET深度学习模型的图片抠像完整工具,面向处理复杂图像任务的开发者和工程师,解决无绿幕条件下自动分离前景对象的实际难题。它利用U2NET网络对图像内容的理解能力,摆脱传统色度抠图对纯色背景的依赖&#xff0…

2026/9/21 1:06:36 阅读更多 →
开源调度模拟器:从联锁逻辑到进路排布的铁路信号实战指南

开源调度模拟器:从联锁逻辑到进路排布的铁路信号实战指南

简介:《火车信号模拟游戏》(Train Signalling Simulation)是一款开源的铁路信号模拟游戏,面向铁路信号学习者、策略游戏爱好者与程序员,围绕真实调度场景中的信号控制、轨道占用、列车运行等核心问题,提供交…

2026/9/21 1:06:36 阅读更多 →
ABB机器人资料合集:从坐标系标定到速度控制的核心知识梳理

ABB机器人资料合集:从坐标系标定到速度控制的核心知识梳理

简介:ABB机器人资料合集面向工业机器人操作人员、服务商与维护工程师,系统梳理了IRB 120、IRB 1200、IRB 1410、IRB 1600、IRB 2600、IRB 4600、IRB 6700及IRB 2400等主流型号,覆盖焊接、码垛、搬运、喷涂、打磨等典型应用场景,兼…

2026/9/21 1:05:36 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →