开源大模型提示指南(以ChatGLM3为例)

1. 简介

注意:该项目需要在GPU环境下执行,如16G V100

随着大型语言模型(LLM)技术日渐成熟,提示工程(Prompt Engineering)变得越来越重要。一些研究机构如微软、OpenAI等都发布了 LLM 提示工程指南。最近,Llama 系列开源模型的提出者 Meta 也针对 Llama 2 发布了一份交互式提示工程指南,涵盖了 Llama 2 的快速工程和最佳实践。不过都是英文的,受此启发,我针对中文开源模型的调用写了一个Prompt指南。使用的模式是ChatGLM3-6B。

本来还想写一个商业模型的指南,后来发现这些优化内容很多都已经内置在商业模型中了,例如让文心一言做数学题: 

所以就只写了开源模型的指南。

Meta的关于LLama 2的Prompt的优化建议:https://github.com/facebookresearch/llama-recipes/blob/main/examples/Prompt_Engineering_with_Llama_2.ipynb

2. 环境安装

安装官方文档首先需要仓库:

git clone https://github.com/THUDM/ChatGLM3 cd ChatGLM3

然后使用 pip 安装依赖:

pip install -r requirements.txt

考虑到方便大家使用,本项目已经下载ChatGLM仓库,直接解压即可。

In [1]

# 解压ChatGLMS3项目, 也可以直接从Github上clone
!unzip /home/aistudio/ChatGLM3-main.zip
!mv ChatGLM3-main ChatGLM3
Archive:  /home/aistudio/ChatGLM3-main.zip
40c6dc126e50311c86cc33d4adf0102a2cad72d3
   creating: ChatGLM3-main/
  inflating: ChatGLM3-main/DEPLOYMENT.md  
  inflating: ChatGLM3-main/MODEL_LICENSE  
  inflating: ChatGLM3-main/PROMPT.md  
  inflating: ChatGLM3-main/README.md  
  inflating: ChatGLM3-main/cli_demo.py  
  inflating: ChatGLM3-main/requirements.txt  
   creating: ChatGLM3-main/resources/
  inflating: ChatGLM3-main/resources/WECHAT.md  
  inflating: ChatGLM3-main/resources/cli-demo.png  
  inflating: ChatGLM3-main/resources/web-demo.gif  
  inflating: ChatGLM3-main/resources/web-demo2.gif  
  inflating: ChatGLM3-main/resources/web-demo2.png  
  inflating: ChatGLM3-main/resources/wechat.jpg  
   creating: ChatGLM3-main/tool_using/
  inflating: ChatGLM3-main/tool_using/README.md  
  inflating: ChatGLM3-main/tool_using/cli_demo_tool.py  
  inflating: ChatGLM3-main/utils.py  
  inflating: ChatGLM3-main/web_demo.py  
  inflating: ChatGLM3-main/web_demo2.py  

在安装需要的包的时候,因为模块比较多,所以进行持久化安装, 使用持久化路径, 方便下次使用。在使用的时候只需要增加如下代码即可:

import sys

sys.path.append('/home/aistudio/external-libraries')

In [1]

# 添加如下代码, 这样每次环境(kernel)启动的时候
import sys 
sys.path.append('/home/aistudio/external-libraries')

In [ ]

# 因为模块比较多,所以进行持久化安装, 使用持久化路径, 方便下次使用
!mkdir /home/aistudio/external-libraries
%cd ChatGLM3
!pip install -r requirements.txt -t /home/aistudio/external-libraries

调用代码的时候,官方给的例子是:

from transformers import AutoTokenizer, AutoModel

tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm3-6b", trust_remote_code=True)

model = AutoModel.from_pretrained("THUDM/chatglm3-6b", trust_remote_code=True, device='cuda')

model = model.eval()

在执行的时候自动下载模型文件,因为文件很大,所以本项目已经下载完毕。大家只要解压即可。

3. Prompt演示

首先是获取模型,在本项目中,直接使用本地模型。然后就可以与模型对话了。

In [1]

