<jupyter_start><jupyter_text>ERNIE模型初尝试 项目介绍【项目的最初目的】：使用飞桨已有的官方套件，初步实现一个相似问题（严谨实用向）回复功能。**【项目最终实现】：使用飞桨已有的官方套件，初步实现一个（额，文本生成，无聊向的）回复功能，看一下通过对烦恼类的简短的问题+回复的学习，最终能自动生成什么回复。** 数据介绍选择飞桨自带的baike_qa2019 百科类问答json版数据集（链接：https://aistudio.baidu.com/aistudio/competition/detail/63/0/task-definition）数据集为压缩文件，解压后有2个子文件。训练数据集baike_qa_train.json和测试数据集baike_qa_valid.json。每条训练数据是一个字典形式，key有5个：qid问答id，category问答划分的类别(如教育/科学-理工学科-地球科学)，title问题，desc问题描述，answer回答，如下所示：{'qid': 'qid_5982723620932473219', 'category': '教育/科学-理工学科-地球科学', 'title': '人站在地球上为什么没有头朝下的感觉 ', 'desc': '', 'answer': '地球上重力作用一直是指向球心的，因此\r\n只要头远离球心，人们就回感到头朝上。'} ***----因为模型选择已偏航(文本生成，认为返回的答案并不严谨)，就选择了category是烦恼的类别，问题和回复都很简短的（认为简短的相对不那么严肃）问题和答案进行学习*** 模型介绍计划：通过计算文本相似性来进行问题匹配，返回和输入最大相似的问题的回复由于：目前对飞桨了解不够充分，没有找到合适的模型。通过在项目集搜索，找到了使用paddlehub的ERNIE-GEN进行问答系统搭建的项目。ERNIE的github网址为 https://github.com/PaddlePaddle/ERNIE ，里面介绍：ERNIE在工业界得到了大规模应用，如搜索引擎、新闻推荐、广告系统、语音交互、智能客服等。而2020.5开源的 ERNIE-GEN 模型是最强文本生成预训练模型。所以ernie-gen可能更偏向于文本生成，非返回原有的资源库结果。但是目前没有发现适合的其他官方套件，所以想用ernie-gen尝试一下。  安装依赖包<jupyter_code>!pip install paddlehub==2.2.0
!pip install paddle-ernie
# 1.4 持久化安装, 需要使用持久化路径
# !mkdir /home/aistudio/external-libraries
# !pip install paddle-ernie -t /home/aistudio/external-libraries
# !pip install paddlehub==2.1.1 -t /home/aistudio/external-libraries

# 1.5 持久化安装后，添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: 
# import sys 
# sys.path.append('/home/aistudio/external-libraries')<jupyter_output><empty_output><jupyter_text>模型训练 数据处理ERNIE-GEN模型要求的数据输入格式是：编号\t文本1\t文本2的格式，和原数据格式不符合，故先对数据进行处理<jupyter_code># 1.1 查看工作区文件, 该目录下的变更将会持久保存. 请及时清理不必要的文件, 避免加载过慢.
# !ls /home/aistudio/work

# 1.2 解压挂载的数据集在同级目录下
!unzip -oq data/data107726/百科类问答json版.zip -d data/data107726/

# 1.3 查看当前挂载的数据集目录, 该目录下的变更重启环境后会自动还原
!ls /home/aistudio/data/data107726
# 2. 处理数据格式
# 根据模型要求，处理成：编号\t问题\t答案的形式
# 由于数据量太大，内存不足会报错，限制了总文本的长度
import json

def resave_2txt(raw_path, raw_encod, save_path, save_encod, max_len=None):
    try:
        max_len = int(max_len)
    except:
        max_len = float('inf')
    tmp_len = 0
    save_txt = []
    with open(raw_path,'r',encoding=raw_encod) as f:
        for line in f.readlines():
            dic_v = json.loads(line)
            if '烦恼' in dic_v['category'].split('-'):
                txt_line = str(tmp_len) + '\t' + dic_v['title'].replace('\n','').replace('\r','')  + '\t' + dic_v['answer'].replace('\n','').replace('\r','')
                if len(txt_line)>30:
                    pass
                else:
                    if tmp_len <= max_len:
                        save_txt.append(txt_line)
                        tmp_len += 1
                        with open(save_path, 'a+', encoding=save_encod) as f:
                            f.write(txt_line + '\n')
                    else:
                        break
    
    return save_txt


train_txt = resave_2txt('data/data107726/baike_qa_train.json', 'utf-8', 'data/data107726/baike_qa_train.txt', 'utf-8', 180)
valid_txt = resave_2txt('data/data107726/baike_qa_valid.json', 'utf-8', 'data/data107726/baike_qa_valid.txt', 'utf-8', 30)
print(f'训练集数据量：{len(train_txt)}, 验证集数据量：{len(valid_txt)}\n')
print('训练集数据样例：\n', train_txt[0])<jupyter_output>训练集数据量：181, 验证集数据量：28

