- 人工智能
- 大模型
- 微调
- 模型推理服务
【免费下载链接】PaddleFormers
PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.
导读
本文以 PaddleFormers 仓库中的ernie_gen_poetry模型模块为核心,系统讲解基于 ERNIE-GEN 框架的中文古诗生成模型的原理、安装方式、命令行与 Python API 预测方法,以及如何借助 PaddleHub Serving 将模型一键部署为在线诗歌生成服务。读完本文,你将掌握从模型加载到 beam search 解码、再到 HTTP 服务调用的完整实战链路,并理解 ERNIE-GEN 在生成任务上的核心机制。
一、模型基本信息与 ERNIE-GEN 框架
ernie_gen_poetry是一个文本-文本生成类 PaddleHub 模型模块,其基本信息如下表所示:
| 模型名称 | ernie_gen_poetry |
|---|---|
| 类别 | 文本-文本生成 |
| 网络 | ERNIE-GEN |
| 数据集 | 开源诗歌数据集 |
| 是否支持 Fine-tuning | 否 |
| 模型大小 | 422M |
| 最新更新日期 | 2021-02-26 |
| 数据指标 | - |
ERNIE-GEN 的核心机制
该模块基于 ERNIE-GEN(An Enhanced Multi-Flow Pre-training and Fine-tuning Framework for Natural Language Generation)框架构建。ERNIE-GEN 是面向生成任务的预训练-微调框架,其核心创新点包括:
- span-by-span 生成任务:首次在预训练阶段加入 span-by-span 生成任务,让模型每次能够生成一个语义完整的片段,而不是逐词零散生成;
- 填充式生成机制(Infilling)与噪声感知机制(Noise-aware):在预训练和微调过程中,通过这两种机制缓解"曝光偏差"(exposure bias)问题,即训练与推理阶段解码分布不一致带来的误差累积;
- 多片段-多粒度目标文本采样策略:增强源文本和目标文本的关联性,加强了编码器和解码器的交互。
ernie_gen_poetry正是采用开源诗歌数据集对 ERNIE-GEN 进行微调后得到的诗歌生成模型,输入一句诗歌开头,即可续写出对仗工整的古诗下文。模型模块的元信息定义在 module.py 中,summary字段明确描述了其用途:"This module has fine-tuned for poetry generation task"。
二、安装与环境准备
1、环境依赖
使用ernie_gen_poetry需要满足以下依赖版本:
paddlepaddle >= 2.0.0paddlehub >= 2.0.0,安装方式参见 PaddleHub 安装文档paddlenlp >= 2.0.0
从 module.py 的源码可以看出,模型加载链路依赖paddlehub与paddlenlp两个关键库:前者负责 Module 注册、命令行与 Serving 管理,后者提供ErnieTokenizer和ErnieForGeneration预训练模型实现。
2、安装模型
通过 PaddleHub 命令行一条命令即可完成模型安装:
$ hub install ernie_gen_poetry安装完成后,模型会被默认放置在${HUB_HOME}/.paddlehub/modules目录下(若未设置${HUB_HOME}环境变量,则默认存放在主目录$HOME下),之后即可通过命令行或 Python API 调用。
如果安装过程遇到问题,可参考:
- 零基础 Windows 安装
- 零基础 Linux 安装
- 零基础 MacOS 安装
3、环境验证
安装完成后,可用hub list命令确认模型是否成功安装到本地(详见 PaddleHub 命令行工具说明),并检查 CUDA 环境:若计划使用 GPU 预测,需确保已安装paddlepaddle-gpu并设置CUDA_VISIBLE_DEVICES环境变量。
三、模型 API 预测
ernie_gen_poetry提供命令行与 Python API 两种预测方式,二者最终都会走到 module.py 中由@serving装饰器标记的generate方法。
1、命令行预测
$ hub run ernie_gen_poetry --input_text="昔年旅南服,始识王荆州。" --use_gpu True --beam_width 5命令行参数说明:
--input_text:诗歌的开头,即待续写的起始文本;--use_gpu:是否采用 GPU 进行预测;--beam_width:beam search 宽度,决定每个诗歌开头输出的下文数目。
从源码看,命令行入口由@runnable装饰器标记的run_cmd实现(module.py):它会解析--use_gpu(通过ast.literal_eval将字符串转为布尔值)与--beam_width(int 类型),再调用generate方法返回结果。更多命令行用法可参考 PaddleHub 命令行指令。
2、预测代码示例
import paddlehub as hub module = hub.Module(name="ernie_gen_poetry") test_texts = ['昔年旅南服,始识王荆州。', '高名出汉阴,禅阁跨香岑。'] results = module.generate(texts=test_texts, use_gpu=True, beam_width=5) for result in results: print(result) # ['一见便倾盖,论交更绸缪。别来二十年,日月如奔流。人生会合难,俯仰成春秋。', '一见便倾盖,论交更绸缪。别来二十年,日月如奔流。人生会合难,况乃岁月遒。君家富文史,我老无田畴。相逢不相识,各在天一陬。人生百年内,聚散如浮沤。况我与夫子,相逢', '一见便倾盖,论交更绸缪。别来二十年,日月如奔流。人生会合难,况乃岁月遒。君家富文史,我老无田畴。相逢不相识,各在天一陬。人生百年内,聚散如浮沤。况我与君别,飘零', '一见便倾盖,论交更绸缪。别来二十年,日月如奔流。人生会合难,况乃岁月遒。君家富文史,我老无田畴。相逢不相识,各在天一陬。人生百年内,聚散如浮沤。况复各异乡,各在', '一见便倾盖,论交更绸缪。别来二十年,日月如奔流。人生会合难,况乃岁月遒。君家富文史,我老无田畴。相逢不相识,各在天一陬。人生百年内,聚散如浮沤。况复各异乡,风雨'] # ['地僻无尘到,山高见水深。钟声传远寺,塔影落前林。欲问西来意,庭前柏树林。', '地僻无尘到,山高见水深。钟声传远寺,塔影落前林。欲问西来意,庭前柏树阴。', '地僻无尘到,山高见水深。钟声传远寺,塔影落前林。欲问西来意,庭前有桂林。', '地僻无尘到,山高见水深。钟声传远寺,塔影落前林。欲问西来意,庭前柏正森。', '地僻无尘到,山高见水深。钟声传远寺,塔影落前林。欲问西来意,庭前有桂阴。']可以看到,对于每个诗歌开头,模型都会基于beam_width=5输出 5 个候选下文,且续写的诗句保持了五言对仗、押韵等古诗特征。
3、generate API 详解
def generate(texts, use_gpu=False, beam_width=5):- 功能:预测 API,输入诗歌开头,输出诗歌下文。
- 参数:
texts(list[str]):诗歌的开头列表;use_gpu(bool):是否使用 GPU 预测;若使用 GPU,请先设置CUDA_VISIBLE_DEVICES环境变量;beam_width(int):beam search 宽度,决定每个诗歌开头输出的下文数目。
- 返回:
results(list[list[str]]):诗歌下文列表,每个诗歌开头会生成beam_width个下文。
输入校验与前置检查
generate内部首先会对输入做严格校验(module.py):输入必须是"元素非空且均为字符串的列表",否则抛出ValueError(这一检查在 1.0.2 版本中专门得到完善)。随后对每个输入文本进行诗歌格式检查并给出警告:
- 若文本不含
,或。,会被判定为不完整的诗句,可能产生不合理输出; - 若逗号前后字数不等(缺乏对仗),同样会提示可能产生不合理输出;
- 若文本包含非中文字符(除
,、。外),也会给出警告。
设备设置与模型加载
在 GPU 使用上,源码做了兜底逻辑:如果use_gpu=True但环境变量CUDA_VISIBLE_DEVICES未设置,会自动回退为 CPU并打印日志警告(module.py),随后通过paddle.set_device('gpu')或paddle.set_device('cpu')完成设备切换。
模型加载流程为:ErnieForGeneration.from_pretrained("ernie-1.0")加载 ERNIE 基础模型,再通过paddle.load加载微调后的诗歌生成权重ernie_gen_poetry.pdparams,最后用set_dict注入权重(module.py)。同时,tokenizer 会将[PAD]、[UNK]特殊 token 在输出阶段替换为空字符串,避免解码结果中出现占位符。
四、解码原理:beam search 续写流程
诗歌续写的核心解码逻辑位于 decode.py 中。模块主流程如下(module.py):
- 对输入文本调用
tokenizer.encode得到input_ids与token_type_ids; - 调用
beam_search_infilling执行填充式 beam search 解码,关键解码参数包括:eos_id=[SEP]、sos_id=[CLS]、attn_id=[MASK]、pad_id=[PAD]、unk_id=[UNK];max_decode_len=80(最大解码长度)、max_encode_len=20(最大编码长度);beam_width(由用户指定)、tgt_type_id=1;
- 将解码得到的 token id 序列通过
rev_lookup映射回文本,截断到[SEP]位置后拼接输出。
beam_search_infilling(decode.py)是典型的束搜索实现,其中几个关键机制值得注意:
- cache tile 与 reorder:首轮将编码器输出的 KV cache 按
beam_width平铺(tile_),每轮解码后按父 beam id 重排(reorder_),实现多束共享编码器输出的高效推理; - mask_prob 掩码机制:对已结束(finished)的束,将其非
[EOS]位置的概率压到-9999.,防止已结束束继续产生新词; - hyp_score 长度惩罚:
log_probs / pow((5 + length) / 6, length_penalty),对长句做适度惩罚,默认length_penalty=1.0; - 首步约束:第一步只在束 0 上扩展(
is_first_step分支),保证搜索起点唯一; - gather_tree 回溯:解码结束后通过
gather_tree按父束 id 回溯整棵搜索树,得到每个束的完整生成序列。
此外,decode.py 还提供了greedy_search_infilling(贪心搜索)实现(decode.py),其结构与 beam search 类似但不维护束状态,可作为对照理解 beam search 的优势:束搜索保留多个候选路径,能显著降低贪心搜索的局部最优风险,这也是诗歌续写这类开放式生成任务通常选用 beam search 的原因。
五、服务部署:一键启动在线诗歌生成服务
PaddleHub Serving 可以部署一个在线诗歌生成服务,将该接口用于在线 Web 应用,无需自行搭建网络框架。
第一步:启动 PaddleHub Serving
$ hub serving start -m ernie_gen_poetry -p 8866执行该命令后即完成服务化 API 的部署,默认端口号为 8866。
NOTE:如使用 GPU 预测,需在启动服务之前设置CUDA_VISIBLE_DEVICES环境变量,否则不需要设置。
从 PaddleHub Serving 一键服务部署文档 可以看到,Serving 底层基于 Flask 与 Gunicorn 处理网络请求,后端直接调用 PaddleHub 预测接口,并支持通过--use_multiprocess与--workers利用多核提升并发能力。需要说明的是,--use_gpu与--use_multiprocess不可共用,且 Windows 操作系统只支持单进程方式。
第二步:发送预测请求
配置好服务端后,以下代码即可实现发送预测请求并获取预测结果:
import requests import json # 发送HTTP请求 data = {'texts':['昔年旅南服,始识王荆州。', '高名出汉阴,禅阁跨香岑。'], 'use_gpu':False, 'beam_width':5} headers = {"Content-type": "application/json"} url = "http://127.0.0.1:8866/predict/ernie_gen_poetry" r = requests.post(url=url, headers=headers, data=json.dumps(data)) # 保存结果 results = r.json()["results"] for result in results: print(result) # serving运行结果同本地运行结果(见上)请求 URL 的格式为http://127.0.0.1:<port>/predict/<MODULE>,其中<MODULE>为模型名;请求体中的texts、use_gpu、beam_width参数与本地generateAPI 一一对应。停止服务时,使用hub serving stop --port 8866即可,不指定端口则默认关闭 8866 端口的服务。更多信息可参考 服务部署文档。
六、扩展:从 ernie_gen 微调自己的文本生成模型
虽然ernie_gen_poetry本身不支持 Fine-tuning(其定位是直接可用的成品模型),但同目录下的基础模块ernie_gen提供了完整的微调链路,可用于快速制作特定场景的生成模型。其说明见 ernie_gen/README.md,关键 API 为:
module.finetune( train_path='train.txt', dev_path='dev.txt', max_steps=300, batch_size=2 ) module.export(params_path=result['last_save_path'], module_name="ernie_gen_test", author="test")其中训练数据格式为"序号\t输入文本\t标签",例如"1\t床前明月光\t疑是地上霜",注意\t不能使用空格替代。PaddleHub 官方已提供多个微调好的生成模型,除本文的诗歌生成外,还包括对联生成、情话生成、藏头诗生成等,说明 ERNIE-GEN 框架具备较强的任务迁移能力。
七、更新历史
| 版本 | 更新内容 |
|---|---|
| 1.0.0 | 初始发布 |
| 1.0.1 | 修复 Windows 中的编码问题 |
| 1.0.2 | 完善 API 的输入文本检查 |
| 1.1.0 | 修复兼容性问题 |
如需安装指定版本,可使用带版本号的安装命令:
$ hub install ernie_gen_poetry==1.1.0总结
ernie_gen_poetry是 ERNIE-GEN 生成框架在中文古诗创作场景下的直接落地成果:依托 span-by-span 预训练、填充式生成与噪声感知机制,结合开源诗歌数据集微调,实现了高质量的古诗续写能力。在 PaddleFormers 仓库中,你可以通过 module.py 查看完整的模型加载、输入校验与调用链,通过 decode.py 理解 beam search 解码细节,并通过hub run、Python API 或 PaddleHub Serving 三种方式快速完成本地预测与在线服务部署。
- 人工智能
- 大模型
- 微调
- 模型推理服务
【免费下载链接】PaddleFormers
PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.
相关推荐
PaddleFormers 藏头诗生成实战指南:ERNIE-GEN 预训练语言模型 ernie_gen_acrostic_poetry 的安装、预测与服务化部署
PaddleFormers 藏头诗生成实战指南:ERNIE GEN 预训练语言模型 ernie_gen_acrostic_poetry 的安装、预测与服务化部署
人工智能大模型微调模型推理服务PaddleFormers 人像抠图实战:modnet_mobilenetv2_matting 模块的安装、API 预测与在线服务部署
PaddleFormers 人像抠图实战:modnet_mobilenetv2_matting 模块的安装、API 预测与在线服务部署 导读 本文以 Paddl
人工智能大模型微调模型推理服务PaddleFormers 中 ERNIE 2.0 Large 预训练语义模型(ernie_v2_eng_large)实战指南:安装、预测 API 与服务化部署
PaddleFormers 中 ERNIE 2.0 Large 预训练语义模型(ernie_v2_eng_large)实战指南:安装、预测 API 与服务化部署
人工智能大模型微调模型推理服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考