手把手教你在云环境炼丹:Stable Diffusion LoRA 模型保姆级炼制教程

news2024/11/26 5:20:18

 很多同学都想要自己的专属AI模型,但是大模型的训练比较费时费力,不太适合普通用户玩。AI开发者们也意识到了这个问题,所以就产生了微调模型,LoRA就是其中的一种。在AI绘画领域,只需要少量的一些图片,就可以训练出一个专属风格的LoRA模型,比如某人的脸、某个姿势、某种画风、某种物体,等等。

训练模型经常被大家戏称为“炼丹”,这个词既给我们带来了美好的期待,也体现了模型创作过程的不易。如同炼丹需要精心呵护,AI模型的训练也需要耐心和细致。然而,即使付出了辛勤的努力,最终的结果也未必能如人意。这是大家需要做好的心理准备。

LoRA的原理网上已经有很多介绍,我就不说了。本文专门介绍在云环境怎么训练LoRA模型,所谓云环境就是租用云服务器,而不是在本地电脑上,这特别适合想一展身手但是手里又没有一块好显卡的同学。

这里的云环境选择我经常使用的AutoDL:https://www.autodl.com , 关于AutoDL的使用方法,本文只围绕训练LoRA模型做一些简单的介绍,想了解更多的同学请看我写的另一篇文章:手把手教你在云环境部署 Stable Diffusion WebUI 。

本文将使用 kohya_ss 这个开源项目来训练LoRA模型, 下面正式开始。

云环境

AutoDL上需要先充值然后才能租用服务器,可以先来2块钱的,以便完成本次训练。

服务器

简单说下,计费方式选择“按量计费”,地区选择“内蒙A区”,GPU型号选择“RTX A5000”,GPU数量选择“1”,然后选择1个有空闲GPU的主机。

镜像这里选择“社区镜像”,输入“yinghuoai-kohya”,在弹出的菜单中选择我发布的这个镜像。

然后点击“立即创建”就可以了。

在 AutoDL 控制台等待服务器实例开机,开机成功后,在快捷工具这里可以看到一些操作项,点击其中的“JupyterLab”。

在 JupyterLab 中点击笔记本上方的双箭头按钮,它会进行一些初始化操作,并启动 kohya_ss,待看到“Running on local URL”的提示后,就说明启动成功了。

然后回到 AutoDL 控制台,点击快捷工具中的“自定义服务”,即可启动 kohya_ss 的Web界面。

训练目录

为了有效的管理模型训练,我在镜像中创建了几个目录,可以通过“JupyterLab”查看,它们都在 /root/autodl-tmp 下边,autodl-tmp 挂载的是 AutoDL 的数据盘,可以节省宝贵的系统盘空间。

  • /root/autodl-tmp/models:SD大模型目录,训练Lora模型时需要基于某个大模型。
  • /root/autodl-tmp/train:训练数据的目录,包括输入的图片、训练的参数、输出的Lora模型等,我们将在这个目录下创建不同的训练项目目录。

实际效果如下图所示:

快速体验

我在镜像中内置了一份训练数据和训练配置,可以让大家快速体验 Lora 炼丹。

通过 AutoDL 的自定义服务启动页面后,依次点击“LoRA”->“Training”。

  • 在“Configuration file”这里输入我提前预置好的训练配置文件地址:/root/autodl-tmp/train/dudu/config.json ;
  • 然后点击“Load”加载训练参数;
  • 最后点击“Start training”开始训练。

训练的进度需要去 JupterLab 中查看,大约需要8分钟,当看到 steps 显示 100%的时候就说明训练完成了,模型已经保存到目录:/root/autodl-tmp/train/dudu/model

训练过程中会生成几张采样图片,保存在 /root/autodl-tmp/train/dudu/model/sample ,可以打开看看训练的效果:

为了实际体验,需要把模型文件先下载到本地,然后再上传到 Stable Diffusion WebUI,使用文生图生成图片,参考参数:

  • 大模型:realisticVisionV51_v51VAE,其它真实模型也可以试试。
  • 提示词:masterpiece, best quality, 1dog, solo, sitting, looking at viewer, outdoor, the background is egyptian pyramids,tall pyramids <lora:dudu_log:0.8>
  • 反向提示词:low quality, worst quality, harness, tree, bad anatomy,bad composition, poor, low effort
  • 图片尺寸:768*768

