Enterprise Cookbook Argilla
数据标注与 Argilla Spaces
作者: Moritz Laurer
本 Notebook 展示了系统地评估大型语言模型(LLM)输出并创建 LLM 训练数据的工作流程。你可以通过使用本 Notebook 评估你最喜爱的 LLM 在没有任何微调的情况下在特定任务上的零样本性能。如果你希望提高性能,你可以轻松地重用此工作流程来创建训练数据。
示例用例:代码生成。 在本教程中,我们展示了如何为代码生成任务创建高质量的测试和训练数据。然而,相同的工作流程也可以适应其他与你特定用例相关的任务。
在本 Notebook 中,我们将进行以下步骤:
- 下载示例任务的数据。
- 提示两个 LLM 对这些任务作出响应。这将生成“合成数据”以加速手动数据创建。
- 在 HF Spaces 上创建一个 Argilla 标注界面,以比较和评估两个 LLM 的输出。
- 将示例数据和零样本 LLM 的响应上传到 Argilla 标注界面。
- 下载已标注的数据。
你可以根据自己的需求调整本 Notebook,例如在步骤 (2) 使用不同的 LLM 和 API 提供商,或在步骤 (3) 调整标注任务。
安装需要的包并连接到 HF Hub
下载示例任务数据
首先,我们下载一个包含 LLM 代码生成任务的示例数据集。我们希望评估两个不同的 LLM 在这些代码生成任务上的表现。我们使用来自 bigcode/self-oss-instruct-sc2-exec-filter-50k 数据集的指令,该数据集用于训练 StarCoder2-Instruct 模型。
Dataset structure:
Dataset({
features: ['fingerprint', 'sha1', 'seed', 'response', 'concepts', 'prompt', 'instruction', 'id'],
num_rows: 3
})
Example instructions:
['Write a Python function named `get_value` that takes a matrix (represented by a list of lists) and a tuple of indices, and returns the value at that index in the matrix. The function should handle index out of range errors by returning None.', 'Write a Python function `check_collision` that takes a list of `rectangles` as input and checks if there are any collisions between any two rectangles. A rectangle is represented as a tuple (x, y, w, h) where (x, y) is the top-left corner of the rectangle, `w` is the width, and `h` is the height.\n\nThe function should return True if any pair of rectangles collide, and False otherwise. Use an iterative approach and check for collisions based on the bounding box collision detection algorithm. If a collision is found, return True immediately without checking for more collisions.']
对示例任务提示两个 LLM 以获取它们的响应。
使用 chat_template 格式化指令
在将指令发送到 LLM API 之前,我们需要使用正确的 chat_template 格式化指令,以便对每个需要评估的模型进行适配。这实际上是指在指令周围加上特殊的标记。有关 chat_template 的详细信息,请参阅 文档。
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used. /home/user/miniconda/lib/python3.9/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`. warnings.warn( Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
First prompt formatted for mistralai/Mixtral-8x7B-Instruct-v0.1: <s>[INST] Write a Python function named `get_value` that takes a matrix (represented by a list of lists) and a tuple of indices, and returns the value at that index in the matrix. The function should handle index out of range errors by returning None. [/INST] First prompt formatted for meta-llama/Meta-Llama-3-70B-Instruct: <|begin_of_text|><|start_header_id|>user<|end_header_id|> Write a Python function named `get_value` that takes a matrix (represented by a list of lists) and a tuple of indices, and returns the value at that index in the matrix. The function should handle index out of range errors by returning None.<|eot_id|><|start_header_id|>assistant<|end_header_id|>
将指令发送到 HF 推理 API
现在,我们可以将指令发送到两个 LLM 的 API,以获取可以评估的输出。首先,我们需要定义一些参数,以确保正确生成响应。Hugging Face 的 LLM API 由 文本生成推理 (TGI) 容器提供支持。有关 TGI OpenAPI 规范,请参见 此处,并可参考 Transformers 生成参数的详细说明 文档。
[!TIP]
一旦推理 API 示例完成,下面的代码将会更新。
0%| | 0/3 [00:00<?, ?it/s]
0%| | 0/3 [00:00<?, ?it/s]
---First generation of mistralai/Mixtral-8x7B-Instruct-v0.1:
Here's a Python function that meets your requirements:
```python
def get_value(matrix, indices):
try:
return matrix[indices[0]][indices[1]]
except IndexError:
return None
```
This function takes a matrix (represented by a list of lists) and a tuple of indices as input. It first tries to access the value at the given indices in the matrix. If the indices are out of range, it catches the `IndexError` exception and returns `None`.
---First generation of meta-llama/Meta-Llama-3-70B-Instruct:
Here is a Python function that does what you described:
```
def get_value(matrix, indices):
try:
row, col = indices
return matrix[row][col]
except IndexError:
return None
```
Here's an explanation of how the function works:
1. The function takes two arguments: `matrix` (a list of lists) and `indices` (a tuple of two integers, representing the row and column indices).
2. The function tries to access the value at the specified indices using `matrix[row][col]`.
3. If the indices are out of range (i.e., `row` or `col` is greater than the length of the corresponding dimension of the matrix), an `IndexError` exception is raised.
4. The `except` block catches the `IndexError` exception and returns `None` instead of raising an error.
Here's an example usage of the function:
```
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(get_value(matrix, (0, 0))) # prints 1
print(get_value(matrix, (1, 1))) # prints 5
print(get_value(matrix, (3, 0))) # prints None (out of range)
print(get_value(matrix, (0, 3))) # prints None (out of range)
```
I hope this helps! Let me know if you have any questions.
将 LLM 输出存储在数据集中
现在,我们可以将 LLM 的输出与原始指令一起存储在一个数据集中。
Dataset({
, features: ['instructions', 'response_model_1', 'response_model_2'],
, num_rows: 3
,}) 创建并配置你的 Argilla 数据集
我们使用 Argilla,这是一个为 AI 工程师和领域专家设计的协作工具,用于构建高质量的数据集以支持他们的项目。
我们通过 HF Space 运行 Argilla,你可以通过几次点击便能设置好,无需进行本地配置。你可以按照 这些指引 创建 HF Argilla Space。有关 HF Argilla Spaces 的更多配置,请参阅详细的 文档。如果你希望,也可以通过 Argilla 的 Docker 容器在本地运行 Argilla(参见 Argilla 文档)。

程序化地与 Argilla 交互
在我们定制数据集以适应特定任务并上传将在 UI 中显示的数据之前,我们需要先完成一些设置。
将此 notebook 连接到 Argilla: 现在,我们可以将此 notebook 连接到 Argilla,以便程序化地配置你的数据集并上传/下载数据。
编写良好的标注指南
为你的人工标注员编写良好的指南与编写高质量的训练代码一样重要(也是一项具有挑战性的任务)。良好的指南应满足以下标准:
- 简洁明了:指南应简洁明了,以便那些对任务一无所知的人也能理解。在发布之前,最好请至少一位同事重新阅读指南,确保没有歧义。
- 可重复和明确:完成标注任务所需的所有信息应包含在指南中。一个常见的错误是,在与选定的标注员沟通时,未能正式解释指南的内容。未来的标注员将无法获取这些信息,如果没有在指南中明确说明,他们可能会以不同于预期的方式完成任务。
- 简短而全面:指南应尽可能简短,但包含所有必要的信息。标注员通常不会认真阅读冗长的指南,因此请尽量保持简洁,同时确保内容全面。
请注意,编写标注指南是一个迭代过程。建议你自己先做几十个标注,并根据数据中学到的经验来完善指南,然后再将任务分配给他人。随着任务的演变,对指南进行版本管理也很有帮助。有关更多提示,请参见这篇 博客文章。
累积评分 vs. Likert 量表: 注意,上述指南要求标注员通过为明确的标准加分来进行累积评分。另一种方法是使用 "Likert 量表",在这种方法中,标注员被要求在一个连续的尺度上对响应进行评分,例如从 1(非常差)到 3(一般)再到 5(非常好)。我们通常推荐使用累积评分,因为它迫使你和标注员将质量标准明确化,而仅仅将响应评分为 "4"(好)是模糊的,不同的标注员可能会对其有不同的解释。
将你的 Argilla 数据集定制为特定任务
现在,我们可以为特定任务创建自己的 code-llm 任务,定义标注所需的字段、问题和元数据。有关如何配置 Argilla 数据集的更多信息,请参阅 Argilla 文档。
运行上述代码后,你将在 Argilla 中看到新的自定义 code-llm 数据集(以及之前可能创建的任何其他数据集)。
将数据加载到 Argilla
此时,数据集仍然为空。让我们使用以下代码加载一些数据。
Argilla 的标注 UI 将类似于下图所示:

标注
就是这样,我们已经创建了 Argilla 数据集,现在可以开始在 UI 中进行标注了!默认情况下,记录会在完成 1 次标注后标记为已完成。查看以下指南,了解如何 自动分配标注任务 和 在 Argilla 中进行标注。
重要提示:如果你在 HF Space 中使用 Argilla,请确保启用持久存储,以便你的数据安全存储,并且不会在一段时间后被自动删除。对于生产环境,确保在进行任何标注之前就启用持久存储,以避免数据丢失。
下一步
就这样!你已经使用 HF 推理 API 创建了合成 LLM 数据,在 Argilla 中创建了数据集,将 LLM 数据上传到 Argilla,评估/修正了数据,并在标注后将数据以简单的表格格式下载,用于后续使用。
我们特别设计了这个流程和界面来支持 两个主要用例:
-
评估:你现在可以简单地使用
score_response_1和score_response_2列中的数值分数来计算哪一个模型整体表现更好。你还可以检查评分非常低或非常高的响应,以进行详细的错误分析。在测试或训练不同模型时,你可以重复使用这个流程,并跟踪不同模型随时间的改进。 -
训练:在标注足够数据后,你可以从数据中创建训练-测试集,并微调你自己的模型。你可以使用高度评价的响应文本进行监督式微调,利用 TRL SFTTrainer,或者直接使用评分来进行偏好微调技术,如 DPO,使用 TRL DPOTrainer。有关不同 LLM 微调技术的优缺点,请参见 TRL 文档。
调整和改进:许多方面可以进行改进,以便将此流程定制为适应你的特定用例。例如,你可以提示一个 LLM 来评估两个 LLM 输出的结果,指令与人类标注员指南非常相似("LLM 作为评审" 方法)。这可以帮助进一步加速你的评估流程。请参见我们的 LLM 作为评审的示例实现 和我们的整体 开源 AI 指南,其中包含许多其他创意。