📑 充分利用 Argilla TextFields 中的 Markdown#
正如您可能已经注意到的,Argilla 在其文本字段中支持 Markdown。这意味着您可以轻松添加格式,例如 粗体、斜体 或高亮文本、链接,甚至插入 HTML 元素,例如图像、音频、视频和 iframe。这是一个功能强大的工具,供您使用。让我们深入了解一下!
在本笔记本中,我们将介绍 Markdown 的基础知识,以及如何在 Argilla 中使用它。
利用
displaCy
的强大功能进行 NER 和关系提取。探索多模态:视频、音频和图像。
检查 PDF。
让我们开始吧!
友情提示: Markdown 中的多媒体功能已在此处,但仍处于实验阶段。在我们探索早期阶段时,由于 ElasticSearch 的限制,文件大小受到限制,并且可视化和加载时间可能会因您的浏览器而异。我们正在努力改进这一点,并欢迎您的反馈和建议!🌟🚀
运行 Argilla#
对于本教程,您需要运行 Argilla 服务器。部署和运行 Argilla 有两个主要选项
在 Hugging Face Spaces 上部署 Argilla:如果您想使用外部笔记本(例如 Google Colab)运行教程,并且您在 Hugging Face 上有一个帐户,您只需点击几下即可在 Spaces 上部署 Argilla
有关配置部署的详细信息,请查看 Hugging Face Hub 官方指南。
使用 Argilla 的快速入门 Docker 镜像启动 Argilla:如果您想在 本地计算机上运行 Argilla,这是推荐选项。请注意,此选项仅允许您在本地运行教程,而不能使用外部笔记本服务。
有关部署选项的更多信息,请查看文档的部署部分。
提示
本教程是一个 Jupyter Notebook。有两种运行方式
使用此页面顶部的“在 Colab 中打开”按钮。此选项允许您直接在 Google Colab 上运行笔记本。不要忘记将运行时类型更改为 GPU,以加快模型训练和推理速度。
通过单击页面顶部的“查看源代码”链接下载 .ipynb 文件。此选项允许您下载笔记本并在本地计算机或您选择的 Jupyter Notebook 工具上运行它。
设置环境#
要完成本教程,您需要使用 pip
安装 Argilla 客户端和一些第三方库
[ ]:
# %pip install --upgrade pip
%pip install argilla
%pip install datasets
%pip install spacy spacy-transformers
%pip install Pillow
%pip install span_marker
%pip install soundfile librosa
!python -m spacy download en_core_web_sm
让我们进行所需的导入
[ ]:
import argilla as rg
from argilla.client.feedback.utils import audio_to_html, image_to_html, video_to_html, pdf_to_html
import re
import os
import pandas as pd
import span_marker
import tarfile
import glob
import subprocess
import random
import spacy
from spacy import displacy
from datasets import load_dataset
from huggingface_hub import hf_hub_download
如果您正在使用 Docker 快速入门镜像或 Hugging Face Spaces 运行 Argilla,则需要使用 URL
和 API_KEY
初始化 Argilla 客户端
[ ]:
# Replace api_url with the url to your HF Spaces URL if using Spaces
# Replace api_key if you configured a custom API key
# Replace workspace with the name of your workspace
rg.init(
api_url="https://#:6900",
api_key="owner.apikey",
workspace="admin"
)
如果您正在运行私有的 Hugging Face Space,您还需要按如下方式设置 HF_TOKEN
[ ]:
# # Set the HF_TOKEN environment variable
# import os
# os.environ['HF_TOKEN'] = "your-hf-token"
# # Replace api_url with the url to your HF Spaces URL
# # Replace api_key if you configured a custom API key
# rg.init(
# api_url="https://[your-owner-name]-[your_space_name].hf.space",
# api_key="admin.apikey",
# extra_headers={"Authorization": f"Bearer {os.environ['HF_TOKEN']}"},
# )
利用 displaCy
#
SpaCy 是一个著名的自然语言处理 (NLP) 开源库。它为不同语言提供了广泛的模型,并且非常易于使用。提供的选项之一是 `displaCy
<https://spacy.io/usage/visualizers>`__,它是 NLP 模型输出的可视化工具。在本教程中,我们将使用它来可视化 NER 模型的输出。
使用 displaCy
#
首先,我们将通过导入英语 SpaCy 管道 (en_core_web_sm
) 来解释 displaCy
的工作原理,同时排除默认的 NER 组件。稍后,我们使用 add_pipe
方法替换此组件,以在管道的末尾引入新的 span_marker
组件。这个新组件负责使用指定的模型进行 NER 训练。
[ ]:
# Load the custom pipeline
nlp = spacy.load(
"en_core_web_sm",
exclude=["ner"]
)
nlp.add_pipe("span_marker", config={"model": "tomaarsen/span-marker-bert-tiny-fewnerd-coarse-super"})
现在,您可以检查如何使用 displacy.render
函数(它接受文本和模型的输出)返回 HTML 字符串。下面提供了两个示例:第一个说明了句子的依存关系树,而第二个展示了 NER 的发现。
[3]:
# Show the dependency parse
doc = nlp("Rats are various medium-sized, long-tailed rodents.")
displacy.render(doc, style="dep")
c:\Users\sarah\miniconda3\envs\argilla\lib\site-packages\datasets\table.py:1395: FutureWarning: promote has been superseded by mode='default'.
block_group = [InMemoryTable(cls._concat_blocks(list(block_group), axis=axis))]
c:\Users\sarah\miniconda3\envs\argilla\lib\site-packages\datasets\table.py:1421: FutureWarning: promote has been superseded by mode='default'.
table = cls._concat_blocks(blocks, axis=0)
[12]:
# Show the entity recognition
text = "When Sebastian Thrun started working on self-driving cars at Google in 2007, few people outside of the company took him seriously."
doc2 = nlp(text)
displacy.render(doc2, style="ent")
您还可以使用
create_token_highlights
和自定义颜色映射向文本添加自定义高亮。例如from argilla.client.feedback.utils import create_token_highlights tokens = ["This", "is", "a", "test"] weights = [0.1, 0.2, 0.3, 0.4] html = create_token_highlights(tokens, weights, c_map=custom_RGB) # 'viridis' by default
示例:使用 displaCy 输出创建 FeedbackDataset
#
在该示例中,我们展示了如何创建一个 Argilla FeedbackDataset
,并将 displaCy 输出添加到其中。这样,我们可以检查模型的准确性,并评估用户是否想要对依存关系和/或实体应用更正。
首先,我们 配置 ``FeedbackDataset`` </practical_guides/create_dataset.html#configure-the-dataset>`__。在字段中,我们使用三个 TextField 来显示默认文本、依存关系和实体。同时,在问题中,我们添加一个 LabelQuestion、一个 MultiLabelQuestion 和两个 TextQuestion。
[2]:
# Create the FeedbackDataset configuration
dataset_spacy = rg.FeedbackDataset(
fields=[
rg.TextField(name="text", required= True, use_markdown=True),
rg.TextField(name="dependency-tree", required= True, use_markdown=True),
rg.TextField(name="entities", required= True, use_markdown=True)
],
questions=[
rg.LabelQuestion(name="relevant", title="Is the text relevant?", labels=["Yes", "No"], required=True),
rg.MultiLabelQuestion(name="question-multi", title="Mark which is correct", labels=["flag-pos", "flag-ner"], required=True),
rg.TextQuestion(name="dependency-correction", title="Write the correct answer if needed", use_markdown=True),
rg.TextQuestion(name="ner-correction", title="Write the correct answer if needed", use_markdown=True)
]
)
dataset_spacy
[2]:
FeedbackDataset(
fields=[TextField(name='text', title='Text', required=True, type='text', use_markdown=True), TextField(name='dependency-tree', title='Dependency-tree', required=True, type='text', use_markdown=True), TextField(name='entities', title='Entities', required=True, type='text', use_markdown=True)]
questions=[LabelQuestion(name='relevant', title='Is the text relevant?', description=None, required=True, type='label_selection', labels=['Yes', 'No'], visible_labels=None), MultiLabelQuestion(name='question-multi', title='Mark which is correct', description=None, required=True, type='multi_label_selection', labels=['flag-pos', 'flag-ner'], visible_labels=None), TextQuestion(name='dependency-correction', title='Write the correct answer if needed', description=None, required=True, type='text', use_markdown=True), TextQuestion(name='ner-correction', title='Write the correct answer if needed', description=None, required=True, type='text', use_markdown=True)]
guidelines=None)
)
现在,我们从 Hugging Face 加载基本的 few-nerd 数据集。此数据集包含一些句子和 NER 模型的输出。我们将使用此数据集来展示如何在 Argilla 中使用 displaCy。
[ ]:
# Read the HF dataset
dataset_fewnerd = load_dataset("DFKI-SLT/few-nerd", "supervised", split="train[:20]")
接下来,我们将使用此数据集来填充我们的 Argilla FeedbackDataset
。我们将使用 displacy.render
函数将 displacy 输出渲染为 html,并将 jupyter=False
设置添加到 FeedbackDataset
。我们还将文本和 NER 模型的输出添加到 FeedbackDataset
。最后,我们还将添加 markdown 格式的表格,以支持对 NER 和依存关系注释的基本支持。
[15]:
# Load the custom pipeline
nlp = spacy.load(
"en_core_web_sm",
exclude=["ner"]
)
nlp.add_pipe("span_marker", config={"model": "tomaarsen/span-marker-bert-tiny-fewnerd-coarse-super"})
# Read the dataset and run the pipeline
texts = [" ".join(x["tokens"]) for x in dataset_fewnerd]
docs = nlp.pipe(texts)
[ ]:
# Define the function to set the correct width and height of the SVG element
def wrap_in_max_width(html):
html = html.replace("max-width: none;", "")
# Remove existing width and height setting based on regex width="/d"
html = re.sub(r"width=\"\d+\"", "overflow-x: auto;", html)
html = re.sub(r"height=\"\d+\"", "", html)
# Find the SVG element in the HTML output
svg_start = html.find("<svg")
svg_end = html.find("</svg>") + len("</svg>")
svg = html[svg_start:svg_end]
# Set the width and height attributes of the SVG element to 100%
svg = svg.replace("<svg", "<svg width='100%' height='100%'")
# Wrap the SVG element in a div with max-width and horizontal scrolling
return f"<div style='max-width: 100%; overflow-x: auto;'>{svg}</div>"
[ ]:
# Add the records to the FeedbackDataset
records = []
for doc in docs:
record = rg.FeedbackRecord(
fields={
"text": doc.text,
"dependency-tree": displacy.render(doc, style="dep", jupyter=False),
"entities": displacy.render(doc, style="ent", jupyter=False)
},
suggestions=[{
"question_name": "dependency-correction",
"value": pd.DataFrame([{"Label": token.dep_, "Text": token.text} for token in doc]).to_markdown(index=False)
},
{
"question_name": "ner-correction",
"value": pd.DataFrame([{"Label": ent.label_, "Text": ent.text} for ent in doc.ents]).to_markdown(index=False),
}
]
)
records.append(record)
dataset_spacy.add_records(records)
[ ]:
# Push the dataset to Argilla
dataset_spacy = dataset_spacy.push_to_argilla(name="exploiting_displacy", workspace="admin")
探索多模态:视频、音频和图像#
正如我们已经提到的,Argilla 支持在 markdown 字段中处理视频、音频和图像,前提是它们以 HTML 格式设置。为了方便起见,我们提供了三个函数:video_to_html
、audio_to_html
和 image_to_html
。这些函数接受文件路径或文件的字节数据,并返回相应的 HTMurl,以在 Argilla 用户界面中渲染媒体文件。此外,您还可以为视频和图像设置像素或百分比的 width
和 height
(默认为原始尺寸),并为音频和视频将 autoplay
和 loop
属性设置为 True
(默认为 False)。
我们将使用 TextField 定义我们的 FeedbackDataset
以添加媒体内容。我们还将添加一个问题,要求用户描述视频、音频或图像文件。
[4]:
# Configure the FeedbackDataset
ds_multi_modal = rg.FeedbackDataset(
fields=[rg.TextField(name="content", use_markdown=True, required=True)],
questions=[rg.TextQuestion(name="description", title="Describe the content of the media:", use_markdown=True, required=True)],
)
ds_multi_modal
[4]:
FeedbackDataset(
fields=[TextField(name='content', title='Content', required=True, type='text', use_markdown=True)]
questions=[TextQuestion(name='description', title='Describe the content of the media:', description=None, required=True, type='text', use_markdown=True)]
guidelines=None)
)
我们将使用相应的函数调用 add_records
方法,并将媒体内容添加到 FeedbackDataset
。
[24]:
# Add the records
records = [
rg.FeedbackRecord(fields={"content": video_to_html("/content/snapshot.mp4", autoplay=True)}),
rg.FeedbackRecord(fields={"content": audio_to_html("/content/sea.wav", autoplay=True, loop=True)}),
rg.FeedbackRecord(fields={"content": image_to_html("/content/peacock.jpg", width="50%", height="50%")}),
]
ds_multi_modal.add_records(records)
[ ]:
# Push the dataset to Argilla
ds_multi_modal = ds_multi_modal.push_to_argilla("multi-modal-basic", workspace="admin")
示例:创建多模态视频-音频-图像 FeedbackDataset
#
多模态数据集可用于创建包含文本和不同类型媒体内容的数据集。它可用于不同的任务,例如图像字幕、视频字幕、音频字幕等等。现在,我们将创建我们自己的示例,这些示例将结合视频、音频和图像,这些示例可以使用元数据属性进行筛选。
为此,我们将使用 Hugging Face 的三个不同数据集
视频:我们使用动作识别数据集,来自 UCF101 的 ucf101-subset。此数据集包含来自 YouTube 的真实动作视频,分为 101 个动作。
音频:我们使用音频分类数据集,ccmusic-database/bel_folk。此数据集包含 1 分钟的中国民乐音频剪辑,以及音乐的流派。
图像:我们使用图像分类数据集,zishuod/pokemon-icons。此数据集包含需要分类的宝可梦图像。
首先,我们将创建 Feedback 数据集的配置。这将涉及几个关键组件
TextField:这将用于添加媒体内容。
TextQuestion:一个用于详细描述内容的功能。
RatingQuestion:这将使我们能够有效地评估内容的质量。
LabelQuestion:用于标记内容最合适的年龄段的重要部分。
此外,我们将使用三个元数据属性增强配置,以简化内容管理
第一个属性将标识分配的注释者组。
第二个属性将指定媒体来源。
第三个属性将突出显示每个记录中内容的来源数据集。
[ ]:
# We configure the FeedbackDataset
multi_modal_dataset = rg.FeedbackDataset(
guidelines="Please, read the question carefully and try to answer it as accurately as possible.",
fields=[
rg.TextField(name="content", use_markdown=True, required=True),
],
questions=[
rg.TextQuestion(
name="description",
title="Describe the content of the media.",
use_markdown=True,
required=True
),
rg.RatingQuestion(
name="quality",
description="Rate the overall quality of the content on a scale from 1 to 5.",
required=True,
values=[1, 2, 3, 4, 5]
),
rg.LabelQuestion(
name="age_group",
description="Select the most appropriate age group for this content.",
required=True,
labels = ["Children", "Teens", "Adults", "All Ages"]
),
],
metadata_properties = [
rg.TermsMetadataProperty(
name="groups",
title="Annotation groups",
values=["group-a", "group-b", "group-c"],
),
rg.TermsMetadataProperty(
name="media",
title="Media source",
values=["video", "audio", "image"],
),
rg.TermsMetadataProperty(
name="source-dataset",
title="Original dataset source",
),
],
allow_extra_metadata = False
)
try:
multi_modal_dataset = rg.FeedbackDataset.from_argilla("multi-modal")
except:
multi_modal_dataset = multi_modal_dataset.push_to_argilla("multi-modal")
multi_modal_dataset
然后,我们需要加载和预处理数据集,以便能够将媒体内容添加到 FeedbackDataset
。
视频内容:我们下载数据集并解压缩它。然后,从训练集中,我们从每个类中随机选择两个 .avi 文件,并使用 ffmpeg 将它们转换为 .mp4。
[ ]:
# Download the dataset
hf_dataset_identifier = "sayakpaul/ucf101-subset"
filename = "UCF101_subset.tar.gz"
file_path = hf_hub_download(repo_id=hf_dataset_identifier, filename=filename, repo_type="dataset")
[ ]:
# Unpack the files
with tarfile.open(file_path) as t:
t.extractall(".")
[ ]:
# Set the paths to the input and output directories.
base_directory = "/content/UCF101_subset/train"
output_directory = "/content/UCF101_subset/random"
# Check if the output directory exists, if not, create it.
if not os.path.exists(output_directory):
os.makedirs(output_directory)
# Iterate over the directories (each corresponding to a class) in the 'train' folder.
for folder in os.listdir(base_directory):
folder_path = os.path.join(base_directory, folder)
# Check if it's a directory.
if os.path.isdir(folder_path):
# Get all .avi files in the directory.
avi_files = glob.glob(os.path.join(folder_path, "*.avi"))
# Randomly select 2 .avi files.
selected_files = random.sample(avi_files, 2)
for avi_file in selected_files:
# Define the output .mp4 file path.
mp4_file = os.path.join(output_directory, os.path.basename(avi_file).replace(".avi", ".mp4"))
# Command to convert .avi to .mp4 using ffmpeg.
command = f"ffmpeg -i \"{avi_file}\" -c:v libx264 -c:a aac \"{mp4_file}\""
try:
subprocess.run(command, check=True, shell=True)
print(f"Converted {avi_file} to {mp4_file}")
except subprocess.CalledProcessError as e:
print(e)
print("Conversion process is complete.")
音频内容:我们从 HF 加载前 20 个样本并对其进行洗牌。
[ ]:
my_audio_dataset = load_dataset("ccmusic-database/bel_folk", split="train[:20]")
my_audio_dataset = my_audio_dataset.shuffle()
[ ]:
my_audio_dataset[0]
{'audio': {'path': '/root/.cache/huggingface/datasets/downloads/extracted/1ce3c7fd0658e784a55187bcf1d5dccffc4dadff041a3bd7abb7d399eb383d9e/dataset/audio/Bel_f (32).wav',
'array': array([-1.19754369e-03, -1.13605941e-03, -3.28621594e-04, ...,
4.34814254e-04, 2.44393945e-04, 7.59907998e-05]),
'sampling_rate': 44100},
'image': <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=476x349>,
'label': 1,
'gender': 0,
'singing_method': 1}
图像数据集:我们从 HF 加载前 20 个样本并对其进行洗牌。
[ ]:
my_image_dataset = load_dataset("zishuod/pokemon-icons", split="train[:20]")
my_image_dataset = my_image_dataset.shuffle()
[ ]:
my_image_dataset[0]
{'image': <PIL.PngImagePlugin.PngImageFile image mode=RGB size=72x72>,
'label': 4}
最后,我们将添加数据并将其推送到我们的 FeedbackDataset。我们将使用 video_to_html
、audio_to_html
和 image_to_html
函数来添加内容。
添加视频记录
[ ]:
# Set the directory where we saved our samples
random_dir = output_directory
# Get a list of all entries in the directory
entries = os.listdir(random_dir)
# Shuffle the list of entries to avoid any bias
random.shuffle(entries)
# Iterate over all the entries in random order
for entry in entries:
# Define the full path
fullPath = os.path.join(random_dir, entry)
# Add the records to the FeedbackDataset
record = rg.FeedbackRecord(
fields={"content": video_to_html(fullPath)},
metadata={"groups":"group-a", "media":"video", "source-dataset":"https://hugging-face.cn/datasets/sayakpaul/ucf101-subset"}
)
try:
multi_modal_dataset.add_records(record, show_progress=True)
except Exception as e:
print(e)
pass
添加音频记录
[ ]:
# Iterate over the samples in the dataset
for entry in my_audio_dataset:
# Add the records to the FeedbackDataset
record = rg.FeedbackRecord(
fields={"content": audio_to_html(entry["audio"]["path"])},
metadata={"groups":"group-b", "media":"audio", "source-dataset":"https://hugging-face.cn/datasets/ccmusic-database/bel_folk"}
)
try:
multi_modal_dataset.add_records(record, show_progress=True)
except Exception as e:
print(e)
pass
添加图像记录
[ ]:
# Set a temporary path to save the image
temp_img_path = "temp_img.png"
# Iterate over the samples in the dataset
records = []
for entry in my_image_dataset:
# Save the image to the temporary path
entry["image"].save(temp_img_path, format="png")
# Add the records to the FeedbackDataset
record = rg.FeedbackRecord(
fields={"content": image_to_html(temp_img_path, file_type="png")},
metadata={"groups":"group-c", "media":"image", "source-dataset":"https://hugging-face.cn/datasets/zishuod/pokemon-icons"}
)
try:
multi_modal_dataset.add_records(record, show_progress=True)
except Exception as e:
print(e)
pass
最后,我们可以将 FeedbackDataset 推送到 HuggingFace。
[ ]:
# Push to HuggingFace Hub
multi_modal_dataset.push_to_huggingface("argilla/multi-modal-dataset")
检查 PDF#
Argilla 也支持 PDF。您可以使用 pdf_to_html
函数将 PDF 添加到 TextField,这与我们之前所做的类似。此函数接受文件路径、URL 或文件的字节数据,并返回相应的 HTML,以在 Argilla 用户界面中渲染 PDF。或者,您还可以设置像素或百分比的 width
和 height
(默认为 1000px)。下面,您可以看到如何使用此函数的示例。
[ ]:
# In this case, we will use the URL of the PDF file
file_url = "https://arxiv.org/pdf/2310.06825.pdf"
# Configure the FeedbackDataset
ds_pdf = rg.FeedbackDataset(
fields=[
rg.TextField(name="content", use_markdown=True, required=True),
],
questions=[
rg.TextQuestion(name="description", use_markdown=True, required=True)
],
)
# Push the dataset to Argilla
ds_pdf = ds_pdf.push_to_argilla(name='analyze_pdf_dataset', workspace='argilla')
# Add the records using pdf_to_html
records = [
rg.FeedbackRecord(fields={"content": pdf_to_html(file_source=file_url, width="700px", height="700px")})]
ds_pdf.add_records(records)
提示
您还可以在 Argilla UI 中查看 .docx
、.pptx
或 .xlsx
,方法是将 use_markdown=True
设置为 true,并在它们位于公共 URL 上时嵌入它们。例如,您可以将它们上传到您的 Google Drive,并通过将共享设置更改为“拥有链接的任何人都可以查看”来获取公共 URL。
file_url = "your-sharable-link.xlsx"
html = f"<embed src={file_url} type=application/pdf width=700px height=700px/></embed>"
ds = rg.FeedbackDataset(...)
records = [
rg.FeedbackRecord(fields={"xlsx_file": html})]
ds.add_records(records)
ds = ds.push_to_argilla(name='xlsx', workspace='argilla')
既然您已经了解了 Markdown 技巧,现在轮到您创建自己的多模态 FeedbackDataset 了!🔥