Fooocus框架代码分析

2023-10-12 17:30
文章标签 分析 代码 框架 fooocus

本文主要是介绍Fooocus框架代码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

由于Fooocus的优秀推理能力,后续考虑从webui切换到Fooocus上,因此对其中的代码要进行深入分析,Fooocus的sdxl版本在11g的显存上跑起来压力不大,但是webui的sdxl版本起码12g。尤其要对比其和webui的优化点,但是在代码层面,并不是和webui同一档次的框架,webui采用了支持hook式的插件系统,但是fooocus因为其midjourney的指向,所以并不是走三方插件的路子。

在autodl上:python launch.py --listen --port 6006

entry_with_update.py

# 启动
python entry_with_update.py --listenlaunch.py ->
prepare_environment()->
ini_comfy_args()->
- args_manager.py -> args = comfy_cli.args ->backend/headless/comfy/cli_args.py
download_models()->webui.py ->
- run_button.click().then(fn=generate_clicked)->
-- modules/async_worker.py->workers()->threading.Thread(target=worker).start()
-- handler()-> # 传入参数并配置
-- prompt_processing/vary/upscale/inpaint/controlnet/
-- imgs = pipeline.process_diffusin(...)-> 

modules/default_pipeline.py -> process_diffusion() 主pipeline,webui中是StableDiffusionProcessingTxt2Img和StableDiffusionProcessingImg2Img两个核心接口。

if latent is None:empty_latent = core.generate_empty_latent(width,height,1)
else:empty_latent = latentsampled_latent = core.ksampler(final_unet,final_refiner,positive_cond,negative_cond,empty_latent,steps,denoise,callback,cfg_scale,sampler_name,scheduler_name,switch)    
decoded_latent = core.decode_vae(vae,sampled_latent,...)
images = core.pytorch_to_numpy(decoded_latent)  

默认方法:refresh_everything()

refresh_everything()->refresh_refiner_model(refiner_model_name)
refresh_base_model(base_model_name)
refresh_loras(loras)prepare_text_encoder(True)

core.py -> generate_empty_latent()