%cd /home/aistudio/data/data245452
!unzip chatglm3-6b.zip
/home/aistudio/data/data245452
/opt/conda/envs/python35-paddle120-env/lib/python3.10/site-packages/IPython/core/magics/osm.py:417: UserWarning: using dhist requires you to install the `pickleshare` library.
  self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
Archive:  chatglm3-6b.zip
  inflating: configuration_chatglm.py  
  inflating: config.json             
  inflating: README.md               
  inflating: MODEL_LICENSE.txt       
  inflating: gitattributes.txt       
  inflating: tokenization_chatglm.py  
  inflating: tokenizer_config.json   
  inflating: tokenizer.model         
  inflating: quantization.py         
  inflating: pytorch_model.bin.index.json  
  inflating: modeling_chatglm.py     

In [2]

# 添加如下代码, 这样每次环境(kernel)启动的时候
import sys 
sys.path.append('/home/aistudio/external-libraries')
# 获取model
from transformers import AutoTokenizer, AutoModel
tokenizer = AutoTokenizer.from_pretrained("/home/aistudio/data/data245452", trust_remote_code=True)
model = AutoModel.from_pretrained("/home/aistudio/data/data245452", trust_remote_code=True, device='cuda')
model = model.eval()
/opt/conda/envs/python35-paddle120-env/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
Loading checkpoint shards: 100%|██████████| 7/7 [00:47<00:00,  6.79s/it]

In [4]

DEFAULT_MODEL = model
DEFAULT_TOKENIZER = tokenizer
from typing import Dict, List

def completion(
    prompt: str,
    history = [],
    model = DEFAULT_MODEL,
    tokenizer = DEFAULT_TOKENIZER,
    temperature: float = 0.6,
    top_p: float = 0.9,
) -> str:
    response, history = model.chat(tokenizer, prompt, history=history, temperature=temperature, top_p=top_p)
    return response

def chat_completion(
    prompt: str,
    history = [],
    model = DEFAULT_MODEL,
    tokenizer = DEFAULT_TOKENIZER,
    temperature: float = 0.6,
    top_p: float = 0.9,
) -> str:
    return completion(
        prompt,
        history,
        model,
        tokenizer,
        temperature,
        top_p,
    )

def assistant(content: str):
    return { "role": "assistant", "content": content }

def user(content: str):
    return { "role": "user", "content": content }

def complete_and_print(prompt: str, model = DEFAULT_MODEL):
    print(f'==============\n{prompt}\n==============')
    response = completion(prompt, history=[], model= model)
    print(response, end='\n\n')

In [26]

complete_and_print('你好')
==============
你好
==============
你好👋!我是人工智能助手 ChatGLM3-6B,很高兴见到你,欢迎问我任何问题。

3.1 Completion API

In [5]

complete_and_print("典型的天空颜色是: ")
==============
典型的天空颜色是: 
==============
典型的天空颜色是蓝色和蓝色-灰色。在不同时间和天气条件下,天空的颜色可能略有不同,但蓝色和蓝色-灰色通常被认为是典型的天空颜色。

In [54]

complete_and_print ("你是哪个型号的版本?")
==============
你是哪个型号的版本?
==============
我是 ChatGLM3-6B,是清华大学 KEG 实验室和智谱 AI 公司于 2023 年共同训练的语言模型。我的任务是针对用户的问题和要求提供适当的答复和支持。我并不是一个特定的版本,而是不断在训练和优化的过程中迭代升级的。

Chat Completion 模型提供了与 LLM 互动的额外结构,将结构化消息对象数组而不是单个文本发送到 LLM。此消息列表为 LLM 提供了一些可以继续进行的「背景」或「历史」信息。

通常,每条消息都包含角色和内容:

具有系统角色的消息用于开发人员向 LLM 提供核心指令。具有用户角色的消息通常是人工提供的消息。具有助手角色的消息通常由 LLM 生成。

In [6]

response = chat_completion (prompt="我最喜欢的颜色是什么?", history=[
user ("我最喜欢的颜色是蓝色."),
assistant ("很高兴知道!"),
])
print (response)
# "Sure, I can help you with that! Your favorite color is blue."
您最喜欢的颜色是蓝色。

3.2 LLM 超参数

