【大语言模型】自动化问答对生成——使用ernie-bot将PDF文档转化为QA对

参考文章:【大模型】自动化问答生成:使用GPT-3.5将文档转化为问答对_文档转qa-CSDN博客

新增part

本篇文章相对参考文章增加的部分有:

1. 从PDF中提取txt文本

2. 将txt文本进行分割,以满足ernie的prompt对字符数和token数的限制

详细步骤

  1. 从PDF中提取文本
  2. 按生成式模型能接受的最大字符数和token数分割文本;
  3. 定义问题生成prompt
  4. 定义问答对生成prompt
  5. 定义问题生成函数
  6. 定义问答对生成函数
  7. 主程序:使用生成式模型生成问答对,并将结果写入txt文件;

详细代码

import datetime
import time
import fitz  # PyMuPDF
import requests
import json
import numpy as np
from transformers import BertTokenizer


# 从PDF中提取文本
# 从PDF文件中提取文本函数
def extract_text_from_pdf(pdf_path):
    text = ""
    pdf_document = fitz.open(pdf_path)
    for page_num in range(len(pdf_document)):
        page = pdf_document.load_page(page_num)
        text += page.get_text()
    return text

#定义文本分割函数
def split_text(text, max_length, max_tokens):
    """将文本按字符数和token数分割成不超过max_length字符和max_tokens的段落"""
    paragraphs = []
    current_paragraph = ""
    current_tokens = 0

    for line in text.split("\n"):
        line_tokens = tokenizer.encode(line, add_special_tokens=False)
        if (len(current_paragraph) + len(line) + 1 <= max_length) and (current_tokens + len(line_tokens) + 1 <= max_tokens):
            current_paragraph += line + "\n"
            current_tokens += len(line_tokens) + 1  # +1 for the newline token
        else:
            paragraphs.append(current_paragraph.strip())
            current_paragraph = line + "\n"
            current_tokens = len(line_tokens) + 1

    if current_paragraph:
        paragraphs.append(current_paragraph.strip())
    return paragraphs
    
# 初始化BERT tokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")

# 提取PDF文件中的文本并按token数和字符数分割
pdf_files = ["CSST科学白皮书_v1.2.pdf"]
max_length = 18000
max_tokens = 4620
documents = []
for pdf in pdf_files:
    text = extract_text_from_pdf(pdf)
    paragraphs = split_text(text, max_length, max_tokens)
    documents.extend(paragraphs)

# 将分割后的文本块分别存储到多个txt文件中,并保存文件名到一个列表中
file_names = []
for idx, doc in enumerate(documents, start=1):
    file_name = f"text_file{idx}.txt"
    with open(file_name, "w", encoding="utf-8") as file:
        file.write(doc)
    file_names.append(file_name)

print("文本文件已成功生成。")
print("生成的文件名列表:", file_names)

#定义问题生成prompt
prompt1 = '''
#01 你是一个问答对数据集处理专家。

#02 你的任务是根据我给出的内容,生成适合作为问答对数据集的问题。

#03 问题要尽量短,不要太长。

#04 一句话中只能有一个问题。

#05 最多生成15个问题。

#06 生成问题示例:

"""

"积分视场光谱仪是什么?"
"多通道成像仪的研制单位是哪个?"
介绍一下暗能量。

"""

#07 以下是我给出的内容:

"""

{{此处替换成你的内容}}

"""
'''

#定义问答对生成prompt
prompt2 = '''
#01 你是一个问答对数据集处理专家。

#02 你的任务是根据我的问题和我给出的内容,生成对应的问答对。

#03 答案要全面,只使用我的信息,如果找不到答案,就回复从文档中找不到答案。

#04 你必须根据我的问答对示例格式来生成:

"""

{"content": "星冕仪模块三个主要观测目标是什么?", "summary": "星冕仪模块是三个主要观测目标是:1.近邻恒星高对比度成像普查。2.视向速度探测已知系外行星后随观测。3.恒星星周盘高对比度成像监测,并对恒星外星黄道尘强度分布进行定量分析。"}

{"content": "空间站光学仓是什么?", "summary": "中国空间站光学舱将是一台 2 米口径的空间天文望远镜,主要工作在近紫外-可见光-近红外波段,兼具大视场巡天和精细观测能力,立足于2020-30 年代国际天文学研究的战略前沿,在科学上具有极强的竞争力,将与欧美同期的大型天文项目并驾齐驱,优势互补,并在若干方向上有所超越,有望取得对宇宙认知的重大突破"}

#05 我的问题如下:

"""

{{此处替换成你上一步生成的问题}}

"""

#06 我的内容如下:

"""

{{此处替换成你的内容}}

"""
'''

