☰
PaddleFormers 中的 ERNIE-GEN 诗歌生成模型:ernie_gen_poetry 的安装、预测与在线服务部署实战
2026/9/25 2:03:34 网站建设 项目流程
  • 人工智能
  • 大模型
  • 微调
  • 模型推理服务

【免费下载链接】PaddleFormers

PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleFormers
点击查看免费下载

导读

本文以 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.0
  • paddlehub >= 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):

  1. 对输入文本调用tokenizer.encode得到input_ids与token_type_ids;
  2. 调用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;
  3. 将解码得到的 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.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleFormers
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询