用 LoRA 打造更快的 AI 模型。
AI 模型功能越来越强大,结构也越来越复杂,它们的速率也成为了衡量先进程度的标准之一。
如果 AI 是一辆豪华跑车,那么 LoRA 微调技术就是让它加速的涡轮增压器。LoRA 强大到什么地步?它可以让模型的处理速率提升 300%。还记得 LCM-LoRA 的惊艳表现吗?其他模型的十步,它只需要一步就能达到相媲美的效果。
这是怎么做到的?Raphael G 的博客详细说明了 LoRA 如何在提高模型推理效率和速率方面取得显著成效,并介绍了这一技术实现的改进及其对 AI 模型性能的重大影响。以下为机器之心对本篇博客不改变原意的编译和整理。
原博客链接:https://huggingface.co/raphael-gl
我们已经能够大大加快基于公共扩散模型的公共 LoRA 在 Hub 中的推理速率,这能够节省大量的计算资源,并带给用户更快更好的使用体验。
要对给定模型进行推理,有两个步骤:
1. 预热阶段,包括下载模型和设置效劳 ——25 秒。
2. 然后是推理工作本身 ——10 秒。
经过改进,预热时候能够从 25 秒缩短到 3 秒。现在,我们只需不到 5 个 A10G GPU 就能为数百个分别的 LoRA 供应推理效劳,而对用户要求的响应时候则从 35 秒减少到 13 秒。
下面让我们进一步讨论如何利用 Diffusers 库中最近开发的一些功能,通过单个效劳以动态方式为许多分别的 LoRA 供应效劳。
什么是 LoRA
LoRA 是一种微调技术,属于「参数高效微调」(parameter-efficient fine-tuning,PEFT)方法系列,该方法致力于在微调过程减少受影响可训练参数的数量。它在提高微调速率的同时,还能减少微调检查点的大小。
LoRA 的方法并不是通过对模型的全部权重进行微小改动来微调模型,而是冻结大部分层,只在注意力模块中训练少数特定层。此外,我们通过在原始权重上添加两个较小矩阵的乘积来避免触及这些层的参数。这些小矩阵的权重会在微调过程中更新,然后保存到磁盘中。这意味着全部模型的原始参数都被保留下来,使用者可以用自适应方法在其上加载 LoRA 权重。
LoRA(Low-Rank Adaptation,低秩自适应)的名称来源于上文提到的小矩阵。有关该方法的更多信息,可以参阅下方博客或原论文。
相关博客链接:https://huggingface.co/blog/lora
论文链接 https://arxiv.org/abs/2106.09685
下图显示了两个较小的橙色矩阵,它们被保存为 LoRA 适配器的一部分。接下来,我们可以加载 LoRA 适配器,并将其与蓝色基本模型合并,得到黄色微调模型。最重要的是,我们还可以卸载适配器,这样就可以在任何时候返回到原始基本模型。
换句话说,LoRA 适配器就像是基本模型的附加组件,可以按需添加和卸载。由于 A 级和 B 级较小,与模型尺寸相比,它非常轻便。因此,加载速率要比加载整个基本模型快得多。
例如,被广泛用作许多 LoRA 适配器基本模型的 Stable Diffusion XL Base 1.0 模型 repo,我们会发现它的大小约为 7 GB。然而,像这样的典型 LoRA 适配器仅占用 24 MB 空间。
在 Hub 上,蓝色基本模型的数量远远少于黄色模型。如果能从蓝色快速切换到黄色,反之亦然,那么我们就有办法为许多分别的黄色模型供应效劳,并且只需少数分别的蓝色摆设。
LoRA 的优势
Hub 上拥有约 2500 个分别的公共 LoRA,其中绝大多数(约 92%)基于 Stable Diffusion XL Base 1.0 模型。
在这种同享机制之前,要为全部这些模型(例如上文图中全部黄色合并矩阵)摆设专用效劳,并至少占用一个新的 GPU。启动效劳并准备好为特定模型的要求供应效劳的时候约为 25 秒,此外还有推理时候,在 A10G 上以 25 个推理步骤进行 1024×1024 SDXL 推理扩散的时候约为 10 秒。如果一个适配器只是偶尔被要求,它的效劳就会被停止,以释放被其他适配器抢占的资源。
如果你要求的 LoRA 不那么受欢迎,即使它是基于 SDXL 模型的,就像迄今为止在 Hub 上发现的绝大多数适配器一样,也需要 35 秒来预热并在第一次要求时获得响应。
不过,以上已成为过去时,现在要求时候从 35 秒缩短到 13 秒,因为适配器将只使用几个分别的「蓝色」基本模型(如 Diffusion 的两个重要模型)。即使你的适配器不那么火热,其「蓝色」效劳也很有可能已经预热。换句话说,即使你不经常要求你的模型,也很有可能避免了 25 秒的预热时候。蓝色模型已经下载并准备就绪,我们要做的就是卸载之前的适配器并加载新的适配器,只需要 3 秒钟。
总的来说,尽管我们已经有办法在各个摆设之间同享 GPU 以充分利用它们的计算能力,但相比之下仍然需要更少的 GPU 来支持全部分别的模型。在 2 分钟内,大约有 10 个分别的 LoRA 权重被要求。我们只需使用 1 到 2 个 GPU(如果有要求突发,可能会更多)就能为全部这些模型供应效劳,而无需启动 10 个摆设并让它们保持运行。
实现
我们在推理 API 中实现了 LoRA 同享。当在平台上对一个模型发起要求时,我们首先判断这是否是一个 LoRA,然后确定 LoRA 的基本模型,并将要求路由到一个能够效劳该模型的共同的后端效劳器群。
推理要求通过保持基本模型运行状态,并即时加载 / 卸载 LoRA 来效劳。这样,你就可以重复使用相同的计算资源来同时效劳多个分别的模型。
LoRA 的结构
在 Hub 中,LoRA 可通过两个属性来识别:
LoRA 会有一个 base_model 属性,这是 LoRA 建立的基本模型,用于执行推理过程中使用。由于不仅 LoRA 拥有这样的属性(任何复制的模型都会有一个),所以它还需要一个 lora 标签来正确识别。
数据展示
每次推理多花 2 到 4 秒钟,我们就能为很多分别的 LoRA 供应效劳。不过在 A10G GPU 上,推理时候大大缩短,而适配器加载时候变化不大,因此 LoRA 的加载 / 卸载成本相对更高。
全部数字的单位为秒。
批处理如何?
最近有一篇非常有趣的论文,介绍了如何通过在 LoRA 模型上执行批量推理来提高吞吐量。简而言之,全部推理要求都将被批量收集,与通用基本模型相关的计算将一次性完成,然后再计算剩余的特定适配器产品。
论文链接 https://arxiv.org/pdf/2311.03285.pdf
我们没有采用这种技术。相反,我们坚持单个顺序推理要求。因为我们观察到对于扩散器来说,吞吐量不会随着批处理规模的增加而显著提高。在我们执行的简单图像生成基准测试中,当批量大小为 8 时,吞吐量只增加了 25%,而延迟却增加了 6 倍。
关于加载 / 卸载 LoRA 的内容,请阅读博客原文。