☰
doccano文本标注实战:从部署到训练流水线全链路指南
2026/10/15 14:11:41 网站建设 项目流程

文本标注这件事,说简单也简单,说磨人也真磨人。我最早接触标注工作的时候,团队里还在用表格加人工校对的方式,几十条数据还能忍,一旦上到几千条,版本混乱、字段错位、多人协作冲突这些问题就全冒出来了。后来陆续试过几款标注工具,有的太重,部署一次要折腾半天;有的太轻,连最基本的多人协作都撑不住。doccano 是我用下来觉得在"轻量"和"够用"之间平衡得比较好的一款,尤其适合中小团队快速搭建一套自己的文本标注流水线。这篇文章我会把 doccano 从部署、配置、标注到数据导出的完整链路讲清楚,同时把我在实际使用中踩过的坑和总结的技巧一并分享出来,不管你是刚接触标注的新手,还是想给团队换一套工具的老手,应该都能从中找到有用的东西。

1. 先搞清楚 doccano 到底解决什么问题

1.1 文本标注的典型场景与痛点

在聊工具之前,得先明确文本标注到底在标什么。常见的文本标注任务大致可以分成几类:文本分类(给整段文本打一个或多个标签)、命名实体识别(把文本里的实体词框出来并归类)、序列标注(对每个 token 打标签)、关系抽取(标注两个实体之间的关系)、以及机器翻译和摘要类任务的数据对齐。不同任务对工具的要求差别很大,比如分类任务只需要一个标签选择器,而实体识别则需要精确的字符级选区和高亮显示。

传统做法无非是 Excel、在线表格或者自己写脚本。Excel 的问题在于:无法做字符级标注,多人同时编辑容易冲突,数据版本难以追溯。自己写脚本的问题在于:开发成本高,界面交互差,标注员上手慢。doccano 恰好卡在中间——它提供了开箱即用的 Web 界面,支持多种标注任务类型,数据存在数据库里,多人可以同时在线标注,还能通过 API 做自动化集成。

1.2 doccano 的核心能力边界

doccano 本质上是一个基于 Web 的文本标注平台,后端用 Django 搭建,前端是单页应用,数据默认存在 SQLite 里,也支持 PostgreSQL。它的核心能力包括:

  • 多任务类型支持:文本分类、命名实体识别、序列到序列(seq2seq)、序列标注等。
  • 多人协作:支持创建多个用户,分配标注、审核角色,有完整的权限体系。
  • 数据集管理:可以创建多个项目,每个项目独立管理自己的数据和标签体系。
  • API 接口:提供 RESTful API,方便把标注结果拉取到训练流水线里。
  • 导入导出:支持 JSONL、CoNLL、CSV 等格式的导入导出。

但也要清楚它的边界:doccano 不是数据管理平台,不做数据清洗和预处理;它不是模型训练平台,不包含任何训练逻辑;它的界面定制能力有限,如果你需要非常特殊的标注交互(比如音频、视频、图像标注),doccano 并不适合。它专注的就是纯文本标注这一件事。

1.3 什么样的团队适合用它

我的判断标准很简单:如果你的团队在 3 到 20 人之间,标注任务以文本分类和实体识别为主,希望一周内就能把标注流程跑起来,那 doccano 非常合适。如果团队只有一两个人,数据量在几百条以内,其实用表格也能凑合;如果团队超过 50 人,标注任务极其复杂,可能需要考虑更企业级的方案。doccano 的甜点区就是中小规模、快速迭代、以文本为主的标注场景。

2. 部署方式的选择与实操细节

2.1 三种部署路径的取舍

doccano 官方提供了几种部署方式,我逐一试过,这里说说各自的适用场景。

第一种:pip 安装。这是最直接的方式,一条命令就能装好,适合本地快速体验。但它依赖 Python 环境,而且默认用 SQLite,不适合多人同时使用。我一般只用它来做功能验证,不会用在正式标注上。

第二种:Docker 部署。这是我最推荐的方式,尤其是团队协作场景。Docker 把依赖全部打包好,不会污染宿主机环境,迁移和备份也方便。官方提供了 docker-compose 配置,改几个环境变量就能跑起来。

第三种:源码部署。适合需要二次开发的团队。你可以改前端界面、加自定义字段、扩展 API。但维护成本高,每次升级都要处理合并冲突。

下面这张表可以帮你快速决策:

部署方式适用场景优点缺点
pip 安装个人体验、功能验证最快,一条命令SQLite,不适合多人
Docker团队协作、正式使用环境隔离,易迁移需要懂基本 Docker
源码部署二次开发、深度定制完全可控维护成本高

