默认情况下,Linux 会阻止 tmpfs 使用超过 50% 的可用系统内存。这通常是一件好事,但简单的转换脚本会在保存输出文件之前将所有张量数据写入 tmpfs,如果转换后的模型大于系统 RAM 的 50%(ref),则会导致此异常:
Traceback (most recent call last):
File "/home/cebtenzzre/src/forks/llama.cpp/convert-baichuan-hf-to-gguf.py", line 279, in <module>
gguf_writer.add_tensor(new_name, data)
File "/home/cebtenzzre/src/forks/llama.cpp/gguf-py/gguf/gguf.py", line 622, in add_tensor
tensor.tofile(self.temp_file)
OSError: Not enough free space to write 140247040 bytes
这很烦人。您可以设置 TMPDIR=/var/tmp 来解决此问题,但您需要两倍于输出文件大小的可用磁盘空间 - 而我并不总是有这样的空间。
解决这个问题的最小改动是提供一种在 Linux 上有效禁用 use_temp_file 的方法,同时仍然支持使用 /var/tmp(如果需要)。这样,我就可以利用 100% 的 RAM 和交换空间来转换这些模型。如果我们选择这种方式,我们应该确保转换后的张量数据在写入时被释放,以避免不必要的交换——目前还没有。
我们不能仅仅改变简单的脚本来进行动态转换,因为它们一次只加载一个 pytorch 文件,因此对输入张量进行两次传递会产生很高的 I/O 成本。
我们可以将 LazyUnpickler 作为 gguf 模块的一部分。这样,我们可以显著减少内存使用量,避免将整个模型加载到内存中,同时希望非 LLaMA 转换脚本仍然相对简单。
@ggerganov 您觉得怎样?