Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌐 [i18n-ZH] Translate troubleshooting.md into Chinese #27201

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/source/zh/_toctree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@
title: 使用特定于模型的 API
- local: custom_models
title: 共享自定义模型
- local: serialization
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the serialization.md file has already been translated: https://huggingface.co/docs/transformers/main/zh/serialization

title: 导出为 ONNX
- local: troubleshooting
title: 故障排除
title: 开发者指南
181 changes: 181 additions & 0 deletions docs/source/zh/serialization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<!--Copyright 2020 The HuggingFace Team. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be
rendered properly in your Markdown viewer.

-->

# 导出为 ONNX

在生产环境中部署 🤗 Transformers 模型通常需要或者能够受益于,将模型导出为可在专门的运行时和硬件上加载和执行的序列化格式。

🤗 Optimum 是 Transformers 的扩展,可以通过其 `exporters` 模块将模型从 PyTorch 或 TensorFlow 导出为 ONNX 及 TFLite 等序列化格式。🤗 Optimum 还提供了一套性能优化工具,可以在目标硬件上以最高效率训练和运行模型。

本指南演示了如何使用 🤗 Optimum 将 🤗 Transformers 模型导出为 ONNX。有关将模型导出为 TFLite 的指南,请参考 [导出为 TFLite 页面](tflite)。

## 导出为 ONNX