注意:如果你要重新训练这个项目,需要先删除 model 目录下的内容,然后再重新开始训练。


快速体验只能让大家简要领略炼丹的魅力。然而,要炼就一颗完美的丹药,还需备足图片素材、洞悉工具参数设置,以及不断测试优化模型。接下来,我将为大家详细解析如何步步为营,精心打造你的LoRA模型。

准备

主要就是准备好要训练的图片,以及为图片生成提示词。然后才能把它们送进丹炉进行炼制。

挑选图片

训练LoRA模型到底需要几张图片?我没找到具体要求,建议至少10张以上,并且要求图片清晰有质感,如果是针对某种个体的,拍摄目标的角度要多样,这样才可能训练出比较好的模型。

如果你手头没有合适的图片,可以自己拍摄,也可以去百度图片等图片网站找高清大图。

网上的教程大多是训练美女脸的,估计大家也都看烦了,所以我选择了一个狗子的图片进行训练,它的名字叫dudu,样子大概是下图这样的。我准备的图片数量有20张,已经内置到我发布的 AutoDL 镜像中。

裁切图片

图片需要处理成一样的尺寸,尺寸可以是 512*512、512*768,512*640,都是64的倍数。显存低的可以用 512,显存高的可以用 768。这里给大家分享一个裁切图片的网站:BIRME - Bulk Image Resizing Made Easy 2.0 (Online & Free) ,操作方式如下图所示:

  • 左边选择本地要裁切的图片。
  • 右边是裁切设置,可以设置裁切的尺寸等。

注意 RENAME 可以让输出的图片名称更加有序,方便训练程序使用,xxx 代表三位数字,下边的 starting number 代表从哪个数字开始排序。

部署图片

图片处理成功后,需要放到特定的目录中。

我们先在 /root/autodl-tmp/train 下创建一个项目目录,我这里就用狗子的名字:dudu,然后在这个目录下再创建一个 img 目录,用于放置处理好的图片,不过图片还不能直接放到 img 下,还需要创建一个子目录:100_dudu,这个目录的名字是有讲究的,前边的100代表每张图片需要学习100次,后边的 dudu 就是图片的主题名字。

这里的学习次数没有固定的标准,真实图片建议50-100,二次元15-30。如果最终训练出的模型出现过拟合的问题,比如生图提示词写了蓝眼睛但是生成的都是黑眼睛,可以降低下学习次数试试。

把裁切好的图片上传到 /root/autodl-tmp/train/dudu/img/100_dudu 这个目录,如下图所示:

图片打标

所谓打标就是给图片编写提示词,一般先使用提示词反推工具生成提示词,然后再根据实际情况修改生成的提示词。

启动 kohya_ss 后,进入打开的 Web 页面,依次进入“Utilities”->“Captioning”->"BLIP Captioning"。

“Image folder to caption”中输入待打标的图片目录,我这里就是:/root/autodl-tmp/train/dudu/img/100_dudu。

“Caption file extension”是生成的提示词文件的后缀名。

“Prefix to add to BLIP caption”是添加到生成提示词中的固定前缀,训练中如果使用了这些前缀,生成图片时就可以使用这些前缀比较方便的触发Lora模型,但是根据经验也不能保证一定触发。后边还有一个参数“Postfix to add BLIP caption”,这个是固定后缀。前缀在处理图片时的优先级更高一些。

其它参数都用默认就好了,有兴趣的可以研究下,我这里就不展开了。

最后点击“Caption images”。

注意这个工具的页面中都没有进度跟踪,需要到 shell 或者控制台界面查看,看到 100% 的进度条,以及“captioning done”的提示就说明打标完成了。

此时我们进入待训练的图片目录,就可以看到这些打标文件了。可以看到,每张图片都生成了对应的打标文件。

我们可以双击打开这些 txt 文件,查看其中的内容;如果感觉写的不好,可以修改它。

生成的提示词一般多多少都会有些问题。

  • 对于画风类型的Lora,可以保留全部生成的标签,但是在训练时要多训练几轮,训练时间可能比较长。
  • 对于特定角色的Lora,如果我们想保留某个特征作为角色的自带特征,就把对应的标签删除,比如长头发,这样Lora中就会保存长头发作为角色的特征。不过这也是有缺点的,可能导致生成图片时过拟合:提示词不生效,比如输入短发生成的还是长发,严重的还可能导致画面崩坏、模糊不清。

