Hugging Face Transformers 完全新手入门指南
欢迎来到“Hugging Face Transformers 完全新手入门指南”,本指南专为那些希望了解开源机器学习(ML)基础知识的人士设计。我们的目标是揭开 Hugging Face Transformers 的神秘面纱,阐明其工作原理,并非要将您培养成机器学习从业者,而是为了让您能更好地理解并与从业者协作。话虽如此,最好的学习方式是实践,因此我们将通过一个简单的实例,演示如何在 Hugging Face Space 的 notebook 中运行微软的 Phi-2 大语言模型(LLM)。
您可能会想,既然 Hugging Face 上已有大量教程,为什么还要再写一篇?答案在于可访问性:现有的大多数资源都假设读者具备一定的技术背景,包括 Python 编程能力,这可能会阻碍非技术人员掌握机器学习的基础知识。我本人是从 AI 的业务端转过来的,深知学习曲线会构成一道屏障,因此希望为有类似背景的学习者提供一条更平易近人的路径。
因此,本指南专为那些渴望更好地了解开源机器学习但又不想从头学习 Python 的非技术人士量身定制。我们不假设您有任何先验知识,将从零开始解释概念,以确保清晰明了。如果您是工程师,可能会觉得本指南过于基础,但对于初学者来说,它是一个理想的起点。
让我们开始吧……但首先,介绍一些背景知识。
什么是 Hugging Face Transformers?
Hugging Face Transformers 是一个开源的 Python 库,它提供了数千个用于自然语言处理(NLP)、计算机视觉、音频任务等的预训练 Transformers 模型。它通过抽象掉在 PyTorch、TensorFlow 和 JAX 等底层机器学习框架中训练或部署模型的复杂性,简化了实现 Transformer 模型的过程。
什么是库?
库就是可重用代码片段的集合,可以集成到项目中,从而更高效地实现功能,而无需从头编写自己的代码。
值得注意的是,Transformers 库为在 PyTorch、TensorFlow 和 JAX 等常见框架中实现模型提供了可重用的代码。通过调用库中的函数(也称为方法),可以访问这些可重用的代码。
什么是 Hugging Face Hub?
Hugging Face Hub 是一个协作平台,托管了大量用于机器学习的开源模型和数据集,可以把它看作是机器学习领域的 Github。Hub 通过让您轻松发现、学习和与开源社区中有用的机器学习资产互动,促进了分享与协作。Hub 与 Transformers 库集成并协同使用,因为使用 Transformers 库部署的模型都是从 Hub 下载的。
什么是 Hugging Face Spaces?
Hugging Face 的 Spaces 是 Hugging Face Hub 上提供的一项服务,它提供了一个易于使用的图形用户界面(GUI),用于构建和部署 Web 托管的机器学习演示和应用程序。该服务允许您快速构建机器学习演示,上传您自己的应用程序进行托管,甚至可以选择一些预配置的机器学习应用程序立即部署。
在本教程中,我们将通过选择相应的 Docker 容器,部署一个预配置的机器学习应用程序——JupyterLab notebook。
什么是 notebook?
Notebooks 是交互式应用程序,允许您编写和共享可实时执行的代码,并与补充性的叙述文本交织在一起。Notebooks 对数据科学家和机器学习工程师尤其有用,因为它们允许您实时试验代码,并轻松审查和分享结果。
- 创建 Hugging Face 账户
- 访问 hf.co,点击“注册”并创建一个账户(如果您还没有的话)。
- 添加您的账单信息
- 在您的 HF 账户中,进入“设置” > “账单”,将您的信用卡添加到付款信息部分。
为什么需要您的信用卡?
为了运行大多数大语言模型(LLM),您需要一个 GPU,而这不幸不是免费的。不过,您可以从 Hugging Face 租用。别担心,费用不会很高。本教程所需的 GPU,即 NVIDIA A10G,每小时只需几美元。
- 创建一个 Space 来托管您的 notebook
- 在 hf.co 上,转到“Spaces” > “Create New”。
- 配置您的 Space
- 设置您喜欢的 Space 名称
- 选择 Docker > JupyterLab 以选择预配置的 notebook 应用
- 选择 Space 硬件为“Nvidia A10G Small”
- 其他所有选项都可以保留默认设置
- 选择“创建 Space”
什么是 Docker 模板?
Docker 模板是软件环境的预定义蓝图,包含了必要的软件和配置,使开发人员能够以一致且隔离的方式轻松快速地部署应用程序。
为什么我需要选择一个 GPU Space 硬件?
默认情况下,我们的 Space 配备了免费的 CPU,这对于某些应用程序来说已经足够了。然而,大语言模型所需的大量计算可以通过并行运行来显著提高速度,而这正是 GPU 的强项。
选择一个内存足够大的 GPU 来存储模型并提供备用工作内存也很重要。在我们的例子中,一个拥有 24GB 内存的 A10G Small 足以运行 Phi-2。
- 登录 JupyterLab
- 在 Space 完成构建后,您将看到一个登录屏幕。如果您在模板中保留了默认的令牌,您可以用“huggingface”登录。否则,请使用您设置的令牌。
- 创建一个新的 notebook
- 在“Launcher”选项卡中,选择“Notebook”标题下的“Python 3”方块,这将创建一个已安装 Python 的新 notebook 环境。
- 安装所需软件包
- 在您的新 notebook 中,您需要安装 PyTorch 和 Transformers 库,因为它们没有预装在环境中。
- 这可以通过在您的 notebook 中输入 !pip 命令 + 库名来完成。点击播放按钮执行代码,并观察库的安装过程(或者:按 CMD + Return / CTRL + Enter)。
!pip install torch
!pip install transformers
什么是 !pip install?
!pip
是一个从 Python 包索引 (PyPI) 安装 Python 包的命令。PyPI 是一个 Web 仓库,存放了可用于 Python 环境的库。它允许我们通过整合各种第三方插件来扩展 Python 应用程序的功能。
既然我们使用 Transformers,为什么还需要 PyTorch?
Hugging Face 是一个建立在其他框架(如 PyTorch、Tensorflow 和 JAX)之上的库。在这种情况下,我们是将 Transformers 与 PyTorch 一起使用,因此需要安装 PyTorch 才能访问其功能。
- 从 Transformers 中导入 AutoTokenizer 和 AutoModelForCausalLM 类
- 在新的一行输入以下代码并运行
from transformers import AutoTokenizer, AutoModelForCausalLM
什么是类?
可以把类(Classes)想象成创建“对象(Objects)”的代码配方。它们之所以有用,是因为允许我们保存具有属性和功能组合的对象。这反过来简化了编码,因为特定主题所需的所有信息和操作都可以从同一个地方访问。我们将使用这些类来创建两个对象:一个 model
对象和一个 tokenizer
对象。
为什么在安装 Transformers 后还需要再次导入类?
尽管 Transformers 已经安装好了,但 Transformers 内部的特定类并不会自动在您的环境中可用。Python 要求我们显式导入单个类,这有助于避免命名冲突,并确保只有库中必要的部分被加载到您当前的工作上下文中。
- 定义您想运行的模型
- 为了详细说明您想从 Hugging Face Hub 下载并运行的模型,您需要在代码中指定模型仓库的名称。
- 我们通过将一个变量设置为模型名称来实现这一点,这里我们决定将该变量命名为
model_id
。 - 我们将使用微软的 Phi-2,这是一个小巧但功能出奇强大的模型,可以在 https://huggingface.co/microsoft/phi-2 找到。注意:Phi-2 是一个基础模型,而非指令微调模型,因此如果您尝试用它进行聊天,它的回应会很不寻常。
model_id = "microsoft/phi-2"
什么是指令微调模型?
指令微调语言模型是一种在其基础版本上进一步训练的模型,旨在理解和响应用户给出的命令或提示,从而提高其遵循指令的能力。基础模型能够自动补全文本,但通常不能以有用的方式响应命令。稍后当我们尝试提示 Phi 时,就会看到这一点。
- 创建一个模型对象并加载模型
- 要将模型从 Hugging Face Hub 加载到我们的本地环境中,我们需要实例化模型对象。我们通过将上一步定义的“model_id”传递到 AutoModelForCausalLM 类的“.from_pretrained”方法的参数中来完成此操作。
- 运行您的代码,然后去喝杯饮料,模型可能需要几分钟才能下载完成。
model = AutoModelForCausalLM.from_pretrained(model_id)
什么是参数?
参数是传递给函数以计算输出的输入信息。我们通过将参数放在函数括号之间来将其传递给函数。在这种情况下,模型 ID 是唯一的参数,但函数也可以有多个参数,或者没有参数。
什么是方法?
方法(Method)是函数的别称,特指使用特定对象或类的信息的函数。在这种情况下,.from_pretrained
方法使用来自类和 model_id
的信息来创建一个新的 model
对象。
- 创建一个分词器对象并加载分词器
- 要加载分词器,您现在需要创建一个分词器对象。为此,再次将
model_id
作为参数传递到 AutoTokenizer 类的.from_pretrained
方法中。 - 请注意,这里有一些额外的参数,对于本示例来说,理解它们并不重要,所以我们不作解释。
tokenizer = AutoTokenizer.from_pretrained(model_id, add_eos_token=True, padding_side='left')
什么是分词器?
分词器(tokenizer)是一种将句子分割成更小文本片段(词元,即 token)的工具,并为每个词元分配一个称为输入 ID 的数值。这是必需的,因为我们的模型只理解数字,所以我们必须首先将文本转换(即编码)为模型可以理解的格式。每个模型都有自己的分词器词汇表,使用与模型训练时相同的分词器非常重要,否则它会误解文本。
- 创建供模型处理的输入
- 定义一个新变量
input_text
,它将接收您想提供给模型的提示。在本例中,我问的是“你是谁?”,但您可以选择任何您喜欢的内容。 - 将新变量作为参数传递给分词器对象,以创建
input_ids
。 - 向分词器对象传递第二个参数
return_tensors="pt"
,这确保了 token_id 表示为我们所用模型版本(即 PyTorch 而非 Tensorflow)所需的正确向量类型。
input_text = "Who are you?"
input_ids = tokenizer(input_text, return_tensors="pt")
- 运行生成并解码输出
- 现在输入已经是正确的格式,我们需要将其传递给模型。我们通过调用
model
对象上的.generate
方法,将input_ids
作为参数传递,并将其结果赋给一个新变量outputs
。我们还设置了第二个参数max_new_tokens
等于 100,这限制了模型将生成的词元数量。 - 输出目前还不是人类可读的,要将它们恢复为文本,我们必须解码输出。我们可以使用
.decode
方法来完成此操作,并将结果保存到变量decoded_outputs
中。 - 最后,将
decoded_output
变量传递给 print 函数,我们就可以在 notebook 中看到模型的输出了。 - 可选:将
outputs
变量传递给 print 函数,看看它们与decoded outputs
有何不同。
outputs = model.generate(input_ids["input_ids"], max_new_tokens=100)
decoded_outputs = tokenizer.decode(outputs[0])
print(decoded_outputs)
为什么我需要解码?
模型只理解数字,所以当我们以向量形式提供 input_ids
时,它返回的输出也是相同的格式。为了将这些输出恢复为文本,我们需要使用分词器逆转我们最初的编码过程。
为什么输出读起来像个故事?
请记住,Phi-2 是一个基础模型,没有经过对话用途的指令微调,因此它实际上是一个庞大的自动补全模型。根据您的输入,它会基于其之前见过的所有网页、书籍和其他内容,预测接下来最可能出现的内容。
恭喜,您已经成功在您的第一个大语言模型上进行了推理!
我希望通过这个例子能帮助您更好地理解开源机器学习的世界。如果您想继续您的机器学习学习之旅,我推荐我们最近与 DeepLearning AI 合作发布的 Hugging Face 课程。