1.腾讯T2I-adapter源码分析(3)-训练源码分析
2.OpenHarmony 3GPP协议开发深度剖析——一文读懂RIL
3.腾讯T2I-adapter源码分析(1)-运行源码跑训练
4.Spring MVC组件之HandlerAdapter
5.腾讯T2I-adapter源码分析(2)-推理源码分析
6.直播带货源码,码解异步处理中会处理两次请求
腾讯T2I-adapter源码分析(3)-训练源码分析
随着stable-diffusion和midjourney等AI技术展现令人惊叹的码解艺术创作,人们对AI可控绘图的码解追求日益高涨。为提升AI图像生成的码解可控性,Controlnet和T2I-adapter等解决方案应运而生。码解系列文章将从T2I-adapter的码解框架源码讲解源码出发,深入剖析其训练部分的码解实现原理。
本篇我们将聚焦于训练源码的码解解析,通过代码结构的码解梳理,了解T2I-Adapter的码解训练流程。
训练代码的码解运行涉及数据处理、模型加载、码解优化器设置以及实际训练过程。码解在第一部分,码解我们首先设置参数并加载数据,码解如DepthDataset,它从txt文件中读取、对应的深度图和文本描述。
在模型加载阶段,我们区分了stable-diffusion模型和adapter。stable-diffusion模型加载时,其配置与推理阶段有所差异,如增加调度器参数、提高精度、调整分辨率和训练相关参数。adapter模型的加载则遵循推理过程中的初始化方法,通过构建不同模块来实现。
训练过程中,adapter模型的关键结构包括下采样、卷积和ResnetBlock的使用,相比controlnet,T2I-adapter的参数更少,没有注意力层,这使得训练更为高效。模型放入GPU后,使用adamW优化器进行训练,同时设置学习率和数据保存路径。
状态恢复部分,程序会判断是否从头开始或恢复训练,设置log信息。接下来,代码进入实际的训练循环,包括条件编码、隐藏状态生成、a5源码 发卡adapter结果附加至sd模型以及adapter梯度计算。
loss函数定义在模型配置中,采用L2损失来衡量生成图像与给定时间点加噪ground truth的接近程度。训练过程中,loss计算和模型保存都在代码中明确体现。
总的来说,T2I-adapter的训练源码展示了精细的结构和参数设置,确保了AI绘画的可控性和性能。在AI艺术的探索中,每一行代码都承载着技术进步的点滴痕迹。
OpenHarmony 3GPP协议开发深度剖析——一文读懂RIL
市场上针对终端操作系统3GPP协议开发的相关资料较为稀缺,即便在Android领域,相关学习文档也较为有限,更不用说专门的协议开发书籍了。这可能与市场需求有关,目前市场上从事前后端软件开发的人员最多,包括我自己。
鉴于我在某手机协议开发团队工作过一段时间,对协议的AP侧和CP侧开发都有所涉猎,因此我尝试基于OpenAtom OpenHarmony(以下简称“OpenHarmony”)源码编写一些内容,旨在帮助大家了解协议开发领域,尽可能将3gpp协议内容与OpenHarmony电话子系统模块相结合进行讲解。据我所知,目前终端协议开发人才非常紧缺。首先声明,我不是协议专家,且已离开该领域五六年,如有错误,欢迎指正。
谈到终端协议开发,我首先想到的就是RIL。
CP:Communication Processor(通信处理器),通常理解为modem侧,也可以理解为底层协议,这部分由各个modem芯片厂商完成(如海思、高通)。
AP:Application Processor(应用处理器),通常指手机终端,通常理解为上层协议,主要由操作系统Telephony服务进行处理。
RIL:Radio Interface Layer(无线电接口层),通常理解为硬件抽象层,即AP侧将通信请求传给CP侧的源码形病毒入侵型中间层。
AT指令:AT指令是应用于终端设备与PC应用之间连接与通信的指令。
常规的Modem开发与调试可以使用AT指令进行操作,而各家的Modem芯片的AT指令都会有各自的差异。因此,手机终端厂商为了能在各种不同型号的产品中集成不同modem芯片,需要进行解耦设计来屏蔽各家AT指令的差异。
于是,OpenHarmony采用RIL对Modem进行HAL(硬件抽象),作为系统与Modem之间的通信桥梁,为AP侧提供控制Modem的接口,各Modem厂商则负责提供对应于AT命令的Vender RIL(这些一般为封装好的so库),从而实现操作系统与Modem间的解耦。
框架层:Telephony Service,电话子系统核心服务模块,主要功能是初始化RIL管理、SIM卡和搜网模块。对应OpenHarmony的源码仓库OpenHarmony/telephony_core_service。这个模块也是非常重要的一个模块,后期单独再做详细解读。
硬件抽象层:即我们要讲的RIL,对应OpenHarmony的源码仓库OpenHarmony/telephony_ril_adapter。RIL Adapter模块主要包括厂商库加载,业务接口实现以及事件调度管理。主要用于屏蔽不同modem厂商硬件差异,为上层提供统一的接口,通过注册HDF服务与上层接口通讯。
芯片层:Modem芯片相关代码,即CP侧,这些代码各个Modem厂商是不开放的,不出现在OpenHarmony中。
硬件抽象层又被划分为hril_hdf层、hril层和venderlib层。
hril_hdf层:HDF服务,基于OpenHarmony HDF框架,提供hril层与Telephony Service层进行通讯。
hril层:hril层的各个业务模块接口实现,比如通话、短彩信、数据业务等。
vendorlib层:各Modem厂商提供的对应于AT命令库,各个厂商可以出于代码闭源政策,在这里以so库形式提供。目前源码仓中已经提供了一套提供代码的酷狗php解析源码AT命令操作,至于这个是针对哪个型号modem芯片的,我后续了解清楚再补充。
下面是ril_adapter仓的源码结构:
本文解读RIL层很小一部分代码,RIL是如何通过HDF与Telephony连接上的,以后更加完整的逻辑梳理会配上时序图讲解,会更加清晰。首先,我们要对OpenHarmony的HDF(Hardware Driver Foundation)驱动框架做一定了解,最好是动手写一个Demo案例,具体的可以单独去官网查阅HDF资料。
首先,找到hril_hdf.c文件的代码,它承担的是驱动业务部分,源码中是不带中文注释的,为了梳理清楚流程,我给源码关键部分加上了中文注释。
上述代码中配置了对应该驱动的moduleName为"hril_hdf",因此我们需要去找到对应驱动的配置文件,以HiDV开发板为例,它的驱动配置在vendor_hisilicon/HiDV/hdf_config/uhdf/device_info.hcs代码中可以找到,如下:
这里可以发现该驱动对应的服务名称为cellular_radio1,那么telephony_core_service通过HDF与RIL进行通信肯定会调用到该服务名称,因此无查找telephony_core_service的相关代码,可以很快定位到telephony_core_service/services/tel_ril/src/tel_ril_manager.cpp该代码,该代码中有一个关键类TelRilManager,它用来负责管理tel_ril。
看tel_ril_manager.cpp中的一个关键函数ConnectRilAdapterService,它就是用来通过HDF框架获取RIL_ADAPTER的服务,之前定义过RIL_ADAPTER_SERVICE_NAME常量为"cellular_radio1",它就是在vendor_hisilicon/XXXX/hdf_config/uhdf/device_info.hcs中配置的hril_hdf驱动对应的服务名称。
腾讯T2I-adapter源码分析(1)-运行源码跑训练
稳定扩散、midjourney等AI绘图技术,为人们带来了令人惊叹的效果,不禁让人感叹技术发展的日新月异。然而,AI绘图的可控性一直不是很好,通过prompt描述词来操控图像很难做到随心所欲。为了使AI绘制的图像更具可控性,Controlnet、T2I-adapter等技术应运而生。本系列文章将从T2I-adapter的源码出发,分析其实现方法。
本篇是dnf 登录器源码第一篇,主要介绍源码的运行方法,后续两篇将以深度图为例,分别分析推理部分和训练部分的代码。分析T2I-Adapter,也是为了继续研究我一直在研究的课题:“AI生成同一人物不同动作”,例如:罗培羽:stable-diffusion生成同一人物不同动作的尝试(多姿势图),Controlnet、T2I-adapter给了我一些灵感,后续将进行尝试。
T2I-Adapter论文地址如下,它与controlnet类似,都是在原模型增加一个旁路,然后对推理结果求和。
T2I-Adapter和controlnet有两个主要的不同点,从图中可见,其一是在unet的编码阶段增加参数,而controlnet主要是解码阶段;其二是controlnet复制unit的上半部结构,而T2I-Adapter使用不同的模型结构。由于采用较小的模型,因此T2I-Adapter的模型较小,默认下占用M左右,而controlnet模型一般要5G空间。
首先确保机器上装有3.6版本以上python,然后把代码clone下来。随后安装依赖项,打开requirements.txt,可以看到依赖项的内容。然后下载示例,下载的会放到examples目录下。接着下载sd模型到model目录下,再下载T2I-Adapter的模型到目录下,模型可以按需到huggingface.co/TencentA...下载。这里我下载了depth和openpose。sd模型除了上述的v1-5,也还下载了sd-v1-4.ckpt。
根据文档,尝试运行一个由深度图生成的例子,下图的左侧是深度图,提示语是"desk, best quality, extremely detailed",右侧是生成出来的。运行过程比较艰辛,一开始在一台8G显存的服务器上跑,显存不够;重新搭环境在一台G显存的服务器上跑,还是不够;最后用一台G显存的服务器,终于运行起来了。
接下来尝试跑openpose的例子,下图左侧是骨架图,提示词为"Iron man, high-quality, high-res",右侧是生成的图像。
既然能跑推理,那么尝试跑训练。为了后续修改代码运行,目标是准备一点点数据把训练代码跑起来,至于训练的效果不是当前关注的。程序中也有训练的脚步,我们以训练深度图条件为例,来运行train_depth.py。
显然,习惯了,会有一些问题没法直接运行,需要先做两步工作。准备训练数据,分析代码,定位到ldm/data/dataset_depth.py,反推它的数据集结构,然后准备对应数据。先创建文件datasets/laion_depth_meta_v1.txt,用于存放数据文件的地址,由于只是测试,我就只添加两行。然后准备,图中的.png和.png是结果图,.depth.png和.depth.png是深度图,.txt和.txt是对应的文本描述。
文本描述如下,都只是为了把代码跑起来而做的简单设置。设置环境变量,由于T2I-Adapter使用多卡训练,显然我也没这个环境,因此要让它在单机上跑。而代码中也会获取一些环境变量,因此做简单的设置。
做好准备工作,可以运行程序了,出于硬件条件限制,只能把batch size设置为1。在A显卡跑了约8小时,完成,按默认的配置,模型保存experiments/train_depth/models/model_ad_.pth。那么,使用训练出来的模型试试效果,能生成如下(此处只是为了跑起来代码,用训练集来测试),验证了可以跑起来。
运行起来,但这还不够,我们还得看看代码是怎么写法,下一篇见。
PS:《直观理解AI博弈原理》是笔者写的一篇长文,从五子棋、象棋、围棋的AI演进讲起,从深度遍历、MAX-MIN剪枝再到蒙特卡罗树搜索,一步步介绍AI博弈的原理,而后引出强化学习方法,通俗易懂地介绍AlphaGo围棋、星际争霸强化学习AI、王者荣耀AI的一些强化学习要点,值得推荐。
AUTOMATIC的webui是近期很流行的stable-diffusion应用,它集合stable-diffusion各项常用功能,还通过扩展的形式支持controlnet、lora等技术,我们也分析了它的源码实现,写了一系列文章。
Spring MVC组件之HandlerAdapter
HandlerAdapter组件概述:HandlerAdapter组件在Spring MVC框架中作为处理器Handler的适配器,主要职责是适配特定的Handler以处理相应的请求。在源码中,HandlerAdapter接口定义了三个核心方法:判断HandlerAdapter组件是否支持特定handler实例的`supports`方法、使用handler实例处理具体请求的`handle`方法、获取资源最后修改值的`getLastModified`方法(已被废弃)。
HandlerAdapter类图展示了继承结构,HandlerAdapter接口由多个具体实现类继承,如HandlerFunctionAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、SimpleServletHandlerAdapter等,其中RequestMappingHandlerAdapter的继承关系稍微复杂一些。AbstractHandlerMethodAdapter作为HandlerAdapter的抽象子类,提供了`supports`、`handle`、`getLastModified`方法的虚实现。
RequestMappingHandlerAdapter在初始化时默认由Spring MVC容器处理,继承自AbstractHandlerMethodAdapter,并实现了InitializingBean和BeanFactoryAware接口,提供初始化方法处理控制器和处理逻辑的注入。
在RequestMappingHandlerAdapter的初始化过程中,它执行了几个关键操作:初始化RequestMappingHandlerAdapter类中的`initBinderAdviceCache`、`modelAttributeAdviceCache`、`requestResponseBodyAdvice`属性,通过扫描带有@ControllerAdvice注解的bean来实现控制器的注解和方法的管理。此外,它还初始化了`argumentResolvers`、`initBinderArgumentResolvers`和`returnValueHandlers`属性,分别用于参数解析、初始化参数绑定和返回值处理。
RequestMappingHandlerAdapter重写了AbstractHandlerMethodAdapter提供的三个模板方法:在`supportsInternal`方法中直接返回`true`,在`getLastModifiedInternal`方法中返回`-1`,而在`handleInternal`方法中执行处理请求的关键逻辑。处理流程大致包括准备请求参数、使用处理器处理请求和将不同类型的返回值统一为ModelAndView。
在处理请求的逻辑中,RequestMappingHandlerAdapter通过调用checkRequest方法检查请求是否符合预期,并通过invokeHandlerMethod方法执行实际的请求处理,此过程中创建了ServletWebRequest、WebDataBinderFactory和ModelFactory实例,最终通过调用ServletInvocableHandlerMethod的invokeAndHandle方法实现请求处理。
WebDataBinderFactory类用于创建DataBinder对象,主要负责参数绑定,实现了参数与String之间的类型转换,ArgumentResolver在参数解析过程中会使用WebDataBinder。ModelFactory类用于维护Model,初始化和更新Model,提供了初始化和更新Model的逻辑。
Spring MVC组件中的各个HandlerAdapter类和相关实现通过一系列的接口、抽象类和具体类的继承和实现,构建了一个灵活且可扩展的框架,用于处理HTTP请求并返回响应,支持注解驱动的控制器、参数解析、返回值处理等关键功能,形成了高效、灵活的Web应用开发基础。
腾讯T2I-adapter源码分析(2)-推理源码分析
随着stable-diffusion和midjourney展示出AI绘图的惊人潜力,人们对技术进步的惊叹不已。然而,AI绘图的可控性一直是痛点,仅凭描述词控制图像并不尽如人意。为增强AI图像的可控性,Controlnet和T2I-adapter等技术应运而生。本文将通过解析T2I-adapter的推理源码,揭示其工作原理。
本文将深入剖析推理部分的代码,以便理解T2I-Adapter的实际操作。使用如下的命令行指令进行推理,如test_adapter.py,它需要指定条件类型、深度图路径、前置处理器类型、提示语、模型和缩放尺寸等参数。
在test_adapter.py中,主要分为参数读取、模型加载和推理运算三个步骤。参数读取部分包括检查支持的条件、构建提示语,以及根据输入选择前置处理。模型加载涉及stable-diffusion和adapter模型,前者通过配置加载,后者根据输入条件构造Adapter模型。
加载stable-diffusion模型时,代码引用了来自github的CompVis/stable-diffusion库,其中关键部分包括加载参数、模型配置以及UNetModel的改动。Adapter模型的构造与论文中的结构图一致,通过ResnetBlock的组合实现。
在推理过程中,先对输入进行预处理,如深度图的处理。随后,get_adapter_feature和diffusion_inference两个核心函数调用adapter模型,与stable-diffusion模型结合进行特征融合和采样。最后,DDIM采样器接收并处理adapter特征,最终生成图像。
通过以上分析,我们逐步揭示了T2I-adapter的推理机制。后续文章将探讨训练代码。在游戏开发中,AI生成游戏角色动作的应用,如AUTOMATIC,展示了这种技术的实际应用,以解决美术资源匮乏的问题。
直播带货源码,异步处理中会处理两次请求
直播带货源码,在异步处理中会处理两次请求,这是从序列图上观察到的SpringMVC处理异步请求的方式。让我们详细解析处理过程:
HandlerAdapter的处理流程中,异步请求处理有两大环节。首先,处理第一次请求,即异步请求的开始阶段。
在invokeHandleMethod()方法的处理流程中,除了最终直接返回null的操作外,其余步骤与正常流程相同。在SpringMVC中,异步方法仅需返回值是一个Callable对象,因此参数解析与正常流程一致,不同之处在于返回值的解析流程。让我们深入探讨返回值处理的具体过程。
在异步请求执行完毕后,进行第二次请求处理。这一阶段,异步操作完成,系统将处理结果返回给客户端。
通过以上解析,我们了解到直播带货源码在异步处理中会处理两次请求的基本原理。希望本文能为您的理解提供帮助,期待后续文章的深入探讨,敬请关注。