1.DeepSpeed源码笔记3优化器
2.Vue2源码学习笔记 - 7.响应式原理一基础
3.Piccolo引擎源码笔记-反射系统
4.Vuex 4源码学习笔记 - mapState、源码mapGetters、笔记mapActions、组件mapMutations辅助函数原理(六)
5.Vue2源码学习笔记 - 10.响应式原理一computed与watch浅析
DeepSpeed源码笔记3优化器
DeepSpeedZeroOptimizer_Stage3 是源码一个用于训练大模型的优化器,专门针对zero stage 3的笔记策略。它通过将参数W划分为多份,组件比特币源码 分析每个GPU各自维护优化器状态、源码梯度和参数,笔记以实现高效并行计算。组件具体实现过程如下:
在进行前向计算时,源码每个GPU负责其部分数据,笔记所有GPU的组件数据被分成了三份,每块GPU读取一份。源码完成前向计算后,笔记GPU之间执行all-gather操作,组件合并所有GPU的参数W,得到完整的W。
在执行反向传播时,同样进行all-gather操作,收集所有GPU的完整W,然后执行梯度计算。完成反向传播后,立即释放不属于当前GPU管理的W。
在计算梯度后,通过reduce-scatter操作聚合所有GPU的梯度G,得到完整的梯度。接着,释放非当前GPU管理的9999源码梯度G。最后,使用当前GPU维护的部分优化器状态O和聚合后的梯度G来更新参数W,无需额外的allreduce操作。
初始化阶段包括设置参数和配置,如optimizer、flatten、unflatten、dtype、gradient_accumulation_dtype等。这些配置决定了优化器的运行方式和性能。初始化还包括创建参数分组和设置特定的分片操作。
分配模型参数到各个GPU上,通过多种方法如创建参数分组、创建参数子分组等进行细致的划分和管理。这些分组和子分组的创建和管理,是为了更有效地进行梯度聚合和参数更新。
在执行反向传播后,调用LossScaler进行梯度计算,随后通过特定的钩子函数(如reduce_partition_and_remove_grads)进行梯度聚合和释放。
执行优化器的step方法时,进行归一化梯度计算、更新参数和优化器状态,并在完成后清理和更新模型参数。此过程包括执行反向梯度聚合、更新模型参数权重、清理优化器状态和参数。
DeepSpeedZeRoOffload模块则负责模型参数的roid源码划分和管理工作,包括初始化、参数划分和状态更新等。初始化阶段会根据配置将参数分配到不同GPU上,并进行状态更新和参数访问的优化。
在进行参数划分时,首先将模型参数划分为非划分和划分的参数,并根据划分状态进一步处理。初始化外部参数后,会更新模块的状态,包括所有参数的存储位置和管理策略。
在执行partition_all_parameters方法时,根据GPU数量和参数大小计算每个GPU需要处理的部分,从模型参数中提取并分割到对应的GPU上,释放原参数并更新参数状态。
Init过程涉及到初始化配置、实现特定方法(如all_gather、partition等)和状态更新,确保模型参数能被正确地在不同GPU间共享和管理。对于特定的GPU(如主GPU),还会使用广播操作将参数分发给其他GPU。
Vue2源码学习笔记 - 7.响应式原理一基础
深入研究 Vue 的响应式核心,了解响应式机制在 Vue 中的核心地位。Vue 的响应式原理,让数据模型简单直接地管理状态,无需侵入性操作。
当你将普通 JavaScript 对象作为 Vue 实例的 data 选项时,Vue 会遍历对象属性并使用 Object.defineProperty 转换为 getter 和 setter。albert源码此特性仅在 ES5 中可用,不支持 IE8 及以下浏览器。
这些 getter 和 setter 在内部追踪依赖,当属性被访问或修改时,会通知 Vue。类似于 PHP 的魔术方法或 Java 的 getXXX\setXXX,但实现上存在差异。Java 可能拥有更接近的实现,比如 CGLib。
每个 Vue 组件实例对应一个 watcher,记录接触过的数据属性为依赖。当依赖项的 setter 触发时,watcher 被通知,组件重新渲染。
简单 demo 通过 defineReactive 实现响应式设置,允许访问 data 中的属性,设值触发 setter,引用触发 getter。此方法依赖于 Object.defineProperty,是响应式原理的核心。
Proxy 是 ES 定义的类,用于创建对象代理,实现基本操作拦截和自定义。通过简单的 demo 可见,更新和引用数据时会调用 setter/getter 方法。Vue2 使用 Proxy,但用途不多。源码166
总结,学习 Object.defineProperty 和 Proxy 实现响应式的底层方法。它们在数据更新和引用时触发特定方法,执行期望的操作实现响应式。下篇深入 Vue 响应式实现。
Piccolo引擎源码笔记-反射系统
反思系统在游戏引擎中的应用与实现
在游戏开发中,反射系统提供了一种强大的机制,允许程序在运行时获取和修改对象的属性和行为。它在引擎中主要实现两点:一是展示游戏对象的组件及其属性;二是通过键盘编辑改变值,直接作用于游戏,无需重新编译。这一机制有助于开发者进行无缝的组件管理与调试。
在实现中,游戏引擎通过自动生成的反射文件来描述游戏对象的组件信息。以Transform组件为例,该文件详细记录了位置、缩放、旋转等信息及其对应字段名。这些信息组织为类函数、字段函数、方法函数和数组函数的元组,方便进行封装和调用。
实现过程涉及多个模块的协同工作,包括序列化、资源加载与ImGui等。序列化模块通过模板函数实现对各种数据类型的读取,而资源加载模块负责管理关卡中对象的加载过程。在加载过程中,通过反射系统读取组件信息,并通过映射函数将其与对应的类函数关联。这使得组件的序列化和反序列化过程得以实现。
在编辑器部分,通过Tick驱动的机制,引擎实时更新游戏状态。编辑器通过获取当前选中对象及其组件信息,利用反射系统直接操作组件的属性,实现字段的实时修改与应用。这种机制避免了繁琐的重新编译过程,极大地提高了开发效率。
在处理编辑器中的字段修改时,通过反射系统提供的功能,开发者可以直接在编辑器中通过键盘输入修改字段值。这一过程不涉及事件机制的调用,而是通过直接修改对象的字段实现。通过将字段值传递给ImGui::InputFloat()函数,实现字段值的实时更新与显示。这一实现方式简化了编辑器的使用流程,提高了开发效率。
总的来说,游戏引擎中的反射系统通过封装组件信息、实现组件属性的动态获取与修改,为开发者提供了一种高效、灵活的组件管理机制。结合序列化、资源加载与编辑器等模块,形成了一个完整的动态调整与管理游戏对象与组件的框架。通过反思系统,开发者可以更专注于游戏逻辑与创意的实现,而将组件管理与调试等任务交由引擎自动处理,从而提升开发效率与游戏质量。
Vuex 4源码学习笔记 - mapState、mapGetters、mapActions、mapMutations辅助函数原理(六)
在前一章中,我们通过了解Vuex的dispatch功能,逐步探索了Vuex数据流的核心工作机制。通过这一过程,我们对Vuex的整体运行流程有了清晰的把握,为深入理解其细节奠定了基础。本章节,我们将聚焦于Vuex的辅助函数,包括mapState、mapGetters、mapActions、mapMutations以及createNamespacedHelpers,这些函数旨在简化我们的开发流程,使其更符合实际应用需求。
请注意,这些辅助函数在Vue 3的Composition API中不适用,因为它们依赖于组件实例(this),而在Setup阶段,this尚未被创建。因此,它们仅适用于基于选项的Vue 2或Vue 3经典API。
以mapState为例,它允许我们以计算属性的形式访问Vuex中的状态。当组件需要获取多个状态时,通过mapState生成的计算属性可以显著减少代码冗余。若映射的计算属性名称与state子节点名称相同,只需传入字符串数组。此外,通过对象展开运算符,我们能轻松地在已有计算属性中添加新的映射。
深入代码层面,mapState的核心功能在src/helpers.js文件中得以实现。通过normalizeNamespace函数统一处理命名空间和map数据,然后利用normalizeMap函数将数组或对象格式数据标准化,最终返回一个封装后的函数对象。通过这种方式,mapState有效简化了状态访问的实现。
mapGetters、mapMutations、mapActions遵循相似的模式,通过normalizeNamespace统一输入,然后使用normalizeMap统一数据处理,最后返回对象格式的函数集合,支持对象展开运算符的使用。这些函数简化了获取、执行actions和mutations的过程。
createNamespacedHelpers则是为管理命名空间模块提供便利。通过传入命名空间值,它生成一组组件绑定辅助函数,简化了针对特定命名空间的模块操作。此函数通过bind方法巧妙地将namespace参数绑定到返回的函数集合中,实现了高效、灵活的命名空间管理。
本章节对mapState的实现原理进行了深入分析,并展示了其余辅助函数的相似之处。通过理解这些函数的工作机制,我们能更高效地应用Vuex,优化组件间的交互与状态管理。利用这些工具,开发者能够更专注于业务逻辑的实现,而不是繁琐的状态获取和管理。
在探索更多前端知识的旅程中,让我们一起关注公众号小帅的编程笔记,每天更新精彩内容,与编程社区一同成长。
Vue2源码学习笔记 - .响应式原理一computed与watch浅析
本文仅简要介绍Vue2源码中计算属性和侦听属性的初始化过程,深入研究响应式原理将在后续内容中进行。
计算属性初始化:在Vue实例化过程中,传入的计算属性配置被传递至initComputed函数。该函数生成每个计算属性的Watcher对象,且设置lazy选项为真。通过defineComputed函数定义计算属性为响应式变量,实现计算属性的初始化。在defineComputed中,使用Object.defineProperty将计算属性设置为响应式属性,通过生成getter函数(如computedGetter),在获取属性值时,计算并收集依赖。
侦听属性初始化:在initState函数中,侦听属性的初始化调用initWatch函数。此函数直接将侦听属性传递至Vue.prototype.$watch方法,配置侦听属性与回调函数,实现侦听属性的初始化。$watch方法实例化Watcher对象,监听属性变动,当检测到变动时执行回调函数。
总结:计算属性与侦听属性的初始化相对简化,主要依赖于Watcher类。计算属性通过生成Watcher对象与getter函数,实现响应式计算与依赖收集;侦听属性则通过配置Watcher对象与回调函数,实现属性变动时的自动响应。在后续内容中,将深入研究Watcher类及其与计算属性、侦听属性的关联与配合机制。