ziwang-com / zero-lora

zero零训练llm调参

Home Page:http://www.m-f.vip

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

动态应用 LoRA 适配器

ziwang-com opened this issue · comments

ggerganov/llama.cpp#820
添加 LoRA 支持 #820

斯拉伦评论 on Apr 7

动态应用 LoRA 适配器,而无需复制模型文件.

指示:

获取 HF PEFT LoRA 文件和 LoRA 适配器,并将它们放在相同的路径中.对于羊驼,可以在 https://huggingface.co/tloen/alpaca-lora-7b/tree/mainadapter_config.jsonadapter_model.bin
使用进行转换以获得convert-lora-to-ggml.pyggml-adapter-model.bin
python convert-lora-to-ggml.py lora/alpaca-lora-7b
使用 与ggml-adapter-model.bin--lora
./main -m models/7B/ggml-model-f16.bin --lora lora/alpaca-lora-7b/ggml-adapter-model.bin --color -f ./prompts/alpaca.txt -ins -b 256 --top_k 10000 --temp 0.2 --repeat_penalty 1 -t 7
使用量化模型时,质量可能会受到影响。若要避免这种情况,请指定用作基础的 f16/f32 模型。LoRA 适配器修改的层将应用于 lora 基础模型,然后量化为与使用 .未被 LoRA 适配器修改的层将保持不变.--lora-base-m
./main -m models/7B/ggml-model-q4_0.bin --lora lora/alpaca-lora-7b/ggml-adapter-model.bin --lora-base models/7B/ggml-model-f16.bin --color -f ./prompts/alpaca.txt -ins -b 256 --top_k 10000 --temp 0.2 --repeat_penalty 1 -t 7
局限性:

使用禁用 mmap,因为无论如何都必须修改模型。--lora
使用 时,操作用于量化结果,该结果目前在单个线程中完成。并行化将缩短加载时间。--lora-baseggml_cpyggml_cpy
flyinweb用竖起大拇指的表情符号做出反应
tiendung,lin72h,gregnr,ericek111,stoperro,marcom,swittk,mc0ps,cheebeez,michaeloo0和6更多人用心形表情符号做出了反应
Luminalle,msftceo,tekakutli,gorborukov,LiliumSancta,thomasantony,fuchinoko,FNsi,lin72h,81300和20更多人对火箭表情符号做出了反应
@slaren 斯拉伦更改了标题 添加劳拉支持 添加 LoRA 支持 on Apr 7
@MillionthOdin16
百万之奥丁16 评论 on Apr 7
棒!Loras 将非常有用,尤其是他们现在变得多么容易训练🔥

lin72h 用竖起大拇指表情符号做出反应
天东用心表情做出反应
@Piezoid
贡献
Piezoid 评论 on Apr 7
你认为有可能(或希望)生成修补张量的量化版本吗?