LLM API 通常会采用影响输出的创造性和确定性的参数。在每一步中,LLM 都会生成 token 及其概率的列表。可能性最小的 token 会从列表中「剪切」(基于 top_p),然后从剩余候选者中随机(温度参数 temperature)选择一个 token。换句话说:top_p 控制生成中词汇的广度,温度控制词汇的随机性,温度参数 temperature 为 0 会产生几乎确定的结果。

In [10]

def print_tuned_completion (temperature: float, top_p: float):
    response = completion ("写一句赞美梅花的话", temperature=temperature, top_p=top_p)
    print (f'[temperature: {temperature} | top_p: {top_p}]\n {response.strip ()}\n')
print_tuned_completion (0.01, 0.01)
print_tuned_completion (0.01, 0.01)
# These two generations are highly likely to be the same
print_tuned_completion (1.0, 1.0)
print_tuned_completion (1.0, 1.0)
# These two generations are highly likely to be different
[temperature: 0.01 | top_p: 0.01]
 梅花香自苦寒来,幽香浮动暗传达。

[temperature: 0.01 | top_p: 0.01]
 梅花香自苦寒来,幽香浮动暗传达。

[temperature: 1.0 | top_p: 1.0]
 梅花香自苦寒来,幽香超人魅力在。

[temperature: 1.0 | top_p: 1.0]
 梅花香自苦寒来,破冰迎雪展风骨,笑问枝头谁敢称霸,深藏身段自的风华。

In [31]

def print_tuned_completion (temperature: float, top_p: float):
    response = completion ("Write a haiku about llamas", temperature=temperature, top_p=top_p)
    print (f'[temperature: {temperature} | top_p: {top_p}]\n {response.strip ()}\n')
print_tuned_completion (0.01, 0.01)
print_tuned_completion (0.01, 0.01)
# These two generations are highly likely to be the same
print_tuned_completion (1.0, 1.0)
print_tuned_completion (1.0, 1.0)
# These two generations are highly likely to be different
[temperature: 0.01 | top_p: 0.01]
 Soft, fluffy llamas,  
Gentle creatures, big and small,  
Munching on grass.

[temperature: 0.01 | top_p: 0.01]
 Soft, fluffy fur,
Adorable creatures,
Gentle and kind.

[temperature: 1.0 | top_p: 1.0]
 soft, fiberous fleece,
llamas dance in the sun,
galloping with glee.

[temperature: 1.0 | top_p: 1.0]
 peaceful, gentle beings
llamas graze in the grasslands

3.3 prompt 技巧

详细、明确的指令会比开放式 prompt 产生更好的结果:

In [11]

complete_and_print (prompt="描述量子物理学:在不超过24个词的简短句子中。")
# Returns a succinct explanation of quantum physics that mentions particles and states existing simultaneously.
==============
描述量子物理学:在不超过24个词的简短句子中。
==============
量子物理学是研究微观世界的科学,探讨原子、分子和基本粒子的性质和行为。基于量子力学理论和实验观测,描述了物质的最小粒子具有波动性和随机性,揭示了物质世界的基本规律。

我们可以给定使用规则和限制,以给出明确的指令。

风格化,例如:

  • 向我解释一下这一点,就像儿童教育网络节目中教授小学生一样;
  • 我是一名软件工程师,使用大型语言模型进行摘要。用 250 字概括以下文字;
  • 像私家侦探一样一步步追查案件,给出你的答案。

格式化

  • 使用要点;
  • 以 JSON 对象形式返回;
  • 使用较少的技术术语并用于工作交流中。

限制

  • 仅使用学术论文;
  • 切勿提供 2020 年之前的来源;
  • 如果你不知道答案,就说你不知道。

以下是给出明确指令的例子:

In [12]

complete_and_print ("为我解释最新的大语言模型。")
# More likely to cite sources from 2017
complete_and_print ("为我解释最新的大语言模型。始终引用你的来源。不要引用2020年之前的来源。")
# Gives more specific advances and only cites sources from 2020
==============
为我解释最新的大语言模型。
==============
最新的大语言模型是 GPT-3,它是由 OpenAI 于 2020 年 11 月推出的。GPT-3 采用了多模态输入,能够进行自然语言处理、图像识别、视频分析等任务。它还采用了先进的自然语言生成技术,能够生成流畅、自然的文本,用于自然语言生成、机器翻译等任务。GPT-3 的推出标志着人工智能技术的发展进入了一个新的阶段,大模型服务时代已经到来。

