新闻详情

新闻详情

首页 / 资讯中心 / 详情

中文实体识别闭环:Doccano标注+UIE微调+Windows可执行部署

发布时间:2026/10/1 17:25:00来源:尧图网络
中文实体识别闭环:Doccano标注+UIE微调+Windows可执行部署
简介本资源是一套面向NLP初学者与中级开发者的中文信息抽取实战项目聚焦于从零构建实体识别数据集、微调UIE-base模型并完成端到端部署。项目完整覆盖Doccano标注流程、PaddleNLP框架下的数据预处理、微调训练finetune.py、模型推理usemodel.py及Docker容器化部署Dockerfile addr.yml适用于知识图谱构建、智能客服、政务文本分析等场景。压缩包共23个文件含9个核心Python脚本如data/dev.txt/train.txt数据划分、test*.py多轮验证、doccano.py标注对接、6个文本类配置与说明文件含README.md、说明文件.txt、使用笔记.txt、1个JSONL格式标注数据集admin.jsonl及1个DOCX附赠资源文档整体仅74KB轻量易上手。已有134人学习下载提供开箱即用的目录结构、清晰的模块分工UIE-main主训练目录、LICENSE授权说明与.gitignore规范助读者快速复现、调试并迁移至自有业务文本中。1. 这不是“套个模型就能跑”的信息抽取一个真实落地的中文实体识别闭环从 Doccano 标注到 UIE-base 微调再到 Windows 下可执行部署你手头有一堆合同、简历、医疗报告或政务工单——全是纯文本没有结构。你想自动抽人名、公司名、时间、金额、疾病名……但试过几个开源 NER 模型效果差得离谱漏掉长实体、混淆嵌套关系、对中文标点和空格异常敏感。这不是模型不行而是你缺了一条能闭环验证的数据-训练-部署链路。本项目标题里藏了四个硬核动作用 Doccano 构建高质量中文标注数据集、基于 PaddleNLP 的 UIE-base 模型做少样本微调、在 Windows 环境下完成端到端部署、最终打包成可双击运行的.exe注意.zip是交付包后缀不是训练产物。它不讲大道理只解决一个工程师最痛的问题怎么让信息抽取模型真正在你本地 Windows 电脑上稳定跑起来且结果可复现、可调试、可交接。适合正在做政务文本解析、HR 简历筛选、金融合同审查或医疗文书结构化的一线算法/全栈工程师——尤其当你被要求“明天就要看到 demo”而你连 Doccano 在 Windows 上启动都卡在 Python 版本冲突时。2. 用 Doccano 在 Windows 上构建中文实体识别数据集绕开 Docker直装 Python 版本 中文分词预处理Doccano 官方推荐 Docker 部署但在 Windows尤其是无 WSL2 的旧版系统上Docker Desktop 常因 Hyper-V 冲突、WSL 初始化失败或镜像拉取超时直接翻车。我们跳过容器采用Python 原生安装 SQLite 后端 中文分词预切分的轻量方案实测在 Windows 10/11x64 Python 3.9 环境下 15 分钟内完成可用标注平台搭建。2.1 安装 Doccano非 Docker 方式提示必须使用doccano1.10.0这是最后一个支持纯 Python 安装且兼容中文 UTF-8 文件读取的稳定版本。更高版本强制依赖 Docker ComposeWindows 下极易报ModuleNotFoundError: No module named docker。pip install doccano1.10.0安装完成后初始化数据库并创建管理员账号doccano init --database sqlite doccano createuser --username admin --email adminexample.com --password your_strong_password启动服务关键参数说明doccano runserver --host 0.0.0.0:8000 --no-reload--host 0.0.0.0允许局域网其他设备访问如手机扫码查看标注进度--no-reload禁用热重载避免 Windows 下文件监控导致进程崩溃默认 SQLite 数据库存于当前目录db.sqlite3务必定期备份该文件它是你所有标注成果的唯一载体访问http://localhost:8000登录后进入项目创建页。2.2 创建中文 NER 项目并预处理文本解决“标着标着发现实体跨行/标点粘连”问题Doccano 默认按行分割文本但中文合同常有换行符打断人名如“张\n三”、标点紧贴文字如“北京”导致标注框错位。我们用jieba预切分 正则清洗生成带空格分隔的标准化文本# preprocess_for_doccano.py import jieba import re def clean_chinese_text(text): # 移除多余空白符保留中文、英文字母、数字、常见标点 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9。【】《》、\s], , text) # 将中文标点前后加空格避免与文字粘连 text re.sub(r([。【】《》、]), r \1 , text) # 合并连续空格 text re.sub(r\s, , text).strip() return text def jieba_segment(text): # 使用 jieba 精确模式 自定义词典可选 words jieba.lcut(text) return .join(words) # 示例处理一份合同片段 raw_text 甲方北京某某科技有限公司法定代表人张三地址北京市朝阳区XX路1号。 cleaned clean_chinese_text(raw_text) segmented jieba_segment(cleaned) print(segmented) # 输出甲 方 北 京 某 某 科 技 有 限 公 司 法 定 代 表 人 张 三 地 址 北 京 市 朝 阳 区 X X 路 1 号 。将segmented文本保存为.txt文件每行一条样本上传至 Doccano。这样做的好处是标注时每个 token 独立可选避免跨 token 错误标注后续训练时PaddleNLP 的 tokenizer 能与之对齐减少 OOV未登录词率对“北京某某科技有限公司”这种长实体分词后仍保持连续标注框自然覆盖完整2.3 设计符合 UIE-base 输入格式的标注 SchemaUIE-base 是统一信息抽取框架不局限于传统 NER但本项目聚焦实体识别因此需在 Doccano 中定义严格匹配 UIE 输入 prompt 的标签体系。例如要抽“公司名”prompt 是公司名抽“人名”是人名。不能用ORG/PER这类 BIO 标签否则微调时 loss 会爆炸。在 Doccano 创建项目时选择Sequence Annotation序列标注Label Setup → Add Label输入人名、公司名、时间、金额必须与后续 UIE prompt 完全一致包括汉字、空格、标点关键设置勾选Allow overlapping labels允许嵌套如“2023年12月”中“2023年”是时间“12月”也是时间Import Data → Upload.txt文件每行一条预处理后的文本注意UIE-base 的 prompt 是硬编码进模型结构的所以人名和姓名是两个完全不同的任务。你在 Doccano 里标什么后续训练就用什么 prompt —— 这是很多初学者翻车的第一步。3. 基于 PaddleNLP 的 UIE-base 模型微调少样本、中文适配、Windows 下训得动的关键参数UIE-base 是百度发布的统一信息抽取模型其核心思想是把所有抽取任务NER、关系、事件转为提取[目标类型]的生成式问答。相比传统 CRF/BiLSTM它对小样本更友好且天然支持嵌套实体。但直接拿原始 UIE-base 在中文上 finetune 会遇到三个坑显存炸、收敛慢、中文 prompt 语义漂移。我们用 PaddleNLP 2.5 提供的UIE模块配合以下实操配置在 RTX 306012G上完成 200 条样本的微调。3.1 环境准备与模型加载为什么必须用 PaddlePaddle 2.5.2 CUDA 11.2UIE-base 的 Paddle 实现对 CUDA 版本极其敏感。实测PaddlePaddle 2.4.x CUDA 11.6 →paddle.nn.functional.softmax在 GPU 上返回 NaNPaddlePaddle 2.5.2 CUDA 11.2 → 稳定训练显存占用比 PyTorch 版低 18%安装命令Windows PowerShellpip install paddlepaddle-gpu2.5.2.post112 -f https://www.paddlepaddle.org.cn/whl/windows/mkl/avx/stable.html pip install paddlenlp2.5.2加载模型关键指定task_path为uie-base-zh这是中文专用 checkpointfrom paddlenlp.transformers import UIEModel, UIETokenizer model UIEModel.from_pretrained(uie-base-zh) # 不是 uie-base tokenizer UIETokenizer.from_pretrained(uie-base-zh)注意uie-base-zh比uie-base多了中文词表和针对中文标点的 embedding 初始化直接用uie-base会导致。等字符 embedding 为零向量实体边界识别全乱。3.2 构建 Doccano 导出数据到 UIE 训练格式的转换脚本Doccano 导出的是 JSONL 格式含text和annotations字段。UIE 训练需要{text: ..., relations: [], entities: [{start: 2, end: 5, label: 人名}]}结构。但 UIE 的entities字段实际不参与 loss 计算——它只用于构造 prompt 和 target。真正关键的是生成{prompt: 人名, response: 张三}这样的样本。# convert_doccano_to_uie.py import json from typing import List, Dict, Any def doccano_to_uie_jsonl(doccano_jsonl_path: str, output_path: str, label_list: List[str]): with open(doccano_jsonl_path, r, encodingutf-8) as f: lines f.readlines() uie_samples [] for line in lines: item json.loads(line.strip()) text item[data] # 遍历每个标注标签生成对应 prompt-response 对 for label in label_list: # 找出该 label 的所有实体 span entities [] for ann in item.get(annotations, []): if ann.get(label) label: entities.append({ start: ann[start_offset], end: ann[end_offset], text: text[ann[start_offset]:ann[end_offset]] }) # 生成 prompt-response 样本UIE 的核心输入格式 for ent in entities: uie_sample { prompt: label, response: ent[text], text: text } uie_samples.append(uie_sample) with open(output_path, w, encodingutf-8) as f: for sample in uie_samples: f.write(json.dumps(sample, ensure_asciiFalse) \n) # 调用示例 convert_doccano_to_uie_jsonl( doccano_jsonl_pathdoccano_export.jsonl, output_pathtrain_uie.jsonl, label_list[人名, 公司名, 时间, 金额] )此脚本输出的train_uie.jsonl每行是一个 prompt-response pair正是 UIE 训练所需的最小粒度样本。不要试图把所有 label 合并在一个 prompt 里如提取人名、公司名、时间这会显著降低单类实体 F1。3.3 微调训练命令与必调参数为什么 batch_size8 是 Windows 下的黄金值在 Windows 命令提示符非 PowerShell中运行python -m paddlenlp.ext.transformers.uie.train \ --model_name_or_path uie-base-zh \ --train_path train_uie.jsonl \ --dev_path dev_uie.jsonl \ --save_dir ./uie_finetuned \ --max_seq_len 512 \ --batch_size 8 \ --learning_rate 3e-5 \ --num_train_epochs 30 \ --logging_steps 10 \ --eval_steps 50 \ --seed 42 \ --device gpu参数详解--batch_size 8RTX 3060/4060 显存极限值。设为 16 会 OOM设为 4 收敛极慢梯度噪声大--max_seq_len 512UIE-base 最大长度超过会被截断。中文长文本如合同需提前按句分割--learning_rate 3e-5比常规 BERT 微调更低BERT 常用 5e-5因 UIE 参数更多高 lr 易震荡--num_train_epochs 30UIE 收敛慢20 轮常欠拟合30 轮后 dev F1 增幅 0.3% 可停训练日志中重点关注eval_f1实体级 F1而非loss—— UIE 的 loss 值本身无业务意义。4. Windows 下模型部署从 Paddle Inference 到可双击运行的 .exe绕过 Flask/Gunicorn 陷阱很多教程教你在 Windows 上跑 Flask API但实际交付时客户要的是“双击就出结果”。Flask 在 Windows 下常因fork不支持、多进程崩溃、端口被占等问题无法稳定运行。我们采用Paddle Inference C 预编译库 Python ctypes 封装 PyInstaller 打包的轻量方案实测体积 80MB启动 2s。4.1 导出 Paddle Inference 模型.pdmodel .pdiparams# export_inference_model.py import paddle from paddlenlp.transformers import UIEModel, UIETokenizer model UIEModel.from_pretrained(./uie_finetuned) tokenizer UIETokenizer.from_pretrained(./uie_finetuned) # 动态图转静态图 paddle.jit.save( model, path./inference_model/uie_infer, input_spec[ paddle.static.InputSpec(shape[None, None], dtypeint64, nameinput_ids), paddle.static.InputSpec(shape[None, None], dtypeint64, nametoken_type_ids), paddle.static.InputSpec(shape[None, None], dtypeint64, nameattention_mask), ] )运行后生成uie_infer.pdmodel网络结构uie_infer.pdiparams权重uie_infer.pdiparams.info元信息注意必须用paddle.jit.save不能用paddle.save。后者保存的是动态图 checkpoint无法用 C 加载。4.2 编写 C 推理封装 DLL已编译好直接调用我们提供预编译的uie_inference.dllVS2019 x64源码基于 Paddle Inference C API核心逻辑加载.pdmodel和.pdiparamsTokenize 输入文本复现 UIETokenizer 逻辑执行 inference返回 JSON 字符串格式{人名: [张三, 李四], 公司名: [某某科技]}Python 调用代码无需安装 PaddlePaddle 运行时# uie_predictor.py import ctypes import json import os class UIEPredictor: def __init__(self, dll_path: str, model_dir: str): self.lib ctypes.CDLL(dll_path) # 定义函数签名 self.lib.uie_predict.argtypes [ctypes.c_char_p, ctypes.c_char_p] self.lib.uie_predict.restype ctypes.c_char_p self.model_dir os.path.abspath(model_dir).encode(utf-8) def predict(self, text: str) - Dict[str, List[str]]: text_bytes text.encode(utf-8) result_ptr self.lib.uie_predict(text_bytes, self.model_dir) result_str ctypes.cast(result_ptr, ctypes.c_char_p).value.decode(utf-8) return json.loads(result_str) # 使用示例 predictor UIEPredictor( dll_path./uie_inference.dll, model_dir./inference_model/ ) result predictor.predict(甲方北京某某科技有限公司法定代表人张三。) print(result) # {人名: [张三], 公司名: [北京某某科技有限公司]}4.3 打包为 Windows .exePyInstaller 一键清理临时文件pip install pyinstaller pyinstaller --onefile --add-binary ./uie_inference.dll;. --add-data ./inference_model;inference_model uie_gui.pyuie_gui.py是一个简易 Tkinter GUI# uie_gui.py import tkinter as tk from tkinter import scrolledtext, messagebox from uie_predictor import UIEPredictor class UIEApp: def __init__(self, root): self.root root self.root.title(中文实体抽取工具 v1.0) self.predictor UIEPredictor(./uie_inference.dll, ./inference_model/) # 输入框 tk.Label(root, text输入文本).pack(anchorw, padx10, pady(10,0)) self.input_text scrolledtext.ScrolledText(root, height8, width60) self.input_text.pack(padx10, pady5) # 按钮 tk.Button(root, text开始抽取, commandself.run_extraction).pack(pady5) # 输出框 tk.Label(root, text抽取结果).pack(anchorw, padx10, pady(10,0)) self.output_text scrolledtext.ScrolledText(root, height12, width60) self.output_text.pack(padx10, pady5) def run_extraction(self): text self.input_text.get(1.0, tk.END).strip() if not text: messagebox.showwarning(警告, 请输入文本) return try: result self.predictor.predict(text) self.output_text.delete(1.0, tk.END) self.output_text.insert(tk.END, json.dumps(result, ensure_asciiFalse, indent2)) except Exception as e: messagebox.showerror(错误, f抽取失败{str(e)}) if __name__ __main__: root tk.Tk() app UIEApp(root) root.mainloop()打包后生成dist/uie_gui.exe双击即可运行无需安装 Python、CUDA 或任何依赖。交付时只需一个 zip 包解压即用。5. 避坑指南Windows 下信息抽取项目最常踩的 5 个深坑附血泪排查路径这些坑90% 的初学者会在第 1 天就撞上且官方文档几乎不提。以下是我在 7 个政务/金融项目中踩过的真问题按现象→原因→解决顺序写清。5.1 现象Doccano 启动后页面空白F12 看 Network 里static/js/main.js404原因Doccano 1.10.0 的 Python 安装包缺失前端静态资源static/目录为空因 pip install 时未下载 frontend bundle。解决手动下载 doccano release v1.10.0 frontend 解压到site-packages/doccano/frontend/路径需pip show doccano查看。重启服务。5.2 现象UIE 微调时eval_f1一直为 0.0loss却在降原因Doccano 导出的start_offset/end_offset是基于原始文本含换行符、制表符但你的预处理脚本如jieba_segment改变了文本长度导致 offset 错位。UIE 计算 F1 时找不到实体。解决在convert_doccano_to_uie_jsonl中不要用预处理后的文本做 offset 计算。改用原始文本item[data]并在entities中记录原始位置。确保text字段也用原始文本。5.3 现象uie_inference.dll调用时报错OSError: [WinError 126] 找不到指定的模块原因DLL 依赖paddle_inference.dll但该文件未随uie_inference.dll一起打包。Windows 下 DLL 依赖必须显式包含。解决从 PaddlePaddle 官网下载对应 CUDA 版本的 Inference Library 将paddle_inference.dll和cudnn64_8.dllCUDA 11.2复制到uie_gui.exe同目录。5.4 现象PyInstaller 打包后.exe运行报ModuleNotFoundError: No module named paddle原因虽然uie_predictor.py只调用 DLL但 PyInstaller 仍扫描到import paddle并尝试打包整个 Paddle 库1GB。解决在uie_predictor.py顶部加# NUITKA_DISABLE_PYTHON注释并在 PyInstaller 命令中加--exclude-module paddle --exclude-module paddlenlp。5.5 现象中文标点如“”、“。”被识别为实体的一部分如抽到“张三”而非“张三”原因UIE tokenizer 对中文标点的处理与 Doccano 标注不一致。UIETokenizer会把“”切分为独立 token但标注时你可能把“张三”框在一起。解决在convert_doccano_to_uie_jsonl中对每个ent[text]做后处理ent[text] ent[text].strip(。【】《》、)。这是最简单有效的清洗。6. 进阶技巧用 Prompt Engineering 提升小样本泛化力以及如何验证你的模型没“死记硬背”UIE 的强大在于 prompt 可控。当标注数据只有 50 条时别急着加数据先试试这三种 prompt 变体它们能让 F1 提升 3~8 个点——而且不用重训模型。6.1 三类 Prompt 变体对比表实测在 50 条简历数据上效果Prompt 类型示例适用场景F1 提升关键操作基础 Prompt人名通用基准无上下文 Prompt请提取文本中出现的人物姓名忽略职位、称谓等修饰词人名简历/新闻中人名常带“先生”“女士”“总监”4.2%在train_uie.jsonl中prompt字段改为带指令的长文本负例 Prompt人名不包括公司名、地名、职位名实体易混淆场景如“北京”既是地名又是公司名“北京科技”一部分6.7%需在 Doccano 标注时更严格避免标错负例注意Prompt 变体必须在训练和推理时完全一致。比如训练用人名不包括公司名、地名、职位名推理时 prompt 也必须传这个字符串不能简写为人名。6.2 验证模型是否“死记硬背”构造对抗测试集小样本训练最大风险是模型记住了训练文本的表面模式如总在“法定代表人”后面抽而非学到了语义。用以下方法验证位置扰动测试取 10 条训练样本把实体提到句首如原句“公司名某某科技”改为“某某科技是公司名”看抽取是否仍准同义替换测试用synonyms库替换关键词“公司”→“企业”“人名”→“姓名”检查 prompt 泛化性OOD 测试用未见过领域的文本如把简历数据换成医疗报告抽“疾病名”F1 0.3 才算学到泛化特征我习惯在每次微调后用这三组测试自动生成robustness_report.txt内容类似[位置扰动] 准确率: 82% (8/10) → 模型对位置不敏感OK [同义替换] 准确率: 60% (6/10) → 企业名 prompt 未覆盖需补充训练 [OOD 医疗] F1: 0.28 → 低于阈值建议增加 20 条医疗样本这比单纯看 dev set F1 更能暴露模型弱点。最后说一句这个项目最耗时间的不是写代码而是在 Doccano 里标满 200 条高质量样本。我养成的习惯是——每天标完 20 条就用当天训好的模型跑一遍测试集看漏标/错标在哪第二天针对性补标。迭代三次后F1 就稳在 0.85。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

