- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
本篇文章围绕 PaddleNLPpaddlenlp.taskflow.text_generation模块及其 API 参考页(paddlenlp.taskflow.text_generation.rst)展开,完整剖析 Taskflow 框架中文本生成任务的类设计、预置模型、few-shot 构造、静态图推理链路与结果解码机制。读完本文,你将掌握TextGenerationTask的内部工作原理,并能在实际项目中直接使用生成式问答(question_answering)与智能写诗(poetry_generation)两个开箱即用的一键预测能力。
一、text_generation 模块在 Taskflow 中的定位
paddlenlp.taskflow.text_generation是 PaddleNLP Taskflow 一键预测体系中的文本生成任务实现模块。API 参考文档 paddlenlp.taskflow.text_generation.rst 通过 Sphinx 的automodule指令自动生成该模块的成员文档,其技术主体即 text_generation.py 中的TextGenerationTask类。
在 Taskflow 的注册表 taskflow.py 中,文本生成能力被拆分为两个面向不同场景的上层任务,均由该模块提供基类实现:
| 任务名 | 调用方式 | 任务类 | 注册行号 |
|---|---|---|---|
| 生成式问答 | Taskflow("question_answering") | QuestionAnsweringTask | taskflow.py#L164-L175 |
| 智能写诗 | Taskflow("poetry_generation") | PoetryGenerationTask | taskflow.py#L140-L151 |
两者共用同一个预置中文生成模型gpt-cpm-large-cn,并都继承自TextGenerationTask,因此从 question_answering.py 与 poetry_generation.py 的源码可以看到,两个子类本身几乎为空实现,仅定义各自任务的usage示例文本与模型下载 URL,全部逻辑沉淀在基类中——这正是TextGenerationTask作为"一次实现、多任务复用"的模块价值的体现。
二、TextGenerationTask 类设计与初始化流程
TextGenerationTask继承自 Taskflow 的抽象基类Task(定义于 task.py),类注释明确说明其职责是"predict the question or chinese poetry"(生成式问答或中文诗歌续写)。构造函数 text_generation.py#L43-L54 的关键流程如下:
- 默认走静态图推理:
self._static_mode = True,优先使用 Paddle Inference 静态模型执行预测,以获得更好的部署性能。 - 下载预置模型参数:当处于静态模式时,调用
download_file从 URLS 字典 中声明的地址下载gpt-cpm-large-cn_params.tar,并以 md5 值5aad6f81053cfdbba4797f044fcf66d1做完整性校验;文件会被解压到~/.paddlenlp/taskflow/下的任务路径中(路径拼装逻辑见 task.py#L79-L85)。 - 构建推理模型或加载静态模型:静态模式调用
_get_inference_model()读取/转换 Paddle Inference 模型;动态模式则调用_construct_model构建动态图模型。 - 构建 Tokenizer:见下文"分词器选择"小节。
- 记录生成任务类型:
self.kwargs["generation_task"] = task,这是后续 few-shot 模板选择的关键依据。
2.1 分词器选择(_construct_tokenizer)
text_generation.py#L71-L80 中,分词器按模型名分派:
gpt-cpm-large-cn→GPTChineseTokenizer(基于 SentencePiece + jieba 的中文 GPT 分词器,定义于 tokenizer.py#L87);- 其他模型 → 通用
GPTTokenizer。
GPTChineseTokenizer值得注意的细节:它内部用 jieba 对中文文本进行粗切分,再把空格与换行分别映射为特殊字符(" \n"→"\u2582\u2583"),最后由 SentencePiece 模型完成子词编码。其eol_token默认取"\u2583"(换行 token),对应的eol_token_id属性(tokenizer.py#L156-L160)会被 GPT 解码模型用作"终止生成"的判定信号。
2.2 模型构建(_construct_model)
text_generation.py#L62-L69 在动态模式下构造GPTForGreedyGeneration.from_pretrained(self.model, max_predict_len=32),即最大预测长度固定为 32 个 token,并置为eval()模式。GPTForGreedyGeneration是定义于 modeling.py#L1366 的贪心解码专用模型,我们将在第五节详细展开。
2.3 静态图输入规格(_construct_input_spec)
text_generation.py#L56-L60 声明了静态图转换时的输入规格:
self._input_spec = [paddle.static.InputSpec(shape=[None, None], dtype="int64", name="token_ids")]即模型只接收一个形状为[batch_size, seq_len]的int64型 token id 矩阵作为输入,这与后文_run_model中通过self.input_handles[0].copy_from_cpu(ids)喂入的数据完全对应。
三、基于 CPM 的预置模型:gpt-cpm-large-cn
文本生成任务唯一预置模型为gpt-cpm-large-cn。根据 GPT 模型汇总表 的官方说明,该权重为中文 GPT 模型,结构为32 层、2560 hidden、32 头、约 2.6B 参数,在中文语料上预训练。官方文档在 taskflow.md 中将其描述为"最大中文开源 CPM 模型",用于完成问答与写诗两个生成任务。
模型权重与 SentencePiece 词表资源分别在 text_generation.py#L26-L31 的URLS与 tokenizer.py#L119-L127 的pretrained_resource_files_map中登记,均通过from_pretrained/download_file机制自动获取。
四、核心推理链路:_preprocess → _run_model → _postprocess
与其他 Taskflow 任务一致,TextGenerationTask通过 task.py#L567-L571 的__call__把输入依次送入预处理、模型运行、后处理三个抽象方法,完成"原始文本 → 模型结果 → 任务结果"的端到端转换。
4.1 预处理:few-shot 模板与批处理(_preprocess)
text_generation.py#L82-L126 实现了预处理,包含三个关键步骤:
(1)输入合法性检查:调用基类的_check_input_text(task.py#L434-L452),支持单个字符串或字符串列表,空文本会被拒绝。
(2)few-shot 模板构造:核心函数select_few_shot_input(text_generation.py#L93-L102)按generation_task选择不同的前缀模板:
生成式问答(
question_answering):问题:中国的首都是哪里?答案:北京。 问题:{} 答案:智能写诗(
poetry_generation):默写古诗: 大漠孤烟直,长河落日圆。 {}generation_task的取值直接来自构造时写入的self.kwargs["generation_task"](即调用 Taskflow 时的任务名),若传入question_answering、poetry_generation之外的值会抛出ValueError("The generation task must be question or poetry")。随后每个输入文本通过pre_input.format(input_text)拼入模板,再经 tokenizer 编码为input_ids,并记录序列长度len(ids)。
(3)批处理与 Padding:通过 batchify_fn 将同一个 batch 内的样本统一处理:
batchify_fn = lambda samples, fn=Tuple( Pad(axis=0, pad_val=0, dtype="int64"), Stack(dtype="int64"), # seq_len ): fn(samples)其中Pad(axis=0, pad_val=0)沿序列维度(axis=0,即第 0 维为序列长度)用 0 补齐到 batch 内最大长度,Stack负责堆叠序列长度张量。batch 的划分由batch_size控制,默认值为 1(从self.kwargs读取),最终输出字典中包含text(原始输入)与data_loader(分好 batch 的样例列表)。
4.2 模型运行:静态图 Paddle Inference(_run_model)
text_generation.py#L128-L144 以static_mode_guard()上下文(utils.py#L116-L120,内部先paddle.enable_static()后paddle.disable_static())切换到静态图模式,逐 batch 执行:
self.input_handles[0].copy_from_cpu(ids) # 把 batch token ids 拷贝进输入句柄 self.predictor.run() # 运行 Paddle Inference 预测器 result = self.output_handle[0].copy_to_cpu().tolist()预测器本身由基类_prepare_static_mode(task.py#L216-L262)按设备类型配置:CPU 上会enable_mkldnn()、GPU 上enable_use_gpu(100, device_id),同时统一开启 IR 优化、新执行器与内存优化。推理得到的是生成 token id 序列,连同每条样本的真实输入长度lens一起存入inputs,供后处理使用。
4.3 后处理:token id 解码为文本(_postprocess)
text_generation.py#L146-L158 完成最终解码:
single_result["text"] = inputs["text"][index] # 原始输入 single_result["answer"] = self._tokenizer.convert_ids_to_string( preds[index][seq_len:-1] # 截掉输入部分,丢弃最后的终止符 )关键点在于preds[index][seq_len:-1]的切片逻辑:
preds[index]是模型输出的完整 token id 序列(输入 + 生成部分);seq_len是当前样本的输入长度,preds[index][seq_len:-1]只保留新生成的 token;- 末尾的
-1丢弃最后一个 token——它通常是eol_token_id(换行终止符)。
最终每条样本返回{"text": 原问题/上句, "answer": 生成的答案/下句}结构的字典,批量输入则返回字典列表。
五、底层解码机制:GPTForGreedyGeneration
TextGenerationTask的文本生成能力最终由 GPTForGreedyGeneration 承担。类注释明确指出它"use the greedy strategy and generate the output sequence with highest probability"(贪心策略,逐步生成概率最高的 token)。
其forward(modeling.py#L1434-L1458)的循环结构清晰展示了贪心解码过程:
- 对输入
input_ids做一次前向,得到 logits 与cached_kvs; - 取
output[:, -1, :](最后一个位置的 logits),paddle.argmax得到当前步最可能的 tokennid,拼接到src_ids; - 以
nid为输入、携带past_key_values=cached_kvs继续前向(即KV Cache 增量解码,避免重复计算已生成部分); - 循环直到生成长度达到
max_predict_len(此处为 32),或当前 token 等于self.eol_token_id(换行符,对应中文 CPM 模型的"\u2583")提前终止。
从 modeling.py#L1416-L1432 还可以看到,语言模型头直接复用word_embeddings.weight做paddle.matmul(..., transpose_y=True),即典型的tied embedding / weight tying设计——输出词表概率分布由嵌入矩阵转置点乘得到。
六、实战:生成式问答与智能写诗
Taskflow 官方文档 taskflow.md 以及 question_answering.py、poetry_generation.py 中的usage文档字符串给出了可直接运行的官方示例。
6.1 生成式问答
from paddlenlp import Taskflow qa = Taskflow("question_answering") # 单条输入 qa("中国的国土面积有多大?") # [{'text': '中国的国土面积有多大?', 'answer': '960万平方公里。'}] # 批量输入(多条样本一次推理,平均速度更快) qa(["中国国土面积有多大?", "中国的首都在哪里?"]) # [{'text': '中国国土面积有多大?', 'answer': '960万平方公里。'}, # {'text': '中国的首都在哪里?', 'answer': '北京。'}]6.2 智能写诗
from paddlenlp import Taskflow poetry = Taskflow("poetry_generation") # 单条输入:给定上句,续写下句 poetry("林密不见人") # [{'text': '林密不见人', 'answer': ',但闻人语响。'}] # 批量输入 poetry(["林密不见人", "举头邀明月"]) # [{'text': '林密不见人', 'answer': ',但闻人语响。'}, # {'text': '举头邀明月', 'answer': ',低头思故乡。'}]示例中模型的输出实际上是在"问题 + 答案模板"或"古诗续写模板"基础上做续写,再由_postprocess剥离输入前缀与终止符得到纯答案文本。
6.3 可配置参数
根据 taskflow.md 的说明与源码实现,本任务主要支持以下参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
batch_size | 1 | 批处理大小,批量输入多条样本可提升推理吞吐,请结合机器内存/显存调整 |
model | gpt-cpm-large-cn | 任务使用的模型名,不传则使用注册表默认值 |
task_path | None | 自定义本地模型路径,传入后跳过自动下载,改用用户模型 |
device_id | 0 | GPU 等设备 ID,由Taskflow统一透传 |
其中batch_size在 text_generation.py#L90 从self.kwargs读取;model与task_path的默认/自定义逻辑位于 taskflow.py#L834-L867 与 task.py#L79-L85。任务注册表同时记录了task_flag(如question_answering-gpt-cpm-large-cn)与task_priority_path(gpt-cpm-large-cn),前者用于资源下载校验,后者决定本地缓存目录布局。
七、从源码理解任务扩展方式
虽然TextGenerationTask当前只服务问答与写诗两个场景,但模块结构天然支持扩展新的生成式任务:
- 子类化
TextGenerationTask:像QuestionAnsweringTask(question_answering.py#L42)与PoetryGenerationTask(poetry_generation.py#L41)一样,只需提供usage与模型URLS; - 在
TASKS注册表登记:在 taskflow.py#L48 的TASKS字典中新增任务名,指向任务类、task_flag与可选task_priority_path; - 在
select_few_shot_input中补充模板:在 text_generation.py#L93-L102 的模板选择逻辑中为新任务增加 few-shot 前缀(注意需同步放开 L95-L96 的任务名校验白名单)。
由此可见,few-shot 模板 + 通用 GPT 续写模型的组合是文本生成任务可复用的核心范式:模型本身不区分任务,任务语义全部由输入模板编码。
八、小结
paddlenlp.taskflow.text_generation模块以TextGenerationTask为统一基类,封装了"静态图推理优先 + CPM 中文生成模型 + few-shot 模板 + 贪心解码 + 结果解码"的完整文本生成链路,并向上派生出question_answering(生成式问答)与poetry_generation(智能写诗)两个开箱即用的 Taskflow 任务。对于开发者而言,既可以直接调用Taskflow完成中文问答与古诗续写,也可以参照 text_generation.py、question_answering.py 的写法快速扩展新的生成式应用场景。相关官方示例与参数说明还可进一步参考 docs/zh/model_zoo/taskflow.md 与 GPT 模型汇总。
- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
相关推荐
PaddleNLP 文本纠错 Taskflow:基于 ERNIE-CSC 拼音特征的端到端中文拼写纠错实战
PaddleNLP 文本纠错 Taskflow:基于 ERNIE CSC 拼音特征的端到端中文拼写纠错实战 导读 本文围绕 PaddleNLP 的 Taskfl
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPPaddleNLP 大模型文本生成快速上手:基于 AutoTokenizer 与 AutoModelForCausalLM 的 Qwen2 实战指南
PaddleNLP 大模型文本生成快速上手:基于 AutoTokenizer 与 AutoModelForCausalLM 的 Qwen2 实战指南 Paddl
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPWand 高级功能免费解锁:本地补丁 3 步跑通,手机远程面板也能接
Wand 高级功能免费解锁:本地补丁 3 步跑通,手机远程面板也能接 Wand(WeMod)高级功能免费解锁,靠的是本地补丁:工具只改写你自己电脑里客户端的功能
桌面应用前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考