Label Studio

Label Studio 是一个开源的数据标注工具。它允许用户通过一个简单直观的用户界面来标注音频、文本、图像、视频和时间序列等多种数据类型,并支持导出到各种模型格式。

部署

安装与配置

进入 Notebook app 的终端,添加相应的 Helm Chart repository,列出 Chart heartex/label-studio 的所有版本:

helm repo add heartex https://charts.heartex.com/

# 注意 CHART VERSION 和 APP VERSION(Label Studio 版本)之间的对应关系
# 例如 CHART VERSION 1.4.0 和 1.3.4 中的 Label Studio 版本都是 1.11.0
helm search repo heartex/label-studio --versions

安装指定版本的 Chart heartex/label-studio 以部署 Label Studio 应用:

# 安装最新版本
helm repo update heartex
helm install label-studio-demo heartex/label-studio

# 安装指定 CHART VERSION,注意这不是 APP VERSION(Label Studio 版本)
helm install label-studio-demo heartex/label-studio --version <CHART_VERSION>

以上安装全部使用默认配置,完整的默认配置请参阅相应的 values.yaml

# 获取指定 CHART VERSION 的 values.yaml
helm show values heartex/label-studio --version <CHART_VERSION> > values.yaml

其中部分关键配置如下所示(CHART VERSION 1.4.0):

app:
  replicas: 1        # 副本数

  resources:         # 计算资源
    limits: {}
    requests: {}

  ingress:           # Ingress 配置
    enabled: false
    annotations: {}
    className: ""
    host: ""
    tls: []

global:
  persistence:       # 持久化
    config:
      volume:
        accessModes:
        - ReadWriteOnce
        annotations: {}
        existingClaim: ""
        resourcePolicy: ""
        size: 10Gi       # 卷大小
        storageClass: ""
    enabled: true
    type: volume         # 卷

你可以根据需要对这些配置进行修改:

然后将新配置(覆盖默认配置的部分)保存为一个 YAML 文件,通过 -f 选项提供给安装命令:

# 使用修改后的 values.yaml
helm install label-studio-demo heartex/label-studio --version <CHART_VERSION> -f values.yaml

应用架构

应用的系统架构如下图所示(CHART VERSION 1.4.0,默认配置):

architecture

创建的主要 Kubernetes 资源如下表所示:

类型名称作用备注
Servicelabel-studio-demo-ls-app暴露 Label Studio 服务
Deploymentlabel-studio-demo-ls-app部署 Label Studio默认计算资源为 {"limits": {}, "requests": {}}
PVClabel-studio-demo-ls-pvc作为 Label Studio 的持久化存储,存储用户上传的数据文件等选择卷作为持久化方案时存在;默认卷大小为 10Gi
Secretlabel-studio-demo-postgresql存储数据库密钥
Servicelabel-studio-demo-postgresql暴露数据库服务
StatefulSetlabel-studio-demo-postgresql部署数据库默认计算资源为 {"limits": {}, "requests": {"cpu": "250m", "memory": "256Mi"}}
PVCdata-label-studio-demo-postgresql-*作为数据库的持久化存储默认卷大小为 8Gi
Ingresslabel-studio-demo-ls-app提供外部访问启用 Ingress 时存在

运维

查看应用的状态

helm status label-studio-demo

重启应用

kubectl rollout restart deployment/label-studio-demo-ls-app

更新应用

# 更新到最新版本
helm upgrade label-studio-demo heartex/label-studio

# 更新到指定版本
helm upgrade label-studio-demo heartex/label-studio --version <VERSION_NUMBER>

# 回滚更新,首先查看历史版本
helm history label-studio-demo
helm rollback label-studio-demo [REVISION]

移除应用

helm delete label-studio-demo

使用

基本使用

如果在部署应用时配置了 Ingress,那么直接在浏览器中访问相应的地址即可,否则需要进行端口转发。在用户的计算机上,前往模型构建控制台获取应用 Pod 的名称(前缀为 label-studio-demo-ls-app-):

get-pod-name

然后通过 t9k-pf 进行端口转发来访问 Label Studio 应用:

t9k-pf -n <APP_PROJECT> pod <POD_NAME> 8080:8085

在浏览器中访问 http://127.0.0.1:8080/ 进入应用的 Web UI。注册一个用户,Email 和密码可以任意指定:

sign-up

假定任务是图像分类,我们准备了 10 张图片(来自数据集 Cats and Dogs),需要将每一张图片标注为猫或狗。点击 Create Project

create-project

在 Project Name 页面可选地修改 Project 的名称:

project-name

在 Data Import 页面上传 10 张图片:

data-import
file-uploaded

在 Labeling Setup 页面,选择模板 Computer Vision > Image Classification,并将选项编辑为 CatDog,最后点击 Save

labeling-setup
config-template

自动跳转到 Project 的默认标签页,点击 Label All Tasks 以开始标注:

task-list

对于每一张图片,勾选其为 Cat 或 Dog,然后点击 Submit

labeling

标注结束后,点击 Export 以下载指定格式的标注数据。

export

导入大量数据

在导入数据时,如果仅上传少量(几十上百个)的文件,那么使用 Web UI 即可。但假设我们要上传数据集 Cats and Dogs 的总共 25000 张图片,仍然使用 Web UI 会导致其崩溃,这时我们需要寻求另外的导入数据的方法。