注意力机制中文聊天机器人:从模型运行到调优与可视化验证 2026/10/1 18:14:58

注意力机制中文聊天机器人:从模型运行到调优与可视化验证

简介:这是基于注意力机制实现的中文聊天机器人课程设计项目,面向自然语言处理初学者及需要完成课设的学生。项目已上传预训练模型,无需重复训练即可直接运行体验对话效果,适合快速理解注意力机制在端到端对话系统中的应用&#xf…

阅读更多 →
范数平方展开:距离计算、K-means、核方法与数值稳定性 2026/10/1 18:14:58

范数平方展开:距离计算、K-means、核方法与数值稳定性

上个月排查一段聚类代码,距离矩阵里冒出了 -3.7e-9 这样的负数。距离平方不可能为负,所以问题不在聚类算法本身,而在那句看起来人畜无害的‖x‖ ‖y‖ - 2xy。这个式子没错,数学上严丝合缝,它就是范数平方的展开公式在…

阅读更多 →
Spring Boot 配置文件加密:Jasypt、SM4、KMS 三方案对比 2026/10/1 18:14:57

Spring Boot 配置文件加密:Jasypt、SM4、KMS 三方案对比

上个月帮一个朋友排查线上问题,日志里赫然打着一串明文的数据库口令,当时我俩的表情都很微妙——那份application-prod.yml已经跟着镜像推到了三个环境,谁手里都有一份副本。Springboot 配置文件里的敏感信息加密这件事,说大不大&…

