- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
本文面向需要在生产环境中上线 UIE-X 文档信息抽取模型的开发者,完整讲解如何基于 PaddleNLP SimpleServing 将微调后的文档抽取模型封装为 HTTP 服务,包括环境准备、Server 启动、Client 请求、schema 与模型路径定制以及多卡负载均衡部署。读完本文,你将掌握一套可直接复制运行的文档抽取服务化部署方案,并理解其底层基于 FastAPI 与 Taskflow 的实现原理。
本文以仓库中的 基于 PaddleNLP SimpleServing 的服务化部署指南 为核心骨架,配套的 server.py 与 client.py 为可直接运行的示例代码。该部署方案属于 PaddleNLP 信息抽取产业级全流程方案中的"模型部署"环节,与文本抽取场景的部署方案(见 文本抽取 HTTP 部署指南)共同构成完整的服务化部署矩阵。
方案背景:文档抽取场景为何需要服务化部署
在 PaddleNLP 信息抽取应用中,uie-x-base是一个面向纯文本和文档双场景的抽取式模型,支持中英双语,可端到端完成文档、图片、表格的信息抽取。整个应用打通了"数据标注 → 模型训练 → 模型调优 → 预测部署"全流程,其中部署环节的目标是把微调好的模型从 Python 脚本中解放出来,变成一个可供业务系统通过 HTTP 调用的常驻服务。
SimpleServing 正是 PaddleNLP 为这一目标提供的轻量级服务化框架。它基于 FastAPI 构建(源码见 paddlenlp/server/server.py,SimpleServer直接继承FastAPI),开发者只需要编写一个注册了 Taskflow 的server.py,即可通过一条命令行把模型启动为 HTTP 服务,业务方无需接触 PaddlePaddle 与 PaddleNLP 的任何细节,仅凭 HTTP 请求即可获得结构化抽取结果。
典型的应用场景包括:增值税发票信息抽取、报关单关键字段识别、Delivery Note 等单据解析,以及任何"输入一张图片/文档、输出结构化 JSON"的业务诉求。
环境准备
使用带有 SimpleServing 功能的 PaddleNLP 版本(或最新的 develop 版本),安装命令如下:
pip install paddlenlp >= 2.4.4SimpleServing 自 PaddleNLP 2.4.4 起正式具备该能力。安装完成后,可通过paddlenlp server --help确认 CLI 子命令可用,或直接在 Python 中执行from paddlenlp import SimpleServer, Taskflow验证导入是否成功。
需要说明的是,本部署示例运行在文档信息抽取项目目录下,示例代码中的task_path="../../checkpoint/model_best"与image_paths = ["../../data/images/b1.jpg"]均为相对该目录的相对路径,实际使用时请按自身模型与数据存放位置调整。
Server 端:注册并启动文档抽取服务
编写 server.py 注册服务
部署的核心是 server.py。它完成三件事:定义抽取 schema、加载微调模型、注册为可路由的服务。完整代码如下:
from paddlenlp import SimpleServer, Taskflow # The schema changed to your defined schema schema = ["开票日期", "名称", "纳税人识别号", "开户行及账号", "金额", "价税合计", "No", "税率", "地址、电话", "税额"] # The task path changed to your best model path uie = Taskflow( "information_extraction", schema=schema, task_path="../../checkpoint/model_best", ) # If you want to define the finetuned uie service app = SimpleServer() app.register_taskflow("taskflow/uie", uie)逐段解读:
schema声明了需要抽取的字段列表。这里的默认值对应增值税发票的 10 个关键字段,它是 UIE 抽取的"提示词"——模型会按照 schema 中的每一个字段去文档中定位并抽取对应内容;Taskflow("information_extraction", ...)创建信息抽取任务流对象,其中task_path指向微调后的模型权重目录。该目录需包含训练好的model_state.pdparams权重文件(模型微调与导出细节见 文档信息抽取全流程指南);SimpleServer()实例化服务,register_taskflow("taskflow/uie", uie)将 Taskflow 注册到路由taskflow/uie下,注册路径即为后续 Client 请求的 URL 路径。
启动 Server
在simple_serving目录下执行:
paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8189参数说明:
server:app:指向server.py中名为app的SimpleServer实例(模块名:对象名),这是 uvicorn 标准的 ASGI 应用定位语法;--workers 1:工作进程数,示例为 1,可依据机器资源调整;--host 0.0.0.0:监听所有网卡地址,使服务可被外部客户端访问;--port 8189:服务监听端口。
从源码看,paddlenlp server这条命令最终调用的是 paddlenlp/cli/server.py 中的start_backend(app, **kwargs),它把上述参数原样透传给uvicorn.run(app, **kwargs),即由 uvicorn 托管 ASGI 服务生命周期。启动后日志会打印每个启动参数,出现 "Application startup complete" 即表示服务就绪。
Client 端:发起文档抽取请求
启动 Server 后,另开一个终端执行:
python client.pyclient.py 的完整逻辑如下:
import json import requests from paddlenlp.utils.doc_parser import DocParser # Define the document parser doc_parser = DocParser() image_paths = ["../../data/images/b1.jpg"] image_base64_docs = [] # Get the image base64 to post for image_path in image_paths: req_dict = {} doc = doc_parser.parse({"doc": image_path}, do_ocr=False) base64 = doc["image"] req_dict["doc"] = base64 image_base64_docs.append(req_dict) url = "http://0.0.0.0:8189/taskflow/uie" headers = {"Content-Type": "application/json"} data = {"data": {"text": image_base64_docs}} # Post the requests r = requests.post(url=url, headers=headers, data=json.dumps(data)) datas = json.loads(r.text) print(datas)该客户端的关键点:
- 图片编码:使用 PaddleNLP 的 DocParser 解析图片路径,将文档图片转为 base64 编码。这里
do_ocr=False表示不在此处做 OCR,由服务端 UIE-X 模型端到端完成版面理解与抽取; - 请求构造:请求体结构为
{"data": {"text": image_base64_docs}},text字段承载图片 base64 列表,支持一次请求批量提交多张图片; - 请求路径:
http://0.0.0.0:8189/taskflow/uie,其中taskflow/uie必须与 Server 端register_taskflow注册的路由一致,端口 8189 与启动参数对应; - 结果解析:使用
requests发送 JSON POST 请求,并对返回的 JSON 文本解析后打印结构化抽取结果。
整个请求-响应链路为:Client 将图片 base64 化 → POST 到/taskflow/uie→ Server 端 Taskflow 执行 UIE-X 抽取 → 返回结构化 JSON。
Server 自定义参数
替换 schema(抽取字段)
默认 schema 面向增值税发票场景:
schema = ['开票日期', '名称', '纳税人识别号', '开户行及账号', '金额', '价税合计', 'No', '税率', '地址、电话', '税额']实际业务中应替换为自定义字段。从 信息抽取 Taskflow 实现 源码可以看出,schema 不仅支持简单的字段字符串列表(实体抽取),还支持嵌套结构以表达更复杂的抽取任务:
- 关系抽取:
schema = [{"歌曲名称": ["歌手", "所属专辑"]}] - 事件抽取:
schema = [{"地震触发词": ["地震强度", "时间", "震中位置", "震源深度"]}] - 观点抽取:
schema = [{"评价维度": ["观点词", "情感倾向[正向,负向]"]}] - 情感分类:
schema = ['情感倾向[正向,负向]']
服务端内部会将 schema 构建成一棵 SchemaTree(set_schema与_build_tree方法),推理时按树结构逐层遍历,实现多阶段预测(_multi_stage_predict)。修改 schema 后无需改动其他代码,重启服务即生效。
设置模型路径(加载定制模型)
默认加载微调产物:
uie = Taskflow('information_extraction', task_path='../../checkpoint/model_best/', schema=schema)task_path指向包含model_state.pdparams权重文件的目录。若使用 PaddleNLP 内置预训练模型做零样本抽取,可省略task_path,直接通过model="uie-x-base"指定基座。此外 Taskflow 还支持precision参数(如precision='fp16')以半精度方式加载模型,在 GPU 环境下降低显存占用、提升吞吐(相关用法见 文档信息抽取指南 中的"定制模型一键预测"一节)。
多卡服务化预测(负载均衡)
PaddleNLP SimpleServing 支持多卡负载均衡:在注册服务时注册多个分别绑定不同device_id的 Taskflow 实例,Server 会在这些实例间分发请求。示例:
uie1 = Taskflow('information_extraction', task_path='../../checkpoint/model_best/', schema=schema, device_id=0) uie2 = Taskflow('information_extraction', task_path='../../checkpoint/model_best/', schema=schema, device_id=1) service.register_taskflow('uie', [uie1, uie2])这里通过device_id将两个模型实例分别绑定到 GPU 0 和 GPU 1,并以列表形式整体注册。从 SimpleServer.register_taskflow 源码 可以看到,register_taskflow内部首先校验注册对象必须是Taskflow实例或Taskflow列表(单个实例会被自动包装为列表),再交给TaskflowManager统一管理,从而实现对多实例请求的负载均衡调度。
Client 自定义参数
客户端最常调整的参数是待抽取的图片列表:
# Changed to image paths you wanted image_paths = ['../../data/images/b1.jpg']将其替换为业务实际的图片路径即可,如image_paths = ['invoice_1.jpg', 'invoice_2.jpg']。客户端支持批量提交,多张图片会以列表形式随请求体发送,Server 端逐张抽取后一并返回结果。
部署链路与源码佐证
为便于读者深入,将本次部署涉及的关键源码位置汇总如下:
| 环节 | 仓库文件 | 说明 |
|---|---|---|
| 服务注册与启动 | paddlenlp/server/server.py | SimpleServer继承 FastAPI,register_taskflow完成 Taskflow 注册与类型校验 |
| CLI 启动入口 | paddlenlp/cli/server.py | start_backend将--workers/--host/--port透传给uvicorn.run |
| Server 示例 | simple_serving/server.py | 文档抽取服务注册完整示例 |
| Client 示例 | simple_serving/client.py | base64 图片编码与 HTTP POST 请求示例 |
| 抽取核心实现 | paddlenlp/taskflow/information_extraction.py | schema 树构建、多阶段预测、set_schema动态更新 |
| 文档解析工具 | paddlenlp/utils/doc_parser.py | DocParser负责图片解析与 base64 转换 |
| 上游全流程 | 文档信息抽取指南 | 数据标注、模型微调、评估与预测的完整说明 |
| 应用总览 | 信息抽取应用 README | UIE 系列模型能力矩阵与产业级方案总览 |
常见问题排查
- 启动报
ModuleNotFoundError:确认 PaddleNLP 版本 ≥ 2.4.4,且paddlenlp server与 Python 环境一致(注意避免多环境混用 pip)。 - 请求 404:检查 Client 请求 URL 中的路由
taskflow/uie与 Server 端register_taskflow的第一个参数是否完全一致;同时确认端口号与--port启动参数一致。 - 请求连接失败:确认 Server 以
--host 0.0.0.0启动且未开启防火墙拦截;本地调试可改用127.0.0.1。 - 抽取结果为空或字段缺失:优先检查
schema字段命名是否与业务目标一致,以及task_path是否指向包含model_state.pdparams的正确目录;若使用零样本模式,可尝试切换基座模型。
总结
本文完整呈现了基于 PaddleNLP SimpleServing 的文档信息抽取服务化部署方案:从pip install paddlenlp >= 2.4.4的环境准备,到server.py中通过SimpleServer注册 UIE-X 任务流并启动 uvicorn 服务,再到client.py中以 DocParser 完成图片编码并发出 HTTP 请求的闭环,最后深入讲解了 schema 替换、自定义模型路径与多卡负载均衡三类自定义参数及其底层源码逻辑。开发者只需替换 schema、模型路径与图片路径三处配置,即可将该方案复用到任意文档抽取业务场景,实现模型的快速上线与迭代。
- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
相关推荐
FF14动画跳过插件:告别冗长副本动画的终极解决方案
FF14动画跳过插件:告别冗长副本动画的终极解决方案 还在为《最终幻想14》国服副本中那些无法跳过的动画而烦恼吗?FFXIV_ACT_CutsceneSkip插
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPGetQzonehistory:QQ空间历史说说免费备份方案
GetQzonehistory:QQ空间历史说说免费备份方案 你有多久没翻过 QQ 空间里那些老说说了?想逐条找回文字、配图和评论时,手动复制既慢又容易漏。Ge
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPTimesFM 2.5架构深度解析:时间序列基础模型的设计原理与性能优化
TimesFM 2.5架构深度解析:时间序列基础模型的设计原理与性能优化 TimesFM(Time Series Foundation Model)是Googl
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考