2.2 Docker 部署的完整步骤与参数解释

我以 Docker 部署为例,把每一步都拆开讲。首先确认宿主机装好了 Docker 和 docker-compose,这两个是前提。然后拉取官方镜像,创建数据卷目录,这一步很关键——数据卷决定了你的标注数据存在哪里,一旦容器重建,没有挂载数据卷的话数据就全丢了。

# 创建数据持久化目录 mkdir -p /data/doccano/data # 拉取镜像 docker pull doccano/doccano:latest # 启动容器,映射端口和数据卷 docker run -d \ --name doccano \ -p 8000:8000 \ -v /data/doccano/data:/data \ -e ADMIN_USERNAME=admin \ -e ADMIN_EMAIL=admin@example.com \ -e ADMIN_PASSWORD=your_secure_password \ doccano/doccano:latest

这里有几个参数值得展开说。-p 8000:8000是把容器内的 8000 端口映射到宿主机,如果你宿主机 8000 被占用了,改成-p 9000:8000即可,注意冒号左边是宿主机端口,右边是容器端口,别写反了。-v挂载数据卷,左边是宿主机路径,右边是容器内路径,doccano 默认把数据存在/data下,所以挂载这个目录就能持久化。三个环境变量分别设置管理员用户名、邮箱和密码,第一次启动时会自动创建这个管理员账号。

注意:ADMIN_PASSWORD一定要设一个强密码,doccano 默认没有强制密码复杂度,但标注数据往往涉及业务敏感信息,弱密码风险很大。

启动之后,用docker logs doccano看一下日志,确认没有报错,然后浏览器访问http://你的服务器IP:8000,用刚才设置的管理员账号登录,能看到项目列表页就说明部署成功了。

2.3 生产环境必须调整的几个配置

默认配置只适合本地测试,正式用之前有几处必须改。

数据库换成 PostgreSQL。SQLite 在并发写入时会锁库,多人同时标注很容易出现写入失败。PostgreSQL 支持真正的并发,数据量大了性能也稳。你可以在 docker-compose 里加一个 postgres 服务,然后把 doccano 的数据库连接指向它。

开启 HTTPS。doccano 默认是 HTTP,标注数据在网络上明文传输不安全。生产环境建议在前面挂一个反向代理,配置证书,把 HTTP 流量转成 HTTPS。

设置合理的会话超时。默认会话时间比较短,标注员标到一半被踢出去会很不爽。可以在环境变量里调整会话有效期,我一般设成 8 小时,覆盖一个完整工作日。

配置定期备份。数据卷虽然持久化了,但误删、磁盘故障这些风险还是存在。我习惯用 cron 每天凌晨把数据库 dump 一份,保留最近 7 天,这样即使出问题也能快速恢复。

3. 从零搭建一个标注项目的完整流程

3.1 项目创建与任务类型的选择逻辑

登录之后第一件事是创建项目。doccano 会让你选项目类型,这个选择很关键,因为项目一旦创建,任务类型就不能改了。选错了只能重建项目,之前标的数据就白费了。

选类型的逻辑是这样的:如果你要给整段文本打标签,比如判断一条评论是正面还是负面,选文本分类;如果你要把文本里的实体词框出来,比如从新闻里标出人名、地名、机构名,选命名实体识别;如果你要做翻译或者摘要,输入一段输出一段,选序列到序列;如果你要对每个词打标签,选序列标注。

我见过有人把实体识别任务建成了文本分类,结果发现没法框选实体,只能重建。所以创建项目前一定要想清楚任务形态。

创建项目时需要填几个字段:项目名称、描述、项目类型。名称建议用英文加下划线,比如news_ner_2024,因为后面 API 调用时会用到项目 ID,英文名方便识别。描述写清楚这个项目标什么数据、给谁用,方便团队其他人理解。

3.2 标签体系的定义与常见误区

项目建好后,下一步是定义标签。标签体系的设计直接决定了标注质量,这里有几个坑我踩过。

标签粒度不要太细。有人一上来就定义几十个标签,结果标注员记不住,标注一致性极差。我的经验是,初始标签控制在 10 个以内,先跑通流程,后面根据实际数据再增补。

标签之间要互斥且完备。互斥是指一个实体只能属于一个标签,不能既算人名又算地名;完备是指所有可能出现的情况都有对应标签,不能出现"其他"这种兜底标签满天飞的情况。如果确实有难以归类的,可以设一个"其他"标签,但要严格控制使用频率。