训练集数据样例：
 0	婆媳关系该怎样处理 	少见面，见面时投其所好，少告状。<jupyter_text>模型训练
由于对自己的要求是使用已有套件，初步实现目的。除了报错之外，对于参数暂时没有太多研究。

训练时发现的报错有：
1. 数据集的处理：一些问题回复本身含\n，需要替换成其他字符，否则保存数据的时候，\n之后的数据单独为一条记录，不符合要求的数据格式(编号\t文本\t文本)
2. max_encode_len(int)最长编码长度 和  max_decode_len(int) 最长解码长度，受输入的数据长度影响，若数据长度较长，而此处设置的比较小，则会报错
3. batch_size：有一些报错会提出需要调小batch_size<jupyter_code># 3.训练模型
# 暂时无脑先走流程，流程走完再调具体
# 具体流程和参数可参考链接：https://aistudio.baidu.com/aistudio/projectdetail/878918?channelType=0&channel=0

import paddlehub as hub
module = hub.Module(name="ernie_gen")

result = module.finetune(
    use_gpu = True,
    train_path='data/data107726/baike_qa_train.txt',
    dev_path='data/data107726/baike_qa_valid.txt',
    save_dir="ernie_gen_result",
    max_steps=600,
    max_encode_len=100,
    max_decode_len=100,
    noise_prob=0.2,
    batch_size=2,
    log_interval=20
)
# 查看训练结束时的模型保存路径 和 模型困惑度
print(result)
# 导出模型
module.export(params_path=result['last_save_path'], module_name="ernie_gen_baikeqa", author="zhuqianer")
# 安装module
!hub install ernie_gen_baikeqa
print(train_txt[:10])<jupyter_output>['0\t婆媳关系该怎样处理 \t少见面，见面时投其所好，少告状。', '1\t爱情的力量有多大？ \t拥有了真爱就像拥有了全世界', '2\t交朋友！想恋爱！！第一次怎么表达啊？ \t自然点说出真心话', '3\t爱情是什么感觉？爱一个人是什么感觉呢？ \t时刻为TA着想', '4\t你最爱的人是谁？ \t是我自己', '5\t学生爱上老师该怎么办 \t想办法搞定她', '6\t做爱时该想些什么呢？ \t什么也不想想,舒服就好!', '7\t军人婚姻 \t军嫂都是伟大滴`~`~`~', '8\t怎么区分是处男不是处男 \t我路过的来赚分的', '9\t谁是世界上最乖的人？MANORWOMAN \tBABY']<jupyter_text>模型预测1. 不同的问题返回的答案还是有区别的；2. 和训练集的答案可以说是完全无关了，但是还是挺好玩的3. 回复中有很多重复字和标点，应该是训练数据的问题<jupyter_code># 测试

import paddlehub as hub

module = hub.Module(name="ernie_gen_baikeqa")

test_texts = ['婆媳吵架怎么办','我帅吗']
# generate包含3个参数，texts为输入文本列表，use_gpu指定是否使用gpu，beam_width指定beam search宽度。
results = module.generate(texts=test_texts, use_gpu=True, beam_width=1)
for result in results:
    print(result)<jupyter_output>[2022-03-02 17:04:51,290] [    INFO] - Already cached /home/aistudio/.paddlenlp/models/ernie-1.0/ernie_v1_chn_base.pdparams
[2022-03-02 17:04:51,292] [   DEBUG] - init ErnieModel with config: {'attention_probs_dropout_prob': 0.1, 'hidden_act': 'relu', 'hidden_dropout_prob': 0.1, 'hidden_size': 768, 'initializer_range': 0.02, 'max_position_embeddings': 513, 'num_attention_heads': 12, 'num_hidden_layers': 12, 'type_vocab_size': 2, 'vocab_size': 18000, 'pad_token_id': 0}
[2022-03-02 17:04:54,348] [    INFO] - loading pretrained model from /home/aistudio/.paddlenlp/models/ernie-1.0/ernie_v1_chn_base.pdparams
[2022-03-02 17:04:55,304] [    INFO] - param:mlm_bias not set in pretrained model, skip
[2022-03-02 17:04:55,306] [    INFO] - param:mlm.weight not set in pretrained model, skip
[2022-03-02 17:04:55,308] [    INFO] - param:mlm.bias not set in pretrained model, skip
[2022-03-02 17:04:55,309] [    INFO] - param:mlm_ln.weight not set in pretrained model, skip
[2022-03-02 17:04:55,311] [  [...]
{'fraction_non_alphanumeric': 0.14481279894441695, 'fraction_numerical': 0.05574797954807851, 'mean_word_length': 4.688555347091932, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '576554', 'license': 'Apache-2.0', 'n_tokens_mistral': 3607, 'n_tokens_neox': 3782, 'n_words': 321, 'path': '3521598.ipynb', 'repo_name': 'HopeWind/ernie_test', 'size': '6063'}