From ef716736165cbbac433a3c4b2c3ea97246b3d6b9 Mon Sep 17 00:00:00 2001 From: jiaqiw09 <60021713+jiaqiw09@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:48:46 -0600 Subject: [PATCH] translate big_models.md and performance.md to chinese (#27334) * translate performance.md * tranlsate performance.md and big_models.md * update translation * update review --- docs/source/zh/_toctree.yml | 6 ++ docs/source/zh/big_models.md | 123 ++++++++++++++++++++++++++++++++++ docs/source/zh/performance.md | 63 +++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 docs/source/zh/big_models.md create mode 100644 docs/source/zh/performance.md diff --git a/docs/source/zh/_toctree.yml b/docs/source/zh/_toctree.yml index a0ee896f09..d5226c7884 100644 --- a/docs/source/zh/_toctree.yml +++ b/docs/source/zh/_toctree.yml @@ -42,6 +42,12 @@ - local: tflite title: 导出为 TFLite title: 开发者指南 +- sections: + - local: performance + title: 综述 + - local: big_models + title: 实例化大模型 + title: 性能和可扩展性 - sections: - local: task_summary title: 🤗Transformers能做什么 diff --git a/docs/source/zh/big_models.md b/docs/source/zh/big_models.md new file mode 100644 index 0000000000..92442ea298 --- /dev/null +++ b/docs/source/zh/big_models.md @@ -0,0 +1,123 @@ + + +# 实例化大型模型 + +当你想使用一个非常大的预训练模型时,一个挑战是尽量减少对内存的使用。通常从PyTorch开始的工作流程如下: + +1. 用随机权重创建你的模型。 +2. 加载你的预训练权重。 +3. 将这些预训练权重放入你的随机模型中。 + +步骤1和2都需要完整版本的模型在内存中,这在大多数情况下不是问题,但如果你的模型开始达到几个GB的大小,这两个副本可能会让你超出内存的限制。更糟糕的是,如果你使用`torch.distributed`来启动分布式训练,每个进程都会加载预训练模型并将这两个副本存储在内存中。 + + + +请注意,随机创建的模型使用“空”张量进行初始化,这些张量占用内存空间但不填充它(因此随机值是给定时间内该内存块中的任何内容)。在第3步之后,对未初始化的权重执行适合模型/参数种类的随机初始化(例如正态分布),以尽可能提高速度! + + + +在本指南中,我们将探讨 Transformers 提供的解决方案来处理这个问题。请注意,这是一个积极开发的领域,因此这里解释的API在将来可能会略有变化。 + +## 分片checkpoints + +自4.18.0版本起,占用空间超过10GB的模型检查点将自动分成较小的片段。在使用`model.save_pretrained(save_dir)`时,您最终会得到几个部分`checkpoints`(每个的大小都小于10GB)以及一个索引,该索引将参数名称映射到存储它们的文件。 + +您可以使用`max_shard_size`参数来控制分片之前的最大大小。为了示例的目的,我们将使用具有较小分片大小的普通大小的模型:让我们以传统的BERT模型为例。 + + +```py +from transformers import AutoModel + +model = AutoModel.from_pretrained("bert-base-cased") +``` + +如果您使用 [`PreTrainedModel.save_pretrained`](模型预训练保存) 进行保存,您将得到一个新的文件夹,其中包含两个文件:模型的配置和权重: + +```py +>>> import os +>>> import tempfile + +>>> with tempfile.TemporaryDirectory() as tmp_dir: +... model.save_pretrained(tmp_dir) +... print(sorted(os.listdir(tmp_dir))) +['config.json', 'pytorch_model.bin'] +``` + +现在让我们使用最大分片大小为200MB: + +```py +>>> with tempfile.TemporaryDirectory() as tmp_dir: +... model.save_pretrained(tmp_dir, max_shard_size="200MB") +... print(sorted(os.listdir(tmp_dir))) +['config.json', 'pytorch_model-00001-of-00003.bin', 'pytorch_model-00002-of-00003.bin', 'pytorch_model-00003-of-00003.bin', 'pytorch_model.bin.index.json'] +``` + +在模型配置文件最上方,我们可以看到三个不同的权重文件,以及一个`index.json`索引文件。这样的`checkpoint`可以使用`[~PreTrainedModel.from_pretrained]`方法完全重新加载: + +```py +>>> with tempfile.TemporaryDirectory() as tmp_dir: +... model.save_pretrained(tmp_dir, max_shard_size="200MB") +... new_model = AutoModel.from_pretrained(tmp_dir) +``` + +对于大型模型来说,这样做的主要优点是在上述工作流程的步骤2中,每个`checkpoint`的分片在前一个分片之后加载,从而将内存中的内存使用限制在模型大小加上最大分片的大小。 + +在后台,索引文件用于确定`checkpoint`中包含哪些键以及相应的权重存储在哪里。我们可以像加载任何json一样加载该索引,并获得一个字典: + +```py +>>> import json + +>>> with tempfile.TemporaryDirectory() as tmp_dir: +... model.save_pretrained(tmp_dir, max_shard_size="200MB") +... with open(os.path.join(tmp_dir, "pytorch_model.bin.index.json"), "r") as f: +... index = json.load(f) + +>>> print(index.keys()) +dict_keys(['metadata', 'weight_map']) +``` + +目前元数据仅包括模型的总大小。我们计划在将来添加其他信息: +```py +>>> index["metadata"] +{'total_size': 433245184} +``` + +权重映射是该索引的主要部分,它将每个参数的名称(通常在PyTorch模型的`state_dict`中找到)映射到存储该参数的文件: + +```py +>>> index["weight_map"] +{'embeddings.LayerNorm.bias': 'pytorch_model-00001-of-00003.bin', + 'embeddings.LayerNorm.weight': 'pytorch_model-00001-of-00003.bin', + ... +``` + +如果您想直接在模型内部加载这样的分片`checkpoint`,而不使用 [`PreTrainedModel.from_pretrained`](就像您会为完整`checkpoint`执行 `model.load_state_dict()` 一样),您应该使用 [`modeling_utils.load_sharded_checkpoint`]: + + +```py +>>> from transformers.modeling_utils import load_sharded_checkpoint + +>>> with tempfile.TemporaryDirectory() as tmp_dir: +... model.save_pretrained(tmp_dir, max_shard_size="200MB") +... load_sharded_checkpoint(model, tmp_dir) +``` + +## 低内存加载 + +分片`checkpoints`在上述工作流的第2步中降低了内存使用,但为了在低内存环境中使用该模型,我们建议使用基于 Accelerate 库的工具。 + +请阅读以下指南以获取更多信息:[使用 Accelerate 进行大模型加载](./main_classes/model#large-model-loading) diff --git a/docs/source/zh/performance.md b/docs/source/zh/performance.md new file mode 100644 index 0000000000..afe41c8fdd --- /dev/null +++ b/docs/source/zh/performance.md @@ -0,0 +1,63 @@ + + +# 性能与可扩展性 + +训练大型transformer模型并将其部署到生产环境会面临各种挑战。 +在训练过程中,模型可能需要比可用的GPU内存更多的资源,或者表现出较慢的训练速度。在部署阶段,模型可能在生产环境中难以处理所需的吞吐量。 + +本文档旨在帮助您克服这些挑战,并找到适合您使用场景的最佳设置。教程分为训练和推理部分,因为每个部分都有不同的挑战和解决方案。在每个部分中,您将找到针对不同硬件配置的单独指南,例如单GPU与多GPU用于训练或CPU与GPU用于推理。 + +将此文档作为您的起点,进一步导航到与您的情况匹配的方法。 + +## 训练 + +高效训练大型transformer模型需要使用加速器硬件,如GPU或TPU。最常见的情况是您只有一个GPU。您应用于单个GPU上提高训练效率的方法可以扩展到其他设置,如多个GPU。然而,也有一些特定于多GPU或CPU训练的技术。我们在单独的部分中介绍它们。 + +* [在单个GPU上进行高效训练的方法和工具](perf_train_gpu_one):从这里开始学习常见的方法,可以帮助优化GPU内存利用率、加快训练速度或两者兼备。 +* [多GPU训练部分](perf_train_gpu_many):探索此部分以了解适用于多GPU设置的进一步优化方法,例如数据并行、张量并行和流水线并行。 +* [CPU训练部分](perf_train_cpu):了解在CPU上的混合精度训练。 +* [在多个CPU上进行高效训练](perf_train_cpu_many):了解分布式CPU训练。 +* [使用TensorFlow在TPU上进行训练](perf_train_tpu_tf):如果您对TPU还不熟悉,请参考此部分,了解有关在TPU上进行训练和使用XLA的建议性介绍。 +* [自定义硬件进行训练](perf_hardware):在构建自己的深度学习机器时查找技巧和窍门。 +* [使用Trainer API进行超参数搜索](hpo_train) + + +## 推理 + +在生产环境中对大型模型进行高效推理可能与训练它们一样具有挑战性。在接下来的部分中,我们将详细介绍如何在CPU和单/多GPU设置上进行推理的步骤。 + +* [在单个CPU上进行推理](perf_infer_cpu) +* [在单个GPU上进行推理](perf_infer_gpu_one) +* [多GPU推理](perf_infer_gpu_one) +* [TensorFlow模型的XLA集成](tf_xla) + +## 训练和推理 + +在这里,您将找到适用于训练模型或使用它进行推理的技巧、窍门和技巧。 + +* [实例化大型模型](big_models) +* [解决性能问题](debugging) + +## 贡献 + +这份文档还远远没有完成,还有很多需要添加的内容,所以如果你有补充或更正的内容,请毫不犹豫地提交一个PR(Pull Request),或者如果你不确定,可以创建一个Issue,我们可以在那里讨论细节。 + +在做出贡献时,如果A比B更好,请尽量包含可重复的基准测试和(或)该信息来源的链接(除非它直接来自您)。