修改提示词是个大工程,这里为了尽快演示,就不修改提示词了。

另外在这个工具中,我们可以看到,除了 BLIP,还有三个给图片打标的方法,不过我都没有跑成功,有兴趣的可以一起研究下。

如果你不使用 kohya_ss 自带的打标工具,也是完全可以的,比如 SD WebUI 的“训练”功能中也可以裁切图片并反推提示词,只是需要手动上传打标文件到这里的训练目录中。这里再推荐一个提示词编辑工具:https://github.com/starik222/BooruDatasetTagManager,有兴趣的可以去试试。

训练

参数设置

训练模型的参数很多,还会涉及到深度学习的一些概念,之前没接触过的同学可能会感觉头疼,不过没关系,我会尽量把主要的参数说清楚。

kohya_ss 启动后,依次进入“LoRA”->“Training”。

Source Model

设置训练使用的 Stable Diffusion 大模型,“Model Quic Pick”这里可以选择一些 SD 的基础大模型,训练的时候会先去 HuggingFace 下载,不过我实际测试跑不同,所以这里选择 custom,然后自己上传一个模型,因为训练图片是真实世界的狗子,所以这里使用了realisticVisionV51(使用AutoDL镜像的同学不用再上传,已经内置了),这是一个真实视觉模型。

Folders

设置训练模型时的输入输出目录。

  • Image folder 是训练数据集的目录,也就是原图片的目录,注意只到 img 这一级,不是直接存放图片的目录,这里的完整路径是:/root/autodl-tmp/train/dudu/img 。
  • Output folder 是训练出的Lora模型保存的目录,训练过程中的采样图片也保存在这个目录下,和 Image folder 使用同一个上级目录就行了,这里的完整路径是:/root/autodl-tmp/train/dudu/model 。
  • Logging folder 顾名思义,就是训练的日志目录,和 Image folder 使用同一个上级目录就行了,这里的完整路径是:/root/autodl-tmp/train/dudu/log 。
  • Model output name 是训练出的Lora模型的文件名前缀。

Parameters

进入到真正的参数设置环节了,前边只是些开胃小菜。

先来看基本参数(Basic):

  • Train batch size:同时训练的样本图片数,默认为1,显存 12G 以上可以设置为2-6,请根据实际显存使用情况设置,数值越大训练速度越快。
  • Epoch:训练的轮数,一轮就是把所有的样本图片完成一次训练。一般需要训练多轮,然后根据实际生图情况选择合适的轮次模型。轮数越大,训练需要的时间越多。
  • Save every N epochs:每隔几轮保存一次训练出的模型,我们想要测试每一轮输出的模型,所以这里填写1。
  • Caption Extension:样本图片对应的打标文件的后缀名,之前打标用的是 .txt,这里填上就行了。
  • Mixed precision 和 Save precision:计算使用的浮点数精度控制,都选择fp16就好了,可以节省内存使用。bf16精度略低,但是表示的整数范围更大,数据类型转换也更容易,不过要看显卡能不能支持。
  • Number of CPU threads per core:单个CPU核心的线程数,可以理解为一个CPU核心可以同时干两件事。一般都是2,我租用的这台服务器也是2,可以用 lscpu 等命令查看。不确定的设置为1。
  • Seed:训练使用的随机数,随便填一个就行。如果需要提升之前构建过的模型(在 LoRA network weights 中填写之前构建过的模型),使用相同的随机数。
  • Cache latents:勾选上,可以让训练速度更快。
  • Learning rate:学习率,可以理解为每次学习走过的长度,值越小,训练的越慢,值越大,步子越大,就不容易找到规律,模型难以收敛。所谓收敛就是通过训练让模型不断得到优化的过程,难以收敛就是无法优化模型,模型生成的角色和样本图片偏差过大。