#配置文心一言
# 设置百度文心一言的API密钥和端点
API_KEY = "your_api_key"
SECRET_KEY = "your_secret_key"

def get_access_token():
    """
    使用 AK,SK 生成鉴权签名(Access Token)
    :return: access_token,或是None(如果错误)
    """
    url = "https://aip.baidubce.com/oauth/2.0/token"
    params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
    return str(requests.post(url, params=params).json().get("access_token"))


#定义问题生成函数
def generate_question(text_content, more=False):
    url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=" + get_access_token()
    content= "生成适合作为问答对的问题"
    if more:
        content = "尽可能多生成适合作为问答对的问题"
    prompt = prompt1.replace("{{此处替换成你的内容}}", text_content)
    payload = json.dumps({
        "messages": [
            {
                "role": "user",
                "content": content
            }
        ],
        "temperature": 0.95,
        "top_p": 0.8,
        "system":prompt
    })
    headers = {
        'Content-Type': 'application/json'
    }
    start_time = time.time()
    response = requests.request("POST", url, headers=headers, data=payload)
    x = json.loads(response.text)
    print("耗时", time.time() - start_time)
    print(x)
    if response.status_code == 200:
        return x['result']
    else:
        print(f"Error: {response.status_code}")
        print(response.content)
        return None


#定义问答对生成函数
def generate_qa(text_content, question_text=None):
    url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=" + get_access_token()
    content= "拼成问答对"
    prompt = prompt2.replace("{{此处替换成你上一步生成的问题}}", question_text).replace("{{此处替换成你的内容}}", text_content)
    payload = json.dumps({
        "messages": [
            {
                "role": "user",
                "content": content
            }
        ],
        "temperature": 0.95,
        "top_p": 0.8,
        "system":prompt
    })
    headers = {
        'Content-Type': 'application/json'
    }
    start_time = time.time()
    response = requests.request("POST", url, headers=headers, data=payload)
    x = json.loads(response.text)
    print("耗时", time.time() - start_time)
    print(x)
    if response.status_code == 200:
        return x['result']
    else:
        print(f"Error: {response.status_code}")
        print(response.content)
        return None


#将生成的问答对写入.txt文件
def write_to_file(content):
    timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
    file_name = f"new_file_{timestamp}.txt"
    with open(file_name, "w", encoding="utf-8") as file:
        file.write(content)
    print("File 'new_file.txt' has been created and written.")


#读取PDF生成的txt文件
def read_file(file_name):
    try:
        with open(file_name, "r", encoding='utf-8') as file:
            content = file.read()
        return content
    except FileNotFoundError:
        print(f"File '{file_name}' not found.")


#主程序
def main():
    for file in file_names:
        text_content = read_file(file)
        print ('text_content\n', text_content)
        question_text = generate_question(text_content=text_content, more=False)
        print('question_text\n', question_text)
        qa_text = generate_qa(text_content=text_content, question_text=question_text)
        print('qa_text\n', qa_text)
        write_to_file(qa_text)

if __name__ == '__main__':
    main()

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ERNIE-Bot-turbo是一种基于百度AI技术ERNIE(Enhanced Representation through Knowledge Integration)的聊天机器人,它可以进行智能对话和知识问答ERNIE-Bot-turbo在原有ERNIE-Bot的基础上,通过使用更大的预训练模型ERNIE2.0和更多的训练数据,提高了对话和问答的准确性和流畅性,同时还增加了多轮对话和情感分析等功能。以下是关于ERNIE-Bot-turbo的一些信息: - ERNIE-Bot-turbo的提问方式与普通聊天机器人相同,用户可以直接在对话框中输入问题或语句,ERNIE-Bot-turbo会自动进行分析并给出回答。 - ERNIE-Bot-turbo的知识库涵盖了广泛的领域,包括文化、科技、体育、社会、历史等多个方面,用户可以向ERNIE-Bot-turbo提出不同领域的问题。 - ERNIE-Bot-turbo支持多轮对话,可以针对用户的问题进行追问和回答,实现更加流畅的对话。 - ERNIE-Bot-turbo还具有情感分析功能,可以识别用户的情感状态并根据情感状态给出不同的回答,增强了对话的真实感和情感交互性。 下面是一个样例对话: 用户:你好,请问你叫什么名字? ERNIE-Bot-turbo:你好,我是ERNIE-Bot-turbo,很高兴为您服务。 用户:你会哪些知识领域? ERNIE-Bot-turbo:我的知识库涵盖了广泛的领域,包括文化、科技、体育、社会、历史等多个方面,您可以向我提出不同领域的问题。 用户:你会情感分析吗? ERNIE-Bot-turbo:是的,我能够识别您的情感状态并根据情感状态给出不同的回答,增强了对话的真实感和情感交互性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值