==============
为我解释最新的大语言模型。始终引用你的来源。不要引用2020年之前的来源。
==============
最新的大语言模型是GPT-3,它是由OpenAI团队开发的语言模型。GPT-3是自然语言处理领域中最具代表性的模型之一,它能够对自然语言文本进行建模,并生成与输入文本相似的自然语言输出。GPT-3采用了一种称为Transformer的深度神经网络架构,它能够处理变长的序列数据,并在语言生成任务中取得了很好的表现。

GPT-3有三个版本,分别是GPT-3,GPT-3-Turbo和GPT-3-Elite。GPT-3是基础版本,它具有1750亿个参数,能够生成高质量的自然语言文本。GPT-3-Turbo是GPT-3的加强版,它采用了更高效的算法和更优化的模型结构,能够在更短的时间内生成更多的文本。GPT-3-Elite则是GPT-3-Turbo的进一步优化版本,它采用了更多的训练数据和更复杂的训练算法,能够在更多的任务中表现出色。

总的来说,GPT-3是一种非常先进和强大的语言模型,它在自然语言处理领域中具有广泛的应用前景。

3.4 零样本(zero-shot) prompting

一些大型语言模型(例如 Llama 2)能够遵循指令并产生响应,而无需事先看过任务示例。没有示例的 prompting 称为「零样本 prompting(zero-shot prompting)」。例如:

In [15]

complete_and_print("文本:这是我看过的最好的电影!\n文本的情感是:")
# 返回积极情感
complete_and_print("文本:这个电影的导演努力过头了。\n文本的情感是:")
# 返回消极情感
==============
文本:这是我看过的最好的电影!
文本的情感是:
==============
非常喜欢!

==============
文本:这个电影的导演努力过头了。
文本的情感是:
==============
负面

3.5 少样本(few-shot) prompting

添加所需输出的具体示例通常会产生更加准确、一致的输出。这种方法称为「少样本 prompting(few-shot prompting)」。例如:

In [16]

def sentiment(text):
    response = chat_completion(text, history=[
        user("你是一个情感分类器。对于每条消息,请给出积极/中性/消极的百分比。"),
        user("我喜欢它"),
        assistant("70% 积极 30% 中性 0% 消极"),
        user("它可以更好"),
        assistant("0% 积极 50% 中性 50% 消极"),
        user("它还行"),
        assistant("25% 积极 50% 中性 25% 消极"),
    ])
    return response

def print_sentiment(text):
    print(f'输入:{text}')
    print(sentiment(text))

print_sentiment("我觉得还好")
# 更有可能返回积极、中性和消极的平衡混合
print_sentiment("我爱它!")
# 更有可能返回100% 积极
print_sentiment("糟糕的服务 0/10")
# 更有可能返回100% 消极
输入:我觉得还好
50% 积极 30% 中性 20% 消极
输入:我爱它!
90% 积极 10% 中性 0% 消极
输入:糟糕的服务 0/10
100% 消极

3.6 角色扮演 Role Prompting

Llama 2 在指定角色时通常会给出更一致的响应,角色为 LLM 提供了所需答案类型的背景信息。

例如,让 Llama 2 对使用 PyTorch 的利弊问题创建更有针对性的技术回答:

In [17]

complete_and_print("解释使用PyTorch的利弊。")
# 更有可能解释使用PyTorch的利弊,涵盖一般领域,如文档、PyTorch社区,并提到陡峭的学习曲线
complete_and_print("你的角色是给与处理复杂数据集的高级工程师高度技术建议的机器学习专家。解释使用PyTorch的利弊。")
# 往往会得到更多关于技术方面的利弊,提供更多有关模型层如何工作的技术细节
==============
解释使用PyTorch的利弊。
==============
PyTorch是一个广泛使用的深度学习框架,具有许多优点和一些缺点。以下是使用PyTorch的一些利弊:

优点:

