大型模型推理
加速提供的最大进步之一是 大型模型推理,它允许您对无法完全安装在显卡上的模型进行推理。
本教程将向您展示如何在 Accelerate 和 Hugging Face 生态系统中使用大型模型推理。
Accelerate
下面展示了加载 PyTorch 模型的典型工作流程。ModelClass
是一个超出设备(mps 或 cuda)的 GPU 内存的模型。
import torch
my_model = ModelClass(...)
state_dict = torch.load(checkpoint_file)
my_model.load_state_dict(state_dict)
使用大型模型推理,第一步是使用 init_empty_weights
上下文管理器初始化模型的空骨架。这不需要任何内存,因为 my_model
是“无参数”的。
from accelerate import init_empty_weights
with init_empty_weights():
my_model = ModelClass(...)
接下来,权重被加载到模型中以进行推理。
load_checkpoint_and_dispatch()
方法在空模型中加载检查点,并将权重分发到所有可用设备上的每个层,从最快的设备(GPU、MPS、XPU、NPU、MLU、MUSA)开始,然后移动到较慢的设备(CPU 和硬盘)。
设置 device_map="auto"
会自动首先填充 GPU 上的所有可用空间,然后是 CPU,最后是硬盘驱动器(最慢的选择),如果仍然没有足够的内存。
有关如何设计自己的设备映射的更多详细信息,请参阅设计设备映射指南。
from accelerate import load_checkpoint_and_dispatch
model = load_checkpoint_and_dispatch(
model, checkpoint=checkpoint_file, device_map="auto"
)
如果某些层“块”不应该被拆分,请将它们传递给 no_split_module_classes
(有关更多详细信息,请参见这里)。
模型权重也可以被分成多个检查点,以节省内存,例如,当 state_dict
不适合内存时(有关更多详细信息,请参见这里)。
现在模型已完全分发,您可以进行推理。
input = torch.randn(2,3)
input = input.to("cuda")
output = model(input)
每次输入通过一个层时,它都会从 CPU 发送到 GPU(或从磁盘到 CPU 到 GPU),计算输出,并将该层从 GPU 中移除,一直回到起点。虽然这会增加一些推理开销,但它使您能够在系统上运行任何大小的模型,只要最大的层适合您的 GPU 即可。
可以使用多个 GPU 或“模型并行”,但在任何给定时间只有一个 GPU 会处于活动状态。这会迫使 GPU 等待上一个 GPU 发送输出。您应该使用 Python 正常启动您的脚本,而不是其他工具,例如 torchrun 和 accelerate launch。
您可能也对流水线并行感兴趣,它同时利用所有可用 GPU,而不是一次只使用一个 GPU。但是,这种方法灵活性较差。有关更多详细信息,请参阅内存高效的流水线并行指南。
下面看一下大型模型推理的完整示例。
import torch
from accelerate import init_empty_weights, load_checkpoint_and_dispatch
with init_empty_weights():
model = MyModel(...)
model = load_checkpoint_and_dispatch(
model, checkpoint=checkpoint_file, device_map="auto"
)
input = torch.randn(2,3)
input = input.to("cuda")
output = model(input)
Hugging Face 生态系统
Hugging Face 生态系统中的其他库,如 Transformers 或 Diffusers,在其from_pretrained 构造函数中支持大型模型推理。
您只需要在from_pretrained 中添加 device_map="auto"
来启用大型模型推理。
例如,使用大型模型推理加载 Big Sciences T0pp 110 亿参数模型。
from transformers import AutoModelForSeq2SeqLM
model = AutoModelForSeq2SeqLM.from_pretrained("bigscience/T0pp", device_map="auto")
加载模型后,会执行之前提到的空初始化和智能分发步骤,并且模型已完全准备好利用您机器中的所有资源。通过这些构造函数,您还可以通过指定 torch_dtype
参数来加载以较低精度表示的模型,从而节省更多内存。
from transformers import AutoModelForSeq2SeqLM
model = AutoModelForSeq2SeqLM.from_pretrained("bigscience/T0pp", device_map="auto", torch_dtype=torch.float16)
下一步
有关大型模型推理的更详细解释,请务必查看概念指南!
< > 在 GitHub 上更新