标签命名要统一风格。要么全用中文,要么全用英文,不要混着来。我一般用英文小写下划线,比如person_name、org_name、location,这样导出数据后直接能用在代码里,不用再做映射。

在 doccano 里,标签是在项目的"标签"页面添加的,可以设置标签的颜色,方便标注时区分。颜色建议选对比度高的,比如红、蓝、绿,避免用相近的色系,否则标注员容易看花眼。

3.3 数据导入的格式要求与预处理

标签定义好之后,就可以导入数据了。doccano 支持 JSONL、CoNLL、CSV 等格式,最常用的是 JSONL,每行一个 JSON 对象。

对于文本分类任务,数据格式是这样的:

{"text": "这家餐厅的服务态度非常好,菜品也很新鲜。"} {"text": "等了半个小时才上菜,体验很差。"}

对于命名实体识别任务,如果是从零开始标,只需要提供text字段;如果是导入已有标注做增量,格式会复杂一些,需要包含label和entities字段。

导入前有个预处理步骤很关键:去重和去空。我遇到过导入的数据里有大量重复文本,标注员标了好几遍同样的内容,浪费了大量时间。还有空文本、纯符号文本,这些都应该在导入前过滤掉。可以用一段简单的 Python 脚本处理:

import json seen = set() with open('raw.jsonl', 'r', encoding='utf-8') as f, \ open('clean.jsonl', 'w', encoding='utf-8') as out: for line in f: obj = json.loads(line) text = obj.get('text', '').strip() # 过滤空文本和重复文本 if not text or text in seen: continue seen.add(text) out.write(json.dumps({'text': text}, ensure_ascii=False) + '\n')

这段脚本做了两件事:去掉首尾空白后为空的文本,以及去重。实测下来,真实业务数据里重复率经常能到 10% 到 20%,预处理一下能省不少标注成本。

4. 标注过程中的协作机制与质量控制

4.1 角色分配与权限管理

doccano 有一套角色体系,理解这套体系是做好协作的前提。主要角色有:项目管理员、标注员、审核员。项目管理员可以创建项目、管理标签、导入导出数据;标注员只能标注分配给自己的数据;审核员可以查看标注结果并做确认或打回。

实际使用中,我建议这样分配:一个项目设 1 到 2 个管理员,负责整体把控;标注员按数据量分配,每人每天标注量控制在合理范围;审核员由经验丰富的人担任,负责抽查和纠错。

在 doccano 里添加成员是在项目的"成员"页面,输入用户名即可添加,然后设置角色。这里有个细节:成员必须先注册账号,管理员才能把他加进项目。所以流程是:管理员创建账号,或者让成员自己注册,然后管理员在项目里添加。

4.2 标注一致性问题的根源与应对

多人标注最大的挑战是一致性。同样一段文本,A 标注员标了 3 个实体,B 标注员标了 5 个,这种差异会直接影响模型训练效果。

一致性问题通常来自三个根源:标签理解不一致、边界判断不一致、标注粒度不一致。标签理解不一致是指对标签定义的理解有偏差,比如"人名"是否包含昵称、笔名;边界判断不一致是指实体边界怎么切,比如"北京市朝阳区"是一个整体还是拆成"北京市"和"朝阳区";标注粒度不一致是指标不标修饰词,比如"著名的科学家"里"著名的"算不算实体的一部分。

应对方法有几个。第一,制定详细的标注规范文档,把每个标签的定义、正例、反例都写清楚,标注员上岗前必须读一遍。第二,先做小批量试标,让所有标注员标同一批数据,然后对比结果,找出分歧点,统一认识。第三,定期做一致性评估,计算 Kappa 系数,低于阈值就停下来重新对齐。

4.3 审核环节的设计与效率优化

审核不是把标注结果全部重看一遍,那样成本太高。我的做法是分层审核:第一层是自动检查,用脚本检查明显的格式错误、标签越界、空标注等;第二层是抽样审核,按 10% 到 20% 的比例随机抽查;第三层是重点审核,对标注员历史准确率低的,提高抽查比例。

doccano 的审核功能在"数据集"页面,审核员可以看到每条数据的标注状态,选择确认或打回。打回时可以写备注,说明问题在哪,标注员看到备注后修改再提交。

这里有个效率技巧:把审核和标注放在同一个界面里做,审核员发现问题直接改,不用来回切换。doccano 支持审核员直接编辑标注结果,改完保存即可。

5. 数据导出与对接训练流水线

5.1 导出格式的选择与转换

标注完成后,数据要导出给训练用。doccano 支持导出 JSONL、CoNLL、CSV 等格式,选哪种取决于你的训练框架。