Label Studio 支持从外部存储同步数据。这里以 Amazon S3 为例。在用户的计算机上准备好数据文件,并将其上传到 S3 bucket:

$ tree .                                       
.
├── 0.jpg
├── 1.jpg
├── 10.jpg
├── 100.jpg
├── 1000.jpg
├── 10000.jpg
├── 10001.jpg
...
├── 9998.jpg
└── 9999.jpg

0 directories, 25000 files

$ rclone copy -P . corps3:my-bucket/kagglecatsanddogs                                                                        
Transferred:      569.808 MiB / 809.542 MiB, 70%, 2.328 MiB/s, ETA 1m42s                                               
Transferred:        16994 / 25000, 68%                                                                                 
Elapsed time:      3m35.2s                                                                                             
Transferring:                                                                                                          
 *                                      2793.jpg:100% /23.680Ki, 0/s, -                                                
 *                                      2794.jpg:100% /20.700Ki, 0/s, -                                                
 *                                      2795.jpg:100% /22.631Ki, 0/s, -                                                
 *                                      2796.jpg:100% /13.476Ki, 0/s, -

在 Label Studio 的项目设置中点击 Cloud Storage > Add Source Storage,选择存储类型 AWS S3,并填写相关的配置,点击 Check Connection 验证连接是否成功,最后点击 Add Storage

add-source-storage
add-source-storage-detail

创建完成之后,点击 Sync Storage,即可从导入数据文件:

sync-storage

回到项目,可以看到数据被导入:

synced

自定义标注 UI

应用内置了大量标注模板,覆盖了各种类型的机器学习任务。除此之外,用户还可以使用类似 XML 的标签来自定义标注 UI,详细语法规则请参阅 Customize the Label Studio User Interface

customize-ui
customize-ui-detail

自动化标注

人工标注数据费时费力,我们可以引入机器学习模型来完成这一工作,这样只需要人工审核即可。

Label Studio 支持添加 ML backend,使用其自动标注或进行在线训练。这里演示使用 SAM 进行语义分割任务的自动标注。

在应用的 Web UI 点击 Account & Settings,以获取用户的 Access Token

access-token

回到 Notebook app 的终端,获取应用 service 的 IP 地址:

kubectl get svc label-studio-demo-ls-app -o jsonpath="{.spec.clusterIP}"

然后使用如下 YAML 配置文件创建 SimpleMLService 以部署 ML backend 服务,其中环境变量 LABEL_STUDIO_HOSTLABEL_STUDIO_ACCESS_TOKEN 的值需要根据上面获取的结果进行修改。镜像 t9kpublic/label-studio-sam:main 构建自示例 Interactive Annotation in Label Studio with Segment Anything Model

sam.yaml
apiVersion: tensorstack.dev/v1beta1
kind: SimpleMLService
metadata:
  name: label-studio-sam
spec:
  replicas: 1
  service:
    type: ClusterIP
    ports:
    - targetPort: 9090
      port: 9090
  custom:
    spec:
      containers:
      - name: server
        image: t9kpublic/label-studio-sam:main
        env:
          - name: SAM_CHOICE
            value: MobileSAM
          - name: LOG_LEVEL
            value: DEBUG
          - name: LABEL_STUDIO_HOST
            value: http://10.233.12.87:80
          - name: LABEL_STUDIO_ACCESS_TOKEN
            value: 381ae0357804f39d01e5d169b8ed0cf548925a57
        ports:
        - containerPort: 9090
        resources:
          limits:
            cpu: 8
            memory: 8Gi
        volumeMounts:
        - mountPath: /dev/shm
          name: dshm
      volumes:
      - name: dshm
        emptyDir:
          medium: Memory
kubectl create -f sam.yaml

获取 ML backend service 的 IP 地址和端口号:

kubectl get svc label-studio-sam -o jsonpath="{.spec.clusterIP}"
kubectl get svc label-studio-sam -o jsonpath="{.spec.ports[0].port}"

再次进入应用的 Web UI,创建一个新的 project,上传一张图片,并且 template 使用如下自定义模板:

<View>
  <Image name="image" value="$image" zoom="true"/>
  <BrushLabels name="tag" toName="image">
  	<Label value="Banana" background="#FF0000"/>
  	<Label value="Orange" background="#0d14d3"/>
  </BrushLabels>
  <KeyPointLabels name="tag2" toName="image" smart="true">
    <Label value="Banana" smart="true" background="#000000" showInline="true"/>
    <Label value="Orange" smart="true" background="#000000" showInline="true"/>
  </KeyPointLabels>
  <RectangleLabels name="tag3" toName="image" smart="true">
    <Label value="Banana" background="#000000" showInline="true"/>
    <Label value="Orange" background="#000000" showInline="true"/>
  </RectangleLabels>
</View>

在 Label Studio 的项目设置中点击 Machine Learning > Add Model,填写 SAM 服务的 URL 和模型名称,勾选 Use for interactive preannotations,然后点击 Validate and Save

add-model
add-model-detail

标注时按照下图的顺序进行操作,可以看到图片中的柯基被正确地分割出来:

auto-annotation

团队协作

应用提供了简单直接的团队协作方式。团队的多个成员分别注册用户、登录并进入同一个项目,通过设定不同的过滤条件来分别标注全部数据的不同子集。

例如设定 ID / <= / 3000 可以仅列举前 3000 个数据;设定 Annotated by / is empty / yes 可以仅列举未被标注的数据。

参考