这一行都是有关学习率的参数设置,也就是怎么让模型收敛的又快又好,都是一些算法,先用我这里默认的吧,不好使再换。

    • LR Scheduler:学习率调度器,它会自动调整学习率,我一般使用constant。
    • LR warmup (% of steps):升温步数,仅在“LR Scheduler”为“constant_with_warmup”时设置,用来控制模型在训练前逐渐增加学习率的步数。
    • Optimizer: 主要用来更新模型中的权重和偏差等参数,以便更好的拟合数据。有的优化器也可以直接影响学习率。先试试 AdamW8bit 吧。
  • Max resolution:训练的最大分辨率,设置为样本图片的分辨率即可。
  • Enable buckets:启动后支持多种分辨率的样本图片,程序会自动裁切,这里我已经都裁切成768了,勾不勾选无所谓了。
  • Text Encoder learning rate:文本编码器的学习率,建议从0.00005开始,后面的Unet learning rate要比前面的大,设置成 0.0001,设置这个值会导致忽略上面的 Learing rate,保持一致吧。
  • Network Rank:模型的神经网络参数维度,默认是8,建议 32、64、128,值越大模型越精细,生成的模型文件也越大。 Network Alpha 保持相同的值就好。

高级参数(Advanced)中我们看下这几个:

  • Clip skip:默认为1。设置为大于1的数时,在训练时可以跳过一些处理,进而可以避免过拟合,增强模型的泛化能力,但也不易过大,会丢失特征。最好与对应大模型在训练时设置的参数相同。
  • Memory efficient attention:可以优化显卡内存的使用,但会导致学习速度变慢。
  • CrossAttention:用于关联图像和提示词的加速算法,一般就选择 xformers,加速图片生成并降低显存占用,xformers只适用于N卡,未来可能应用于其它显卡。

最后还有个采样参数(Samples),使用它可以跟踪训练效果:

Sample every n steps:每学习N步,生成一张图片。

Sample every n epochs:每学习N轮,生成一张图片,实测开启这个会覆盖 Sample every n steps。

Sample sampler:采样器,和SD WebUI中默认的采样器相同。

Sample prompts:采样提示词,这里包括了提示词、反向提示词、图片尺寸、采样步数等。

完成训练

点击“Start Training”之后,还是到控制台中查看处理进度。

因为每张图片学习100步,同时训练的数量是1,所以25张图片训练一次就要学习2500步,同时指定了轮次是3,所以总计是7500步。

训练完成后,可以看到 100% 的提示,模型已经保存到相应的目录。

测试

模型训练好了,怎么知道好不好使呢?那当然要做测试时,实际抽抽卡。

笨点的办法就是挨个测试,测试不同权重、提示词、大模型等情况下的表现。

这里分享一个快速对比测试的方法,使用 X/Y/Z图表。

提示词中增加变量,如下图所示的样子引用Lora模型:

注意这里的:<lora:dudu_log-NUM:WEIGHT> ,NUM和WEIGHT是两个变量。

  • NUM:因为我使用了多轮次的训练,获得了多个Lora模型,所以需要测试不同训练轮次的模型表现,这些模型的名字是有规律的:dudu_log-000001、dudu_log-000002、... ,每增加一轮训练,生成的模型名字序号就会加1。NUM 就是代表 000001、000002 的变量。
  • WEIGHT 是使用当前 Lora 模型的权重变量,这里要测试不同权重下模型的表现。

X/Y/Z图表在文生图、图生图页面的最下方:

脚本类型选择:X/Y/Z图表

X轴类型选择:Prompt S/R,X轴值填写:NUM,000001,000002

Y轴类型选择:Prompt S/R,Y轴值填写:WEIGHT,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1

空格边距填写:2,生成的图片之间做个分割。

然后我们去生成图片,生成图表如下:

然后我们就可以对比不同模型、权重下的出图效果,我这里模型 000002 更接近真实图片,权重 0.5-0.9 效果会比较好,1.0就有点过拟合了。

X/Y/Z图表中还有很多的维度可以测试,比如大模型、迭代步数、采样器、提示词引导系统等等,有兴趣的可以多去尝试下。

优化