( f16 llama model, LoRA's tensors) --> f16 patched tensors --> quantized patched tensors
这将带来量化的加速,并允许对两个文件进行 mmap 映射。来自原始张量的页面不会被错误/加载到内存中(必须禁用)MAP_POPULATE

@slaren
合作者
作者
斯拉伦评论 on Apr 7
@Piezoid我不确定处理这个问题的最佳方法是什么。理想情况下,为简单起见,生成的修补张量将采用与最初相同的格式,因此,如果您修补q4_0模型,您仍然以q4_0模型结束。但是,这可能会显着影响质量,并且可能与修补 f16 模型并在之后即时量化它一样慢或更慢。我们需要运行更多的测试,我可能会尝试实现这两个选项,看看哪个效果最好。

克西德用眼睛表情符号做出反应
@Piezoid
贡献
Piezoid 评论 on Apr 7
@slaren就像你说的, 将 LoRA 增量添加到 q4 量化模型很可能对质量非常不利.量化必须在之后进行。我的建议是生成一个单独的模型文件,仅由添加 LoRA 全秩权重的修补张量组成,并可能将量化作为最后一步。

这个想法是通过只需要修改后的张量的空间来节省磁盘空间。通过脱机完成修补过程,加载时间也可能减少。

您在加载期间修补和量化的建议很有趣,但它需要加载 f16 美洲驼模型并量化尚未修改的张量。
我可能弄错了,因为我不确定哪些张量是量化的,哪些张量是由 LoRA 修补的。

天东用竖起大拇指表情符号做出反应
瓦斯纳姆用困惑的表情符号做出反应
@slaren
合作者
作者
斯拉伦评论 on Apr 7
@Piezoid存储预先修补的张量实际上并不可行,因为文件大小几乎与整个模型相同。lora 的优点是要修补 4096x4096 矩阵,您只需要一个 16x4096 和一个 4096x16 矩阵 (对于排名 16, 可以是任何其他数字).修补它,突然你的 2x16x4096 变成了 4096x4096。

Piezoid和Jon-Chuang用竖起大拇指的表情符号做出反应
@ggerganov
所有者
格尔加诺夫评论 on Apr 8 •
非常有用的信息。

另一种需要考虑的方法是使用矩阵乘法的分配属性:
我们可以将可选的 LoRA 节点添加到计算图中.
例子:(B+C)A=BA+CAllama

cur = ggml_mul_mat(ctx0, model.layers[il].wo, cur);
将变成:

curL = ggml_mul_mat(ctx0, model.layers[il].wo, cur);
if (lora_enabled) {
// can be precomputed once at the cost of more memory
// or we can keep unpacking it each time to save memory
lora = ggml_mul_mat(ctx0, model.loraB[il], model.loraA_trans[il]);

lora = ggml_mul_mat(ctx0, lora, cur); // F32 mul_mat
curL = ggml_add(ctx0, curL, lora);    // F32 add

}
cur = curL;
缺点是由于额外的推理速度较慢,但动态加载新的 LoRA 是微不足道的。基本模型保持不变,可以保持量化。ggml_mul_mat

ott2 用竖起大拙的表情符号做出反应
@slaren
合作者
作者
斯拉伦评论 on Apr 8 •
一个小旁注,我意识到在某些情况下还需要添加比例因子。具体来说,这是 PEFT 为合并 lora 所做的:

self.scaling = self.lora_alpha / self.r
if fan_in_fan_out:
self.weight.data = self.weight.data.T
...
self.weight.data += (
transpose(self.lora_B.weight @ self.lora_A.weight, self.fan_in_fan_out) * self.scaling
)
...
def transpose(weight, fan_in_fan_out):
return weight.T if fan_in_fan_out else weight
其中 和 (秩) 是 中的参数。
在羊驼的情况下,这是一个noop,但情况并非总是如此,例如在gpt4all和.lora_alpharadapter_model.jsonlora_alpha = rlora_alpha=32r=8

@slaren
合作者
作者
斯拉伦评论 on Apr 8
@ggerganov除了性能考虑之外, 要记住的是,应用 lora 的张量完全取决于实现, 例如 alpaca 适用于所有 q,k,v,o,但 gpt4all 仅适用于 q,v.我想如果我们必须单独考虑每一个张量,eval 很快就会变成 spaguetti。

@slaren 斯拉伦力推劳拉分支 2 次,最近一次从 cd2dbea 到 a4539e1
last month
@slaren
合作者
作者
斯拉伦评论 on Apr 8
这现在应该适用于量化模型。修补量化模型似乎还不错,我在羊驼q4_0上得到了 6.6281 的困惑。

ggerganov,lin72h,Piezoid,tekakutli和81300用竖起大拇指的表情符号做出反应
MillionthOdin16,lin72h和mc0ps对火箭表情符号做出了反应
@slaren 斯拉伦力推劳拉从 d00017b 到 af00579 的分支
last month
@ggerganov 格尔加诺夫补充说研究🔬标签 on Apr 10
@slaren 斯拉伦力推劳拉从 af00579 到 0d8999a 的分支
last month
@slaren
合作者
作者
斯拉伦评论 on Apr 11
现在 #801 已合并,使用禁用 mmap。加载速度有点慢,但它现在应该可以在窗口上运行。--lora

@MillionthOdin16
百万之奥丁16 通过电子邮件评论 on Apr 11
棒🔥我将很快在Windows上测试它。此功能非常有用🙂
...
@jon
贡献
钟创评论 on Apr 12 •
因此,为了清楚起见,我们将加载原始参数,然后以批处理方式加载:

加载 fp16 给定矩阵的 LoRA
将原始参数反量化为 fp16
应用劳拉
重新量化以节省内存
粗略估计此适配器“加载”时间有多长?

使用 --lora 禁用 mmap

我想由于您可以修补任意比例的权重,因此修补矩阵的原始权重只加载一次。但是 mmap 对于权重相对较小 + 热插拔 LoRA 的情况可能仍然有用。只是一个想法。

大部分权重的CoW基本上是重复权重,因此非常不可行。

@slaren
合作者
作者
斯拉伦评论 on Apr 12
将 fp16 替换为 fp32,这与它目前的工作方式非常接近:

在 f32 中将矩阵 lora B 和 lora A 相乘
使用 f32 缩放 BA
将 BA 添加到原始权重。这是在必要时进行去量化/重新量化的地方
为我应用适配器的时间从 ~5 秒在 7B 上使用小型 lora 适配器到在 30B 上使用较大的 lora 的分钟以上.到目前为止,最慢的部分是将 lora 矩阵相乘.

可能有一些方法可以加速这一点,但目前我更关心正确性和支持所有用例。

@MillionthOdin16
百万之奥丁16评论 on Apr 12 •
我正在尝试解决Windows上的一些问题。首先,转换脚本和整个过程很简单,所以做得很好,让它变得简单。

我能够很好地加载 7B 美洲驼和 7B 劳拉, 但我注意到我似乎没有得到我期望的响应 应用 Lora.这看起来很奇怪,因为它的行为就好像劳拉根本不存在一样。

当我尝试使用 13B 型号和 13B lora 进行测试时,我在尝试运行 main 时遇到了问题。它提到.我有 64GB 的系统内存,而且它还没有达到最大值,所以我对正在发生的事情感到困惑。not enough space in the context's memory pool

C:\Users\Bradarr\Documents\GitHub\llama.cpp> ./build/bin/main -m D:\models\LLaMA\13B\ggml-model-q4_0-nmap.bin --lora D:\models\loras\bradarr-lora\13B\ggml-adapter-model.bin
main: seed = 1681243691
llama.cpp: loading model from D:\models\LLaMA\13B\ggml-model-q4_0-nmap.bin
llama_model_load_internal: format = ggjt v1 (latest)
llama_model_load_internal: n_vocab = 32000
llama_model_load_internal: n_ctx = 512
llama_model_load_internal: n_embd = 5120
llama_model_load_internal: n_mult = 256
llama_model_load_internal: n_head = 40
llama_model_load_internal: n_layer = 40
llama_model_load_internal: n_rot = 128
llama_model_load_internal: f16 = 2
llama_model_load_internal: n_ff = 13824
llama_model_load_internal: n_parts = 1
llama_model_load_internal: model size = 13B
llama_model_load_internal: ggml ctx size = 7945693.73 KB
llama_model_load_internal: mem required = 9807.47 MB (+ 1608.00 MB per state)
....................................................................................................
llama_init_from_file: kv self size = 400.00 MB
llama_apply_lora_from_file: applying lora adapter from 'D:\models\loras\bradarr-lora\13B\ggml-adapter-model.bin' - please wait ...
llama_apply_lora_from_file: r = 8, alpha = 16, scaling = 2.00
llama_apply_lora_from_file: ggml_new_tensor_impl: not enough space in the context's memory pool (needed 105185904, available 104857600)
有什么指示吗?
超级兴奋地让它工作,因为它开辟了大量的可能性!另外, 只是一个想法, 但可以选择将 lora 融合到基本模型可能会很好.一旦你有一个运行良好的 lora 并不断使用它, 永久捆绑它会很好.

编辑(一些附加信息):

ggml_new_tensor_impl: context memory pool -> (needed 209715232, available 421527552)
ggml_new_tensor_impl: context memory pool -> (needed 419430640, available 421527552)
llama_init_from_file: kv self size = 400.00 MB
llama_apply_lora_from_file: applying lora adapter from 'D:\models\loras\bradarr-lora\13B\ggml-adapter-model.bin' - please wait ...
llama_apply_lora_from_file: r = 8, alpha = 16, scaling = 2.00
llama_apply_lora_from_file: ggml_new_tensor_impl: context memory pool -> (needed 163872, available 104857600)
ggml_new_tensor_impl: context memory pool -> (needed 327920, available 104857600)
ggml_new_tensor_impl: context memory pool -> (needed 105185728, available 104857600)
ggml_new_tensor_impl: not enough space in the context's memory pool (needed 105185904, available 104857600)
@slaren 斯拉伦力推劳拉分支从 0d8999a 到 671190b
last month
@slaren
合作者
作者
斯拉伦评论 on Apr 12 •
@MillionthOdin16感谢您对此进行测试, 确定我尝试过的 lora 是否有任何有意义的影响一直是一场斗争, 但我想我发现了一个问题.您能看到最新的更改是否解决了您的问题吗?

@MillionthOdin16
百万之奥丁16评论 on Apr 12 •
@MillionthOdin16感谢您对此进行测试, 确定我尝试过的 lora 是否有任何有意义的影响一直是一场斗争, 但我想我发现了一个问题.您能看到最新的更改是否解决了您的问题吗?

棒!内存分配问题已修复,现在运行顺利。

我没有得到我期望的 lora 的回应, 所以我怀疑如何应用 lora 有些不对劲.现在我可以运行我的 13B 模型, 更容易看到 lora 何时正常工作 (13B 是我训练最好的 lora).我可以做些什么来帮助排除故障?

我有一个 25MB 的 lora,当放在普通骆驼模型上时,它会显着提高输出.我不知道完全合并到基本模型中的 lora 是否也会有所帮助 (不知道我们是否可以比较这种植入和 lora 融合模型之间的有效权重?

一旦这按预期工作,它将是巨大的。与基本模型相比,在 25MB loras 周围移动要容易得多。而且有很多东西需要通过分层 loras 进行评估,并根据比率对其进行缩放:D

@slaren
合作者
作者
斯拉伦评论 on Apr 12
您使用的是 f16 型号吗?毕竟,尝试将 lora 应用于量化模型可能是一个糟糕的主意.

@MillionthOdin16
百万之奥丁16评论 on Apr 12
你是对的。当美洲驼模型为 f-32 时,输出按预期工作。干得好!

现在我试图找出使其可用的最佳方法。模型与 lora 完全合并并量化为 4 位后, 它仍然产生良好的输出 (我的观点是,最终我们将希望将这些完全量化).

所以我们在 f-32 上合并以保持精度?我想知道允许它在量化模型上工作的最佳方法是什么。在美洲驼的基本模型上运行 lora 的能力本身就很大.cpp因为移动美洲驼的重要变化变得微不足道.有一种方法让用户设置和 lora 并将其融合到模型中,然后将其量化为 4 位将非常有帮助。它不像实时加载 loras 那样简化,但它使 loras 的使用变得更加容易。

你对如何在内存中进行量化有什么想法吗?有没有人测试过量化 lora 是否仍然对量化基础模型有有用的影响?

额外信息
这有效:

PS C:\Users\Bradarr\Documents\GitHub\llama.cpp> ./build/bin/main -m "D:\models\LLaMA\13B\ggml-model-f32.bin" --lora "D:\models\loras\bradarr-lora\13B\ShareGPTUnchained\ggml-adapter-model.bin" --interactive-first
main: seed = 1681250916
llama.cpp: loading model from D:\models\LLaMA\13B\ggml-model-f32.bin
llama_model_load_internal: format = ggjt v1 (latest)
llama_model_load_internal: n_vocab = 32000
llama_model_load_internal: n_ctx = 512
llama_model_load_internal: n_embd = 5120
llama_model_load_internal: n_mult = 256
llama_model_load_internal: n_head = 40
llama_model_load_internal: n_layer = 40
llama_model_load_internal: n_rot = 128
llama_model_load_internal: ftype = 0 (all F32)
llama_model_load_internal: n_ff = 13824
llama_model_load_internal: n_parts = 1
llama_model_load_internal: model size = 13B
llama_model_load_internal: ggml ctx size = 50843293.73 KB
llama_model_load_internal: mem required = 51699.65 MB (+ 1608.00 MB per state)
....................................................................................................
llama_init_from_file: kv self size = 400.00 MB
llama_apply_lora_from_file: applying lora adapter from 'D:\models\loras\bradarr-lora\13B\ShareGPTUnchained\ggml-adapter-model.bin' - please wait ...
llama_apply_lora_from_file: r = 8, alpha = 16, scaling = 2.00
llama_apply_lora_from_file: .......... done (18393.01 ms)

system_info: n_threads = 4 / 24 | AVX = 1 | AVX2 = 1 | AVX512 = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 1 | VSX = 0 |
main: interactive mode on.
sampling: temp = 0.800000, top_k = 40, top_p = 0.950000, repeat_last_n = 64, repeat_penalty = 1.100000
generate: n_ctx = 512, n_batch = 8, n_predict = 128, n_keep = 0
这不会:

PS C:\Users\Bradarr\Documents\GitHub\llama.cpp> ./build/bin/main -m "D:\models\LLaMA\13B\ggml-model-q4_0-nmap.bin" --lora "D:\models\loras\bradarr-lora\13B\ShareGPTUnchained\ggml-adapter-model.bin" --interactive-first
main: seed = 1681251252
llama.cpp: loading model from D:\models\LLaMA\13B\ggml-model-q4_0-nmap.bin
llama_model_load_internal: format = ggjt v1 (latest)
llama_model_load_internal: n_vocab = 32000
llama_model_load_internal: n_ctx = 512
llama_model_load_internal: n_embd = 5120
llama_model_load_internal: n_mult = 256
llama_model_load_internal: n_head = 40
llama_model_load_internal: n_layer = 40
llama_model_load_internal: n_rot = 128
llama_model_load_internal: ftype = 2 (mostly Q4_0)
llama_model_load_internal: n_ff = 13824
llama_model_load_internal: n_parts = 1
llama_model_load_internal: model size = 13B
llama_model_load_internal: ggml ctx size = 7945693.73 KB
llama_model_load_internal: mem required = 9807.47 MB (+ 1608.00 MB per state)
....................................................................................................
llama_init_from_file: kv self size = 400.00 MB
llama_apply_lora_from_file: applying lora adapter from 'D:\models\loras\bradarr-lora\13B\ShareGPTUnchained\ggml-adapter-model.bin' - please wait ...
llama_apply_lora_from_file: r = 8, alpha = 16, scaling = 2.00
llama_apply_lora_from_file: .......... done (10663.88 ms)

system_info: n_threads = 4 / 24 | AVX = 1 | AVX2 = 1 | AVX512 = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 1 | VSX = 0 |
main: interactive mode on.
sampling: temp = 0.800000, top_k = 40, top_p = 0.950000, repeat_last_n = 64, repeat_penalty = 1.100000
generate: n_ctx = 512, n_batch = 8, n_predict = 128, n_keep = 0
@slaren
合作者
作者
斯拉伦评论 on Apr 12
很高兴听到它正在工作!

关于创建预合并模型,已经可以在python中使用类似于alpaca-lora的脚本来执行此操作,该脚本合并lora然后将模型导出为pth,然后可以像往常一样将其转换为ggml。我不确定是否值得在llama.cpp中复制相同的功能,但如果它可以带来一些便利,我并不完全反对它。convert-pth-to-ggml.py

我怀疑在 f16 中加载由 lora 修改的层,然后将它们量化回与模型相同的格式可能足够快,非常实用.所以你可以做类似的事情,它会保留q4_0模型中未修改的层,但 lora 修改的任何层都将从 f16 加载、修补,然后量化为 q4_0 或任何模型中指定的模型格式。main -m models/7B/q4_0.bin --lora-base models/7B/f16.bin --lora mylora.bin-m

@MillionthOdin16
百万之奥丁16评论 on Apr 12
我怀疑在 f16 中加载由 lora 修改的层,然后将它们量化回与模型相同的格式可能足够快,非常实用.所以你可以做类似的事情,它会保留q4_0模型中未修改的层,但 lora 修改的任何层都将从 f16 加载、修补,然后量化为 q4_0 或任何模型中指定的模型格式。main -m models/7B/q4_0.bin --lora-base models/7B/f16.bin --lora mylora.bin-m

好的,我知道了。请注意, 我使用相同的 lora 文件测试 f-32 f-16 和q4_0基本美洲驼模型.f-32 绝对是 LoRa 化的, F16 绝对是 LoRa 化的 (虽然我不知道输出质量与 f-32 有何不同), q4_0似乎没有任何变化由 Lora 产生.尚未检查代码以了解这是否是预期的。

您认为将量化 lora 应用于量化模式可能有什么优点吗?有时我们会得到有趣的结果,而且肯定会更快(假设你想用准确性换取速度)。

Regarding creating pre-merged models, it is already possible to do that in python by using a script similar to this one from alpaca-lora that merges the lora and then exports the model as pth, which can then be converted to ggml as usual with . I am not sure that it is worth replicating the same feature in llama.cpp, but I am not entirely opposed to it if it can bring some convenience.convert-pth-to-ggml.py

Yes, I've seen the scripts, but I think for most users the understanding of model file formats and what they currently have vs what format they need is very confusing. My thought is that loras have the ability to significantly change the model outputs, are super lightweight, and are becoming more accessible and easier to train with projects like @lxe/simple-llm-finetuner. If we are able to streamline the use of loras and conversion of a lora adapter to a ggml model format they are familiar with, we can make learning about language models much easier (abstracting away as much pytorch/GPU/heavy ML stuff as possible). I know you already know this haha, I'm just excited about how this and similar projects make very technical areas easy to play with.

@MillionthOdin16
MillionthOdin16 commented on Apr 12
Also, I've noticed a scaling factor in console and you've mentioned it some. Is this something that directly affects the 'impact' of the lora weights on the overall model? If so, it could be useful to break it out as an argument to make experimentation easier. With stable diffusion they've done some pretty cool things with mixing different lora layers (so I'm thinking about this for down the line)

@slaren
合作者
作者
斯拉伦评论 on Apr 12
f-32 绝对是 LoRa 化的, F16 绝对是 LoRa 化的 (虽然我不知道输出质量与 f-32 有何不同), q4_0似乎没有任何变化由 Lora 产生.尚未检查代码以了解这是否是预期的。

据我了解,美洲驼模型原生为 f16,因此我不希望使用 f32 模型带来太大好处。

您认为将量化 lora 应用于量化模式可能有什么优点吗?有时我们会得到有趣的结果,而且肯定会更快(假设你想用准确性换取速度)。

这样做的问题是,loras对权重进行了非常小的修改,当应用于量化模型时,这些变化可能会完全消失在噪声中。使用量化的 lora 只会使问题变得更糟, 我认为这根本行不通.

另外,我注意到控制台中有一个缩放因子,您已经提到了一些。这是否直接影响 lora 权重对整体模型的“影响”?

这只是 PEFT 库根据 lora 的参数和等级做的事情, 我认为它根本不应该修改, 但谁知道它可能有什么影响.在其他洛拉之上应用 loras 对我来说似乎非常可疑,我根本不希望它有效,但我想在某些情况下它可能会?无论如何,我会把这个实验留给 GPU 人员,如果他们发现有价值的东西,我们可以在这里向后移植它。lora_alpha