如果是文本分类,导出 JSONL 最方便,每行包含text和label两个字段,直接能喂给大多数分类模型。如果是命名实体识别,CoNLL 格式是业界标准,每行一个 token 加一个标签,句子之间用空行分隔。但 doccano 导出的 CoNLL 有时需要做后处理,比如把标签从B-PER、I-PER这种 BIO 格式转成你框架需要的格式。

我一般导出 JSONL,然后在训练脚本里做转换,这样灵活度最高。导出时注意选择"已确认"的数据,不要把未审核的数据也导出来,否则会引入噪声。

5.2 通过 API 实现自动化拉取

如果标注是持续进行的,每次都手动导出很麻烦。doccano 提供了 REST API,可以写脚本定时拉取已确认的标注数据。

import requests BASE_URL = 'http://your-server:8000' API_TOKEN = 'your_api_token' PROJECT_ID = 1 headers = {'Authorization': f'Token {API_TOKEN}'} url = f'{BASE_URL}/api/projects/{PROJECT_ID}/examples' response = requests.get(url, headers=headers) data = response.json() for item in data['results']: print(item['text'], item.get('label'))

API Token 在用户设置页面可以生成。拉取时注意分页,doccano 默认每页返回一定数量,数据量大时要循环拉取。另外,API 返回的数据包含标注状态,可以只取confirmed状态的,过滤掉未审核的。

5.3 标注数据到训练数据的质量校验

数据导出后不要直接拿去训练,先做一轮质量校验。我通常会检查这几项:标签分布是否合理,有没有某个标签占比超过 80% 的情况;实体边界是否有明显错误,比如实体跨句、实体包含标点;文本长度分布是否正常,有没有超长或超短的异常样本。

这些检查可以用 pandas 快速做:

import pandas as pd df = pd.read_json('exported.jsonl', lines=True) # 检查标签分布 print(df['label'].value_counts()) # 检查文本长度 df['text_len'] = df['text'].str.len() print(df['text_len'].describe())

发现异常后,回到 doccano 里定位到具体数据,修正后重新导出。这个反馈闭环跑顺了,标注质量会一轮比一轮好。

6. 实际使用中踩过的坑与经验总结

6.1 数据丢失的几种典型场景

我遇到过两次数据丢失,都是血泪教训。第一次是容器重建时忘了挂载数据卷,SQLite 文件在容器内部,容器一删数据全没。第二次是数据库迁移时直接覆盖了旧库,没有先备份。

避免数据丢失的核心原则就一条:任何操作前先备份。具体做法是,数据卷必须挂载到宿主机;每天定时 dump 数据库;重大操作(升级、迁移、改配置)前手动备份一次。备份文件不要放在同一台机器上,异地存一份更稳妥。

6.2 性能瓶颈的定位与优化

数据量上到几万条之后,doccano 的界面会变慢,尤其是项目列表页和数据集页。定位下来,瓶颈主要在数据库查询和前端渲染。

优化手段有几个:数据库换成 PostgreSQL 并加索引;前端分页调小,每页显示 20 条而不是 100 条;关闭不必要的实时统计;如果用了反向代理,开启 gzip 压缩。实测下来,这些调整能让几万条数据的项目保持流畅。

6.3 标注员培训与激励的实操心得

工具再好,最终还是要靠人来标。我总结了几条培训经验:新标注员先标 50 条试标数据,通过审核后才能正式上岗;每周开一次短会,同步本周发现的问题和统一口径;建立标注员准确率排行榜,准确率高的给奖励,形成正向激励。

还有一点很重要:不要让标注员长时间连续标注。连续标注超过两小时,准确率会明显下降。我一般安排标注员每小时休息 10 分钟,每天标注时间不超过 6 小时,这样整体效率反而更高。

6.4 什么情况下该考虑换工具

doccano 不是万能的。如果你遇到这几种情况,可能要考虑换方案:需要标注图像、音频、视频等多模态数据;团队规模超过 50 人,需要更细的权限和流程管理;需要和现有的数据平台深度集成,doccano 的 API 满足不了;需要非常定制化的标注界面,源码改造成本太高。

但在纯文本标注、中小团队、快速迭代这些场景下,doccano 依然是我会优先推荐的工具。它的部署简单、上手快、功能够用,这三点在早期项目里比什么都重要。

我在实际使用中最大的体会是:工具只是载体,真正决定标注质量的是规范、流程和人。doccano 帮你把工具这一环的成本降到最低,剩下的精力应该花在标注规范的设计和团队的管理上。把这两件事做好,即使换任何工具,你都能跑出一套高质量的标注流水线。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询