1. 动态计算图:PyTorch使用动态计算图,使得模型的构建和调试更加直观和灵活。

2. 自动微分:PyTorch可以自动计算梯度,使得反向传播更加高效。

3. 简单易用:PyTorch的API简单易用,使得初学者可以快速上手。

4. 强大的GPU加速:PyTorch可以利用GPU进行加速,使得训练速度更快。

5. 灵活的编程模型:PyTorch支持多种编程模型,包括Python、C++和Java。

缺点:

1. 内存占用较高:PyTorch需要大量的内存进行计算,特别是在处理大型模型时。

2. 需要GPU:PyTorch需要使用GPU进行加速,如果没有GPU,则需要使用CPU进行计算,这可能会导致训练速度变慢。

3. 缺少移动端支持:PyTorch目前还没有针对移动设备的版本,因此无法在移动设备上进行训练和推理。

4. 相对于TensorFlow,PyTorch的社区规模较小:尽管PyTorch社区正在不断发展壮大,但相对于TensorFlow,它的社区规模较小,这意味着在遇到问题时可能需要花费更多的时间来寻找解决方案。

5. 模型转换困难:PyTorch的模型转换相对困难,特别是在转换模型结构时。这可能会导致训练时间增加,并且可能会影响模型的性能。

总的来说,PyTorch是一个强大的深度学习框架,具有许多优点,但也存在一些缺点。用户需要根据具体需求和情况选择是否使用PyTorch。

==============
你的角色是给与处理复杂数据集的高级工程师高度技术建议的机器学习专家。解释使用PyTorch的利弊。
==============
PyTorch是一种广泛使用的深度学习框架,它提供了灵活性和强大的计算图,使得构建和调试深度学习模型变得更加直观和高效。但是,与任何技术一样,PyTorch也有其优点和缺点。

优点:
1. 灵活性:PyTorch提供了动态计算图,使得模型的构建过程更加直观和灵活。模型可以随时在不同的步骤之间移动数据,而无需进行复制和粘贴。

2. 易于调试:由于PyTorch的计算图是可视化的,因此可以轻松地追踪和调试模型。这对于初学者和不熟悉深度学习的人来说是非常有用的。

3. 自动求导:PyTorch提供了自动求导系统,使得反向传播变得更加简单和自动。

4. 优秀的社区支持:PyTorch拥有一个庞大的社区,提供了大量的教程、资源和第三方库,使得学习和使用PyTorch变得更加容易。

缺点:
1. 内存消耗:由于PyTorch使用动态计算图,因此在训练大型模型时可能会消耗大量的内存。

2. 缺少移动设备支持:PyTorch主要是一个基于计算机的深度学习框架,对于移动设备的支持相对较少。

3. 模型部署困难:由于PyTorch的计算图是基于Python的,因此将其转换为可以在移动设备上运行的格式可能需要额外的步骤和技术。

4. 相对于TensorFlow的稳定性:在某些情况下,PyTorch的动态计算图可能会导致模型的稳定性问题。

总的来说,PyTorch是一种非常有用的深度学习框架,特别是对于需要高度灵活性和易于调试性的项目。然而,如果对性能要求很高,或者需要移动设备上的部署,那么可能需要考虑使用TensorFlow等其他更稳定的框架。

3.7 思维链

简单地添加一个「鼓励逐步思考」的短语可以显著提高大型语言模型执行复杂推理的能力(Wei et al. (2022)),这种方法称为 CoT 或思维链 prompting:

In [18]

complete_and_print("谁活得更久,埃尔维斯·普雷斯利还是莫扎特?")
# 往往会给出“莫扎特”这个错误答案
complete_and_print("谁活得更久,埃尔维斯·普雷斯利还是莫扎特?让我们仔细地、一步一步地思考这个问题。")
# 给出正确答案“埃尔维斯”
==============
谁活得更久,埃尔维斯·普雷斯利还是莫扎特?
==============
很不幸,两位艺术家都早已去世。埃尔维斯·普雷斯利于1977年去世,享年42岁;而莫扎特于1791年去世,享年35岁。因此,根据两位艺术家的出生年份,莫扎特比埃尔维斯·普雷斯利活得久。