仅分享我的一点经验和体会。上面也提到了一些,这里做个总结。

  • 训练用的图片一定要高清,不要模糊,角色尽量多角度,原图对训练结果的差异特别大。如果没有高清的图,可以去 SD WebUI 的图生图中重绘模糊的图片,或者使用其它的软件高清化图片。
  • 训练用的提示词:在提示词中去掉你想在生成图片时保留的角色特征,增加你允许生成图片时替换的角色特征。比如你想保留角色的长头发,那就在提示词中去掉长头发,这样生成图片时就有很大的概率都是长头发;如果你想要角色的眼睛颜色可以替换,就在训练提示词中写上黑色眼睛,这样生成图片时就可以使用蓝色眼睛的提示来更换角色的眼睛颜色。
  • 多轮次训练:训练一轮的效果可能不好,成本允许的话,建议多训练几轮,然后对比不同轮次下的模型出图效果,选择最适合的那个。
  • 训练步数:每张图片训练多少次才合适?训练的少了提取的特征不够,训练多了容易过拟合。二次元建议15-30次,其它图片50-100次。训练的图片少,每张图就可以多训练几次,训练的图片多,每张图就可以少训练几次。

资源下载

本文使用的模型、插件,生成的图片,都已经上传到了我整理的SD绘画资源中,后续也会持续更新,如有需要,请关注公众号:萤火遛AI(yinghuo6ai),发消息:SD,即可获取下载地址。


以上就是本文的主要内容,如有问题欢迎留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/912507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

七夕情侣飞行棋游戏限定版本源码/解锁版

七夕情侣飞行棋限定版本源码已经发布&#xff01;这是一款专为情侣打造的桌游&#xff0c;让您与您的另一半一起感受浪漫的体验。 更为重要的是&#xff0c;这个版本已经移除了路由器限制&#xff0c;解锁了全部功能&#xff0c;而且没有任何加密措施&#xff0c;您只需将源码…

将ChatGPT集成整合到业务中时,3个要做和3个不要做的事项

​关于ChatGPT的讨论甚多&#xff0c;毫无疑问的是&#xff0c;几乎每个人都应该使用它&#xff0c;无论用于个人生活问题的解答还是工作中简化日常任务。越来越多的行业也正在探索这项技术的应用场景&#xff0c;从优化客户服务体验、简化旅行计划到便捷的内容创作等&#xff…

day 35 | ● 343. 整数拆分 ● 96.不同的二叉搜索树

343. 整数拆分 他是有三个数进行比较&#xff0c;原来的dp[i]、dp[j] * (i - j)、j*(i - j)。为什么第二个不包含第三个呢&#xff0c;因为我们设定的dp为至少两个数的乘积&#xff0c;所以dp[j]不包含j本身。 func integerBreak(n int) int {dp : make([]int, n 1)dp[1] 0d…

python 画二部图

1. 特色二部图 修改节点与边颜色、大小等 import networkx as nx import matplotlib.pyplot as plt plt.figure(设备-用户关系图, figsize(4, 6)) # 设置画布大小list_fid [1, 2, 3, 4] # 添加设备节点 list_uid ["a", "b", "c"] # 添加用…

【HCIP】14.BGP反射器

反射器规则 非非不反 如果路由反射器从自己的非客户机学习到的一条IBGP路由&#xff0c;则它将该路由反射给所有客户如果RR从自己的客户机学习到一条IBGP路由&#xff0c;则反射给所有非客户&#xff0c;以及除了该客户之外的所有客户如果RR学习到的EBGP路由&#xff0c;则反…

【高级IO】- 多路转接之 poll | epoll

目录 I/O多路转接 - poll poll 函数 poll 服务器 poll 服务器 poll 的优点 poll 的缺点 I/O 多路转接 - epoll epoll 的相关系统调用 epoll_create 函数 epoll_ctl 函数 epoll_wait 函数 epoll 工作原理 epoll 服务器 ​编辑 epoll 的优点&#xff08;与 sele…

vr游乐场项目投资方案VR主题游乐馆互动体验

VR文旅景区沉浸互动体验项目是指利用虚拟现实技术在文旅景区中创建沉浸式的互动体验项目。通过虚拟现实技术&#xff0c;游客可以身临其境地体验景区的风景和文化&#xff0c;与虚拟场景中的元素进行互动。 普乐蛙VR设备 普乐蛙VR设备案例分享 这种项目可以为游客带来全新的旅游…

2023年中秋月饼市场趋势分析(月饼京东销售数据分析)

中秋将至&#xff0c;月饼作为节令食品将再次掀起消费热潮。今年月饼市场的需求如何呢&#xff0c;是更受欢迎还是热度有所降低&#xff0c;结合数据我们一起来看今年月饼市场的销售表现。 在这里&#xff0c;我们分别选取了2022年第31周-32周和2023年第31周-32周&#xff08;…