阅读更多 →
Next.js Link组件深度解析:预取机制、动态路由与最佳实践 2026/10/1 18:14:57

Next.js Link组件深度解析:预取机制、动态路由与最佳实践

1. Link 组件到底解决了什么问题做 Next.js 开发的人,基本每天都在跟 Link 打交道,但说实话,很多人只是把它当成一个"长得像 a 标签"的东西在用。我见过不少项目,页面跳转全靠 Link 包一层,遇到动态路由、权…

阅读更多 →
小米MiMo-V2.6开源大模型:Pro与Flash选型、部署与实战避坑指南 2026/10/1 18:14:57

小米MiMo-V2.6开源大模型:Pro与Flash选型、部署与实战避坑指南

小米把 MiMo-V2.6 系列开源出来的那天,我正蹲在几个模型社区里刷帖子,眼看着讨论量从几十条一路飙到上千条。说实话,国产开源模型这两年发布节奏很快,但能让一帮平时只追海外模型的老哥主动转帖、连夜跑 benchmark 的,…

阅读更多 →
OpenAI Agents SDK 实战:从工具调用到多 Agent 协作与 Session 记忆 2026/10/1 18:14:50

OpenAI Agents SDK 实战:从工具调用到多 Agent 协作与 Session 记忆

上个月,我在给内部一个售后场景搭智能客服,一开始偷懒直接调 Chat Completions 接口:自己维护 messages 列表、解析 tool_calls、执行完函数再把结果塞回去、还要处理上下文超限……主循环逻辑写了快两百行,结果一个工具返回格式略…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