opEmptyLatentImage.generate(width,height,batch_size)[0]- backend/headless/nodes.py -> EmptyLatentImage.generate()
- latent = torch.zeros([bs,4,height//8,width//8]) -> {'samples':latent}

core.py->ksampler()->backend/headless/comfy/sample.py

core->ksampler()latent_image = latent['sampler']
noise = comfy.sample.prepare_noise(latent_image,seed,...)samples = comfy.sample.sample(model,noise,steps,cfg,sampler_name,scheduler,positive,negative,latent_image,...)
- backend/headless/comfy/sample.py->sample()
- real_model,positive_copy,negative_copy,noise_mask,models=prepare_sampling(model,noise.shape,positive...)
- sampler = comfy.samplers.KSampler(...)
- sampler = sampler.sample(noise,positive_copy,negative_copy,cfg,latent_image...)
-- sampler = sampler_class(self.sampler)
-- sample(self.model,noise,positive,...)

sampler_class()->backend/headless/comfy/samplers.py

sampler_class(name)->
sampler = ksampler(name)->class KSAMPLER(Sampler)

sample->modules/sample_hijack.py (backend/headless/comfy/samplers.py) 劫持了comfy中的sample

sample_hijack(model,noise,positive,negative,cfg,device,sampler,sigmas,model_options,latent_image,denoise_mask,callback,...) ->positive = positive[:]
negative = negative[:]model_wrap = model_wrap(model)
- model_denoise = CFGNoisePredictor(model)
- model_wrap = k_diffusion_external.CompVisDenoiser(model_denoise)calculate_start_end_timesteps(model_wrap,negative)
calculate_start_end_timesteps(model_wrap,positive)
for c in positive/negative:create_cond_with_same_area_if_none(negative/positive,c)
pre_run_control(model_wrap,negative+positive) # cfg相关latent_image = model.process_latent_in(latent_image)samples = samplers.sample(model_wrap,sigmas,extra_args,...)
model.process_latent_out(samples)

backend/headless/comfy/samplers.py

class KSAMPLER->sample(model_wrap,sigmas,extra_args,callback,...)
model_k = KSamplerOInpaint(model_wrap)if sampler_name == "dpm_fast":samples = k_diffusion_sampling.sample_dpm_fast(model_k,noise,...)
elif sampler_name == "dpm_adaptive":samples = k_diffusion_sampling.sample_dpm_adaptive(model_k,noise,...)
else:samples = getattr(k_diffusion_sampling,"sample_{}".format(sampler_name))(model_k,noise,...)

backend/headless/comfy/k_diffusion/sampling.py

sampler_dpmpp_2m_sde_gpu(model,x,sigmas,extra_args,callback,...)
noise_sampler = BrownianTreeNoiseSampler(x,sigma_min,..) if noise_sampler is None else noise_sampler
sample_dpmpp_2m_sde(model,x,...)

sample_dpmpp_2m_sde

for i in trange(len(sigmas)-1):denoised = model(x,sigmas[i]*s_in,**extra_args)if callback is not None:callback({'x':x,'i':i,'sigma':sigma[i],'sigma_hat':sigmas[i],'denoised':denoised})if sigmas[i+1] == 0:x = denoisedelse:# DPM-Solver++(2M) SDEt, s = -sigmas[i].log(), -sigmas[i + 1].log()h = s - teta_h = eta * hx = sigmas[i + 1] / sigmas[i] * (-eta_h).exp() * x + (-h - eta_h).expm1().neg() * denoisedif old_denoised is not None:r = h_last / hif solver_type == 'heun':x = x + ((-h - eta_h).expm1().neg() / (-h - eta_h) + 1) * (1 / r) * (denoised - old_denoised)elif solver_type == 'midpoint':x = x + 0.5 * (-h - eta_h).expm1().neg() * (1 / r) * (denoised - old_denoised)if eta:x = x + noise_sampler(sigmas[i], sigmas[i + 1]) * sigmas[i + 1] * (-2 * eta_h).expm1().neg().sqrt() * s_noise

backend/headless/nodes.py 节点就是类

NODE_CLASS_MAPPINGS = {"KSampler": KSampler,"CheckpointLoaderSimple": CheckpointLoaderSimple,"CLIPTextEncode": CLIPTextEncode,"CLIPSetLastLayer": CLIPSetLastLayer,"VAEDecode": VAEDecode,"VAEEncode": VAEEncode,"VAEEncodeForInpaint": VAEEncodeForInpaint,"VAELoader": VAELoader,"EmptyLatentImage": EmptyLatentImage,"LatentUpscale": LatentUpscale,"LatentUpscaleBy": LatentUpscaleBy,"LatentFromBatch": LatentFromBatch,"RepeatLatentBatch": RepeatLatentBatch,"SaveImage": SaveImage,"PreviewImage": PreviewImage,"LoadImage": LoadImage,"LoadImageMask": LoadImageMask,"ImageScale": ImageScale,"ImageScaleBy": ImageScaleBy,"ImageInvert": ImageInvert,"ImageBatch": ImageBatch,"ImagePadForOutpaint": ImagePadForOutpaint,"EmptyImage": EmptyImage,"ConditioningAverage": ConditioningAverage,"ConditioningCombine": ConditioningCombine,"ConditioningConcat": ConditioningConcat,"ConditioningSetArea": ConditioningSetArea,"ConditioningSetAreaPercentage": ConditioningSetAreaPercentage,"ConditioningSetMask": ConditioningSetMask,"KSamplerAdvanced": KSamplerAdvanced,"SetLatentNoiseMask": SetLatentNoiseMask,"LatentComposite": LatentComposite,"LatentBlend": LatentBlend,"LatentRotate": LatentRotate,"LatentFlip": LatentFlip,"LatentCrop": LatentCrop,"LoraLoader": LoraLoader,"CLIPLoader": CLIPLoader,"UNETLoader": UNETLoader,"DualCLIPLoader": DualCLIPLoader,"CLIPVisionEncode": CLIPVisionEncode,"StyleModelApply": StyleModelApply,"unCLIPConditioning": unCLIPConditioning,"ControlNetApply": ControlNetApply,"ControlNetApplyAdvanced": ControlNetApplyAdvanced,"ControlNetLoader": ControlNetLoader,"DiffControlNetLoader": DiffControlNetLoader,"StyleModelLoader": StyleModelLoader,"CLIPVisionLoader": CLIPVisionLoader,"VAEDecodeTiled": VAEDecodeTiled,"VAEEncodeTiled": VAEEncodeTiled,"unCLIPCheckpointLoader": unCLIPCheckpointLoader,"GLIGENLoader": GLIGENLoader,"GLIGENTextBoxApply": GLIGENTextBoxApply,"CheckpointLoader": CheckpointLoader,"DiffusersLoader": DiffusersLoader,"LoadLatent": LoadLatent,"SaveLatent": SaveLatent,"ConditioningZeroOut": ConditioningZeroOut,"ConditioningSetTimestepRange": ConditioningSetTimestepRange,
}

这篇关于Fooocus框架代码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/197348

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip