当前位置:   article > 正文

Datawhale 动手学大模型应用开发 第六章第七章笔记 迭代优化prompt / 大模型评估 / 项目结构 / Gradio&FastAPI_gradio和fastapi

gradio和fastapi

第六章 验证迭代

6.1 整体介绍

在这里插入图片描述

项目初期只有初步的几个样例供大模型测试,所以咱们不等开发集全部构建完毕,直接敏捷开发。开发是以迭代的形式进行。步骤如下:

  • 在最初几个样本上初步调出可以work的prompt
  • 随着公司提供更多用例,整理出没有通过的样例(记为Bad Case),针对性优化prompt。
  • 随着用例越来越多,手工运行调优已经很费劲了,这时将Bad Case整理成一个集合,并指定该样本集合的性能评估指标,从整体上优化prompt

6.2 如何找出BadCase,如何针对性优化

1. 人为 找出回答的不足,针对往prompt加入新要求

  • 核心: 围绕具体业务展开思考,人为 找出初始回答的缺点不足,并针对性进行提升改进

  • 示例:

    1. 测试后觉得目前回答太短了,则将原始prompt中的
    “尽量使答案简明扼要”  
    ==改成==》
    ”””你应该使答案尽可能详细具体,但不要偏题。
    如果答案比较长,请酌情进行分段,以提高答案的阅读体验”””
    
    2. 进一步测试后觉得回答变长后,有点条例不清了。于是进一步改成
    ”””你应该使答案尽可能详细具体,但不要偏题。
    如果答案比较长,请酌情进行分段,以提高答案的阅读体验
    (++)如果答案有几点,你应该分点标号回答,让答案清晰具体
    ”””
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

2. 克服幻觉的方法

[ 标明知识来源, 两步思维链(step-2让模型检查) ]

  • 保证真实性,克服幻觉 的 针对性prompt
    ++ “请你附上回答的来源原文,以保证回答的正确性。”
    ++ ”基于提供的上下文,反思回答中有没有不正确或不是基于上下文得到的内容,如果有,修改回答“

  • 整体示例:

    template_v4 = """
    请你依次执行以下步骤:
    ① 使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答案。
    你应该使答案尽可能详细具体,但不要偏题。如果答案比较长,请酌情进行分段,以提高答案的阅读体验。
    如果答案有几点,你应该分点标号回答,让答案清晰具体。
    上下文:
    {context}
    问题: 
    {question}
    有用的回答:
    ② 基于提供的上下文,反思回答中有没有不正确或不是基于上下文得到的内容,如果有,修改回答"""
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

3. 增加一个指令解析来抽出 用户要的output格式

  • 原因:用户问题中有时候会对输出格式做出要求。但是由于是两步一起问大模型的,所以常常被忽略了。所以我们在QALLM前,增加一个指令解析LLM,将【格式要求】和【问题内容】解析拆分。然后再用两部思维链分步进行。

  • 示例

    问题:LLM的分类是什么?给我返回一个 Python List
    初始回答:根据提供的上下文,LLM的分类可以分为基础LLM和指令微调LLM。
    
    • 1
    • 2
    prompt_input = '''
    请判断以下问题中是否包含对输出的格式要求,并按以下要求输出:
    请返回给我一个可解析的Python列表,列表第一个元素是对输出的格式要求,应该是一个指令;第二个元素是去掉格式要求的问题原文
    如果没有格式要求,请将第一个元素置为空
    需要判断的问题:
    {}
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    基于prompt_input得出一个 输出结构的rule (第一个元素)
    "['给我返回一个 Python List', 'LLM的分类是什么?']"
    
    • 1
    • 2
    prompt_output = '''
    请根据回答文本和输出格式要求,按照给定的格式要求对问题做出回答
    需要回答的问题:
    {}
    
    回答文本:
    {}
    
    输出格式要求:
    {}
    
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    
    "['基础LLM', '指令微调LLM']"
    
    • 1
    • 2

6.3 大模型评估方法

人工评估(打分量化/多方面打分)

  • 打分量化
    例如验证集中有100个测试用例
    接着基于 prompt_ver_A 得到对应的100个回答,同理得到 prompt_ver_B 的100个回答。
    进而人工给每个答案打分(例如在0-5分之间打分)。
    最终 prompt_ver_Aprompt_ver_B 各自算出一个平均分,进而选定最终的prompt

  • 上边的打分量化可以进一步变为 多方面打分
    例如:

    • 知识查找正确性
    • 回答一致性
    • 回答幻觉比例 等等

    之后再汇总得到最终的分数。

简单自动评估(客观题/答案相似)

评估大模型回答质量 其实本质上就归属于NLP中的一个常见问题——“评估生成的序列质量”

此问题的解决方法一般是设定一些自动化评估函数

  • 人工预先标注正确答案,然后根据 BLEU等 计算相似度
    两个序列通过jieba分词后,传给nltk的sentence_bleu计算即可

  • 传统的方法还有计算困惑度,但是大模型应该是无法是使用这种方式的

  • 将正确句子转变成选择题 ,看大模型是否能选对。
    重写整理下教程的相关代码,代码如下:

    def multi_select_score(true_answer : str, generate_answer : str) -> float:
        # true_answer represents target answer.
    		# generate_answer represents the answer generated by LLM
        true_answers = list(true_answer)
    		
    		## 为了防止幻觉,可以加大对错误选择的惩罚力度
    		score_dict = {'错误多选': -1,   
    									'全对': 1, 
    									'漏选': 0.5,
    									'未选任何项': 0}
    
        # ---错误多选---
    		answer_label_set = ['A', 'B', 'C', 'D']
    		n_correct = 0
        true_answer = set(true_answer)
        for each_generate_answer in set(generate_answer):  # don't forget SET
    				if each_generate_answer in true_answer:
    						n_correct += 1
    				else:
    						return score_dict['错误多选']
    		# -----剩下三种情况-------
        if if_correct == 0:
            return score_dict['未选任何项']
        elif if_correct == len(true_answers):
            return score_dict['全对']
        else:
            return score_dict['漏选']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    ## 相关例子供运行
    prompt_template = '''
    请你做如下选择题:
    题目:南瓜书的作者是谁?
    选项:A 周志明 B 谢文睿 C 秦州 D 贾彬彬
    你可以参考的知识片段:
    {}
    
    请仅返回选择的选项
    如果你无法做出选择,请返回空
    '''
    
    four_ans = [
    	"B C",
    	"除了 A 周志华之外,其他都是南瓜书的作者",
    	"应该选择 B C D",
    	"我不知道"
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

大模型评估

写 评估prompt让GPT-4来帮完成评估即可。

  • 主要评估模型要比当前模型更强。不然怎么能提供有力的指导。

  • 本仓库写的prompt很赞,收藏一波~

    prompt = '''
    你是一个模型回答评估员。
    接下来,我将给你一个问题、对应的知识片段以及模型根据知识片段对问题的回答。
    请你依次评估以下维度模型回答的表现,分别给出打分:
    
    ① 知识查找正确性。评估系统给定的知识片段是否能够对问题做出回答。如果知识片段不能做出回答,打分为0;如果知识片段可以做出回答,打分为1。
    
    ② 回答一致性。评估系统的回答是否针对用户问题展开,是否有偏题、错误理解题意的情况,打分分值在0~1之间,0为完全偏题,1为完全切题。
    
    ③ 回答幻觉比例。该维度需要综合系统回答与查找到的知识片段,评估系统的回答是否出现幻觉,打分分值在0~1之间,0为全部是模型幻觉,1为没有任何幻觉。
    
    ④ 回答正确性。该维度评估系统回答是否正确,是否充分解答了用户问题,打分分值在0~1之间,0为完全不正确,1为完全正确。
    
    ⑤ 逻辑性。该维度评估系统回答是否逻辑连贯,是否出现前后冲突、逻辑混乱的情况。打分分值在0~1之间,0为逻辑完全混乱,1为完全没有逻辑问题。
    
    ⑥ 通顺性。该维度评估系统回答是否通顺、合乎语法。打分分值在0~1之间,0为语句完全不通顺,1为语句完全通顺没有任何语法问题。
    
    ⑦ 智能性。该维度评估系统回答是否拟人化、智能化,是否能充分让用户混淆人工回答与智能回答。打分分值在0~1之间,0为非常明显的模型回答,1为与人工回答高度一致。
    
    你应该是比较严苛的评估员,很少给出满分的高评估。
    用户问题:
    {}
    
    待评估的回答:
    {}
    
    给定的知识片段:
    {}
    
    你应该返回给我一个可直接解析的 Python 字典,字典的键是如上维度,值是每一个维度对应的评估打分。
    不要输出任何其他内容。
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

混合评估用于本项目

核心: 对问题做一个分类,再操作

  • 对于一些有固定正确答案就转成客观题去测试,
  • 否则主观性很强的,或者知识正确性都可以用大模型去测
  • 评估是否拟人化,是否智能,则推荐用人工去评估

第七章 前后端搭建

project代码解析

原来这里有项目解析,我在第二章笔记中写了LLM调用的项目结构解析呢,
本项目的后端逻辑分为三个模块

  • LLM调用
  • 数据库构建
  • 检索问答链

Gradio搭建界面

  • 搭建界面

    # 导入所需的import gradio as gr
    
    def generate(input, temperature):
        output = llm.predict(input, temperature=temperature)
        return output
    
    # 创建一个 Web 界面
    # 输入:一个文本框和一个滑块
    # 输出:一个文本框显示生成的文本
    demo = gr.Interface(
        fn=generate, 
        inputs=[
            gr.Textbox(label="Prompt"),  # 文本输入框
            gr.Slider(label="Temperature", value=0,  maximum=1, minimum=0)  # 滑块用于选择模型的 temperature
        ], 
        outputs=[gr.Textbox(label="Completion")],  # 显示生成文本的文本框
        title="Chat Robot",  # 界面标题
        description="Local Knowledge Base Q&A with llm",  # 界面描述
        # allow_flagging="never", 
    )
    
    # 关闭可能已经启动的任何先前的 gradio 实例
    gr.close_all()
    
    # 启动 Web 界面
    # 使用环境变量 PORT1 作为服务器的端口号
    demo.launch(share=True, server_port=int(os.environ['PORT1']))
    
    # 结果
    # Running on local URL:  http://127.0.0.1:7860
    # To create a public link, set `share=True` in `launch()`.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
  • 这块没有好好看,之后再好好补回来

Fastapi前后端分离

  • 总结: FastAPI 没什么要学的,就是一个构建api的web框架,类似flask,但是快三倍。
  • 使用流程:
    • 构建一个app对象:app = FastAPI()
    • 定义一个数据模型:
      这个BaseModel是一个接受post请求的数据类。其从Pydantic 导入,内部有一些写好的验证代码来保证传入的数据符合定义时的声明。
    • 定义一个后端逻辑方法,实现QA的逻辑。
    • @app.post("/your_url_which_after_port/")
      (别忘记了 将后端逻辑方法加上async,保证并发)

详解project代码

暂时还没有看完代码

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/368250
推荐阅读
相关标签
  

闽ICP备14008679号