==============
谁活得更久,埃尔维斯·普雷斯利还是莫扎特?让我们仔细地、一步一步地思考这个问题。
==============
让我们一步一步地思考这个问题。

首先,我们要明确两位艺术家的生平和年代。

埃尔维斯·普雷斯利(Elvis Presley)出生于1935年6月8日,于1988年6月12日去世,享年52岁。

莫扎特(Wolfgang Amadeus Mozart)出生于1756年12月17日,于1791年12月5日去世,享年35岁。

从这些信息中,我们可以看出两位艺术家相差很远。莫扎特在35岁时就去世了,而普雷斯利则活了52年。

所以,从这个角度来看,埃尔维斯·普雷斯利活得比莫扎特久。

3.8 自洽性(Self-Consistency)

LLM 是概率性的,因此即使使用思维链,一次生成也可能会产生不正确的结果。自洽性通过从多次生成中选择最常见的答案来提高准确性(以更高的计算成本为代价):

In [19]

import re
from statistics import mode

def gen_answer():
    response = completion(
        "约翰发现15个数字的平均值是40。"
        "如果每个数字加10,那么数字的平均数是多少?"
        "报告答案时,请用三个反引号括起来,例如:```123```"
    )
    match = re.search(r'```(\d+)```', response)
    if match is None:
        return None
    return match.group(1)

answers = [gen_answer() for i in range(5)]

print(
    f"答案:{answers}\n",
    f"最终答案:{mode(answers)}",
    )

# Llama-2-70B的示例运行(全部正确):
# [50, 50, 750, 50, 50]  -> 50
# [130, 10, 750, 50, 50] -> 50
# [50, None, 10, 50, 50] -> 50
答案:[None, None, None, '60', '425']
 最终答案:None

3.9 检索增强生成

有时我们可能希望在应用程序中使用事实知识,那么可以从开箱即用(即仅使用模型权重)的大模型中提取常见事实:

In [20]

complete_and_print("加利福尼亚的首都是什么?")
# 给出正确答案“萨克拉门托”
==============
加利福尼亚的首都是什么?
==============
加利福尼亚州的首府是萨克拉门托。

然而,LLM 往往无法可靠地检索更具体的事实或私人信息。模型要么声明它不知道,要么幻想出一个错误的答案:

In [21]

complete_and_print("2023年12月12日,门洛帕克的气温是多少?")
#"我只是一个AI,我无法访问实时天气数据或历史天气记录。"
complete_and_print("周六晚上我的晚餐预订是几点,我应该穿什么?")
#"我无法访问您的个人信息[...] 我可以提供一些一般性指导"
==============
2023年12月12日,门洛帕克的气温是多少?
==============
很抱歉,作为一个人工智能助手,我无法预测未来的具体日期和地点的天气情况。建议您查询当地的天气预报来获取相关信息。

==============
周六晚上我的晚餐预订是几点,我应该穿什么?
==============
很抱歉,作为一个人工智能助手,我无法获取您所在的具体时间和地点的信息,因此无法确切地告诉您周六晚上您的晚餐预订是几点。此外,由于我无法观察到您的具体场合和需求,所以无法为您提供合适的着装建议。

但是,一般来说,在晚餐预订的场合,您可以穿着得体、正式的服装,例如商务休闲装、正装、礼服等。根据餐厅的氛围和您与他人的约定,您还可以选择合适的鞋子、配饰等。建议您根据具体情况进行选择。

检索增强生成(RAG)是指在 prompt 中包含从外部数据库检索的信息(Lewis et al. (2020))。RAG 是将事实纳入 LLM 应用的有效方法,并且比微调更经济实惠,微调可能成本高昂并对基础模型的功能产生负面影响。

In [22]

MENLO_PARK_TEMPS = {
    "2023-12-11": "52华氏度",
    "2023-12-12": "51华氏度",
    "2023-12-13": "51华氏度",
}

def prompt_with_rag(retrieved_info, question):
    complete_and_print(
        f"给定以下信息:'{retrieved_info}',回答:'{question}'"
    )

