paddle版本问题
bug
### Describe the bug
使用3.0以下的话,examples中ernie_csc目录下可以按照项目中执行,但是当paddle3.0以后模型导出和预测需修改如下:
export_model.py
import argparse
import os
import paddle
from paddle.static import InputSpec
from paddlenlp.data import Vocab
from paddlenlp.transformers import ErnieModel
import sys
sys.path.append('../..')
from pycorrector.ernie_csc.model import ErnieForCSC
parser = argparse.ArgumentParser()
parser.add_argument("--params_path", type=str, default='./checkpoints/best_model.pdparams',
help="Path to trained model parameters.")
parser.add_argument("--output_path", type=str, default='./infer_model/static_graph_params',
help="Path to save the static graph model (Paddle 3.x uses .json + .pdiparams).")
parser.add_argument("--model_name_or_path", type=str, default="ernie-1.0", choices=["ernie-1.0"])
parser.add_argument("--pinyin_vocab_file_path", type=str, default="pinyin_vocab.txt")
args = parser.parse_args()
def main():
# 加载拼音词表
pinyin_vocab = Vocab.load_vocabulary(
args.pinyin_vocab_file_path, unk_token='[UNK]', pad_token='[PAD]')
# 加载预训练 ERNIE
ernie = ErnieModel.from_pretrained(args.model_name_or_path)
# 构建 CSC 模型
model = ErnieForCSC(
ernie,
pinyin_vocab_size=len(pinyin_vocab),
pad_pinyin_id=pinyin_vocab[pinyin_vocab.pad_token]
)
# 加载训练参数
model_dict = paddle.load(args.params_path)
model.set_dict(model_dict)
model.eval()
# 转静态图
model = paddle.jit.to_static(
model,
input_spec=[
InputSpec([None, None], "int64", "input_ids"),
InputSpec([None, None], "int64", "pinyin_ids")
],
full_graph=True
)
# 创建输出目录
output_dir = os.path.dirname(args.output_path)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 保存模型
paddle.jit.save(model, args.output_path)
print(f"模型已保存为 {args.output_path}.json + {args.output_path}.pdiparams")
predict.py
# -*- coding: utf-8 -*-
import paddle
from paddlenlp.data import Vocab, Pad, Stack, Tuple
from paddlenlp.transformers import ErnieTokenizer
from functools import partial
from pycorrector.ernie_csc.utils import convert_example, parse_decode
# Paddle 3.x 支持直接用 CPU 或 GPU
# paddle.set_device("gpu") # 如果有可用 GPU 且 cuda/cuDNN 环境正确
paddle.set_device("gpu") # 遇到 CUDA/cuDNN 兼容问题可以临时使用 CPU
class Predictor:
def __init__(self, model_path, tokenizer, pinyin_vocab, max_seq_length=64):
self.max_seq_length = max_seq_length
# 加载 Paddle 3.x 导出的静态图模型
self.model = paddle.jit.load(model_path)
self.model.eval()
self.tokenizer = tokenizer
self.pinyin_vocab = pinyin_vocab
# batchize 函数,自动 pad
self.batchify_fn = lambda samples: [
data for data in Tuple(
Pad(axis=0, pad_val=self.tokenizer.pad_token_id, dtype='int64'), # input_ids
Pad(axis=0, pad_val=self.tokenizer.pad_token_type_id, dtype='int64'), # token_type_ids
Pad(axis=0, pad_val=self.pinyin_vocab.token_to_idx[self.pinyin_vocab.pad_token], dtype='int64'), # pinyin_ids
Stack(axis=0, dtype='int64') # seq_len
)(samples)
]
def predict(self, sentences, batch_size=1):
examples = []
texts = []
trans_func = partial(
convert_example,
tokenizer=self.tokenizer,
pinyin_vocab=self.pinyin_vocab,
max_seq_length=self.max_seq_length,
is_test=True
)
# 先将文本转换为模型输入
for text in sentences:
example = {"source": text.strip()}
input_ids, token_type_ids, pinyin_ids, length = trans_func(example)
examples.append((input_ids, token_type_ids, pinyin_ids, length))
texts.append(example["source"])
results = []
# 按 batch_size 分批处理
for i in range(0, len(examples), batch_size):
batch = examples[i:i + batch_size]
token_ids, token_type_ids, pinyin_ids, length = self.batchify_fn(batch)
# 转为 paddle Tensor
token_ids = paddle.to_tensor(token_ids, dtype="int64")
pinyin_ids = paddle.to_tensor(pinyin_ids, dtype="int64")
# 推理
corr_logits, det_error_probs = self.model(token_ids, pinyin_ids)
# 取 argmax
det_pred = det_error_probs.argmax(axis=-1).numpy()
char_preds = corr_logits.argmax(axis=-1).numpy()
# decode
for j in range(len(length)):
pred_result = parse_decode(
texts[i + j], char_preds[j], det_pred[j],
length[j], self.tokenizer, self.max_seq_length
)
results.append(''.join(pred_result))
return results
if __name__ == "__main__":
tokenizer = ErnieTokenizer.from_pretrained("ernie-1.0")
pinyin_vocab = Vocab.load_vocabulary(
"pinyin_vocab.txt", unk_token='[UNK]', pad_token='[PAD]'
)
predictor = Predictor(
model_path="infer_model/static_graph_params", # Paddle 3.x 导出路径
tokenizer=tokenizer,
pinyin_vocab=pinyin_vocab,
max_seq_length=64
)
samples = [
'遇到逆境时,我们必须勇于面对,而且要愈挫愈勇,这样我们才能朝着成功之路前进。',
'人生就是如此,经过磨练才能让自己更加坚强,才能使自己更加乐观。',
]
results = predictor.predict(samples, batch_size=2)
for source, target in zip(samples, results):
print("Source:", source)
print("Target:", target)
关闭于 2026-01-07 0 条评论