1.探索TensorFlow核心组件系列之Session的源码运行源码分析
2.[fastllm]cuda-kernels源码解析
3.SWIG定义
4.SWIG教程《二》
探索TensorFlow核心组件系列之Session的运行源码分析
TensorFlow作为一个前后端分离的计算框架,旨在实现前端在任何设备、源码任何位置上使用API构建模型,源码而不受硬件资源限制。源码那么,源码TensorFlow是源码xenomai源码教程如何建立前后端的连接呢?在这一过程中,Session起着关键桥梁作用,源码它连接前后端通道,源码并通过session.run()触发计算,源码将前端的源码计算图转化为graphdef pb格式发送至后端。后端接收此格式,源码将计算图重建、源码剪枝、源码分裂,源码并分配到设备上,源码最终在多个Executor上执行计算。
Session管理着计算图、变量、队列、锁、设备和内存等多种资源,确保资源安全、高效地使用。协作翻译源码在Session生命周期中,包含创建、运行、关闭和销毁四个阶段,确保模型运行的正确性和效率。
在Session创建时,使用BaseSession初始化,通过调用TF_NewSessionRef创建实例。此过程涉及确定图实例、判断混合精度设置以及创建Session。在分布式框架中,Python通过swig自动生成的函数符号映射关系调用C++层实现。
Session运行主要通过session.run()触发,该方法在BaseSession的run()中实现,涉及创建fetch处理器、获取最终fetches和targets,调用_do_run方法启动计算,并输出结果。在本地模式下,Session初始化会生成DirectSession对象。
综上所述,Session在TensorFlow架构中扮演着核心角色,源码输出失败连接前后端,管理资源,并确保模型高效、安全地运行。
[fastllm]cuda-kernels源码解析
在fastllm中,CUDA-kernels的使用是关键优化点之一,主要涉及以下几个高频率使用的kernel:gemv_int4、gemv_int8、gemm_int8、RMSNorm、softmax、RotatePosition2D、swiglu等。其中,gemm是计算密集型的,而其余大部分都是内存受限型。利用量化bit进行计算,比原始的torch转为浮点数更快,同时,没有进行融合操作,为后续优化留下了空间。
gemv_int4 kernel:主要用于实现float*int4的跑腿源码出售GEMV乘积,其中偏置值设定为最小值。在计算中,矩阵被划分为不同的tile,不同tile之间并行操作。在遍历m/2的过程中,找到对应int4值的位置,通过保存的mins找到最小值minv。同一组的两个int4值共享同一个minv,计算结果的最终和被保存在sdata[0]上,用于更新对应m列位置的output值。结果向量为n*1。
gemv_int8 kernel:在功能上与gemv_int4类似,但偏置值由保存的minv变为了zeros。
gemm_int8 kernel:此kernel负责计算n*m矩阵与m*k矩阵的乘积。计算过程涉及多个tile并行,block内部保存的是部分和。考虑到线程数量限制,通常会有优化空间。最终结果通过为单位进行更新。
layerNorm实现:此kernel实现layernorm计算,通过计算均值和方差来调整数据分布。计算中,源码vip加入sdata存储所有和,sdata2存储平方和。每个block内计算部分和后,规约得到全局的均值和方差,从而更新output。
RMS kernels解析:RMSNorm kernel实现RMS归一化,通过计算输入的平方和和均值,进而更新output。
softmax kernels解析:计算输入的softmax值,涉及最大值查找、指数计算和规约求和等步骤,以防止浮点数下溢。
RotatePosition2D Kernels解析:用于旋转位置编码,线程展开成三层循环。LlamaRotatePosition2D、NearlyRotatePosition和RotatePosition2D在旋转方式上有所区别,体现在不同的位置上进行计算。
AttentionMask Kernels解析:对输入按照mask掩码置值,普通mask直接置为maskv,而Alibimask则是置为相对位置的值之和。具体含义可能涉及空间上的概念,但文中未详细说明。
swiglu kernels解析:作为激活函数,这些kernel在原地操作中执行常见函数,线程足够使用,直接按照公式计算即可。
综上所述,fastllm中CUDA-kernels的使用旨在通过优化计算过程和内存操作,提升模型的计算效率,实现更高效的推理和训练。
SWIG定义
SWIG是一个功能强大的开发工具,它的主要目标是协助开发者将用C或C++编写的软件无缝地融入到各种高级编程语言中。这个工具支持的编程语言种类繁多,包括但不限于Perl、PHP、Python、Tcl、Ruby和PHP等脚本语言,以及C#、Common Lisp(CLISP、Allegro CL、CFFI、UFFI)、Java、Modula-3、OCAML和R等非脚本语言。甚至,SWIG还能处理编译器或汇编语言的项目,如Guile、MzScheme和Chicken。
SWIG在实际应用中,常被用来构建高级语言的解析环境或编程接口,它作为一种工具,既可用于开发过程中的测试,也能够作为原型设计的首选。通过SWIG,开发者可以创建出高效、易用的用户界面。此外,SWIG的开放源代码特性使其具有极高的灵活性,无论是商业项目还是个人开发,都可以自由地使用、发布和修改SWIG,适应各种应用场景。
SWIG教程《二》
在SWIG教程中,了解变量属性的管理非常重要。使用%immutable指令可以创建只读字段,一旦变量被标记为不可变,除非明确使用%mutable指令将其改为可变状态,否则它始终为只读。
注意兼容性,先前的%readonly和%readwrite指令虽然仍能工作,但会生成警告信息。更推荐使用%immutable和%mutable指令,同时不要忘记额外的分号。
重命名功能允许在转换目标语言时处理关键字冲突。rename指令的范围从声明开始到文件结束,因此在引入重命名的头文件时,确保其在rename之后。
SWIG提供了强大的重命名工具,不仅限于单个命名,还可以批量重命名。例如,通过匹配规则为所有函数添加前缀,将所有蛇形命名转换为驼峰命名,剔除命名中的特定字符,以及对操作符重载函数进行重命名。
使用ignore指令可以忽略不需要封装的内容。可以选择性地忽略大部分符号,同时仅封装所需的方法或类,如在特定头文件中仅封装名为“Star”的类。
回调函数的实现需要提前声明,不能直接传入目标函数。一旦声明为回调,无法在目标函数中作为普通函数调用。对于既作为回调也作为普通函数调用的情况,可以采取特定的声明方式。
SWIG自动生成C++类的默认构造函数和析构函数,但可以通过指令或参数选项禁止。使用%nodefaultctor指令或命令行参数-nodefaultctor可以避免生成默认构造函数。对于析构函数,同样可以使用%nodefaultdtor指令禁止生成。
SWIG虽然能处理大部分C++语法,但并非完整的解析器,仍有部分语法无法解析。为C++类添加成员函数时,使用%extend指令为C类型的结构体绑定额外的成员函数,以辅助创建和使用。
SWIG输出的C/C++代码分为五部分,包括用户自定义的预处理器宏、内部支持代码、用户定义的支持代码、自动生成的封装代码,以及初始化模块的函数。
代码注入功能允许在特定代码段中插入自定义代码,使用指令或section名实现。例如,%runtime指令代替了使用%insert("runtime")。%{ ...%}指令实际上是%header %{ ...%}的简写。
在封装中使用初始化代码时,可以利用Init段进行特定的初始化操作。辅助函数的编写通常通过代码注入来简化,inline指令则提供了一种将代码块在封装和源代码中重复使用的方式,尽管其只适用于函数和变量,对于头文件的封装仍需通过%include指令告知SWIG。