def ask_for_temperature(day):
    temp_on_day = MENLO_PARK_TEMPS.get(day) or "未知温度"
    prompt_with_rag(
        f"门洛帕克在{day}的温度为{temp_on_day}'",  # 检索到的事实
        f"门洛帕克在{day}的温度是多少?",  # 用户问题
    )

ask_for_temperature("2023-12-12")
# "当然!2023年12月12日门洛帕克的温度为51华氏度。"

ask_for_temperature("2023-07-18")
# "根据提供的信息,我无法提供2023年7月18日门洛帕克的温度,因为信息显示温度未知。"
==============
给定以下信息:'门洛帕克在2023-12-12的温度为51华氏度'',回答:'门洛帕克在2023-12-12的温度是多少?'
==============
门洛帕克在2023-12-12的温度是51华氏度。

==============
给定以下信息:'门洛帕克在2023-07-18的温度为未知温度'',回答:'门洛帕克在2023-07-18的温度是多少?'
==============
很抱歉,根据提供的信息,无法确定门洛帕克在2023-07-18的温度。因为温度信息是未知的。

3.10 程序辅助语言模型

LLM 本质上不擅长执行计算,例如:

In [24]

complete_and_print("""
计算以下数学问题的答案:
((-5 + 93 * 4 - 0) * (4^4 + -7 + 0 * 5))
""")

# 给出类似于 92448、92648、95463 的错误答案
==============

计算以下数学问题的答案:
((-5 + 93 * 4 - 0) * (4^4 + -7 + 0 * 5))

==============
首先,我们需要按照运算顺序进行计算,即先进行括号内的运算,然后进行乘法和除法,最后进行加法和减法。

计算过程如下:

(-5 + 93 * 4 - 0) = (-5 + 372 - 0) = 367

(4^4 + -7 + 0 * 5) = (256 + -7 + 0 * 5) = 244

然后将两个结果相乘:

367 * 244 = 89988

所以,((-5 + 93 * 4 - 0) * (4^4 + -7 + 0 * 5)) 的答案是 89988。

Gao et al. (2022) 提出「程序辅助语言模型(Program-aided Language Models,PAL)」的概念。虽然 LLM 不擅长算术,但它们非常擅长代码生成。PAL 通过指示 LLM 编写代码来解决计算任务。

In [49]

def extract_code(text):  
    # 使用正则表达式匹配代码块
    # 默认python
    pattern = r'```python.*?\n(.*?)```'  
    matches = re.findall(pattern, text, re.DOTALL)  
    if matches:  
        # 如果匹配成功,返回第一个匹配到的代码块  
        return matches[0]  
    else:  
        # 如果匹配失败,返回空字符串  
        return "" 

input="""
    # Python code to calculate: ((-5 + 93 * 4 - 0) * (4^4 + -7 + 0 * 5))
    """
response, history = model.chat(tokenizer, input, history=[])
print(response)
exec(extract_code(response))
import math

result = ((-5 + 93 * 4 - 0) * (math.pow(4, 4) + -7 + 0 * 5))
print(result)

3.11 限制多余标记

一个常见的问题是输出时出现多余标记(例如,“当然!这是更多关于...的信息”)。

看看这个改进,它结合了一个角色、规则和限制、明确的说明以及一个例子:

In [30]

complete_and_print(
    "以JSON格式给出门洛帕克的邮政编码,字段为'zip_code'"
)
# 可能会返回JSON,还会返回“当然!这是JSON...”

complete_and_print(
    """
    你是一个只输出JSON的机器人。
    你以JSON格式回复,字段为'zip_code'。
    示例问题:帝国大厦的邮政编码是多少?示例答案:{'zip_code': 10118}
    现在我的问题是:门洛帕克的邮政编码是多少?
    """
)
# "{'zip_code': 94025}"
==============
以JSON格式给出门洛帕克的邮政编码,字段为'zip_code'
==============
'zip_code': '90210'

==============

    你是一个只输出JSON的机器人。
    你以JSON格式回复,字段为'zip_code'。
    示例问题:帝国大厦的邮政编码是多少?示例答案:{'zip_code': 10118}
    现在我的问题是:门洛帕克的邮政编码是多少?
    
==============
{'zip_code': 94101}
  • 16
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

军哥说AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值