[ONNX (Open Neural Network eXchange 开放神经网络交换)](http://onnx.ai) 是一个开放的标准,它定义了一组通用的运算符和一种通用的文件格式,用于表示包括 PyTorch 和 TensorFlow 在内的各种框架中的深度学习模型。当一个模型被导出为 ONNX时,这些运算符被用于构建计算图(通常被称为*中间表示*),该图表示数据在神经网络中的流动。

通过公开具有标准化运算符和数据类型的图,ONNX使得模型能够轻松在不同深度学习框架间切换。例如,在 PyTorch 中训练的模型可以被导出为 ONNX,然后再导入到 TensorFlow(反之亦然)。

导出为 ONNX 后,模型可以:
- 通过 [图优化(graph optimization)](https://huggingface.co/docs/optimum/onnxruntime/usage_guides/optimization) 和 [量化(quantization)](https://huggingface.co/docs/optimum/onnxruntime/usage_guides/quantization) 等技术进行推理优化。
- 通过 [`ORTModelForXXX` 类](https://huggingface.co/docs/optimum/onnxruntime/package_reference/modeling_ort) 使用 ONNX Runtime 运行,它同样遵循你熟悉的 Transformers 中的 `AutoModel` API。
- 使用 [优化推理流水线(pipeline)](https://huggingface.co/docs/optimum/main/en/onnxruntime/usage_guides/pipelines) 运行,其 API 与 🤗 Transformers 中的 [`pipeline`] 函数相同。

🤗 Optimum 通过利用配置对象提供对 ONNX 导出的支持。多种模型架构已经有现成的配置对象,并且配置对象也被设计得易于扩展以适用于其他架构。

现有的配置列表请参考 [🤗 Optimum 文档](https://huggingface.co/docs/optimum/exporters/onnx/overview)。

有两种方式可以将 🤗 Transformers 模型导出为 ONNX,这里我们展示这两种方法:

- 使用 🤗 Optimum 的 CLI(命令行)导出。
- 使用 🤗 Optimum 的 `optimum.onnxruntime` 模块导出。

### 使用 CLI 将 🤗 Transformers 模型导出为 ONNX

要将 🤗 Transformers 模型导出为 ONNX,首先需要安装额外的依赖项:

```bash
pip install optimum[exporters]
```

请参阅 [🤗 Optimum 文档](https://huggingface.co/docs/optimum/exporters/onnx/usage_guides/export_a_model#exporting-a-model-to-onnx-using-the-cli) 以查看所有可用参数,或者在命令行中查看帮助:

```bash
optimum-cli export onnx --help
```

运行以下命令,以从 🤗 Hub 导出模型的检查点(checkpoint),以 `distilbert-base-uncased-distilled-squad` 为例:

```bash
optimum-cli export onnx --model distilbert-base-uncased-distilled-squad distilbert_base_uncased_squad_onnx/
```

你应该能在日志中看到导出进度以及生成的 `model.onnx` 文件的保存位置,如下所示:

```bash
Validating ONNX model distilbert_base_uncased_squad_onnx/model.onnx...
-[✓] ONNX model output names match reference model (start_logits, end_logits)
- Validating ONNX Model output "start_logits":
-[✓] (2, 16) matches (2, 16)
-[✓] all values close (atol: 0.0001)
- Validating ONNX Model output "end_logits":
-[✓] (2, 16) matches (2, 16)
-[✓] all values close (atol: 0.0001)
The ONNX export succeeded and the exported model was saved at: distilbert_base_uncased_squad_onnx
```

上面的示例说明了从 🤗 Hub 导出检查点的过程。导出本地模型时,首先需要确保将模型的权重和分词器文件保存在同一目录(`local_path`)中。在使用 CLI 时,将 `local_path` 传递给 `model` 参数,而不是 🤗 Hub 上的检查点名称,并提供 `--task` 参数。你可以在 [🤗 Optimum 文档](https://huggingface.co/docs/optimum/exporters/task_manager)中查看支持的任务列表。如果未提供 `task` 参数,将默认导出不带特定任务头的模型架构。

```bash
optimum-cli export onnx --model local_path --task question-answering distilbert_base_uncased_squad_onnx/
```

生成的 `model.onnx` 文件可以在支持 ONNX 标准的 [许多加速引擎(accelerators)](https://onnx.ai/supported-tools.html#deployModel) 之一上运行。例如,我们可以使用 [ONNX Runtime](https://onnxruntime.ai/) 加载和运行模型,如下所示:

```python
>>> from transformers import AutoTokenizer
>>> from optimum.onnxruntime import ORTModelForQuestionAnswering

>>> tokenizer = AutoTokenizer.from_pretrained("distilbert_base_uncased_squad_onnx")
>>> model = ORTModelForQuestionAnswering.from_pretrained("distilbert_base_uncased_squad_onnx")
>>> inputs = tokenizer("What am I using?", "Using DistilBERT with ONNX Runtime!", return_tensors="pt")
>>> outputs = model(**inputs)
```

从 Hub 导出 TensorFlow 检查点的过程也一样。例如,以下是从 [Keras 组织](https://huggingface.co/keras-io) 导出纯 TensorFlow 检查点的命令:

```bash
optimum-cli export onnx --model keras-io/transformers-qa distilbert_base_cased_squad_onnx/
```

### 使用 `optimum.onnxruntime` 将 🤗 Transformers 模型导出为 ONNX

除了 CLI 之外,你还可以使用代码将 🤗 Transformers 模型导出为 ONNX,如下所示:

```python
>>> from optimum.onnxruntime import ORTModelForSequenceClassification
>>> from transformers import AutoTokenizer

>>> model_checkpoint = "distilbert_base_uncased_squad"
>>> save_directory = "onnx/"

>>> # 从 transformers 加载模型并将其导出为 ONNX
>>> ort_model = ORTModelForSequenceClassification.from_pretrained(model_checkpoint, export=True)
>>> tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)

>>> # 保存 onnx 模型以及分词器
>>> ort_model.save_pretrained(save_directory)
>>> tokenizer.save_pretrained(save_directory)
```

### 导出尚未支持的架构的模型

如果你想要为当前无法导出的模型添加支持,请先检查 [`optimum.exporters.onnx`](https://huggingface.co/docs/optimum/exporters/onnx/overview) 是否支持该模型,如果不支持,你可以 [直接为 🤗 Optimum 贡献代码](https://huggingface.co/docs/optimum/exporters/onnx/usage_guides/contribute)。

### 使用 `transformers.onnx` 导出模型

<Tip warning={true}>

`tranformers.onnx` 不再进行维护,请如上所述,使用 🤗 Optimum 导出模型。这部分内容将在未来版本中删除。

</Tip>

要使用 `tranformers.onnx` 将 🤗 Transformers 模型导出为 ONNX,请安装额外的依赖项:

```bash
pip install transformers[onnx]
```

将 `transformers.onnx` 包作为 Python 模块使用,以使用现成的配置导出检查点:

```bash
python -m transformers.onnx --model=distilbert-base-uncased onnx/
```

以上代码将导出由 `--model` 参数定义的检查点的 ONNX 图。传入任何 🤗 Hub 上或者存储与本地的检查点。生成的 `model.onnx` 文件可以在支持 ONNX 标准的众多加速引擎上运行。例如,使用 ONNX Runtime 加载并运行模型,如下所示:

```python
>>> from transformers import AutoTokenizer
>>> from onnxruntime import InferenceSession

>>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
>>> session = InferenceSession("onnx/model.onnx")
>>> # ONNX Runtime expects NumPy arrays as input
>>> inputs = tokenizer("Using DistilBERT with ONNX Runtime!", return_tensors="np")
>>> outputs = session.run(output_names=["last_hidden_state"], input_feed=dict(inputs))
```

可以通过查看每个模型的 ONNX 配置来获取所需的输出名(例如 `["last_hidden_state"]`)。例如,对于 DistilBERT,可以用以下代码获取输出名称:

```python
>>> from transformers.models.distilbert import DistilBertConfig, DistilBertOnnxConfig

>>> config = DistilBertConfig()
>>> onnx_config = DistilBertOnnxConfig(config)
>>> print(list(onnx_config.outputs.keys()))
["last_hidden_state"]
```

从 Hub 导出 TensorFlow 检查点的过程也一样。导出纯 TensorFlow 检查点的示例代码如下:

```bash
python -m transformers.onnx --model=keras-io/transformers-qa onnx/
```

要导出本地存储的模型,请将模型的权重和分词器文件保存在同一目录中(例如 `local-pt-checkpoint`),然后通过将 `transformers.onnx` 包的 `--model` 参数指向该目录,将其导出为 ONNX:

```bash
python -m transformers.onnx --model=local-pt-checkpoint onnx/
```
193 changes: 193 additions & 0 deletions docs/source/zh/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
<!---
Copyright 2022 The HuggingFace Team. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be
rendered properly in your Markdown viewer.

-->

# 故障排除

错误是难免的,但我们随时为你提供帮助!本指南涵盖了一些我们最常见到的问题以及它们的解决方法。但本指南并不会涵盖所有的 🤗 Transformers 问题。如果你需要更多故障排除方面的帮助,请尝试:

<Youtube id="S2EEG3JIt2A"/>

1. 在[论坛](https://discuss.huggingface.co/)上寻求帮助。你可以将问题发布到特定类别下,例如 [初学者](https://discuss.huggingface.co/c/beginners/5) 或 [🤗 Transformers](https://discuss.huggingface.co/c/transformers/9)。请在论坛帖子内详细描述问题,并附上可重现的代码,以增加解决问题的可能性!

<Youtube id="_PAli-V4wj0"/>

2. 如果是与库相关的 bug,请在 🤗 Transformers 代码仓库中提交一个 [Issue](https:/huggingface/transformers/issues/new/choose)。并且尽可能详细得描述与 bug 有关的信息,以帮助我们更好地定位以及修复问题。

3. 如果你使用的是较旧版本的 🤗 Transformers,请查阅[迁移](migration)指南,因为新旧版本之间引入了一些重要的更改。

有关故障排除和获取帮助的更多详情,请参阅 Hugging Face 课程的[第 8 章](https://huggingface.co/course/chapter8/1?fw=pt)。


## 防火墙环境

一些云和内联网上的 GPU 实例对外部连接设置了防火墙,导致连接错误。当你的脚本尝试下载模型权重或数据集时,下载将挂起,随后超时并显示以下报错信息:

```
ValueError: Connection error, and we cannot find the requested files in the cached path.
Please try again or make sure your Internet connection is on.
```

在这种情况下,你应该尝试以 [离线模式](installation#offline-mode) 运行 🤗 Transformers 以避免连接错误。

## CUDA 内存不足

在没有适当硬件的情况下,训练数百万参数的大型模型可能会很有挑战性。当 GPU 内存不足时,你可能会遇到以下常见错误:

```
CUDA out of memory. Tried to allocate 256.00 MiB (GPU 0; 11.17 GiB total capacity; 9.70 GiB already allocated; 179.81 MiB free; 9.85 GiB reserved in total by PyTorch)
```

以下的一些解决方案或许能够减少你的内存使用:

- 在 [`TrainingArguments`] 中减少 [`per_device_train_batch_size`](main_classes/trainer#transformers.TrainingArguments.per_device_train_batch_size) 值的大小。
- 尝试在 [`TrainingArguments`] 使用 [`gradient_accumulation_steps`](main_classes/trainer#transformers.TrainingArguments.gradient_accumulation_steps) 以有效地增加总的 batch size。

<Tip>

请参考性能[指南](performance)以获取更多节省 GPU 内存的技巧。

</Tip>

## 无法加载已保存的 TensorFlow 模型

TensorFlow 的 [model.save](https://www.tensorflow.org/tutorials/keras/save_and_load#save_the_entire_model) 方法会将整个模型 - 架构、权重、训练配置 - 保存在单个文件中。但是,你再次加载模型文件时,可能会遇到错误,因为 🤗 Transformers 可能不会加载模型文件中的所有与 TensorFlow 相关的对象。为了避免保存和加载 TensorFlow 模型时出现问题,我们建议你:

- 使用 [`model.save_weights`](https://www.tensorflow.org/tutorials/keras/save_and_load#save_the_entire_model) 将模型权重保存为 `h5` 扩展的文件格式,然后使用 [`~TFPreTrainedModel.from_pretrained`] 重新加载模型:

```py
>>> from transformers import TFPreTrainedModel
>>> from tensorflow import keras

>>> model.save_weights("some_folder/tf_model.h5")
>>> model = TFPreTrainedModel.from_pretrained("some_folder")
```

- 使用 [`~TFPretrainedModel.save_pretrained`] 保存模型,然后使用 [`~TFPreTrainedModel.from_pretrained`] 再次加载模型权重:

```py
>>> from transformers import TFPreTrainedModel

>>> model.save_pretrained("path_to/model")
>>> model = TFPreTrainedModel.from_pretrained("path_to/model")
```

## ImportError

你可能会遇到的另一个常见错误是 `ImportError`,尤其是使用新发布的模型时:

```
ImportError: cannot import name 'ImageGPTImageProcessor' from 'transformers' (unknown location)
```

对于这些错误类型,请确保您已安装了最新版本的 🤗 Transformers 以访问最新的模型:

```bash
pip install transformers --upgrade
```

## CUDA error:触发设备端断言

有时你可能会遇到一般 CUDA 错误,有关设备代码错误。

```
RuntimeError: CUDA error: device-side assert triggered
```

请先尝试在CPU上运行代码,以获取更详细的错误消息。将以下环境变量添加到代码开头,以将设备切换至 CPU:

```py
>>> import os

>>> os.environ["CUDA_VISIBLE_DEVICES"] = ""
```

另一种选择是从 GPU 获得更好的回溯。将以下环境变量添加到代码的开头,以使回溯指向错误源:

```py
>>> import os

>>> os.environ["CUDA_LAUNCH_BLOCKING"] = "1"
```

## padding token 未进行 mask 时的输出错误

在某些情况下,如果 `input_ids` 包括 padding token,输出的 `hidden_state` 可能是不正确的。为了进行演示,请加载一个模型和分词器。你可以访问模型的 `pad_token_id` 查看它的值。一些模型的 `pad_token_id` 也许为 `None`,但你始终能够手动设置它。

```py
>>> from transformers import AutoModelForSequenceClassification
>>> import torch

>>> model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
>>> model.config.pad_token_id
0
```

以下示例展示了模型在没有屏蔽 padding token 情况下的输出:

```py
>>> input_ids = torch.tensor([[7592, 2057, 2097, 2393, 9611, 2115], [7592, 0, 0, 0, 0, 0]])
>>> output = model(input_ids)
>>> print(output.logits)
tensor([[ 0.0082, -0.2307],
[ 0.1317, -0.1683]], grad_fn=<AddmmBackward0>)
```

这是第二个序列的实际输出:

```py
>>> input_ids = torch.tensor([[7592]])
>>> output = model(input_ids)
>>> print(output.logits)
tensor([[-0.1008, -0.4061]], grad_fn=<AddmmBackward0>)
```

大多数时候,你应该为模型提供一个 `attention_mask` 来忽略 padding token,以避免这种潜在错误。现在第二个序列的输出与其实际输出一致了:

<Tip>

默认情况下,分词器会根据该分词器的默认设置为你创建一个 `attention_mask`。

</Tip>

```py
>>> attention_mask = torch.tensor([[1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0]])
>>> output = model(input_ids, attention_mask=attention_mask)
>>> print(output.logits)
tensor([[ 0.0082, -0.2307],
[-0.1008, -0.4061]], grad_fn=<AddmmBackward0>)
```

当提供 padding token 时,🤗 Transformers 不会自动创建 `attention_mask` 对其进行掩盖(mask),原因如下:

- 一些模型没有 padding token。
- 某些用例中,用户希望模型处理 padding token。

## ValueError: 无法识别此类 AutoModel 的配置类 XYZ

通常,我们建议使用 [`AutoModel`] 类来加载模型的预训练实例。该类可以根据配置自动从给定的检查点(checkpoint)推断并加载正确的架构。从检查点加载模型时看到此 `ValueError`,意味着 Auto 类无法从给定检查点中,找到配置与你尝试加载的模型类型之间的映射。这个错误最常发生在加载的检查点不支持给定任务的时候。你将在以下示例中看到此错误,因为 GPT2 模型不支持问答(question answering)任务:

```py
>>> from transformers import AutoProcessor, AutoModelForQuestionAnswering

>>> processor = AutoProcessor.from_pretrained("gpt2-medium")
>>> model = AutoModelForQuestionAnswering.from_pretrained("gpt2-medium")
ValueError: Unrecognized configuration class <class 'transformers.models.gpt2.configuration_gpt2.GPT2Config'> for this kind of AutoModel: AutoModelForQuestionAnswering.
Model type should be one of AlbertConfig, BartConfig, BertConfig, BigBirdConfig, BigBirdPegasusConfig, BloomConfig, ...
```