抖音推出AI机器人,竟被鸡兔同笼难倒

自从Chatgpt横空出世爆火后&#xff0c;咱国内也掀起了一波AI的风潮&#xff0c;前几期有评测过百度的“文心一言”&#xff0c;总的来说体验还不错&#xff0c;但是距离Chatgpt还是有上升的空间&#xff0c;因为它的上下文理解还是不够智能。 百度有文心一言&#xff0c;阿里…

基于CentOS搭建私有仓库harbor

环境&#xff1a; 操作系统&#xff1a;CentOS Linux 7 (Core) 内核&#xff1a; Linux 3.10.0-1160.el7.x86_64 目录 安装搭建harbor &#xff08;1&#xff09;安装docker编排工具docker compose &#xff08;2&#xff09;下载Harbor 安装包 &#xff08;3&…

【操作系统】寄存器

概念 寄存器是CPU内部用来存放数据的一些小型存储区域&#xff0c;用来暂时存放参与运算的数据和运算结果。其实寄存器就是一种常用的时序逻辑电路&#xff0c;但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的&#xff0c;因为一个锁存器或触发器…

docker与docker-compose搭建redis1主2从3哨兵

docker安装redis docker pull redis:latest创建目录结构 用于挂载数据卷配置文件等 运行redis容器 主redis配置 下面这种方式挂载的配置文件不生效。 docker run -d \--name master_redis_6379 \-p 6379:6379 \--restart unless-stopped \-v /mydata/master_redis/data:/da…

IDEA中导入多module的Maven项目无法识别module的解决办法

首先举个栗子 这是正常的多module工程&#xff08;spring cloud项目&#xff09; 正常工程.png 这是导入出现问题的多module工程 导入出现问题的工程.png 原因&#xff1a; 出现该问题&#xff0c;是由于打开工程的时候IDEA只编译了最外层的pom.xml文件&#xff0c;而内部的…

在线成绩查询

在如今快节奏的社会中&#xff0c;家长们越来越重视孩子的学习情况。为了满足家长们对孩子学习情况的关注&#xff0c;老师们需要一个方便、快速、及时的学生成绩在线查询系统。 今天&#xff0c;我将向大家推荐一个教师必备的工具——易查分&#xff01;相比传统的自行开发的成…

前端下载文件方式(Blob)

以下以下载图标svg文件为例&#xff0c;实现点击按钮下载文件&#xff0c;其中icon结构如下&#xff1a; const DownloadSvg (props) > {function download(downfile) {const tmpLink document.createElement("a");const objectUrl URL.createObjectURL(downfi…

恒驰喜讯 | 荣获2023超聚变合作伙伴大会“聚心同力销售支撑奖”

“创价值、同信念、共成长”&#xff0c;8月18日&#xff0c;2023超聚变合作伙伴大会在北京举行。来自全国各地超过1500家行业、商业、服务生态伙伴&#xff0c;共同探讨算力产业发展。聚菁英&#xff0c;共赢算力未来。作为超聚变的核心合作伙伴&#xff0c;上海恒驰信息系统有…

《Go 语言第一课》课程学习笔记(十)

复合数据类型 同构复合类型&#xff1a;从定长数组到变长切片 由多个同构类型&#xff08;相同类型&#xff09;或异构类型&#xff08;不同类型&#xff09;的元素的值组合而成&#xff0c;这类数据类型在 Go 语言中被称为复合类型。 数组有哪些基本特性&#xff1f; Go 语…

SOA通信中间件常用的通信协议

摘要&#xff1a; SOA&#xff08;面向服务的架构&#xff09;的软件设计原则之一是模块化。 前言 SOA&#xff08;面向服务的架构&#xff09;的软件设计原则之一是模块化。模块化可以提高软件系统的可维护性和代码重用性&#xff0c;并且能够隔离故障。举例来说&#xff0c;…

【算法随记】在计算过程中模的情况

https://leetcode.cn/problems/power-of-heroes/ 计算过程中&#xff0c;可以放心模的情况&#xff1a; 加减乘 先模再加再模和直接加再模一样 a m o d m b m o d m ≡ a b ( m o d m ) a\mod mb\mod m ≡ ab \ (\mod m) amodmbmodm≡ab (modm) 先模再减再模和直接减再模…